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
| Header | Required | Description |
|---|---|---|
X-API-Key | Yes | Your API key. |
Content-Type | Yes | application/json |
Idempotency-Key | Yes | A unique value per logical collection. Retries with the same key return the original collection. See Idempotency. |
Body parameters
| Field | Type | Required | Description |
|---|---|---|---|
amount | string | Yes | Decimal amount > 0 to collect, e.g. "500.00". |
currency | string | Yes | Source fiat currency. CAD for Interac e-Transfer. |
method | string | Yes | One of interac_etransfer, ach, eft. Must be enabled for your organization. |
customer_reference | string | No | Your own identifier for the paying customer. Echoed back. |
metadata | object | No | Arbitrary key/value pairs echoed back on the collection. |
Request
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.
{
"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
referencefrom 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.settledwebhook. - Idempotent. Reusing the
Idempotency-Keywith the same body returns the original collection; with a different body it returns409 idempotency_conflict. - Expiry. A collection that isn't paid before
expires_atmoves toexpired. Create a new one to retry.
Errors
| HTTP | type | code | When |
|---|---|---|---|
| 400 | invalid_request_error | bad_request | Missing Idempotency-Key, malformed body, or an invalid amount. |
| 401 | authentication_error | api_key_missing / api_key_invalid | No key, or an unknown/revoked key. |
| 403 | permission_error | scope_insufficient | The key lacks collections:write. |
| 403 | compliance_error | kyb_required | Live mode with an unverified business. |
| 409 | invalid_request_error | idempotency_conflict | The idempotency key was reused with a different request. |
| 422 | invalid_request_error | unsupported_method | The method or currency is not enabled for your organization. |
| 429 | rate_limit_error | rate_limited | Too many requests. Back off and retry. |
| 503 | api_error | provider_unavailable | The 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.
awaiting_payment ──▶ received ──▶ settled (USDC credited to your balance)
│ │
▼ ▼
expired failed
│
(cancel before payment) ──▶ cancelled| Status | Meaning | Terminal? |
|---|---|---|
awaiting_payment | Created; waiting for the customer to send funds. | No |
received | The provider has received the customer's payment. | No |
settled | Settled to USDC and credited to your balance. | Yes |
failed | The pay-in failed or was returned by the provider. | Yes |
expired | No payment arrived before expires_at. | Yes |
cancelled | You 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.
| Event | Fires when | Status |
|---|---|---|
collection.received | The provider receives the customer's payment. | received |
collection.settled | Funds are settled to USDC and credited to your balance. | settled |
collection.failed | The pay-in failed or was returned. | failed |
collection.expired | No payment arrived before expiry. | expired |
{
"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.
curl https://api.caiboglobal.com/v1/collections/col_7a1b2c3d4e5f \
-H "X-API-Key: $CAIBO_API_KEY"Errors
| HTTP | type | code | When |
|---|---|---|---|
| 401 | authentication_error | api_key_missing / api_key_invalid | No key, or an unknown/revoked key. |
| 403 | permission_error | scope_insufficient | The key lacks collections:read. |
| 404 | invalid_request_error | resource_missing | No such collection for your organization. |
List collections
GET /v1/collections — Scope: collections:read
Returns your organization's collections, newest first, cursor-paginated.
Query parameters
| Parameter | Type | Description |
|---|---|---|
limit | integer | Page size, 1–100. Defaults to 25. |
starting_after | string | A collection id; returns the page after it. See Pagination. |
status | string | Filter by a single status, e.g. settled. |
Request
curl "https://api.caiboglobal.com/v1/collections?limit=25&status=settled" \
-H "X-API-Key: $CAIBO_API_KEY"Response — 200 OK
{
"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
| HTTP | type | code | When |
|---|---|---|---|
| 401 | authentication_error | api_key_missing / api_key_invalid | No key, or an unknown/revoked key. |
| 403 | permission_error | scope_insufficient | The key lacks collections:read. |
| 429 | rate_limit_error | rate_limited | Too many requests. |