Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.superbank.co/llms.txt

Use this file to discover all available pages before exploring further.

Flow of Funds

Refresher on how instant on-ramping works with Superbank’s API.

Pre-requisites

Before you begin, ensure you have:
  1. A Superbank Developer account with API access
  2. A prefunded account with sufficient USDC balance
  3. Your API key.
Click here to learn how

On-Ramping

Step 1: Receive an instant on-ramping request

Your user sends a real-time on-ramping request via your UI, or API. Persist their destination wallet address (destination.wallet_address).

Step 2: Create a Settlement Request

Create a settlement request by sending a POST request to /v0/settlement-requests endpoint on Superbank’s API. We recommend supplying an external_id (your own identifier for this settlement) and optional metadata (free-form key/value pairs) on create. Both are echoed back on every read and webhook, and external_id is filterable on the list endpoint — meaning you don’t need to persist anything from the create response (not Superbank’s id, not payment_instructions). Look the settlement up by external_id whenever you need it; the full record (including payment_instructions) comes back on every lookup.

Request

cURL
curl --request POST \
  --url https://api-sandbox.superbank.co/v0/settlement-requests \
  --header 'Content-Type: application/json' \
  --header 'X-Api-Key: YOUR_API_KEY' \
  --data '{
    "type": "STABLECOIN_TO_STABLECOIN",
    "payment_reason": "REMITTANCES",
    "amount": 20,
    "external_id": "txn_abc123",
    "metadata": {
      "user_id": "usr_42",
      "source": "mobile_app"
    },
    // Optional. Override only when your processor's settlement window
    // differs from the T+3 default. ISO 8601, must be in the future, max 30 days out.
    "reconciliation_expected_at": "2026-05-04T17:00:00Z",
    "destination": {
      "currency": "USDC",
      "rail": "SOLANA",
      "is_third_party": true,
      "wallet_address": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
      "beneficiary": {
        "type": "BUSINESS",
        "address": {
          "country_code": "US"
        },
        "business_name": "Acme Corp"
      }
    }
  }'
Picking the right payment_reason. The enum is broad and is used for categorisation and reporting, not customer-visible metadata. For typical fintech flows the values you’ll actually use are: REMITTANCES (cross-border consumer transfers), PAYMENT_FOR_GOODS_AND_SERVICES (merchant payments), EMPLOYEE_SALARIES_OR_WAGES (payroll). Pick the closest specific value rather than reaching for OTHER.
destination.is_third_party — pick what’s true, not what’s convenient. Set true when the beneficiary is not your own registered company (e.g., a payout to a vendor, contractor, or end-user). Set false only when the destination is your own company / registered account.

Response

