Collections

Give each user permanent payment details. Every payment converts and pays out on its own.

A collection gives one of your users payment details that never change. Your user saves them once and pays in whenever they like. Each payment converts and pays out on its own. You do not create a quote or an order for each payment.

Collections work in two directions.

CollectionYour user pays inPulse pays outCollection type
StablecoinUSDT or USDC to permanent deposit addressesNaira to a bank accountofframp
Naira Coming soonNaira to a permanent account in their own nameStablecoin to a wallet addressonramp

This guide covers stablecoin collections. Naira collections are coming soon. To join as an early partner, contact us.

Stablecoin collections

The user gets permanent deposit addresses, one for each network family. Each deposit becomes an offramp order on its own. Pulse checks the deposit, converts it at the current rate, and pays naira to the collection's payout account.

Add a payout account

Register the bank account that receives the naira. Pulse verifies it with the bank.

Create a collection

Create one collection for each user. The response contains the user's deposit addresses.

Track deposits

Each deposit sends the order webhooks, carrying your collection reference.

Add a payout account

A payout account is a recipient. Send the bank code and the 10-digit account number. Pulse verifies the account with the bank and returns the registered name. Check the name before you use the account.

curl -X POST "https://engine-api.pilot.pulseshiga.io/v1/recipients" \
  -H "X-API-Key: <your key>" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "bank_account",
    "is_default": true,
    "bank_account": { "bank_code": "058", "account_number": "0123456789" }
  }'
{
  "status": true,
  "data": {
    "id": "0199d1a4-…",
    "type": "bank_account",
    "is_default": true,
    "bank_account": {
      "bank_code": "058",
      "bank_name": "GTBank",
      "account_number": "0123456789",
      "account_name": "ACME SAVINGS LTD"
    },
    "created_at": "2026-10-15T09:12:40Z"
  }
}

Get bank codes from GET /v1/banks.

The default account

Set is_default: true on one bank account. A collection created without recipient_id pays out to the default account. Setting a new default replaces the previous one.

You can register several accounts and give each collection its own. For example, pay each user's deposits to that user's own bank account.

Delete an account

DELETE /v1/recipients/{id} removes an account. Pulse refuses with recipient_in_use while a collection uses the account, or while orders paying to it are not finished. Move those collections to another account first.

Create a collection

Create one collection for each user. Set reference to your own ID for that user, up to 128 characters.

curl -X POST "https://engine-api.pilot.pulseshiga.io/v1/collections" \
  -H "X-API-Key: <your key>" \
  -H "Content-Type: application/json" \
  -d '{
    "reference": "user-48213",
    "recipient_id": "0199d1a4-…",
    "customer": { "name": "Ada Obi", "email": "ada@example.com" }
  }'
{
  "status": true,
  "data": {
    "id": "0199d1b7-…",
    "reference": "user-48213",
    "type": "offramp",
    "status": "active",
    "recipient_id": "0199d1a4-…",
    "customer": { "name": "Ada Obi", "email": "ada@example.com" },
    "deposit_addresses": [
      {
        "address": "0x64e6e8b84beb0ba8ab43a09d4b8a48aa23ecc394",
        "networks": ["BASE", "POLYGON", "ARBITRUM", "OPTIMISM", "ETHEREUM", "CELO", "PLASMA"]
      },
      {
        "address": "9S1Pdxe5K6ZRmMZUrZDgig33udTb5TScRehXmYiP69he",
        "networks": ["SOLANA"]
      }
    ],
    "created_at": "2026-10-15T09:14:02Z"
  }
}

Leave out recipient_id to pay out to your default account. Without a default account, the request returns no_default_recipient.

Deposit addresses

Show your user every entry in deposit_addresses. One EVM address serves every network in its networks list. A Solana address serves SOLANA only. Read the networks from the response rather than from this page.

The user can send USDT or USDC only where the network supports that asset. PLASMA supports USDT only. See Supported networks for the assets on each network.

Send on a listed network

A deposit on a network the address does not list is held, and may not be recoverable.

Reference and retries

reference makes the request safe to retry. Sending the same reference again returns the existing collection, with the same addresses. Pulse ignores the other fields on a repeat request. Use PATCH /v1/collections/{id} to change the payout account.

Customer details

customer.name and customer.email are required. Your user is the person who owns the addresses.

Track deposits

Each deposit creates an offramp order and sends the order webhooks:

order.payment_received
      ↓
order.conversion_initiated
      ↓
order.payout_initiated
      ↓
order.completed

order.held               ← instead, when Pulse cannot process the deposit

A deposit has no order.awaiting_payment event, because the payment arrives before the order exists.

Every event carries your collection reference, so you can match each deposit to your user. order.payment_received also carries the deposit's transaction_hash, the sender's from_address, and a payout object with the naira amount and rate. See order.payment_received.

To list a collection's deposits, filter orders by collection_id:

curl "https://engine-api.pilot.pulseshiga.io/v1/orders?collection_id=0199d1b7-…" \
  -H "X-API-Key: <your key>"

last_deposit_at on the collection shows when its latest deposit arrived.

Held deposits

Pulse holds a deposit it cannot convert automatically, and sends order.held with a held_reason. The order status is held.

held_reasonMeaning
unsupported_networkThe deposit arrived on a network Pulse does not support.
unsupported_currencyThe asset is not USDT or USDC.
collection_disabledThe collection was disabled when the deposit arrived.
below_minimumThe deposit is below 10 USDT or USDC.
above_maximumThe deposit is worth more than ₦100,000,000.
no_routePulse could not price the deposit at that moment.

Held funds stay with Pulse. Contact support with the order ID to resolve a held deposit.

Manage collections

RequestWhat it does
GET /v1/collectionsLists your collections, newest first. Filter by reference, status, from, and to.
GET /v1/collections/{id}Gets one collection with its addresses.
PATCH /v1/collections/{id}Changes recipient_id, or sets status to active or disabled.

Disabling a collection keeps its addresses. Pulse holds any deposit that arrives while the collection is disabled. Set it back to active to resume conversions.

A new recipient_id applies to deposits that arrive after the change.

Errors

CodeMeaning
account_verification_failedThe bank could not verify the account. Check the bank code and account number.
recipient_not_foundrecipient_id does not match one of your payout accounts.
no_default_recipientSend recipient_id, or set a default payout account.
recipient_in_useA collection or an unfinished order still uses this account.
default_recipient_conflictAnother default was set at the same time. Retry.
collection_not_foundThe collection does not exist for your business.

See Errors and retries for the response shape.

On this page