Documentação

Documentação da API

Integre pagamentos PIX à sua aplicação com a API da SyntraPay. Cobranças, links de checkout prontos para vender, saques, consulta de saldo, webhooks e monitoramento de infrações MED, tudo via REST.

URL base
https://api.syntrapay.com.br

Todos os valores monetários são inteiros em centavos (ex.: 1490 = R$ 14,90). As respostas usam JSON.

02 / Começando

Autenticação

Autentique cada requisição enviando sua chave de API no header Authorization, sem o prefixo Bearer. Gere e gerencie suas chaves no painel em Integrações → Credenciais.
Authorization: sk_live_sua_chave_aqui

Exemplo: primeira cobrança

curl -X POST https://api.syntrapay.com.br/transactions \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json" \
  -d '{ "amount": 1490 }'

03 / Começando

Escopos

Cada chave de API possui escopos que definem quais ações ela pode executar. Selecione os escopos ao criar a chave e conceda apenas o necessário.
payments.create
Criar cobranças PIX.
payments.read
Consultar cobranças e transações.
transfers.read
Consultar transferências.
withdrawals.create
Criar saques PIX e transferências internas, e cotar o saque em USDT.
withdrawals.crypto
Sacar em cripto (USDT). Usado junto com withdrawals.create e só vale em chave com lista de IPs permitidos.
withdrawals.read
Consultar saques.
webhooks.manage
Gerenciar webhooks.
links.read
Consultar links de pagamento, métricas e checkouts.
links.manage
Criar, editar, duplicar, apagar e restaurar links de pagamento.
Novo · integração assistida por IA

Implementar com IA

Deixe a IA escrever a integração pra você. Escolha o que quer fazer e a linguagem: geramos um prompt com todo o contexto da API já embutido (endpoints, parâmetros, exemplos e regras). Copie e cole no seu assistente, ou abra direto no ChatGPT ou Claude.
01

Escolha a tarefa

Selecione o que quer construir e a sua linguagem.

02

Copie o prompt

Já vem com todo o contexto da API. Ou abra direto no ChatGPT/Claude.

03

Cole e rode

A IA devolve o código pronto. Ajuste sua chave e publique.

Gerador de prompt

O que você quer fazer?

Linguagem

Você é um engenheiro de software sênior. Implemente uma integração com a API de pagamentos PIX da SyntraPay em Node.js (use o fetch nativo; se for API do Next.js, use Route Handlers em app/api).

OBJETIVO: criar uma cobrança PIX e mostrar o QR Code e o código copia-e-cola para o pagador.

CONTEXTO DA API:
- Base URL: https://api.syntrapay.com.br
- Autenticação: envie a chave no header "Authorization: sk_live_sua_chave_aqui" (SEM o prefixo Bearer).
- Todos os valores monetários são inteiros em centavos (ex.: 1490 = R$ 14,90).
- Requisições e respostas em JSON.

ENDPOINTS ENVOLVIDOS:
### Criar cobrança: POST /transactions
Cria uma cobrança PIX e retorna o QR Code (base64) e o código copia-e-cola para o pagador. O valor é sempre em centavos.
Escopo necessário: payments.create
Parâmetros:
    - amount (integer, obrigatório, em body): Valor em centavos (mín. 100 = R$ 1,00). Ex.: 1490 = R$ 14,90.
    - webhook (string, em body): URL para notificar quando o pagamento for aprovado (sobrescreve o webhook global desta cobrança).
    - split_email (string, em body): E-mail de outra conta SyntraPay para dividir o valor (split).
    - split_tax (integer, em body): Percentual destinado ao parceiro no split (1 a 99, padrão 50).
    - customer (object, em body): Dados do pagador para rastreio (name, document). Opcional.
    - products (array, em body): Itens da venda, usados por integrações de tracking (ex.: Utmify).
    - trackingParameters (object, em body): UTMs da campanha (utm_source, utm_medium, etc.).
    - Idempotency-Key (string, em header): Chave única sua para evitar cobranças duplicadas em reenvios. A resposta é repetida por 24h para a mesma chave.
Exemplo de corpo: {"amount":1490}
Resposta 201 Created:
{
  "message": "Transaction created successfully",
  "status": "pending",
  "id": "9c1e7b2a-3f4d-4a8b-bc12-5e6f7a8b9c0d",
  "amount": 1490,
  "qrCodeBase64": "data:image/png;base64,iVBORw0KGgoAAA...",
  "copyPaste": "00020126580014br.gov.bcb.pix...6304ABCD",
  "expiresAt": "2026-07-18T15:30:00.000Z",
  "fee": 44,
  "storeId": "usr_a1b2c3"
}

REQUISITOS:
- Código pronto para produção, organizado e comentado em português.
- Trate erros pelo envelope { status, code, message } e pelos códigos HTTP retornados.
- Em requisições POST, envie um header "Idempotency-Key" único para evitar duplicidade em reenvios.
- Leia a chave de API de uma variável de ambiente (nunca deixe hardcoded).
- Ao final, mostre um exemplo de uso.

Se faltar alguma informação, me pergunte antes de assumir.

Contexto completo da API

Prefere entregar tudo de uma vez? Copie a referência inteira (auth, endpoints, exemplos, webhooks e erros) e cole no seu assistente ou agente de IA. Depois é só pedir qualquer integração, que ele já tem o contexto.

Funciona com ChatGPT, Claude, Cursor, GitHub Copilot, Windsurf e qualquer LLM que aceite contexto colado.

05 / Referência da API

Cobranças (PIX)

Crie e consulte cobranças PIX. Todos os valores são inteiros em centavos (ex.: 1490 = R$ 14,90).
POST/transactionsEscopo: payments.create

