Swapnoir
PT

API pública · v1 · Gratuita

API da Swapnoir

Cotações em tempo real, moedas aceitas e rastreamento de pedidos para sua carteira, bot ou site. Somente leitura, sem chave de API, sem conta.

URL base
https://swapnoir.com/api/v1
Autenticação
Nenhuma
Formato
JSON, UTF-8
Erros
RFC 9457

Visão geral

A API da Swapnoir oferece ao seu app os mesmos dados em tempo real usados pelo serviço de troca da swapnoir.com. É uma pequena API REST via HTTPS com três endpoints, que retorna JSON e é descrita em um arquivo OpenAPI 3.1 que você pode carregar no Postman, Insomnia, Scalar ou em um gerador de código.

Mostre cotações em tempo real

Widgets de preço, calculadoras e bots. As estimativas já incluem todas as taxas do pagamento.

Envie usuários para uma troca

Abra uma troca pré-preenchida em swapnoir.com a partir do seu app com um único link.

Rastrear pedidos

Acompanhe uma troca pelo ID do pedido e avise seus usuários quando ela for concluída.

Início rápido

Sem cadastro. Execute estes comandos em um terminal; cada um funciona de forma independente.

  1. Liste o que pode ser trocado. Use o id de cada moeda nas outras chamadas.
    curl "https://swapnoir.com/api/v1/currencies"
  2. Obtenha uma estimativa em tempo real. Quanto XMR você recebe por 0.01 BTC, já descontadas as taxas?
    curl "https://swapnoir.com/api/v1/estimate?from=BTC&to=XMR&amount=0.01"
  3. Envie seu usuário para a troca e acompanhe-a. O usuário conclui a troca em swapnoir.com e recebe uma página do pedido. Com o ID dela, você acompanha o pedido.
    curl "https://swapnoir.com/api/v1/orders/K7M2QX9PRT4B"

Teste ao vivo

GET /api/v1/estimate?from=BTC&to=XMR&amount=0.01&rate=float

Requisições e dados

URL basehttps://swapnoir.com/api/v1. Somente HTTPS.
MétodosTodos os endpoints são GET. Os parâmetros vão na query string ou no caminho.
Respostasapplication/json, UTF-8. Os erros usam application/problem+json.
ValoresStrings decimais como "0.01", para que não haja perda de precisão. Envie valores com ponto e no máximo decimals casas decimais da moeda.
IDs de moedasMoeda mais rede, por exemplo BTC, USDT-TRC20. Nas requisições, não diferencia maiúsculas de minúsculas; nas respostas, vem sempre em maiúsculas.
Datas e horasISO 8601 em UTC, por exemplo 2026-10-05T12:00:00.000Z.
NavegadoresO CORS é aberto (Access-Control-Allow-Origin: *), então você pode chamar a API de uma página web. Nenhum cookie é usado.
TorTambém disponível via Tor em http://swapnoqyyp3mfh3hoypzmvpnau7gymt7c32tybx2qew3s7sw7bzz7aqd.onion/api/v1, com os mesmos endpoints e limites.
VersionamentoA versão fica no caminho. Dentro da v1, só adicionamos coisas: novos endpoints, novos parâmetros opcionais, novos campos de resposta e novas moedas; por isso, ignore os campos que você não conhece. Qualquer mudança que quebraria uma integração é lançada como uma nova versão, e a v1 continua funcionando em paralelo.

Autenticação

Nenhuma. Não há chaves de API, contas nem tokens, e as requisições não são vinculadas a ninguém. Nunca envie credenciais, frases-semente ou chaves privadas para a API; ela nunca vai pedi-las.

Limites de requisições

Os limites são contados por conexão, em uma janela móvel de um minuto.

EndpointRequisições por minuto
GET /currencies60
GET /estimate90
GET /orders/{id}30