Some fields (e.g. outbound_payment, inbound_payment, timestamps, failure fields) are omitted in the examples on this page for brevity — see the Settlement Request reference for the full schema.
{
  "id": "39760060-846e-4d5a-8583-7ee62553f79b",
  "type": "STABLECOIN_TO_STABLECOIN",
  "payment_reason": "REMITTANCES",
  "status": "REQUEST_STARTED",
  "amount": "20.00000000",
  "external_id": "txn_abc123",
  "metadata": {
    "user_id": "usr_42",
    "source": "mobile_app"
  },
  "source": null,
  "destination": {
    "currency": "USDC",
    "rail": "SOLANA",
    "is_third_party": true,
    "wallet_address": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
    "beneficiary": {
      "type": "BUSINESS",
      "business_name": "Acme Corp",
      "address": {
        "country_code": "US"
      }
    }
  },
  "payment_instructions": {
    "amount": "20.00000000",
    "currency": "USDC",
    "rail": "SOLANA",
    "wallet_address": "AWE1XaAdRuxzjqy8Q7q75MFbPTs1W6Zbp3zvYWcDGjTj",
    "chain": "SOLANA",
    "valid_until": "2026-01-26T15:50:10.074Z"
  },
  "outbound_payment": null,
  "inbound_payment": null,
  "created_at": "2026-01-26T15:45:10.047Z",
  "updated_at": "2026-01-26T15:45:10.047Z",
  "processing_at": null,
  "completed_at": null,
  "reconciliation_expected_at": null
}
You don’t need to persist anything from this response - not Superbank’s id, and not payment_instructions. Both come back on the lookup. Look the settlement up later via the external_id filter whenever the next step runs:
cURL
curl 'https://api-sandbox.superbank.co/v0/settlement-requests?external_id=txn_abc123' \
  --header 'X-Api-Key: YOUR_API_KEY'
{
  "data": [
    {
      "id": "39760060-846e-4d5a-8583-7ee62553f79b",
      "external_id": "txn_abc123",
      "metadata": { "user_id": "usr_42", "source": "mobile_app" },
      "status": "REQUEST_STARTED",
      "payment_instructions": {
        "amount": "20.00000000",
        "currency": "USDC",
        "rail": "SOLANA",
        "wallet_address": "AWE1XaAdRuxzjqy8Q7q75MFbPTs1W6Zbp3zvYWcDGjTj",
        "valid_until": "2026-01-26T15:50:10.074Z"
      },
      "...": "..."
    }
  ],
  "meta": { "page": 1, "limit": 20, "total": 1, "total_pages": 1 }
}
external_id is not enforced as unique on Superbank’s side. If you reuse the same value (intentionally or by mistake), the response can include multiple settlements. If you need to disambiguate, filter the results client-side using metadata.

Step 3: Start on-ramping with your infrastructure provider

Use thepayment_instructions returned in the previous step as the on-ramping destination to request the deposit instructions from your infrastructure provider. For example, here’s how to do it with Bridge as your infrastructure provider.

Request

cURL
curl --location --request POST 'https://api.bridge.xyz/v0/transfers' \
--header 'Api-Key: <API Key>' \
--header 'Idempotency-Key: <Unique Idempotency Key>' \
--data-raw '{
  "amount": "1.0",
  "source": {
    "payment_rail": "ach_push",
    "currency": "usd",
  },
  "destination": {
    "payment_rail": "solana",
    "currency": "usdc",
    "to_address": "AWE1XaAdRuxzjqy8Q7q75MFbPTs1W6Zbp3zvYWcDGjTj",
  },
}'

Response

{
  "id": "transfer_123",
  "state": "awaiting_funds",
  "amount": "1.0",
  "source": {
    "payment_rail": "ach_push",
    "currency": "usd"
  },
  "destination": {
    "payment_rail": "solana",
    "currency": "usdc",
    "to_address": "AWE1XaAdRuxzjqy8Q7q75MFbPTs1W6Zbp3zvYWcDGjTj"
  },
  "source_deposit_instructions": {
    "bank_account_number": "123456789",
    "bank_routing_number": "101019644",
    "amount": "1.0",
    "currency": "usd",
    "deposit_message": "BVI7depositmessage"
  },
  "receipt": {
    "initial_amount": "1.0",
    "exchange_fee": "0.0",
    "final_amount": "1.0",
    "destination_tx_hash": "0xc0ffee"
  },
  "created_at": "2023-05-05T19:39:14.316Z",
  "updated_at": "2023-05-05T19:39:15.231Z"
}

Step 4: Update settlement request status to FUNDS_SENT

Once the End-User has initated the payment using your infrastructure provider, update the settlement request status to FUNDS_SENT by sending the PUT request to /v0/settlement-requests/:id. This triggers the instant settlement from your pre-funded wallet, to your User’s destination wallet.

Request

cURL
curl --request PUT \
  --url https://api-sandbox.superbank.co/v0/settlement-requests/39760060-846e-4d5a-8583-7ee62553f79b \
  --header 'Content-Type: application/json' \
  --header 'X-Api-Key: YOUR_API_KEY' \
  --data '{
    "status": "FUNDS_SENT"
  }'