Criar cobrança

Cria uma cobrança PIX e retorna o QR Code (base64) e o código copia-e-cola para o pagador. O valor é sempre em centavos.

Parâmetros

amountbodyobrigatório
integer: Valor em centavos (mín. 100 = R$ 1,00). Ex.: 1490 = R$ 14,90.
webhookbody
string: URL para notificar quando o pagamento for aprovado (sobrescreve o webhook global desta cobrança).
split_emailbody
string: E-mail de outra conta SyntraPay para dividir o valor (split).
split_taxbody
integer: Percentual destinado ao parceiro no split (1 a 99, padrão 50).
customerbody
object: Dados do pagador para rastreio (name, document). Opcional.
productsbody
array: Itens da venda, usados por integrações de tracking (ex.: Utmify).
trackingParametersbody
object: UTMs da campanha (utm_source, utm_medium, etc.).
Idempotency-Keyheader
string: Chave única sua para evitar cobranças duplicadas em reenvios. A resposta é repetida por 24h para a mesma chave.

Campos da resposta

id
string: Identificador único da cobrança.
status
string: Status inicial (pending).
amount
integer: Valor da cobrança em centavos.
qrCodeBase64
string: Imagem do QR Code em data URI (base64).
copyPaste
string: Código PIX copia-e-cola.
expiresAt
string: Data/hora de expiração (ISO 8601).
fee
integer: Taxa aplicada em centavos.
storeId
string: Identificador da sua conta.

Requisição

curl -X POST "https://api.syntrapay.com.br/transactions" \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json" \
  -d '{"amount":1490}'

Resposta

201 Created
{
  "message": "Transaction created successfully",
  "status": "pending",
  "id": "9c1e7b2a-3f4d-4a8b-bc12-5e6f7a8b9c0d",
  "amount": 1490,
  "qrCodeBase64": "data:image/png;base64,iVBORw0KGgoAAA...",
  "copyPaste": "00020126580014br.gov.bcb.pix...6304ABCD",
  "expiresAt": "2026-07-18T15:30:00.000Z",
  "fee": 44,
  "storeId": "usr_a1b2c3"
}
400 Bad Request
{
  "status": "error",
  "code": "BAD_REQUEST",
  "message": "400: Amount must be at least 100 cents (R$ 1,00)"
}
GET/transactions/:idEscopo: payments.read

Consultar cobrança

Consulta os detalhes e o status atual de uma cobrança pelo seu ID. Ao fazer polling do status, use nocache=1 para ler sempre direto do banco.

Parâmetros

idpathobrigatório
string: ID da transação retornado na criação.
nocachequery
string: Defina como 1 para ignorar o cache (útil em polling de status).

Campos da resposta

id
string: Identificador da cobrança.
status
string: PENDING, PAID, FAILED, CANCELED ou EXPIRED.
amount
integer: Valor em centavos.
fee
integer: Taxa em centavos.
payer
object: Dados do pagador ({ name, document }).
paidAt
string: Data/hora do pagamento (ISO) ou null.

Requisição

curl -X GET "https://api.syntrapay.com.br/transactions/9c1e7b2a-3f4d-4a8b-bc12-5e6f7a8b9c0d" \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json"

Resposta

200 OK
{
  "id": "9c1e7b2a-3f4d-4a8b-bc12-5e6f7a8b9c0d",
  "status": "PAID",
  "type": "DEPOSIT",
  "reason": "PIX_PAYMENT",
  "amount": 1490,
  "fee": 44,
  "payer": { "name": "João da Silva", "document": "***.456.789-**" },
  "storeId": "usr_a1b2c3",
  "createdAt": "2026-07-18T14:30:00.000Z",
  "paidAt": "2026-07-18T14:31:12.000Z"
}
404 Not Found
{
  "status": "error",
  "code": "NOT_FOUND",
  "message": "404: Not Found - Transaction not found"
}
GET/transactionsEscopo: payments.read

Listar transações

Lista as transações da sua conta (cobranças e saques), com paginação e filtros opcionais.

Parâmetros

startquery
integer: Posição inicial (paginação). Padrão 1.
limitquery
integer: Itens por página. Padrão 50.
statusquery
string: Filtra por status (ex.: PENDING, PAID).
typequery
string: Filtra por tipo (DEPOSIT, WITHDRAWAL).
searchquery
string: Busca por ID ou nome do pagador.

Requisição

curl -X GET "https://api.syntrapay.com.br/transactions?limit=50&status=PAID" \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json"

Resposta

200 OK
{
  "status": "success",
  "total": 128,
  "start": 1,
  "limit": 50,
  "count": 50,
  "transactions": [
    {
      "id": "9c1e7b2a-3f4d-4a8b-bc12-5e6f7a8b9c0d",
      "status": "PAID",
      "type": "DEPOSIT",
      "amount": 1490,
      "fee": 44,
      "createdAt": "2026-07-18T14:30:00.000Z"
    }
  ]
}

06 / Referência da API

Checkout (links de pagamento)

Crie links de pagamento por API e receba sem escrever uma linha de front-end. Cada link vira uma página de checkout hospedada por nós, com o preço, as ofertas adicionais, a aparência e as regras que você definir. O preço vive no link: o comprador nunca envia valor.
01

Você cria o link

POST /payment-links com o título e o preço. A resposta traz o checkoutUrl.

02

O cliente paga

Ele abre a URL, preenche os dados e paga por PIX na página hospedada por nós.

03

Você é avisado

O saldo é creditado e o webhook payment.approved dispara com os dados da venda.

Endereço do checkout