Toda resposta traz os cabeçalhos padrão RateLimit-Policy (por exemplo 90;w=60) e RateLimit (por exemplo limit=90, remaining=89, reset=60). Acima do limite, você recebe 429 com um cabeçalho Retry-After em segundos.

  • Armazene /currencies em cache por pelo menos 5 minutos; a lista raramente muda.
  • Enquanto o usuário digita um valor, espere cerca de meio segundo após a última tecla antes de pedir uma estimativa.
  • Consulte um pedido no máximo a cada 10 segundos e pare quando final for true.

Erros

Os erros usam o formato padrão RFC 9457 problem details. Verifique o status HTTP e depois decida com base em code, que nunca muda. detail é uma mensagem em inglês simples que você pode mostrar ao seu usuário, e type aponta para a linha correspondente abaixo.

422 Exemplo
{
  "type": "https://swapnoir.com/api#error-amount_too_small",
  "title": "Amount below minimum",
  "status": 422,
  "detail": "The minimum for this pair is 0.00005799 BTC.",
  "code": "amount_too_small",
  "min_amount": "0.00005799"
}
CódigoHTTPSignificado
invalid_parameter400Um parâmetro de consulta está ausente ou malformado. param indica qual.
same_currency400from e to são a mesma moeda.
receive_not_supported400A moeda to é só de envio (Lightning).
amount_too_small422O valor está abaixo do mínimo para este par. min_amount contém o mínimo.
pair_not_supported422Este par de moedas e redes não é oferecido.
pair_unavailable503Não há cotação disponível para este par no momento. Tente mais tarde ou use outro valor.
not_found404Não existe pedido com este ID, ou o pedido foi excluído.
rate_limited429Você atingiu o limite de requisições. Aguarde o número de segundos indicado em Retry-After.
internal_error500Algo deu errado do nosso lado. Tente mais tarde.

Referência

Listar moedas

GET/api/v1/currencies

Todas as moedas e redes aceitas pela Swapnoir. Um token em outra rede é uma moeda diferente, por exemplo USDT-TRC20 e USDT-ERC20. A lista muda raramente; armazene-a em cache por alguns minutos.

O exemplo mostra três das moedas. Os campos da resposta abaixo são por moeda.

Requisição

curl "https://swapnoir.com/api/v1/currencies"
const res = await fetch("https://swapnoir.com/api/v1/currencies");
const { currencies } = await res.json();

// Currencies a user can receive
const receivable = currencies.filter((c) => c.receive);
import requests

r = requests.get("https://swapnoir.com/api/v1/currencies", timeout=10)
r.raise_for_status()
currencies = r.json()["currencies"]

Resposta

200 OK
{
  "currencies": [
    {
      "id": "BTC",
      "ticker": "BTC",
      "name": "Bitcoin",
      "network": "Bitcoin",
      "decimals": 8,
      "send": true,
      "receive": true,
      "memo": null,
      "icon_url": "https://swapnoir.com/assets/coins/btc.svg"
    },
    {
      "id": "BTC-LN",
      "ticker": "BTC",
      "name": "Bitcoin",
      "network": "Lightning",
      "decimals": 8,
      "send": true,
      "receive": false,
      "memo": null,
      "icon_url": "https://swapnoir.com/assets/coins/btc.svg"
    },
    {
      "id": "XRP",
      "ticker": "XRP",
      "name": "XRP",
      "network": "XRP Ledger",
      "decimals": 6,
      "send": true,
      "receive": true,
      "memo": "Destination tag",
      "icon_url": "https://swapnoir.com/assets/coins/xrp.svg"
    }
  ]
}
Campos da resposta
CampoTipoDescrição
idstringMoeda e rede.
tickerstring
namestring
networkstring
decimalsintegerMáximo de casas decimais aceitas nos valores.
sendbooleanPode ser usada como from.
receivebooleanPode ser usada como to.
memostring or nullNome do campo extra que algumas redes exigem junto com o endereço, como Destination tag; null quando não é usado.
icon_urlstring

Obter uma estimativa

GET/api/v1/estimate

Quanto de to o usuário recebe por amount de from, com todas as taxas de troca e de rede do pagamento já incluídas. As estimativas são em tempo real e não ficam reservadas: o valor final é definido quando a troca é criada (taxa fixa) ou quando o depósito é confirmado (taxa flutuante).