Response

{
  "id": "39760060-846e-4d5a-8583-7ee62553f79b",
  "type": "STABLECOIN_TO_STABLECOIN",
  "payment_reason": "REMITTANCES",
  "status": "FUNDS_SENT",
  "amount": "20.00000000",
  "external_id": "txn_abc123",
  "metadata": {
    "user_id": "usr_42",
    "source": "mobile_app"
  },
  "source": null,
  "destination": {
    "currency": "USDC",
    "rail": "SOLANA",
    "is_third_party": true,
    "wallet_address": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
    "beneficiary": {
      "type": "BUSINESS",
      "business_name": "Acme Corp",
      "address": {
        "country_code": "US"
      }
    }
  },
  "payment_instructions": {
    "amount": "20.00000000",
    "currency": "USDC",
    "rail": "SOLANA",
    "wallet_address": "AWE1XaAdRuxzjqy8Q7q75MFbPTs1W6Zbp3zvYWcDGjTj",
    "chain": "SOLANA",
    "valid_until": "2026-01-26T15:50:10.074Z"
  },
  "outbound_payment": {
    "id": "2a9d2a2c-d97b-4973-baf1-78e31d37a024",
    "type": "PAYOUT",
    "status": "PROCESSING",
    "amount": "20.00000000",
    "currency": "USDC",
    "created_at": "2026-01-26T15:45:51.589Z"
  },
  "inbound_payment": null,
  "created_at": "2026-01-26T15:45:10.047Z",
  "updated_at": "2026-01-26T15:45:51.589Z",
  "processing_at": "2026-01-26T15:45:51.594Z",
  "completed_at": null,
  "reconciliation_expected_at": "2026-01-29T15:45:51.594Z"
}

Step 5: Instant settlement completed

Once you confirm the funds are sent via Step 4, Superbank moves USDC from your pre-funded wallet to the End-User’s wallet in real time. The End-User receives their USDC instantly (blockchain speed).

Detecting Completion

Between Step 5 (Superbank moves the funds) and Step 6 (you call REQUEST_COMPLETED with the transaction hash), your system needs to know that the settlement is done. There are two ways to find out, and we strongly recommend the first. Subscribe a webhook endpoint and listen for settlement_request.updated events where data.status === 'SETTLEMENT_COMPLETED'. As soon as Superbank moves the funds, you’ll get a signed POST to your endpoint and can immediately fire Step 6.
{
  "event": "settlement_request.updated",
  "data": {
    "id": "39760060-846e-4d5a-8583-7ee62553f79b",
    "status": "SETTLEMENT_COMPLETED",
    "previous_status": "FUNDS_SENT",
    "amount": "20.00000000",
    "external_id": "txn_abc123",
    "metadata": { "user_id": "usr_42", "source": "mobile_app" },
    "outbound_payment_id": "2a9d2a2c-d97b-4973-baf1-78e31d37a024",
    "updated_at": "2026-01-26T15:48:08.670Z"
  },
  "timestamp": "2026-01-26T15:48:08.700Z"
}
The full envelope, the X-Superbank-Event and X-Superbank-Signature headers, and the complete list of event types are documented in the Webhooks guide.

Polling (fallback)

If you can’t accept webhooks, poll GET /v0/settlement-requests/:id until status === 'SETTLEMENT_COMPLETED'. Recommended interval: 5 seconds or longer. Polling more aggressively wastes your rate-limit budget without speeding up settlement (the underlying blockchain confirmation is the gating factor, not our API).
cURL
curl https://api-sandbox.superbank.co/v0/settlement-requests/39760060-846e-4d5a-8583-7ee62553f79b \
  --header 'X-Api-Key: YOUR_API_KEY'
Webhooks are the better choice in almost every case: lower latency, no wasted requests, and you don’t have to keep state about what you’re polling for.