https://pay.syntrapay.com.br/<publicId>
https://pay.syntrapay.com.br/<publicId>/<slug>

O publicId é a identidade do link e nunca muda: use sempre o checkoutUrl devolvido pela API. O slug é apenas decorativo, pode ser alterado ou removido a qualquer momento, e os endereços já divulgados continuam abrindo.

Regras do checkout

  • O preço vive no link, nunca na requisição do comprador: não existe forma de pagar um valor diferente do configurado.
  • Criação é deduplicada: a mesma configuração enviada de novo em até 24 horas devolve o link existente (HTTP 200, deduplicated: true) em vez de criar outro. Para forçar um segundo link igual, envie allowDuplicate: true.
  • O checkout também deduplica: o mesmo comprador pedindo a mesma cotação (mesmo valor, quantidade e ofertas) reaproveita a cotação aberta, então ele nunca fica com dois PIX para a mesma compra.
  • Valor mínimo de R$ 1,00 por cobrança. O teto é o limite por depósito da sua conta, aplicado no momento do pagamento (se o limite mudar, os links já criados passam a respeitar o novo valor).
  • Até 200 links não arquivados por conta e até 3 ofertas adicionais por link.
  • O corpo da requisição é limitado a 64 KB. Escritas: 30 por minuto por conta; leituras: 120 por minuto.
  • A conta precisa estar ativada para criar ou duplicar links.
  • Chaves de API criadas antes destes escopos não os possuem: marque links.read e links.manage em Integrações → Credenciais, ou gere uma chave nova.
  • Imagens, vídeos e redirecionamentos passam por validação de segurança: use URLs públicas e https.

Objeto do link: campos aninhados

Todos são opcionais na criação e na edição, e cada um tem um padrão pronto para vender. Na edição, o que você não enviar permanece como está.

appearance: aparência do checkout
theme
string: "light" ou "dark". Padrão: light.
primaryColor
string: Cor dos botões e destaques no formato #RRGGBB. Padrão: #6D3BF5.
buttonText
string: Texto do botão de pagamento, até 40 caracteres. Padrão: "Pagar agora".
summaryPosition
string: "above" ou "below": resumo do pedido acima ou abaixo dos dados do comprador.
showSteps
boolean: Exibe as etapas Dados › Pagamento › Entrega. Padrão: true.
funnel: prova social
showOnlineCounter
boolean: Exibe o contador de pessoas vendo a oferta agora.
onlineCounterMin
integer: Piso do contador (1 a 999). Padrão: 12.
onlineCounterMax
integer: Teto do contador (1 a 999, nunca menor que o piso). Padrão: 78.
showCompanyWatermark
boolean: Exibe a assinatura da SyntraPay no rodapé. Padrão: true.
showSecurityBadge
boolean: Exibe o selo de compra segura. Padrão: true.
media: vídeo e banner
videoUrl
string: Endereço do vídeo no YouTube ou no Vimeo. Envie null para remover.
videoProvider
string: Somente leitura: "youtube" ou "vimeo", detectado por nós.
videoEmbedUrl
string: Somente leitura: URL de incorporação que geramos a partir do vídeo enviado.
bannerUrl
string: Banner do topo do checkout (https). Recomendado 1200x300.
socialProof: barra de prova social
imageUrl
string: Imagem da barra (https), normalmente prints de depoimentos.
showOnCheckout
boolean: Exibe a barra na tela de checkout.
showOnPaymentTop
boolean: Exibe a barra no topo da tela de pagamento PIX.
countdown: contador regressivo
enabled
boolean: Liga o contador no topo do checkout.
minutes
integer: Duração em minutos (1 a 1440). Padrão: 15.
bgColor
string: Cor de fundo em #RRGGBB. Padrão: #111827.
textColor
string: Cor do texto em #RRGGBB. Padrão: #FFFFFF.
textAbove
string: Texto acima do relógio, até 80 caracteres.
textBelow
string: Texto abaixo do relógio, até 80 caracteres.
expiredText
string: Texto exibido quando o tempo acaba, até 80 caracteres.
pixScreen: tela de pagamento PIX
showGuarantee
boolean: Exibe o selo de garantia.
guaranteeDays
integer: Dias de garantia (1 a 365). Padrão: 7.
showTimer
boolean: Exibe o cronômetro de validade do PIX. Padrão: true.
timerMinutes
integer: Minutos exibidos no cronômetro (1 a 1440). Padrão: 15.
fields: dados pedidos ao comprador
name
object: { visible, required }: nome do comprador.
email
object: Sempre visível e obrigatório. O cadastro do cliente e o e-mail de confirmação dependem dele, então o que for enviado aqui é ignorado.
phone
object: { visible, required }: telefone.
document
object: { visible, required }: CPF ou CNPJ.
postPayment: depois do pagamento
redirectUrl
string: Para onde levar o comprador após pagar (https obrigatório). Só é entregue depois que o pagamento é confirmado.
thankYouMessage
string: Mensagem da tela de obrigado, até 500 caracteres.
sendCustomerEmail
boolean: Envia o e-mail de confirmação da compra ao comprador. Padrão: true.
orderBumps[]: ofertas adicionais (máximo 3)
id
string: Gerado por nós (bmp_…). Reenvie o id existente ao editar para preservar a oferta; um id desconhecido vira uma oferta nova.
title
string: Obrigatório. Até 80 caracteres.
description
string: Até 300 caracteres.
imageUrl
string: Imagem da oferta (https).
priceCents
integer: Preço em centavos, mínimo 100. O teto é o limite por depósito da conta.
active
boolean: Se a oferta aparece no checkout. Padrão: true.

Venda pelo checkout no webhook