Parâmetros

NomeLocalDescrição
fromobrigatórioqueryMoeda que o usuário envia. Exemplo: BTC.
toobrigatórioqueryMoeda que o usuário recebe. BTC-LN é só de envio. Exemplo: XMR.
amountobrigatórioqueryValor de from, em formato decimal com ponto e no máximo decimals casas decimais da moeda. Exemplo: 0.01.
ratequeryfloat (padrão) acompanha o mercado até o depósito ser confirmado. fixed trava o valor quando a troca é criada. Um de float, fixed. Exemplo: float.

Requisição

curl "https://swapnoir.com/api/v1/estimate?from=BTC&to=XMR&amount=0.01&rate=float"
const params = new URLSearchParams({ from: "BTC", to: "XMR", amount: "0.01" });
const res = await fetch(`https://swapnoir.com/api/v1/estimate?${params}`);
const data = await res.json();

if (!res.ok) {
  // RFC 9457 problem, e.g. data.code === "amount_too_small"
  throw new Error(data.detail);
}
console.log(data.amount_to, data.to);
import requests

r = requests.get(
    "https://swapnoir.com/api/v1/estimate",
    params={"from": "BTC", "to": "XMR", "amount": "0.01"},
    timeout=10,
)
data = r.json()
if not r.ok:
    raise RuntimeError(data["code"] + ": " + data["detail"])
print(data["amount_to"], data["to"])

Resposta

200 OK
{
  "from": "BTC",
  "to": "XMR",
  "rate_type": "float",
  "amount_from": "0.01",
  "amount_to": "1.57166029",
  "rate": "157.166029",
  "usd_value": "866.32",
  "quoted_at": "2026-10-05T12:00:00.000Z"
}
422 Abaixo do mínimo
{
  "type": "https://swapnoir.com/api#error-amount_too_small",
  "title": "Amount below minimum",
  "status": 422,
  "detail": "The minimum for this pair is 0.00005799 BTC.",
  "code": "amount_too_small",
  "min_amount": "0.00005799"
}
400 Parâmetro inválido
{
  "type": "https://swapnoir.com/api#error-invalid_parameter",
  "title": "Invalid parameter",
  "status": 400,
  "detail": "Unknown currency `DOG`. See /api/v1/currencies.",
  "code": "invalid_parameter",
  "param": "from"
}
Campos da resposta
CampoTipoDescrição
fromstringMoeda e rede.
tostringQualquer moeda, exceto as que são só de envio.
rate_typestringTipo de taxa
amount_fromstringO valor consultado.
amount_tostringO que o usuário recebe, após todas as taxas.
ratestringValor de to por 1 from, após as taxas.
usd_valuestring or nullValor aproximado de amount_from em dólares americanos, quando conhecido.
quoted_atstring

Obter um pedido

GET/api/v1/orders/{id}

Status em tempo real e detalhes de uma troca. O ID do pedido é a última parte da URL da página do pedido. Qualquer pessoa com o ID pode ver o pedido, então trate-o como uma senha. Consulte no máximo a cada 10 segundos e pare quando final for true. Os pedidos são excluídos 7 dias após serem finalizados.

Parâmetros

NomeLocalDescrição
idobrigatóriopathID do pedido, por exemplo K7M2QX9PRT4B.

Requisição

curl "https://swapnoir.com/api/v1/orders/K7M2QX9PRT4B"
const res = await fetch(`https://swapnoir.com/api/v1/orders/${orderId}`);
if (res.status === 404) {
  // wrong ID, or the order was deleted
}
const order = await res.json();
console.log(order.status, order.final);
import time
import requests

while True:
    r = requests.get(f"https://swapnoir.com/api/v1/orders/{order_id}", timeout=10)
    if r.status_code == 404:
        break  # wrong ID, or the order was deleted
    order = r.json()
    print(order["status"])
    if order["final"]:
        break
    time.sleep(15)

