Escolha o que quer construir. Cada caso vem em REST, Node e Python — e com um prompt pronto, se você preferir que um agente de código faça.
Receba PIX de clientes e liquide o valor em USDT numa carteira.
# 1. chave de teste — uma chamada
curl -X POST https://api.luniumpay.com/keys/sandbox -H 'Content-Type: application/json' \
-d '{"name":"meu-projeto"}'
# 2. cobrança PIX; o CPF/CNPJ do pagador é exigência do Banco Central
curl -X POST https://api.luniumpay.com/cashin/charge \
-H "X-API-Key: $LUNIUM_KEY" -H 'Content-Type: application/json' \
-d '{"amount_cents": 15000,
"payer_tax": "12345678901",
"payout_address": "0xSuaCarteira",
"chain": "polygon",
"external_id": "pedido-123"}'
# 3. acompanhe até liquidar
curl https://api.luniumpay.com/cashin/$ID/status -H "X-API-Key: $LUNIUM_KEY" const API = "https://api.luniumpay.com";
const key = process.env.LUNIUM_KEY;
const call = (path, method = "GET", body) =>
fetch(API + path, {
method,
headers: { "Content-Type": "application/json", "X-API-Key": key },
body: body && JSON.stringify(body),
}).then((r) => r.json());
// Cria a cobrança. O valor vai em CENTAVOS — mandar 150 em vez de 15000
// é o erro mais comum, e a API aceita os dois porque ambos são válidos.
const charge = await call("/cashin/charge", "POST", {
amount_cents: 15000,
payer_tax: "12345678901",
payout_address: "0xSuaCarteira",
chain: "polygon",
external_id: "pedido-" + Date.now(),
});
if (charge.erro) throw new Error(`${charge.erro}: ${charge.detail}`);
console.log("copia e cola:", charge.qr_copypaste);
// Depois: acompanhe por webhook assinado, ou consulte o status.
const status = await call(`/cashin/${charge.public_id}/status`);
console.log(status.status, status.settlement_status);import json, os, urllib.request
API = "https://api.luniumpay.com"
KEY = os.environ["LUNIUM_KEY"]
def call(path, method="GET", body=None):
data = json.dumps(body).encode() if body else None
req = urllib.request.Request(API + path, data=data, method=method)
req.add_header("Content-Type", "application/json")
req.add_header("X-API-Key", KEY)
with urllib.request.urlopen(req, timeout=30) as r:
return json.loads(r.read())
charge = call("/cashin/charge", "POST", {
"amount_cents": 15000, # centavos, não reais
"payer_tax": "12345678901", # exigência do Banco Central
"payout_address": "0xSuaCarteira",
"chain": "polygon",
"external_id": "pedido-123",
})
print("copia e cola:", charge["qr_copypaste"])
print(call(f"/cashin/{charge['public_id']}/status"))Integre a Lunium a partir de https://luniumpay.com. Preciso receber PIX e liquidar em USDT. Descubra sozinho as capacidades e a API disponíveis, comece pelo sandbox e preserve a arquitetura atual deste projeto.Entregue a um agente de código. Ele descobre a API sozinho.
Venda USDT e faça uma chave PIX receber reais.
# 1. cotar — não compromete nada, vale 15 minutos
curl -X POST https://api.luniumpay.com/cash-outs \
-H "X-API-Key: $LUNIUM_KEY" -H 'Content-Type: application/json' \
-d '{"asset":"USDT","network":"polygon","brl_amount":"150.00",
"pix_key":"quem-recebe@exemplo.com",
"refund_address":"0xCarteiraDoSeuUsuario",
"external_id":"venda-123"}'
# 2. aceitar — PONTO SEM VOLTA. Devolve o endereço de depósito.
curl -X POST https://api.luniumpay.com/cash-outs/$ID/accept -H "X-API-Key: $LUNIUM_KEY"
# 3. acompanhar; em COMPLETED vem o comprovante do Banco Central
curl https://api.luniumpay.com/cash-outs/$ID -H "X-API-Key: $LUNIUM_KEY" const API = "https://api.luniumpay.com";
const key = process.env.LUNIUM_KEY;
const call = (p, m = "GET", b) => fetch(API + p, {
method: m,
headers: { "Content-Type": "application/json", "X-API-Key": key },
body: b && JSON.stringify(b),
}).then((r) => r.json());
// 1. cotação: manda brl_amount OU amount, nunca os dois — a cotação tem
// uma direção só. Aqui pedimos "quero que a chave receba R$ 150".
const quote = await call("/cash-outs", "POST", {
asset: "USDT", network: "polygon", brl_amount: "150.00",
pix_key: "quem-recebe@exemplo.com",
// para onde a cripto volta se o PIX não puder ser pago. Sem isso, ela
// voltaria para a origem on-chain — que é a exchange, se o usuário sacou de uma.
refund_address: "0xCarteiraDoSeuUsuario",
external_id: "venda-" + Date.now(),
});
if (quote.erro) throw new Error(`${quote.erro}: ${quote.detail}`);
console.log(`envie ${quote.amount} USDT → R$ ${quote.brl_amount}`);
// 2. aceitar trava a cotação e devolve o endereço. Depois disso não volta atrás.
const accepted = await call(`/cash-outs/${quote.cashout_id}/accept`, "POST", {});
console.log("depositar em:", accepted.deposit_address);
// 3. em COMPLETED: pix_e2e, receipt_url e verify_url
const done = await call(`/cash-outs/${quote.cashout_id}`);
console.log(done.state, done.pix_e2e ?? "");import json, os, urllib.request
API = "https://api.luniumpay.com"
KEY = os.environ["LUNIUM_KEY"]
def call(path, method="GET", body=None):
data = json.dumps(body).encode() if body else None
req = urllib.request.Request(API + path, data=data, method=method)
req.add_header("Content-Type", "application/json")
req.add_header("X-API-Key", KEY)
with urllib.request.urlopen(req, timeout=30) as r:
return json.loads(r.read())
quote = call("/cash-outs", "POST", {
"asset": "USDT", "network": "polygon",
"brl_amount": "150.00", # ou "amount", nunca os dois
"pix_key": "quem-recebe@exemplo.com",
"refund_address": "0xCarteiraDoSeuUsuario",
"external_id": "venda-123",
})
print(f"envie {quote['amount']} USDT -> R$ {quote['brl_amount']}")
# ponto sem volta
aceita = call(f"/cash-outs/{quote['cashout_id']}/accept", "POST", {})
print("depositar em:", aceita["deposit_address"])
final = call(f"/cash-outs/{quote['cashout_id']}")
print(final["state"], final.get("pix_e2e", ""))Integre a Lunium a partir de https://luniumpay.com. Preciso converter USDT em BRL via PIX. Descubra sozinho a API, comece pelo sandbox e preserve a arquitetura atual deste projeto.Entregue a um agente de código. Ele descobre a API sozinho.
Confirme que um PIX liquidou antes de liberar mercadoria, crédito ou acesso. Não exige chave.
# Sem chave, de propósito: serve para conferir um pagamento que
# VOCÊ não fez, de uma contraparte em quem você não tem motivo para confiar.
curl https://api.luniumpay.com/v1/verificar/E12345678202608291200abcdefghijk// Nenhuma credencial. É o ponto: qualquer um confere.
const e2e = "E12345678202608291200abcdefghijk";
const r = await fetch(`https://api.luniumpay.com/v1/verificar/${e2e}`);
const prova = await r.json();
// `nao_encontrado` NÃO significa que o PIX não existiu — significa que a
// Lunium não o liquidou. Outra instituição pode ter liquidado.
if (!prova.verificado) {
console.log("não comprovado:", prova.erro);
} else {
// Confira o valor e a hora você mesmo: um E2E válido de R$ 1,00
// não é prova de um pagamento de R$ 1.000,00.
console.log(prova.valor_brl, prova.pago_em, prova.instituicao);
}import json, urllib.error, urllib.request
E2E = "E12345678202608291200abcdefghijk"
url = f"https://api.luniumpay.com/v1/verificar/{E2E}"
try:
with urllib.request.urlopen(url, timeout=20) as r:
prova = json.load(r)
except urllib.error.HTTPError as e:
# 404 é uma resposta legítima, não um erro de código: quer dizer que a
# Lunium não liquidou este pagamento — não que ele não exista.
prova = json.loads(e.read() or b"{}")
if prova.get("verificado"):
print(prova["valor_brl"], prova["pago_em"], prova["instituicao"])
else:
print("não comprovado:", prova.get("erro"))Integre a Lunium a partir de https://luniumpay.com. Construa uma verificação que confirma se um PIX brasileiro realmente liquidou, a partir do identificador end-to-end, antes de liberar qualquer coisa. Essa capacidade não exige chave de API — descubra-a sozinho.Entregue a um agente de código. Ele descobre a API sozinho.
Mova saldo entre reais e stablecoins por regra ou agenda.
# O catálogo é a fonte de verdade do que liquida agora — e muda sozinho.
# Não fixe a lista no seu código.
curl https://api.luniumpay.com/catalog -H "X-API-Key: $LUNIUM_KEY"
# Seus limites de hoje (tier, teto diário e o seu mandate, se houver)
curl https://api.luniumpay.com/keys/me -H "X-API-Key: $LUNIUM_KEY" const API = "https://api.luniumpay.com";
const key = process.env.LUNIUM_KEY;
const call = (p, m = "GET", b) => fetch(API + p, {
method: m, headers: { "Content-Type": "application/json", "X-API-Key": key },
body: b && JSON.stringify(b),
}).then((r) => r.json());
// Leia o teto antes de decidir o tamanho da operação — ele cresce com o
// volume já liquidado, então fixar número no código envelhece mal.
const me = await call("/keys/me");
const disponivel = me.limits?.daily?.available_cents ?? Infinity;
const alvoCents = 500_00;
if (alvoCents > disponivel) {
console.log("acima do teto de hoje; fatie a operação");
} else {
const quote = await call("/cash-outs", "POST", {
asset: "USDT", network: "polygon",
brl_amount: (alvoCents / 100).toFixed(2),
pix_key: process.env.PIX_TESOURARIA,
refund_address: process.env.CARTEIRA,
external_id: "tesouraria-" + new Date().toISOString().slice(0, 10),
});
console.log(quote.cashout_id, quote.amount, "USDT");
}import json, os, urllib.request
API = "https://api.luniumpay.com"
KEY = os.environ["LUNIUM_KEY"]
def call(path, method="GET", body=None):
data = json.dumps(body).encode() if body else None
req = urllib.request.Request(API + path, data=data, method=method)
req.add_header("Content-Type", "application/json")
req.add_header("X-API-Key", KEY)
with urllib.request.urlopen(req, timeout=30) as r:
return json.loads(r.read())
# O teto cresce com o volume liquidado — leia, não presuma.
me = call("/keys/me")
print("tier:", me["limits"]["tier"])
quote = call("/cash-outs", "POST", {
"asset": "USDT", "network": "polygon", "brl_amount": "500.00",
"pix_key": os.environ["PIX_TESOURARIA"],
"refund_address": os.environ["CARTEIRA"],
"external_id": "tesouraria-2026-08-29",
})
print(quote["cashout_id"], quote["amount"], "USDT")Integre a Lunium a partir de https://luniumpay.com. Construa um agente de tesouraria que move saldo entre BRL via PIX e USDT conforme uma regra. Descubra sozinho a API e comece pelo sandbox.Entregue a um agente de código. Ele descobre a API sozinho.
Deixe software autônomo pagar no Brasil, dentro de uma política de gastos que ele mesmo define.
# 1. o agente se cadastra e já recebe credencial de teste
curl -X POST https://api.luniumpay.com/mesh/agents -H 'Content-Type: application/json' \
-d '{"name":"meu-agente","contact":"eu@exemplo.com",
"capabilities":["usdt_to_pix"]}'
# 2. a política que ele se impõe. Ela SÓ APERTA os limites da chave,
# nunca amplia — por isso ele mesmo pode defini-la.
curl -X POST https://api.luniumpay.com/mesh/agents/$AGENT_ID/mandate \
-H "X-API-Key: $LUNIUM_KEY" -H 'Content-Type: application/json' \
-d '{"max_por_operacao_cents": 30000, "max_diario_cents": 200000}'const API = "https://api.luniumpay.com";
// 1. cadastro: devolve agent_id e a credencial de teste na mesma resposta
const reg = await fetch(`${API}/mesh/agents`, {
method: "POST", headers: { "Content-Type": "application/json" },
body: JSON.stringify({
name: "meu-agente", contact: "eu@exemplo.com",
capabilities: ["usdt_to_pix"],
}),
}).then((r) => r.json());
const { agent_id } = reg.agent;
const key = reg.api_key; // aparece uma vez só
// 2. a política de gastos do próprio agente
await fetch(`${API}/mesh/agents/${agent_id}/mandate`, {
method: "POST",
headers: { "Content-Type": "application/json", "X-API-Key": key },
body: JSON.stringify({
max_por_operacao_cents: 30_000, // R$ 300 por operação
max_diario_cents: 200_000, // R$ 2.000 por dia
}),
});
// A partir daqui, uma ordem acima do teto é recusada com
// `mandate_valor_acima_do_teto` — pela política dele, não pela nossa.import json, urllib.request
API = "https://api.luniumpay.com"
def post(path, body, key=None):
req = urllib.request.Request(API + path, data=json.dumps(body).encode(), method="POST")
req.add_header("Content-Type", "application/json")
if key:
req.add_header("X-API-Key", key)
with urllib.request.urlopen(req, timeout=30) as r:
return json.loads(r.read())
reg = post("/mesh/agents", {
"name": "meu-agente", "contact": "eu@exemplo.com",
"capabilities": ["usdt_to_pix"],
})
agent_id, key = reg["agent"]["agent_id"], reg["api_key"]
# O mandate só APERTA os limites — o pior que ele faz é limitar você mesmo.
post(f"/mesh/agents/{agent_id}/mandate", {
"max_por_operacao_cents": 30000,
"max_diario_cents": 200000,
}, key=key)
print("agente", agent_id, "com política própria")Integre a Lunium a partir de https://luniumpay.com. Construa um agente que paga uma chave PIX usando stablecoins, com teto por operação e teto diário que ele mesmo configura. Descubra sozinho a API e comece pelo sandbox.Entregue a um agente de código. Ele descobre a API sozinho.
Dê aos usuários da carteira depósito e saque por PIX contra USDT ou USDC.
# depósito: PIX entra, USDT vai para a carteira do usuário
curl -X POST https://api.luniumpay.com/cashin/charge -H "X-API-Key: $LUNIUM_KEY" \
-H 'Content-Type: application/json' \
-d '{"amount_cents":10000,"payer_tax":"$CPF_DO_USUARIO",
"payout_address":"$CARTEIRA_DO_USUARIO","chain":"polygon",
"external_id":"deposito-$UID"}'
# saque: USDT sai da carteira, reais caem na chave PIX dele
curl -X POST https://api.luniumpay.com/cash-outs -H "X-API-Key: $LUNIUM_KEY" \
-H 'Content-Type: application/json' \
-d '{"asset":"USDT","network":"polygon","brl_amount":"100.00",
"pix_key":"$CHAVE_PIX_DO_USUARIO","pix_key_type":"cpf",
"refund_address":"$CARTEIRA_DO_USUARIO","external_id":"saque-$UID"}'const API = "https://api.luniumpay.com";
const key = process.env.LUNIUM_KEY;
const call = (p, m = "GET", b) => fetch(API + p, {
method: m, headers: { "Content-Type": "application/json", "X-API-Key": key },
body: b && JSON.stringify(b),
}).then((r) => r.json());
// DEPÓSITO — o usuário paga um PIX, a carteira dele recebe USDT
export async function depositar(usuario, centavos) {
return call("/cashin/charge", "POST", {
amount_cents: centavos,
payer_tax: usuario.cpf, // exigência do Banco Central
payout_address: usuario.carteira,
chain: "polygon",
external_id: `dep-${usuario.id}-${Date.now()}`,
});
}
// SAQUE — o usuário manda USDT, a chave PIX dele recebe reais
export async function sacar(usuario, reais) {
const q = await call("/cash-outs", "POST", {
asset: "USDT", network: "polygon", brl_amount: reais.toFixed(2),
pix_key: usuario.chavePix,
// pix_key_type só é obrigatório quando a chave tem 11 dígitos puros:
// CPF e telefone têm o mesmo tamanho e não dá para adivinhar.
pix_key_type: usuario.tipoChave,
refund_address: usuario.carteira,
external_id: `saq-${usuario.id}-${Date.now()}`,
});
return call(`/cash-outs/${q.cashout_id}/accept`, "POST", {});
}import json, os, urllib.request
API = "https://api.luniumpay.com"
KEY = os.environ["LUNIUM_KEY"]
def call(path, method="GET", body=None):
data = json.dumps(body).encode() if body else None
req = urllib.request.Request(API + path, data=data, method=method)
req.add_header("Content-Type", "application/json")
req.add_header("X-API-Key", KEY)
with urllib.request.urlopen(req, timeout=30) as r:
return json.loads(r.read())
def depositar(usuario, centavos):
"""PIX entra, USDT vai para a carteira do usuário."""
return call("/cashin/charge", "POST", {
"amount_cents": centavos,
"payer_tax": usuario["cpf"],
"payout_address": usuario["carteira"],
"chain": "polygon",
"external_id": f"dep-{usuario['id']}",
})
def sacar(usuario, reais):
"""USDT sai, reais caem na chave PIX dele."""
q = call("/cash-outs", "POST", {
"asset": "USDT", "network": "polygon",
"brl_amount": f"{reais:.2f}",
"pix_key": usuario["chave_pix"],
"pix_key_type": usuario["tipo_chave"], # obrigatório se forem 11 dígitos
"refund_address": usuario["carteira"],
"external_id": f"saq-{usuario['id']}",
})
return call(f"/cash-outs/{q['cashout_id']}/accept", "POST", {})Integre a Lunium a partir de https://luniumpay.com. Adicione depósito e saque por PIX a uma carteira cripto, liquidando em USDT. Descubra sozinho as capacidades e os campos obrigatórios, e comece pelo sandbox.Entregue a um agente de código. Ele descobre a API sozinho.
# o catálogo inteiro, sem credencial
curl https://api.luniumpay.com/mesh
# chave de teste, uma chamada
curl -X POST https://api.luniumpay.com/keys/sandbox
O sandbox roda o fluxo inteiro sem mover um centavo, e as duas primeiras casas decimais do valor escolhem o desfecho — dá para exercitar os caminhos de erro em CI, em vez de descobri-los em produção.