Collections API

Initiate and track fiat pay-ins that fund your Caibo balance.

Rolling out. Fiat rails (Interac e-Transfer, ACH/EFT) are being enabled progressively. In production these endpoints return 503 provider_unavailable until your organization's collection rail is switched on. The contract below is stable — integrate against it now. See the flow of funds for how a collection settles into your balance.

A collection is an inbound fiat payment from your customer. You create it, hand the customer the returned payment instructions (an Interac e-Transfer target, or an ACH/EFT virtual account), and Caibo's regulated collection provider receives the funds and settles them to USDC on your organization's balance. That balance then funds outbound payouts and fiat payouts.

Create a collection

POST /v1/collections — Scope: collections:write

Creates a collection and returns the payment instructions to present to your customer. Interac e-Transfer is the first supported method for Canadian (CAD) pay-ins; ACH/EFT are part of the same rail.

Headers

HeaderRequiredDescription
X-API-KeyYesYour API key.
Content-TypeYesapplication/json
Idempotency-KeyYesA unique value per logical collection. Retries with the same key return the original collection. See Idempotency.

Body parameters

FieldTypeRequiredDescription
amountstringYesDecimal amount > 0 to collect, e.g. "500.00".
currencystringYesSource fiat currency. CAD for Interac e-Transfer.
methodstringYesOne of interac_etransfer, ach, eft. Must be enabled for your organization.
customer_referencestringNoYour own identifier for the paying customer. Echoed back.
metadataobjectNoArbitrary key/value pairs echoed back on the collection.

Request

bash
curl https://api.caiboglobal.com/v1/collections \
  -H "X-API-Key: $CAIBO_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 3d9c8b7a-1e2f-4a5b-8c9d-0e1f2a3b4c5d" \
  -d '{
    "amount": "500.00",
    "currency": "CAD",
    "method": "interac_etransfer",
    "customer_reference": "cust_88",
    "metadata": { "invoice_id": "INV-2043" }
  }'

Response — 201 Created

Returns the collection with payment_instructions for the chosen method. The shape of payment_instructions depends on method: an Interac e-Transfer target for interac_etransfer, or a virtual account for ach/eft.

json
{
  "id": "col_7a1b2c3d4e5f",
  "object": "collection",
  "status": "awaiting_payment",
  "mode": "live",
  "amount": "500.00",
  "currency": "CAD",
  "method": "interac_etransfer",
  "payment_instructions": {
    "type": "interac_etransfer",
    "send_to": "collect@caiboglobal.com",
    "reference": "CAI-7A1B2C3D",
    "auto_deposit": true
  },
  "customer_reference": "cust_88",
  "metadata": { "invoice_id": "INV-2043" },
  "expires_at": "2026-07-24T14:03:00Z",
  "created_at": "2026-07-23T14:03:00Z"
}

Your customer sends an Interac e-Transfer to send_to and includes reference in the message field. Auto-deposit is enabled, so no security question is required. The collection stays awaiting_payment until the provider receives the funds.

Behavior

  • Instructions are per-collection. Always show the reference from the response — it's how an incoming transfer is matched to this collection.
  • Settlement funds your balance. Once received, the pay-in is settled to USDC and credited to your balance. Track this with the collection.settled webhook.
  • Idempotent. Reusing the Idempotency-Key with the same body returns the original collection; with a different body it returns 409 idempotency_conflict.
  • Expiry. A collection that isn't paid before expires_at moves to expired. Create a new one to retry.

Errors

HTTPtypecodeWhen
400invalid_request_errorbad_requestMissing Idempotency-Key, malformed body, or an invalid amount.
401authentication_errorapi_key_missing / api_key_invalidNo key, or an unknown/revoked key.
403permission_errorscope_insufficientThe key lacks collections:write.
403compliance_errorkyb_requiredLive mode with an unverified business.
409invalid_request_erroridempotency_conflictThe idempotency key was reused with a different request.
422invalid_request_errorunsupported_methodThe method or currency is not enabled for your organization.
429rate_limit_errorrate_limitedToo many requests. Back off and retry.
503api_errorprovider_unavailableThe collection rail is not yet enabled for your organization (rolling out) or is temporarily unavailable.

Collection state machine

A collection has a status. It starts at awaiting_payment and ends in a terminal state once it settles, fails, or expires.

text
awaiting_payment ──▶ received ──▶ settled   (USDC credited to your balance)
        │                │
        ▼                ▼
     expired          failed
        │
(cancel before payment) ──▶ cancelled
StatusMeaningTerminal?
awaiting_paymentCreated; waiting for the customer to send funds.No
receivedThe provider has received the customer's payment.No
settledSettled to USDC and credited to your balance.Yes
failedThe pay-in failed or was returned by the provider.Yes
expiredNo payment arrived before expires_at.Yes
cancelledYou cancelled the collection before payment arrived.Yes

Webhooks

Register for these on your webhook endpoints. Each delivery is signed with Caibo-Signature; verify it as described in the Webhooks guide.

EventFires whenStatus
collection.receivedThe provider receives the customer's payment.received
collection.settledFunds are settled to USDC and credited to your balance.settled
collection.failedThe pay-in failed or was returned.failed
collection.expiredNo payment arrived before expiry.expired
json
{
  "event": "collection.settled",
  "object": "collection",
  "id": "col_7a1b2c3d4e5f",
  "status": "settled",
  "amount": "500.00",
  "currency": "CAD",
  "mode": "live",
  "method": "interac_etransfer",
  "settled_asset": "USDC",
  "settled_amount": "366.00",
  "created_at": "2026-07-23T14:03:00Z"
}
The webhook payload is a snapshot. For anything critical, re-fetch the collection with GET /v1/collections/{id} to confirm its current state.

Retrieve a collection

GET /v1/collections/{id} — Scope: collections:read

Fetches a single collection by id. Returns 404 resource_missing if it doesn't exist or isn't yours.

bash
curl https://api.caiboglobal.com/v1/collections/col_7a1b2c3d4e5f \
  -H "X-API-Key: $CAIBO_API_KEY"

Errors

HTTPtypecodeWhen
401authentication_errorapi_key_missing / api_key_invalidNo key, or an unknown/revoked key.
403permission_errorscope_insufficientThe key lacks collections:read.
404invalid_request_errorresource_missingNo such collection for your organization.

List collections

GET /v1/collections — Scope: collections:read

Returns your organization's collections, newest first, cursor-paginated.

Query parameters

ParameterTypeDescription
limitintegerPage size, 1–100. Defaults to 25.
starting_afterstringA collection id; returns the page after it. See Pagination.
statusstringFilter by a single status, e.g. settled.

Request

bash
curl "https://api.caiboglobal.com/v1/collections?limit=25&status=settled" \
  -H "X-API-Key: $CAIBO_API_KEY"

Response — 200 OK

json
{
  "object": "list",
  "data": [
    {
      "id": "col_7a1b2c3d4e5f",
      "object": "collection",
      "status": "settled",
      "mode": "live",
      "amount": "500.00",
      "currency": "CAD",
      "method": "interac_etransfer",
      "created_at": "2026-07-23T14:03:00Z"
    }
  ],
  "has_more": true,
  "next_cursor": "col_7a1b2c3d4e5f"
}

Errors

HTTPtypecodeWhen
401authentication_errorapi_key_missing / api_key_invalidNo key, or an unknown/revoked key.
403permission_errorscope_insufficientThe key lacks collections:read.
429rate_limit_errorrate_limitedToo many requests.