Resposta

200 OK
{
  "id": "K7M2QX9PRT4B",
  "status": "confirming",
  "final": false,
  "rate_type": "float",
  "created_at": "2026-10-05T12:00:00.000Z",
  "updated_at": "2026-10-05T12:06:12.000Z",
  "from": {
    "currency": "BTC",
    "amount": "0.01"
  },
  "to": {
    "currency": "XMR",
    "amount": "1.57166029",
    "amount_is_final": false
  },
  "deposit": {
    "address": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq",
    "memo": null,
    "expires_at": null
  },
  "payout": {
    "address": "888tNkZrPN6JsEgekjMnABU4TBzc2Dt29EPAvkRxbANsAnjyPbb3iQ1YBRk1UXcdRsiKc9dhwMVgN5S9cQUiyoogDavup3H",
    "memo": null
  },
  "refund": null,
  "transactions": {
    "deposit": {
      "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
      "url": "https://mempool.space/tx/e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
    },
    "payout": null
  },
  "links": {
    "order_page": "https://swapnoir.com/order/K7M2QX9PRT4B",
    "receipt": "https://swapnoir.com/order/K7M2QX9PRT4B/receipt.txt"
  }
}
404 Não encontrado
{
  "type": "https://swapnoir.com/api#error-not_found",
  "title": "Not found",
  "status": 404,
  "detail": "No order with this ID. Orders are deleted 7 days after they finish.",
  "code": "not_found"
}
Campos da resposta
CampoTipoDescrição
idstringID do pedido
statusstringStatus do pedido
finalbooleanTrue para done, expired, refunded e failed: pare de consultar.
rate_typestringTipo de taxa
created_atstring
updated_atstring
fromobject
from.currencystringMoeda e rede.
from.amountstringValor a depositar.
toobject
to.currencystringMoeda e rede.
to.amountstring or nullPagamento estimado, ou o pagamento final quando amount_is_final for true.
to.amount_is_finalboolean
depositobject
deposit.addressstring or nullPara onde o usuário envia o depósito; null enquanto o status for preparing.
deposit.memostring or nullMemo ou tag de destino que deve ser incluído no depósito, quando definido.
deposit.expires_atstring or nullEnvie antes deste horário, quando definido.
payoutobject
payout.addressstring
payout.memostring or null
refundnull or object
refund.addressstring
refund.memostring or null
transactionsobject
transactions.depositnull or object
transactions.deposit.hashstring
transactions.deposit.urlstring or nullLink do explorador de blocos, quando houver.
transactions.payoutnull or object
transactions.payout.hashstring
transactions.payout.urlstring or nullLink do explorador de blocos, quando houver.
linksobject
links.order_pagestring
links.receiptstring

Guias

Criar uma troca

As trocas são criadas em swapnoir.com, assim seu usuário sempre recebe a própria página do pedido e mantém o controle dela. Seu app envia o usuário para lá com as moedas e o valor já preenchidos:

LinkAbre
https://swapnoir.com/exchange?from=BTC&to=XMR&amount=0.01&rate=floatA troca na etapa do endereço, com a estimativa em tempo real exibida. Ideal para botões “Trocar agora”.
https://swapnoir.com/?from=BTC&to=XMR&amount=0.01A página inicial com o formulário de troca preenchido, para que o usuário ainda possa alterar as moedas e o valor.

Ambos aceitam os mesmos from, to, amount e rate opcional que Obter uma estimativa. Para abrir a página em outro idioma, coloque o código do idioma no início, por exemplo /de/exchange?….

<a href="https://swapnoir.com/exchange?from=BTC&to=XMR&amount=0.01&rate=float" rel="noopener">
  Exchange BTC to XMR on Swapnoir
</a>
  1. O usuário cola o endereço de recebimento e, opcionalmente, um endereço de reembolso, passa por uma rápida verificação de segurança e clica em Trocar agora.
  2. O usuário chega à página do pedido, https://swapnoir.com/order/<ID>, com o endereço de depósito e o valor.
  3. Se o seu app precisar acompanhar o pedido, peça ao usuário para colar o link ou o ID do pedido e depois consulte Obter um pedido periodicamente.