Uma venda feita por link dispara o mesmo evento payment.approved de qualquer cobrança, com dois campos a mais: origin igual a CHECKOUT_LINK e o objeto checkout, que diz qual link vendeu, o que foi comprado e quais ofertas adicionais entraram.

{
  "id": "9c1e7b2a-3f4d-4a8b-bc12-5e6f7a8b9c0d",
  "status": "PAID",
  "amount": 24600,
  "origin": "CHECKOUT_LINK",
  "checkout": {
    "paymentLinkId": "plk_7f3a91c25be04d18a6c3e07b",
    "checkoutSessionId": "chs_5b2e91a7c40d38f6",
    "customerId": "cus_3f81ba07d259",
    "publicId": "k7m2p9qx",
    "slug": "curso-completo",
    "priceMode": "fixed",
    "quantity": 1,
    "unitPriceCents": 19700,
    "baseCents": 19700,
    "bumps": [{ "id": "bmp_9c41ab7d02e5", "title": "Mentoria em grupo", "priceCents": 4900 }],
    "bumpsTotalCents": 4900
  }
}

07 / Referência da API

Saques (PIX)

Envie saques PIX e consulte o histórico. Aceita CPF, CNPJ, e-mail, telefone, chave aleatória (EVP) ou copia-e-cola.
POST/withdrawalsEscopo: withdrawals.create

Criar saque

Realiza um saque via PIX para uma chave. O valor é em centavos e é descontado do seu saldo disponível junto com a taxa.

Parâmetros

pixKeybodyobrigatório
string: Chave de destino: CPF, CNPJ, e-mail, telefone, EVP ou copia-e-cola.
amountbodyobrigatório
integer: Valor em centavos (mín. 100 = R$ 1,00). Opcional só quando o copia-e-cola já traz o valor.
descriptionbody
string: Descrição que aparece para o recebedor.
webhookbody
string: URL para notificar quando o saque mudar de status.
Idempotency-Keyheader
string: Chave única sua para evitar saques duplicados em reenvios. A resposta é repetida por 24h para a mesma chave.

Campos da resposta

id
string: Identificador do saque.
status
string: Status inicial (pending).
amount
integer: Valor em centavos.
pixKey
string: Chave PIX de destino.
pixKeyType
string: Tipo detectado: CPF, CNPJ, EMAIL, TELEFONE, CHAVE_ALEATORIA ou COPIA_E_COLA.
fee
integer: Taxa do saque em centavos.

Requisição

curl -X POST "https://api.syntrapay.com.br/withdrawals" \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json" \
  -d '{"pixKey":"cliente@email.com","amount":5000}'

Resposta

201 Created
{
  "message": "Withdraw request created successfully",
  "status": "pending",
  "id": "f1e2d3c4-b5a6-4789-9c0d-1a2b3c4d5e6f",
  "amount": 5000,
  "pixKey": "cliente@email.com",
  "pixKeyType": "EMAIL",
  "fee": 250
}
400 Bad Request
{
  "status": "error",
  "code": "INSUFFICIENT_FUNDS",
  "message": "400: Saldo insuficiente para realizar o saque"
}
GET/withdrawalsEscopo: withdrawals.read

Listar saques

Lista os saques da sua conta, com paginação.

Parâmetros

startquery
integer: Posição inicial (paginação). Padrão 1.
limitquery
integer: Itens por página. Padrão 50.

Requisição

curl -X GET "https://api.syntrapay.com.br/withdrawals" \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json"

Resposta

200 OK
{
  "status": "success",
  "total": 12,
  "start": 1,
  "limit": 50,
  "count": 12,
  "withdrawals": [
    {
      "id": "f1e2d3c4-b5a6-4789-9c0d-1a2b3c4d5e6f",
      "type": "WITHDRAWAL",
      "status": "PAID",
      "amount": 5000,
      "fee": 250,
      "payer": { "pixKey": "cliente@email.com", "pixKeyType": "EMAIL" },
      "end_to_end": "E12345678202607181430...",
      "createdAt": "2026-07-18T14:30:00.000Z",
      "paidAt": "2026-07-18T14:30:20.000Z"
    }
  ]
}
GET/withdrawals/:idEscopo: withdrawals.read

Consultar saque

Consulta os detalhes e o status de um saque pelo seu ID.

Parâmetros

idpathobrigatório
string: ID do saque retornado na criação.

Campos da resposta

id
string: Identificador do saque.
status
string: PENDING, PAID, FAILED, CANCELED ou EXPIRED.
amount
integer: Valor em centavos.
taxes
integer: Taxa cobrada em centavos.
pixKey
string: Chave PIX de destino.
pixKeyType
string: Tipo da chave.
receiver
object: Dados do recebedor ({ name, document }).
paidAt
string: Data/hora da liquidação (ISO) ou null.

Requisição

curl -X GET "https://api.syntrapay.com.br/withdrawals/f1e2d3c4-b5a6-4789-9c0d-1a2b3c4d5e6f" \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json"

Resposta

201 Created
{
  "id": "f1e2d3c4-b5a6-4789-9c0d-1a2b3c4d5e6f",
  "withdrawStatusId": "Successfull",
  "status": "PAID",
  "amount": 5000,
  "taxes": 250,
  "pixKey": "cliente@email.com",
  "pixKeyType": "EMAIL",
  "receiver": { "name": "Maria Souza", "document": "***.123.456-**" },
  "paidAt": "2026-07-18T14:30:20.000Z"
}
404 Not Found
{
  "status": "error",
  "code": "NOT_FOUND",
  "message": "404: Not Found - Withdrawal not found"
}

08 / Referência da API

