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 resolves
the party from the wallet binding on file and returns PIX deposit info
you surface to your user. Once the PIX lands, Nora mints BRS to the
wallet and the intent reaches completed.
Prerequisite
You need a party with a connected Solana wallet first. See
Parties setup — the address you pass as
destinationWallet must match the profile.solanaWallet on a party
you created earlier.
Flow
Create the intent
POST /v2/intents/onramp
| Field | Type | Required | Notes |
|---|---|---|---|
amountCents | integer | Yes | BRL amount in cents, not decimals. 100.00 BRL → 10000. Must be > 0. |
destinationWallet | string | Yes | Solana address that will receive the minted BRS. Must match the profile.solanaWallet of a party you've created. 1–255 chars. |
chainId | string | Yes | "solana" or "polygon" is accepted on request, but today responses only emit "solana" — Polygon is not yet live on the response side. |
clientReference | string | No | Your own correlation ID, up to 255 chars. Echoed on the intent. |
Headers:
| Header | Value |
|---|---|
X-API-Key | Your API key. See Authentication. |
idempotency-key | Recommended. A UUID you pick (format-validated). Reuse on retries, regenerate on new user intents. See Idempotency. |
The intent body does not take a
partyId. Nora resolves the party fromdestinationWallet.
Example:
curl -X POST https://staging.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...",
"partyId": "2f1b...",
"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,
"party": {
"displayName": "João da Silva",
"documentMasked": "***.***.***-01",
"solanaWallet": "So11111111111111111111111111111111111111112"
},
"chainId": "solana"
}Notable response fields:
partyId— resolved by Nora fromdestinationWallet.intentType—"onramp"here.flowVersion— integer; pin on at least the version your code was written against.adapter—"squads","cuiaba", ornullwhile 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:
| Status | Terminal? | Notes |
|---|---|---|
created | no | Accepted server-side, not yet routed. |
requires_compliance | no | Held for compliance review. |
awaiting_fiat_payment | no | Waiting for the user's PIX. |
fiat_received | no | PIX confirmed by the rail. |
minting | no | BRS being minted on-chain. |
awaiting_onchain_transfer | no | |
awaiting_burn_approval | no | (offramp) — not seen on onramp. |
burn_approved | no | (offramp). |
onchain_received | no | |
burning | no | (offramp). |
paying_out | no | (offramp). |
completed | yes | Terminal success. |
expired | yes | PIX window closed before payment. |
canceled | yes | |
failed | yes | |
refunded | yes |
Gotchas
amountCents, notamount. Integer cents, not decimal BRL.- No
partyIdin the body. Nora resolves the party fromdestinationWallet. If the wallet isn't bound to any party in your org, the create call fails with400. - Idempotency keys scope to "this user intent," not "this retry." Regenerate on a new form submission, reuse across network-level retries. See Idempotency.
- Response
chainIdis"solana"today. Even though the request accepts"polygon", the response-side chain enum is Solana-only for now.
See also
- Parties setup — the prerequisite
- Offramp intent — the reverse direction (BRS → BRL)
- Idempotency — key lifecycle
- API Reference: Intents — full endpoint spec
- Intents in the dashboard — operator-side view