Skip to main content
This guide walks through a complete Chainrails ramp integration: discovering supported corridors, requesting quotes, completing KYC when required, creating an order, presenting payment instructions or a hosted widget, and monitoring the order until completion.

Overview

Chainrails aggregates fiat ramp providers behind one API. A user can on-ramp fiat into USDC on a supported destination chain, or off-ramp supported tokens from a source chain into local fiat. There are two execution flows: For headless providers, Chainrails has been built to minimize KYC friction. You only need to KYC once per user to access multiple liquidity providers, and you can submit only the fields that are missing or insufficient for each selected provider.

Before you begin

You need:
  • a Chainrails account;
  • a test or live API key from the Chainrails dashboard;
  • completed Chainrails KYB to access live fiat endpoints;
All examples use:
Keep API keys on your server. Do not expose them in browser or mobile application code.

End-to-end flow

The integration sequence is:
  1. Retrieve supported countries for the requested direction and amount.
  2. Request quotes using the selected country and currency.
  3. Select a quote and inspect its transferType and fieldsRequired.
  4. For a headless quote, complete the Chainrails KYC loop.
  5. Create the ramp order using the selected provider.
  6. Show transferInstructions for a headless order or open widgetUrl for a hosted order.
  7. Poll the order until it reaches a terminal status.

1. Retrieve supported countries

Use the countries endpoint to build your country and currency selector:
Recommended query parameters:
Example response:
Use the countries endpoint instead of deriving a country from a currency. Multiple countries can share a currency, while provider availability and KYC requirements can differ by country. You can also inspect currencies directly:

2. Request quotes

On-ramp quote

Off-ramp quote

Quote parameters: An abbreviated quote response looks like this:
The real response includes the full quote list. The chosen recommended quote creates a balance between price, remaining KYC friction, pending or blocked KYC state, and direct-flow availability.

3. Determine whether KYC is required

Inspect the selected quote’s payment channel:
For a direct/headless quote, check Chainrails KYC before creating the order. For the underlying profile model, assurance levels, and verification states, see Know Your Customer (KYC).
For a widget quote, skip the Chainrails KYC endpoints. Create the order and redirect the user to the returned widgetUrl; the provider owns the verification flow.

Inspect provider requirements

This endpoint describes the applicable policy without inspecting a user:
Example response:
assurance: "provided" means Chainrails needs a stored value. assurance: "verified" means the field must be validated by an accepted verification source.

Get the user’s KYC state

The state response separates requirements into actionable groups: Continue directly to order creation when:
When blocked is true, show a message asking the user to contact support. Do not repeatedly resubmit the same identity data.

4. Complete headless KYC

KYC submission uses one endpoint for profile creation, field storage, text-document checks, and hosted external verification:
Only userEmail, provider, countryCode, and fiatCurrency are required. Include any user information you already have/can obtain in fields (derived from checking provider’s requirements); the engine determines what can be stored, validated, or sent to an external verification flow.
countryCode is the transaction corridor country. fields.country is the user’s current country of residence. They are intentionally separate and do not always need to match.

Text verification flow

The text verification flow provides the least friction. Currently available for just Nigeria, but will be expanded to more countries in the future. Submit the available profile fields and required text documents:
Use uppercase BVN and NIN in the public submission payload. Both values must contain exactly 11 digits. Chainrails validates the documents and compares the returned identity against the submitted names and DOB. Phone and address are mutable fields and do not need an exact registry match.

External document and biometric verification

Outside Nigeria, Chainrails requires the external_verification capability. You can start with only the fields you already have:
When external verification is required, the response includes:
Open verification.url in the same tab, a new tab, or an embedded browser appropriate for your application. callbackUrl controls where the hosted flow returns the user. Chainrails receives the provider webhook asynchronously. Returning to callbackUrl does not by itself mean KYC is approved. Poll GET /api/v1/ramp/kyc until one of these outcomes occurs:
  • canProceed: true — continue to order creation;
  • pendingRequirements is non-empty — keep waiting and poll again;
  • blocked: true — stop and direct the user to support;
  • missing or insufficient fields remain — collect and submit only those fields.

Progressive KYC loop

Do not render one large static form. Build the next form from the latest state:
  1. Read missingRequirements, rejectedRequirements, and insufficientRequirements.
  2. Ask only for those field requirements, dependent on what the provider needs.
  3. Submit the fields to /api/v1/ramp/kyc with the same provider and corridor context.
  4. If a verification URL is returned, send the user through it.
  5. Poll /api/v1/ramp/kyc.
  6. Continue when canProceed is true.
The profile is keyed by normalized email and reused across future transactions. Email ownership verification is the responsibility of your application; the KYC API does not send or validate an email OTP.

5. Create the ramp order

The provider must come from the selected quote. Chainrails fetches a fresh quote during order creation, so you do not pass the previous quoteId.

Headless on-ramp order

Only include keys requested by the selected quote’s fieldsRequired. A field with required: false can be omitted. Example headless response:
Show the transfer instructions and expiry to the user. The user should send the exact fiat amount and include the reference when one is provided.

Widget on-ramp order

For a quote with transferType: "widget", do not call the Chainrails KYC endpoints first:
The response contains a hosted URL:
Redirect the user to widgetUrl. The provider collects its own KYC and payment information there. Do not send Chainrails KYC documents through the order fields object.

Headless off-ramp order

Off-ramp quotes expose payout fields and, where applicable, selectable networkId options. Use the option values exactly as returned by the quote.
The response tells the user how to fund the Chainrails intent:
The user must send the exact token and amount to the returned intent address on the specified source chain. Chainrails then routes the funds and coordinates fiat payout.

6. Handle KYC order errors

Order creation revalidates KYC against the selected provider. This protects against stale frontend state. If KYC is incomplete, the order endpoint returns a 400 response with:
Return to the KYC state and submission loop, then retry order creation. If the response code is KYC_BLOCKED, stop automatic retries and ask the user to contact support.

7. Monitor the order

Get one order

Get an on-ramp order by intent address

List orders

Order statuses progress forward: Poll every few seconds or subscribe to the ramp order webhooks to receive status updates.

Optional order actions

Cancel an order

Cancellation succeeds only while the provider and Chainrails order state remain cancellable.

Confirm an order

Some provider flows can require explicit confirmation after the user completes a deposit action:
Do not call this endpoint automatically for every order. Most headless orders progress through payment/deposit instructions and webhook-driven status updates without a routine client confirmation call.

Implementation checklist

  • Use /ramp/countries with type and amount to build corridor selection.
  • Request quotes with countryCode and userEmail.
  • Select the provider from the quote response rather than hardcoding one.
  • Inspect transferType to choose the headless or widget flow.
  • For headless ramp flows, poll /ramp/kyc and submit only outstanding requirements.
  • Treat countryCode as transaction geography and fields.country as residence.
  • Redirect users through verification.url when external verification is required.
  • Wait for canProceed: true before creating a headless order.
  • Send only quote-defined payment fields in the order fields object.
  • For widget flows, redirect to widgetUrl and let the provider own KYC.
  • Display exact transfer instructions and expiry values from the order response.
  • Poll the order until a terminal status is reached.

Using the Chainrails Modal

If you do not need a custom interface, the easiest way to get started is the Chainrails Modal, which implements country and currency selection, quote retrieval, progressive KYC, hosted verification redirects, order creation, and status monitoring for you. See the Payment Modal documentation for setup instructions.