Saques em cripto (USDT)

Converta saldo em USDT e envie para uma carteira na rede BNB Smart Chain (BEP-20). É a mesma rota do saque PIX: no lugar da pixKey, envie o objeto crypto com a carteira de destino.
01

Você cota

POST /withdrawals/crypto/quote com o valor. A resposta traz as taxas, o total debitado e o USDT estimado.

02

Você saca

POST /withdrawals com amount e crypto.wallet. O saldo é reservado e o saque entra na fila.

03

O USDT chega

Em segundos o status vira PAID e, logo depois, crypto.txHash traz o comprovante na blockchain.

Como o valor é calculado

totalDebit    = amount + ceil(amount × feePercent / 100) + networkFee
estimatedUSDT = amount / 100 / rateBRLPerUSD

Exemplo: amount 10000 (R$ 100,00), taxa 8%, rede R$ 3,00
totalDebit = 10000 + 800 + 300 = 11100 (R$ 111,00)

A taxa percentual e a taxa de rede da sua conta vêm sempre na cotação (quote.feePercent e quote.networkFee). Use esses valores em vez de fixar os números no seu código.

Regras do saque em cripto

  • Só a rede BNB Smart Chain (BEP-20) com o token USDT. Carteira de outra rede (TRC-20, ERC-20, Solana) não recebe e o valor se perde.
  • A transferência é irreversível. Confira o endereço: 42 caracteres começando com 0x.
  • Pela API: a chave precisa dos escopos withdrawals.create e withdrawals.crypto, e de uma lista de IPs permitidos. Chave sem IP fixo não saca em cripto: se ela vazar, ninguém saca de outro servidor.
  • Pelo painel: com a verificação em duas etapas (2FA) ativa, o código é pedido em todo saque, PIX ou cripto.
  • A cada saque em cripto o dono da conta recebe um e-mail com o valor, a carteira e o IP de origem.
  • O amount é o valor que vira cripto. A taxa percentual e a taxa de rede são somadas por cima, e o total (crypto.totalDebit) sai do saldo.
  • O valor em USDT é uma estimativa: a cotação é fechada na conversão. Use a cotação para mostrar o resumo antes de confirmar.
  • Mesma fila do saque PIX: um saque por vez por conta (PIX ou cripto), no máximo 2 pedidos em 5 segundos e os mesmos limites por saque e diário.
  • Se o saque falhar, o valor e as taxas voltam integralmente ao saldo e o webhook transfer-failed é disparado.
  • PAID quer dizer que o valor foi convertido e está a caminho da carteira. O comprovante (crypto.txHash) chega cerca de 30 segundos depois.
POST/withdrawals/crypto/quoteEscopo: withdrawals.create

Cotação do saque em USDT

Calcula quanto USDT será entregue para um valor em reais, já com as taxas da sua conta. Use antes de criar o saque para mostrar o resumo ao usuário, porque a cotação varia com o mercado. Não cria nada e não reserva saldo. Sem amount no corpo, devolve só a cotação e os limites, útil para montar o formulário.

Parâmetros

amountbody
integer: Valor em centavos que será convertido em USDT. Omita para receber só a cotação e os limites.

Campos da resposta

quote.rateBRLPerUSD
number: Cotação atual: quantos reais vale 1 USDT.
quote.feePercent
number: Taxa percentual cobrada sobre o valor convertido.
quote.networkFee
integer: Taxa de rede da BNB Smart Chain, em centavos.
breakdown
object: Resumo do valor informado: amount, platformFee, networkFee, totalFees, totalDebit e estimatedUSDT. null quando amount não é enviado.
breakdown.totalDebit
integer: Total que sai do seu saldo: valor + taxas.
breakdown.estimatedUSDT
number: USDT estimado na carteira de destino.
withinLimits
boolean: Se o amount está entre o mínimo e o máximo. null sem amount.
lowLiquidity
boolean: true quando a conversora está com pouco USDT e a entrega pode demorar mais.
limits
object: minAmount e maxAmount por saque, em centavos.
balance.maxAmount
integer: Maior valor que dá para converter com o saldo atual, já descontando as taxas. 0 se não alcança o mínimo.

Requisição

curl -X POST "https://api.syntrapay.com.br/withdrawals/crypto/quote" \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json" \
  -d '{"amount":10000}'

Resposta

200 OK
{
  "status": "success",
  "quote": {
    "rateBRLPerUSD": 5.244,
    "network": "bsc",
    "networkLabel": "BNB Smart Chain (BEP-20)",
    "token": "USDT",
    "feePercent": 8,
    "networkFee": 300,
    "quotedAt": "2026-10-01T14:30:00.000Z"
  },
  "breakdown": {
    "amount": 10000,
    "platformFee": 800,
    "networkFee": 300,
    "totalFees": 1100,
    "totalDebit": 11100,
    "estimatedUSDT": 19.069412
  },
  "withinLimits": true,
  "lowLiquidity": false,
  "limits": { "minAmount": 2000, "maxAmount": 100000, "feePercent": 8, "networkFee": 300 },
  "balance": { "available": 153045, "maxAmount": 100000 }
}
503 Service Unavailable
{
  "status": "error",
  "code": "CRYPTO_DISABLED",
  "message": "O saque em criptomoeda está temporariamente indisponível."
}
POST/withdrawalsEscopo: withdrawals.crypto

Criar saque em USDT

Mesma rota do saque PIX. Enviando o objeto crypto com a carteira, o valor é convertido em USDT e entregue na rede BNB Smart Chain (BEP-20). Não envie pixKey. O amount é o valor que vira cripto: a taxa percentual e a taxa de rede são somadas por cima e o total sai do saldo. A transferência é irreversível, então confira o endereço. Pela API, a chave precisa dos escopos withdrawals.create e withdrawals.crypto e de pelo menos um IP permitido.

