nora

Onramp intent

Move BRL into BRS tokens minted to a Solana wallet. Your backend creates the intent, Nora returns PIX deposit info, your user pays by PIX, and the tokens land.

An onramp intent is a single BRL → BRS mint. Your backend posts the amount, the destination Solana wallet, and the chain; Nora returns PIX deposit info you surface to your user. Once the PIX lands, Nora mints BRS to the wallet and the intent reaches completed.

Flow

Loading diagram…

Create the intent

POST /v2/intents/onramp

FieldTypeRequiredNotes
amountCentsintegerYesBRL amount in cents, not decimals. 100.00 BRL → 10000. Must be > 0.
destinationWalletstringYesSolana address that will receive the minted BRS. 1–255 chars.
chainIdstringYes"solana" or "polygon" is accepted on request, but today responses only emit "solana" — Polygon is not yet live on the response side.
clientReferencestringNoYour own correlation ID, up to 255 chars. Echoed on the intent.

Headers:

HeaderValue
X-API-KeyYour API key. See Authentication.
idempotency-keyRecommended. A UUID you pick (format-validated). Reuse on retries, regenerate on new user intents. See Idempotency.

Example:

curl -X POST https://sandbox.api.nora.finance/v2/intents/onramp \
  -H "X-API-Key: $NORA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "idempotency-key: $(uuidgen)" \
  -d '{
    "amountCents": 10000,
    "destinationWallet": "So11111111111111111111111111111111111111112",
    "chainId": "solana",
    "clientReference": "ord_123"
  }'

Response:

{
  "id": "8f2a...",
  "instanceId": "4e0b...",
  "intentType": "onramp",
  "flowVersion": 1,
  "adapter": null,
  "status": "awaiting_fiat_payment",
  "statusReason": null,
  "clientReference": "ord_123",
  "metadata": null,
  "expiresAt": "2026-04-22T12:30:00Z",
  "createdAt": "2026-04-22T12:00:00Z",
  "updatedAt": "2026-04-22T12:00:00Z",
  "pixInfo": {
    "keyType": "cnpj",
    "keyValue": "00000000000000",
    "recipientName": "Nora Financeira",
    "bank": "Banco XYZ",
    "description": "Nora onramp ord_123",
    "amountCents": 10000
  },
  "depositInstructions": null,
  "chainId": "solana"
}

Notable response fields:

  • intentType"onramp" here.
  • flowVersion — integer; pin on at least the version your code was written against.
  • adapter"squads", "cuiaba", or null while the intent is still being routed.
  • status — see the lifecycle table below for the full enum.

Render the PIX instructions

Surface pixInfo to the user. Today the only supported pixInfo.keyType is "cnpj" — surface keyValue as a copy button, and recipientName / bank / description / amountCents as display fields. PIX deposits expire — expiresAt on the intent is the hard deadline. If the user hasn't paid by then, the intent transitions to expired and you need a new intent (with a fresh idempotency-key) to retry.

Track completion

Poll GET /v2/intents/:id or subscribe to webhooks. The full intent status enum:

StatusTerminal?Notes
creatednoAccepted server-side, not yet routed.
requires_compliancenoHeld for compliance review.
awaiting_fiat_paymentnoWaiting for the user's PIX.
fiat_receivednoPIX confirmed by the rail.
mintingnoBRS being minted on-chain.
awaiting_onchain_transferno
awaiting_burn_approvalno(offramp) — not seen on onramp.
burn_approvedno(offramp).
onchain_receivedno
burningno(offramp).
paying_outno(offramp).
completedyesTerminal success.
expiredyesPIX window closed before payment.
canceledyes
failedyes
refundedyes

Gotchas

  • amountCents, not amount. Integer cents, not decimal BRL.
  • Idempotency keys scope to "this user intent," not "this retry." Regenerate on a new form submission, reuse across network-level retries. See Idempotency.
  • Response chainId is "solana" today. Even though the request accepts "polygon", the response-side chain enum is Solana-only for now.

See also

On this page