Status dos pedidos

Uma troca normal passa por awaiting → confirming → exchanging → sending → done. Mostre o status ao seu usuário com suas próprias palavras e pare de consultar quando final for true.

StatusFinalSignificado
preparingNãoO endereço de depósito está sendo preparado. Ele costuma aparecer em poucos minutos.
awaitingNãoAguardando o depósito. Envie somente enquanto o pedido estiver neste status e antes de deposit.expires_at.
confirmingNãoO depósito foi detectado e está aguardando confirmações da rede.
exchangingNãoO depósito foi confirmado e está sendo trocado.
sendingNãoAs moedas trocadas estão sendo enviadas para o endereço de recebimento.
processingNãoEm andamento. Usado quando não se conhece um status mais específico.
doneSimConcluída. O pagamento foi enviado; veja transactions.payout.
expiredSimNenhum depósito chegou dentro do prazo. Um depósito atrasado ainda pode ser concluído ou reembolsado pelo suporte.
holdNãoPausado para uma análise de rotina. O usuário deve falar com o suporte e informar o ID do pedido.
attentionNãoAlgo precisa ser verificado, por exemplo um depósito com valor errado. O usuário deve falar com o suporte.
refundingNãoO depósito está sendo devolvido para o endereço de reembolso.
refundedSimO depósito foi devolvido.
failedSimNão foi possível concluir a troca. O usuário deve falar com o suporte.

Moedas aceitas

A mesma lista retornada por Listar moedas. Novas moedas são adicionadas com o tempo, então leia a lista pela API em vez de fixá-la no código.

IDMoedaRedeCasas decimaisRecebimentoMemo
BTCBitcoinBitcoin8Sim–
XMRMoneroMonero12Sim–
ETHEthereumEthereum8Sim–
USDT-TRC20TetherTron (TRC20)6Sim–
USDT-ERC20TetherEthereum (ERC20)6Sim–
USDT-SOLTetherSolana6Sim–
USDC-ERC20USD CoinEthereum (ERC20)6Sim–
LTCLitecoinLitecoin8Sim–
SOLSolanaSolana9Sim–
BTC-LNBitcoin LightningLightning8Só envio–
TRXTronTron6Sim–
BNBBNBBNB Smart Chain (BEP20)8Sim–
DOGEDogecoinDogecoin8Sim–
ZECZcashZcash8Sim–
BCHBitcoin CashBitcoin Cash8Sim–
DASHDashDash8Sim–
XRPXRPXRP Ledger6SimTag de destino

Checklist de integração

  1. Mostre a redeMostre sempre a rede ao lado da moeda, por exemplo USDT na Tron. Enviar pela rede errada pode causar perda de fundos.
  2. Mostre o memoQuando deposit.memo estiver definido, o depósito precisa incluí-lo. Exiba-o com o mesmo destaque do endereço.
  3. Explique a taxa fixaUma troca com taxa fixa paga o valor cotado somente se o usuário enviar exatamente from.amount antes de deposit.expires_at.
  4. Mantenha os IDs de pedidos privadosQualquer pessoa com um ID pode ver esse pedido. Não coloque IDs em ferramentas de análise, logs ou URLs públicas.
  5. Trate os erros pelo códigoDecida com base em code, mostre detail e respeite Retry-After.
  6. Crie links para o site verdadeiroUse links apenas para https://swapnoir.com. Nunca peça aos usuários frases-semente ou chaves privadas.

Histórico de alterações

  • v1 lançada. GET /currencies, GET /estimate, GET /orders/{id}, erros RFC 9457, cabeçalhos RateLimit e a descrição OpenAPI 3.1.

Suporte

Dúvidas, ideias ou limites maiores para sua integração: envie uma mensagem ou fale conosco em info@swapnoir.com. O uso da API é regido pelas nossas páginas de Termos e Privacidade.

Última atualização: .