Parâmetros

amountbodyobrigatório
integer: Valor em centavos a converter em USDT. Mínimo 2000 (R$ 20,00). Máximo 100000 (R$ 1.000,00) ou o seu limite por saque, o que for menor.
crypto.walletbodyobrigatório
string: Carteira de destino na rede BEP-20: 0x seguido de 40 caracteres hexadecimais. Se o endereço tiver maiúsculas e minúsculas, o checksum é conferido.
crypto.networkbody
string: Opcional. Só "bsc" é aceito.
crypto.tokenbody
string: Opcional. Só "USDT" é aceito.
webhookbody
string: URL para notificar quando o saque mudar de status.
Idempotency-Keyheader
string: Chave única sua para evitar saques duplicados em reenvios. A resposta é repetida por 24h para a mesma chave.

Campos da resposta

id
string: Identificador do saque. Use em GET /withdrawals/:id.
status
string: Status inicial: queued. O saque entra na fila e é enviado em segundos.
amount
integer: Valor convertido, em centavos.
fee
integer: Total de taxas em centavos (taxa percentual + taxa de rede).
crypto.wallet
string: Carteira de destino, no formato com checksum.
crypto.estimatedUSDT
number: USDT estimado. A cotação final é fechada na conversão.
crypto.totalDebit
integer: Total debitado do saldo (amount + fee).

Requisição

curl -X POST "https://api.syntrapay.com.br/withdrawals" \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json" \
  -d '{"amount":10000,"crypto":{"wallet":"0x71C7656EC7ab88b098defB751B7401B5f6d8976F"}}'

Resposta

201 Created
{
  "message": "Withdraw request queued successfully",
  "status": "queued",
  "code": "WITHDRAWAL_QUEUED",
  "id": "7b3d9a1c-2e5f-4c8a-9d6b-1a2b3c4d5e6f",
  "amount": 10000,
  "fee": 1100,
  "crypto": {
    "wallet": "0x71C7656EC7ab88b098defB751B7401B5f6d8976F",
    "network": "bsc",
    "token": "USDT",
    "rateBRLPerUSD": 5.244,
    "estimatedUSDT": 19.069412,
    "feePercent": 8,
    "platformFee": 800,
    "networkFee": 300,
    "totalDebit": 11100
  }
}
400 Bad Request
{
  "status": "error",
  "code": "INVALID_WALLET",
  "message": "O endereço deve ter 42 caracteres (recebido: 41)."
}
GET/withdrawals/:idEscopo: withdrawals.read

Consultar saque em USDT

A mesma consulta do saque PIX. No saque em cripto a resposta traz o objeto crypto. Quando o status vira PAID o valor já foi convertido e o USDT está a caminho da carteira; cerca de 30 segundos depois crypto.txHash traz o comprovante na blockchain.

Parâmetros

idpathobrigatório
string: ID do saque retornado na criação.

Campos da resposta

status
string: QUEUED, PROCESSING, SENT (convertendo), PAID ou FAILED. Em FAILED o valor e as taxas voltam ao saldo.
crypto.txHash
string: Hash da transferência na BNB Smart Chain. null até a entrega.
crypto.explorerUrl
string: Link do comprovante no BscScan. null até a entrega.
crypto.deliveredUSDT
number: USDT entregue, quando informado. Antes disso, use estimatedUSDT.
crypto.deliveredAt
string: Data/hora (ISO) em que o hash foi registrado.

Requisição

curl -X GET "https://api.syntrapay.com.br/withdrawals/7b3d9a1c-2e5f-4c8a-9d6b-1a2b3c4d5e6f" \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json"

Resposta

201 Created
{
  "id": "7b3d9a1c-2e5f-4c8a-9d6b-1a2b3c4d5e6f",
  "type": "WITHDRAWAL",
  "reason": "CRYPTO_WITHDRAWAL",
  "status": "PAID",
  "withdrawStatusId": "Successfull",
  "amount": 10000,
  "fee": 1100,
  "taxes": 1100,
  "paidAt": "2026-10-01T14:31:22.000Z",
  "crypto": {
    "wallet": "0x71C7656EC7ab88b098defB751B7401B5f6d8976F",
    "network": "bsc",
    "networkLabel": "BNB Smart Chain (BEP-20)",
    "token": "USDT",
    "feePercent": 8,
    "platformFee": 800,
    "networkFee": 300,
    "totalDebit": 11100,
    "rateBRLPerUSD": 5.244,
    "estimatedUSDT": 19.069412,
    "deliveredUSDT": 19.069412,
    "txHash": "0x9f2c4e7a1b3d5f60718293a4b5c6d7e8f9012a3b4c5d6e7f8091a2b3c4d5e6f7",
    "explorerUrl": "https://bscscan.com/tx/0x9f2c4e7a1b3d5f60718293a4b5c6d7e8f9012a3b4c5d6e7f8091a2b3c4d5e6f7",
    "deliveredAt": "2026-10-01T14:31:52.000Z"
  }
}
404 Not Found
{
  "status": "error",
  "code": "NOT_FOUND",
  "message": "404: Not Found - Withdrawal not found"
}

09 / Referência da API

Saldo

POST/balance

Consultar saldo

Consulta o saldo da sua conta: disponível, bloqueado, em análise (MED) e total. Não requer corpo na requisição.

Campos da resposta

balance_available
number: Saldo disponível para saque.
balance_locked
number: Saldo bloqueado (lock de tempo).
balance_infractions
number: Saldo retido por infrações MED.
netBalance
number: Saldo líquido.