Step 6: Reconcile via REQUEST_COMPLETED

After T+X — when you’ve collected the fiat from the end user and reconciled it on-chain into your Superbank prefunded wallet — close the settlement by calling REQUEST_COMPLETED with the transaction hash of the on-chain reconciliation. The on-chain reconciliation typically happens one of two ways: (a) Direct deposit via payment_instructions. Use the wallet address or bank details shown in payment_instructions from Step 2’s response. Funds deposited there settle automatically into the prefunded wallet, so you don’t need to perform a separate forwarding step. (b) Third-party forwarding. If you receive the funds on a third-party infrastructure first (e.g. Bridge, Coinbase, your own off-ramp), forward the resulting stablecoin on-chain to the Superbank prefunded wallet to reconcile. In both cases, the transaction_hash in the request below is the hash of the on-chain transfer that lands stablecoin in the prefunded wallet — not the destination payment Superbank made to the end user (that’s the OUTBOUND, which auto-confirms in seconds and doesn’t need to be reported back).
This step is crucial. Without the on-chain transaction hash from the reconciliation step, Superbank cannot match the settlement to the inbound funds.

Request

cURL
curl --request PUT \
  --url https://api-sandbox.superbank.co/v0/settlement-requests/39760060-846e-4d5a-8583-7ee62553f79b \
  --header 'Content-Type: application/json' \
  --header 'X-Api-Key: YOUR_API_KEY' \
  --data '{
    "status": "REQUEST_COMPLETED",
    "transaction_hash": "3CBCEbF2yikAza5d8pcxpibrR4hkj78wAZPYGPtXokNsxxUqPG29aSkrNW6nXnvWzjDePgzYgcLa4G9rJ78k8cXo"
  }'

Response

{
  "id": "39760060-846e-4d5a-8583-7ee62553f79b",
  "type": "STABLECOIN_TO_STABLECOIN",
  "payment_reason": "REMITTANCES",
  "status": "REQUEST_COMPLETED",
  "amount": "20.00000000",
  "external_id": "txn_abc123",
  "metadata": {
    "user_id": "usr_42",
    "source": "mobile_app"
  },
  "source": null,
  "destination": {
    "currency": "USDC",
    "rail": "SOLANA",
    "is_third_party": true,
    "wallet_address": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
    "beneficiary": {
      "type": "BUSINESS",
      "business_name": "Acme Corp",
      "address": {
        "country_code": "US"
      }
    }
  },
  "payment_instructions": {
    "amount": "20.00000000",
    "currency": "USDC",
    "rail": "SOLANA",
    "wallet_address": "AWE1XaAdRuxzjqy8Q7q75MFbPTs1W6Zbp3zvYWcDGjTj",
    "chain": "SOLANA",
    "valid_until": "2026-01-26T15:50:10.074Z"
  },
  "outbound_payment": {
    "id": "2a9d2a2c-d97b-4973-baf1-78e31d37a024",
    "type": "PAYOUT",
    "status": "COMPLETED",
    "amount": "20.00000000",
    "currency": "USDC",
    "created_at": "2026-01-26T15:45:51.589Z"
  },
  "inbound_payment": {
    "id": "04621f85-bd40-46a9-a9a9-9fe14be09354",
    "type": "PAYIN",
    "status": "COMPLETED",
    "amount": "20.00000000",
    "currency": "USDC",
    "created_at": "2026-01-26T14:12:08.354Z"
  },
  "created_at": "2026-01-26T15:45:10.047Z",
  "updated_at": "2026-01-26T15:48:08.670Z",
  "processing_at": "2026-01-26T15:45:51.594Z",
  "completed_at": "2026-01-26T15:48:08.657Z",
  "reconciliation_expected_at": "2026-01-29T15:45:51.594Z"
}

Next Steps

Webhooks

Wire up a webhook handler to detect SETTLEMENT_COMPLETED without polling — envelope, headers, signature verification, and the full event list.