Requisição

curl -X POST "https://api.syntrapay.com.br/balance" \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json"

Resposta

200 OK
{
  "codeStatus": 200,
  "balance": {
    "id": "usr_a1b2c3",
    "balance": 1530.50,
    "balance_available": 1530.50,
    "balance_locked": 0,
    "balance_infractions": 0,
    "totalBalances": 8240.00,
    "netBalance": 1530.50,
    "fees": { "saque": 250 }
  }
}

10 / Referência da API

MED: Infrações PIX

Consulte as infrações MED (Mecanismo Especial de Devolução) registradas nas suas transações. Valores em centavos.
GET/infractions

Listar infrações

Lista as infrações MED da sua conta, com um resumo agregado e paginação por intervalo (from/to).

Parâmetros

fromquery
integer: Índice inicial (0-based). Padrão 0.
toquery
integer: Índice final (inclusivo). Padrão 10.
statusquery
string: Filtra por status (ex.: WAITING_PSP, COMPLETED) ou "all".

Campos da resposta

summary.totalCount
integer: Total de infrações.
summary.totalAmount
integer: Soma dos valores (centavos).
summary.waitingPsp
integer: Infrações aguardando o PSP.
summary.completed
integer: Infrações concluídas.
data[].infractionId
string: ID da infração.
data[].type
string: Tipo (ex.: FRAUD, SCAM).
data[].status
string: Status atual da infração.
data[].endToEndId
string: E2E do PIX relacionado.
data[].amount
integer: Valor em centavos.
data[].payerName
string: Nome do pagador (quando disponível).
data[].linkedTransactionId
string: ID da transação vinculada.

Requisição

curl -X GET "https://api.syntrapay.com.br/infractions?from=0&to=10&status=all" \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json"

Resposta

200 OK
{
  "status": "success",
  "summary": {
    "totalCount": 3,
    "totalAmount": 45000,
    "waitingPsp": 1,
    "completed": 2
  },
  "range": { "total": 3, "from": 0, "to": 10 },
  "data": [
    {
      "infractionId": "inf_9a8b7c6d",
      "type": "FRAUD",
      "status": "WAITING_PSP",
      "endToEndId": "E12345678202607181430...",
      "reportedBy": "PACS",
      "amount": 15000,
      "currency": "BRL",
      "creationDate": "2026-07-18T12:00:00.000Z",
      "payerName": "João da Silva",
      "linkedTransactionId": "9c1e7b2a-3f4d-4a8b-bc12-5e6f7a8b9c0d"
    }
  ]
}

11 / Recursos

Webhooks

Configure endpoints para receber eventos em tempo real. Ao criar, enviamos um POST de teste. Sua URL deve responder 200/201/202. Cada disparo inclui o header syntrapay-webhook-secret.

Eventos disponíveis

payment.approved
Uma cobrança PIX foi paga e o valor creditado.
payment.failed
A cobrança falhou, expirou ou foi cancelada.
transfer-approved
Um saque foi concluído. No saque em USDT o payload traz o objeto crypto (carteira, cotação e, quando já disponível, o txHash).
transfer-failed
Um saque falhou ou foi rejeitado. O valor e as taxas voltam ao saldo.
pix.infraction
Uma infração MED foi registrada em uma transação sua.

Cada disparo inclui os headers syntrapay-signature (sha256=…), syntrapay-timestamp e syntrapay-webhook-secret. A assinatura é o HMAC-SHA256 de `${timestamp}.${corpo_bruto}` usando o signing secret do webhook: valide-a e rejeite timestamps antigos (replay).

Verificar a assinatura (Node.js)

import crypto from "crypto"

function verifyWebhook(rawBody, headers, secret) {
  const ts = headers["syntrapay-timestamp"]
  const sig = (headers["syntrapay-signature"] || "").replace("sha256=", "")
  const expected = crypto
    .createHmac("sha256", secret)
    .update(ts + "." + rawBody)   // HMAC de `${ts}.${corpo}`
    .digest("hex")
  const ok =
    sig.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))
  // Rejeite se !ok ou se |agora - ts| > 300s (replay)
  const fresh = Math.abs(Date.now() / 1000 - Number(ts)) < 300
  return ok && fresh
}
GET/webhooksEscopo: webhooks.manage

Listar webhooks

Lista os webhooks da sua conta. O signing secret é retornado mascarado.

Requisição

curl -X GET "https://api.syntrapay.com.br/webhooks" \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json"

Resposta

200 OK
{
  "status": "success",
  "webhooks": [
    {
      "id": "665fbe1c9a2d4e0012ab34cd",
      "url": "https://seusite.com/webhooks/syntrapay",
      "events": ["payment.approved", "payment.failed"],
      "active": true,
      "secret": "whsec_ab12...cd34",
      "createdAt": "2026-07-01T10:00:00.000Z"
    }
  ]
}
POST/webhooksEscopo: webhooks.manage

Criar webhook

Cria um webhook. O signing secret completo é retornado apenas na criação (também pode ser revelado depois com sua senha no painel). Máximo de 10 webhooks por conta.

Parâmetros

urlbodyobrigatório
string: Endpoint HTTPS que receberá os eventos.
eventsbodyobrigatório
array: Lista de eventos (ver tabela de eventos abaixo).

Requisição

curl -X POST "https://api.syntrapay.com.br/webhooks" \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://seusite.com/webhooks/syntrapay","events":["payment.approved","payment.failed"]}'

Resposta

201 Created
{
  "status": "success",
  "webhook": {
    "id": "665fbe1c9a2d4e0012ab34cd",
    "url": "https://seusite.com/webhooks/syntrapay",
    "events": ["payment.approved", "payment.failed"],
    "active": true,
    "secret": "a1b2c3...64-char-hex-secret",
    "createdAt": "2026-07-18T10:00:00.000Z"
  }
}
400 Bad Request
{
  "status": "error",
  "code": "WEBHOOK_TEST_FAILED",
  "message": "A URL não respondeu ao POST de teste."
}
PATCH/webhooksEscopo: webhooks.manage

Editar webhook

Atualiza a URL, os eventos ou o status (ativo/inativo) de um webhook. Só os campos enviados são alterados.

Parâmetros

webhookIdbodyobrigatório
string: ID do webhook a editar.
urlbody
string: Nova URL do endpoint.
eventsbody
array: Nova lista de eventos.
activebody
boolean: Ativa ou desativa o webhook.

Requisição

curl -X PATCH "https://api.syntrapay.com.br/webhooks" \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json" \
  -d '{"webhookId":"665fbe1c9a2d4e0012ab34cd","active":false}'

Resposta

200 OK
{
  "status": "success",
  "webhook": {
    "id": "665fbe1c9a2d4e0012ab34cd",
    "url": "https://seusite.com/webhooks/syntrapay",
    "events": ["payment.approved", "payment.failed"],
    "active": false,
    "createdAt": "2026-07-01T10:00:00.000Z"
  }
}
DELETE/webhooksEscopo: webhooks.manage

Remover webhook

Remove um webhook permanentemente.

Parâmetros

webhookIdbodyobrigatório
string: ID do webhook a remover.

Requisição

curl -X DELETE "https://api.syntrapay.com.br/webhooks" \
  -H "Authorization: sk_live_sua_chave_aqui" \
  -H "Content-Type: application/json" \
  -d '{"webhookId":"665fbe1c9a2d4e0012ab34cd"}'

Resposta

200 OK
{
  "status": "success",
  "message": "Webhook removido com sucesso"
}

12 / Recursos

Erros

Erros retornam um envelope consistente com status, code e message.
{
  "status": "error",
  "code": "BAD_REQUEST",
  "message": "Descrição do erro em português."
}
UNAUTHORIZED
HTTP 401
Chave/token ausente ou inválido no header Authorization.
ACCESS_FORBIDDEN
HTTP 200/403
Sem permissão para acessar o recurso. Chaves de API só acessam as rotas desta documentação.
FORBIDDEN_SCOPE
HTTP 403
A chave de API não possui o escopo necessário para a ação.
FORBIDDEN
HTTP 403
Conta ainda não ativada.
BAD_REQUEST
HTTP 400
Parâmetros ausentes ou inválidos.
VALIDATION_ERROR
HTTP 400
Campo de link de pagamento fora das regras. A resposta traz field com o campo exato.
INVALID_URL
HTTP 400
URL de imagem, banner ou redirecionamento recusada. Use um endereço público https.
TOO_MANY_BUMPS
HTTP 400
Mais de 3 ofertas adicionais no mesmo link.
LINK_LIMIT_REACHED
HTTP 400
Limite de 200 links não arquivados por conta atingido.
NOT_ARCHIVED
HTTP 400
Tentativa de restaurar um link que não está arquivado.
INSUFFICIENT_FUNDS
HTTP 400
Saldo insuficiente para o saque.
INVALID_PIX_KEY
HTTP 400
Chave PIX inválida ou não encontrada.
INVALID_WALLET
HTTP 400
Carteira de destino inválida: formato, tamanho, checksum ou endereço bloqueado (ex.: contrato do USDT).
UNSUPPORTED_NETWORK
HTTP 400
Rede diferente da BNB Smart Chain (BEP-20) no saque em cripto.
UNSUPPORTED_TOKEN
HTTP 400
Token diferente de USDT no saque em cripto.
BELOW_MINIMUM
HTTP 400
Valor abaixo do mínimo do saque em cripto (R$ 20,00).
ABOVE_MAXIMUM
HTTP 400
Valor acima do máximo por saque em cripto.
OUT_LIMIT_EXCEEDED
HTTP 400
Valor acima do seu limite por saque.
DAILY_LIMIT_EXCEEDED
HTTP 400
O saque passaria do seu limite diário de saques.
WITHDRAWAL_PENDING
HTTP 429
Já existe um saque (PIX ou cripto) em andamento. Os saques são processados um por vez.
WITHDRAWAL_BURST_LOCKED
HTTP 429
Mais de 2 pedidos de saque em 5 segundos. Aguarde 10 segundos.
CRYPTO_DISABLED
HTTP 503
Saque em cripto temporariamente indisponível.
IP_ALLOWLIST_REQUIRED
HTTP 400/403
Saque em cripto pela API exige chave com lista de IPs permitidos.
INVALID_IPS
HTTP 400
Lista de IPs permitidos com endereço inválido.
QUOTE_UNAVAILABLE
HTTP 503
Não foi possível obter a cotação do USDT agora. Tente de novo em instantes.
PAYLOAD_TOO_LARGE
HTTP 413
Corpo da requisição acima de 64 KB.
RATE_LIMIT_EXCEEDED
HTTP 429
Muitas escritas ou leituras de link em pouco tempo.
TOO_MANY_REQUESTS
HTTP 429
Limite de requisições atingido. Aguarde e tente novamente.
NOT_FOUND
HTTP 404
Recurso não encontrado.
SERVICE_UNAVAILABLE
HTTP 503
Não foi possível gerar o endereço do checkout agora. Tente novamente.
INTERNAL_ERROR
HTTP 500
Erro interno do servidor.