Download OpenAPI specification:
Draft for review. This is the Relay API v1 contract under review with customers and internal teams. It may change before release. An endpoint's presence here does not mean it is available today.
The Relay API moves money between accounts in Pocket and out to external banks and networks.
internal, ach, wire, or ibft.It also reads balances, instruments and account activity.
Money operations are scoped to an account, referenced by id: a customer (cus_…) or a
business or sub-account (biz_…). The same money endpoints work for either type.
Pocket publishes this OpenAPI contract rather than generated client SDKs.
| Resource | Purpose |
|---|---|
| Accounts | Create and manage sub-accounts, balances, and the member roster. |
| Transactions | Read a unified money-movement activity feed. |
| Transfers | Create, list, and retrieve outbound money movements. |
| Deposits | List and retrieve inbound money movements. |
| FX quotes | Price a cross-currency transfer before creating it. |
| Instruments | Register external bank accounts used as withdrawal destinations. |
| Funding rules | Route matching settled deposits from a parent account into a sub-account. |
| Events | Read and replay event notifications, and configure webhook delivery. |
A transfer moves money out of an account. A deposit is money coming in.
An accepted internal (Pocket-to-Pocket) move creates one txn_ ID:
status set to pending.Transactions form the unified activity feed. When a transfer or deposit object exists, the
feed points to it. A pending movement has not posted to either balance:
available to reserved.settled amount remains unchanged.settled together.settled and available amounts are
credited.Clients create transfers, not deposits. Pocket creates deposits for incoming Automated Clearing House (ACH) payments, the destination side of internal transfers and Pocket-funded advances or rewards.
Card refunds appear in the activity feed as deposits, but do not have deposit objects.
Authorization is based on the account hierarchy associated with the API key. A key may act only on its associated account and that account's complete owned sub-account hierarchy.
Each bearer API key is associated with one account:
Authorization: Bearer <api_key>
401 unauthorized.An account outside that hierarchy, or a resource belonging to it, returns 404 as if it did
not exist. 403 is reserved for actions the key may not perform on an account in the hierarchy.
API keys also carry capability scopes. Each operation states its required scopes at the start
of its description and in x-required-scopes for tooling. The key needs every listed scope.
Scopes control what a key may do. Its account hierarchy controls which accounts it may act on.
403 for a resource in that hierarchy.404.Broad scopes satisfy granular requirements:
read satisfies any *:read requirement.write satisfies any *:write or *:read requirement.*:write scope includes the corresponding *:read operations and the reads
needed to perform and inspect that write. For example, transfers:write permits the source
balance details returned while creating a transfer.write.Available scopes:
| Scope | Permits |
|---|---|
read |
All current read operations. |
write |
All current read and write operations. |
accounts:read / accounts:write |
Account records and metadata. |
balances:read |
Account balances. |
transactions:read |
Unified money-movement activity. |
transfers:read / transfers:write |
Outbound money movement. |
deposits:read |
Inbound money movement. |
batches:read / batches:write |
Batch transfer jobs and line items. |
instruments:read / instruments:write |
External payment instruments. |
members:read / members:write |
Member rosters. |
funding_rules:read / funding_rules:write |
Funding rules and previews. |
webhooks:read / webhooks:write |
Webhook endpoint configuration and secrets. |
events:read / events:write |
Event log reads and event replay. |
Transfers are authorized from the source:
source.account_id must be the account associated with the API key or one of its
sub-accounts.transfers:write applies across every eligible account in that hierarchy, subject to account
state and method-specific requirements.Sending money to an account does not grant read access or any other access to it.
A business may keep a roster of customers it pays. A member is a reference to a Pocket customer account, not delegated access to that account.
404 unless the account is in the hierarchy associated with the API key.An external payment instrument (epi_…) is a verified outside destination for money leaving
Pocket, such as a bank account.
A business can create, list, remove, and use instruments only for accounts in the hierarchy associated with the API key. A roster relationship does not change that rule.
Money-movement field visibility:
memo is the payment note and may be visible to both sides.reference and metadata are visible only from the account-owner side on which they were
set.A counterparty does not see your reference or metadata. A key that owns both sides can read both account-relative views.
An account is a money-holding party identified by a prefixed id (biz_… or cus_…).
id.The optional reference is an opaque, non-unique external reference. Use the reference
filter on list accounts or list balances to find matches; a filter may return more than one.
A wrong-prefix ID for an operation returns 400.
Amounts are decimal strings in major units of the currency. For example, "100.00" means
100 USD. USD supports at most two decimal places.
"9999999999999999.99"."1", "1.0", "1.00", "0.01", and "2500.50"."1", "1.0", and "1.00" produce the same idempotency
request fingerprint.Pocket rejects an amount outside this boundary with 400 invalid_request; param identifies
the actual request field, such as amount, source_amount, or items[n].amount. No resource
is created or changed, and the idempotency_key is not bound.
A USD-to-PKR Inter Bank Funds Transfer (IBFT) can use an explicit quote or accept the current price as part of transfer creation.
net_source_amount equals source_amount minus the sum of source-currency fees.400 invalid_request, with param identifying the submitted source-amount field.rate is destination-currency units per one source-currency unit.destination_amount equals net_source_amount multiplied by rate, rounded half-even to
the destination currency's precision. PKR supports two decimal places.amount equals fx.source_amount, and currency equals
fx.source_currency (USD in v1).fx.destination_amount is the PKR amount delivered to the destination instrument.amount.Display and reconcile the amounts, fees and rate returned on the quote and transfer. Do not recompute them.
JSON request-body limits:
POST /v1/batches: 10 MiB (10,485,760 bytes).The limit applies to the UTF-8-encoded JSON body, including JSON syntax and whitespace but
excluding HTTP headers. Pocket enforces it even when Content-Length is absent.
An oversized body returns 413 Payload Too Large with code payload_too_large. The error has
no field-specific param.
An oversized request creates or changes nothing and does not bind its idempotency key. OpenAPI 3.0 cannot express these whole-body limits. A request can satisfy every field limit and still exceed the body limit.
All timestamps are strings in RFC 3339 / ISO 8601 format.
Z suffix, e.g. 2026-07-31T09:00:00Z.2026-07-31T14:00:00+05:00 and 2026-07-31T09:00:00Z are the same instant.A caller-supplied idempotency_key is required for:
POST requests for accounts, transfers, FX quotes, batches, instruments,
funding rules, and webhook endpoints.PATCH requests accept a key optionally. Without one, retrying after a lost response may apply
an update more than once.
Use a non-blank random value of 1–255 characters, such as a universally unique identifier (UUID). Mint it once per logical operation and reuse it only when retrying that operation.
All operations that accept an idempotency key share one namespace per associated account and environment.
The namespace spans:
PATCH requests.The namespace is not scoped by source account, endpoint, resource family or API credential. Keys associated with the same account share it, including after credential rotation. Sandbox and production use separate namespaces.
Each key identifies one logical operation during the retention window. Reusing it elsewhere in
the same namespace with a different request fingerprint returns 409.
The fingerprint covers:
Metadata key order does not affect the hash. Amounts are compared as decimals, so "10.4" and
"10.40" are equivalent.
A key is bound by the first request that succeeds with a 2xx response. The binding lasts at least 24 hours.
409.409 until the
original completes.A failed request that creates or updates nothing leaves an unbound key available. This includes
resource-state 409 responses. Retry the unchanged operation with the same key.
Quote creation and transfer creation are separate logical operations and use separate keys. For an IBFT transfer request:
A 409 means one of the following:
When retrying after an error:
409 idempotency_conflict, never change the request while reusing the key. Retry an
unchanged in-flight duplicate, or retrieve existing_id when one is returned.409 that created no object, the key remains unbound. Retry the
unchanged request with the same key. Mint a new key if the financial instruction changes.After the retention window expires, a key may be treated as new and can create a second object.
idempotency_key is not returned on objects and is not a business identifier. To store a
pay-run, invoice, employee, or other external ID, use the filterable reference field.
One-time values are never replayed. A webhook secret appears only in the original successful
create or rotate response.
If that response is lost, the same idempotency_key will not recover the secret. Rotate with a
new key to get a fresh one.
Lists return { data, has_more, next_cursor }. Ordering varies by endpoint. A valid
next_cursor continues the first page's ordering.
next_cursor back as cursor, together with limit.400.400.After a cursor error, restart from the first page.
Query filters accept one value unless stated otherwise. The money-movement method filter
accepts a comma-separated list, for example method=ach,wire. Each endpoint accepts only the
methods it can return. An unsupported method returns 400 with code invalid_request and
param=method.
Any endpoint may return 429 with code rate_limited and a Retry-After header when you
exceed the rate limit. Its value is a non-negative base-10 integer giving the number of seconds
to wait after receiving the response. Pocket does not use the HTTP-date form.
For example, Retry-After: 30 means wait at least 30 seconds before retrying.
Error responses use one JSON shape:
{
"code": "invalid_request",
"message": "destination.account_id has an unexpected prefix",
"param": "destination.account_id",
"request_id": "req_01jj0m9w2k3n5p7q9r1s3t5v7w"
}
code is the stable, machine-readable reason. Preserve unknown codes and fall back to the
HTTP status.message explains the error to a human. Do not branch on its wording.param identifies the request field involved, when applicable; otherwise it is absent or
null.request_id identifies the request. Include it when contacting Pocket support.Common HTTP statuses:
| Status | Meaning |
|---|---|
400 |
Malformed input or failed validation. |
401 |
Missing or invalid authentication. |
402 |
The source has insufficient available funds. |
403 |
The key lacks a required scope or cannot act on a visible resource. |
404 |
The resource does not exist or is outside the account hierarchy associated with the API key. |
409 |
The request conflicts with current resource or idempotency state. |
413 |
The UTF-8 JSON request body exceeds the endpoint's limit. |
429 |
A rate limit was exceeded. Wait for the seconds specified by Retry-After. |
500 |
Pocket encountered an internal error. |
503 |
Pricing or another temporary dependency is unavailable. Follow Retry-After when present. |
Reads can be retried after transient server failures. After a timeout or 500 on a
money-writing request, retry only with the same idempotency_key; see Idempotency above.
When webhook delivery is enabled, every request carries a Pocket-Signature header. Use it
to verify that the request came from Pocket and was not altered in transit.
Verify the signature before acting on the payload.
Treat the event as a hint, not the source of truth. Fetch the resource named by subject to
read its current state. Retrieving the event returns its immutable notification envelope, not
the current subject state.
The header is a comma-separated list of fields:
Pocket-Signature: t=1690794000,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd
t: the Unix timestamp (seconds) when we signed the request.v1: a hex-encoded HMAC using the SHA-256 hash function. There may be more than one
v1 value (space- or comma-separated) during secret rotation; a request is valid if any
matches.The signing secret is returned when you create a webhook endpoint or call rotate_secret. It
is shown only in those responses, so store it.
To verify a request:
t and the v1 value(s) from the Pocket-Signature header.t, a literal ., and the raw body:
signed_payload = t + "." + raw_body.HMAC-SHA256(signed_payload, secret) and hex-encode it.v1. If none match, reject the request.t is outside your tolerance for the current time (we recommend 5 minutes) to
guard against replay.During rotate_secret, Pocket signs with both secrets for a grace period. Verify against both
until you have switched to the new secret.
1. Add the employee to the member roster
Supply the identifiers you know. This example uses email and phone:
POST /v1/accounts/{biz_account_id}/members
{
"email": "employee@example.com",
"phone": "+12025550123",
"metadata": {
"employee_id": "EMP-1042"
}
}
The response returns the roster relationship and its customer_id.
201 Created and its relative URL in the
Location header.200 OK.onboarding_required.2. Wait until the employee can be paid
Retrieve the member using the returned customer_id:
GET /v1/accounts/{biz_account_id}/members/{customer_id}
Include the employee in payroll when capabilities.can_receive_transfers is true.
1. Submit the payroll transfers
Give each employee a unique item_id for this batch. Use the employee's customer_id as the
destination account ID.
POST /v1/batches
{
"idempotency_key": "a15e4ae4-52f3-460c-9c1c-5f6b7b90cc44",
"source": { "account_id": "biz_..." },
"recipient_policy": "payable_members",
"reference": "payroll-2026-07",
"items": [
{
"item_id": "line-001",
"destination": { "account_id": "cus_..." },
"amount": "100.00",
"currency": "USD",
"reference": "EMP-1042"
},
{
"item_id": "line-002",
"destination": { "account_id": "cus_..." },
"amount": "120.00",
"currency": "USD",
"reference": "EMP-1089"
}
]
}
The 202 response returns the batch and its batch_... ID.
2. Track the batch
GET /v1/batches/{batch_id}
When every transfer settles, status becomes completed and item_counts.settled equals
item_counts.total.
3. Reconcile each employee
GET /v1/batches/{batch_id}/items
Match each result to the submitted line by item_id. Its transfer_id is the resulting
txn_... ID.
Send money to a Pocket customer or another Pocket account:
POST /v1/transfers/internal
{
"idempotency_key": "d9f80740-7f8e-4f16-b5cc-4fd5bf7d3b21",
"source": { "account_id": "biz_..." },
"destination": { "account_id": "cus_..." },
"amount": "100.00",
"currency": "USD",
"reference": "payrun-2026-07"
}
Read the business's balances and activity. Use parent_id to limit balances to the direct
sub-accounts of one business account.
GET /v1/balances
GET /v1/balances?parent_id=biz_...
GET /v1/transactions?account_id=biz_...
1. Create the child account
POST /v1/accounts
{
"idempotency_key": "7a4409dc-5612-41d9-8e5d-e2fbfb657f83",
"parent_id": "biz_...",
"name": "Payroll operations",
"reference": "payroll-operations"
}
The returned child account is active and can be used as a funding-rule destination.
2. Preview the matching criteria
POST /v1/accounts/{parent_account_id}/funding_rules/preview
{
"criteria": [
{ "field": "sender_name", "operator": "contains", "value": "ACME PAYROLL" }
]
}
Use the preview results to confirm the criteria match the intended settled deposits.
3. Create the funding rule
POST /v1/accounts/{parent_account_id}/funding_rules
{
"idempotency_key": "c20d05c2-40c6-48f6-b2b7-a1aaac33370c",
"destination_account_id": "biz_...",
"criteria": [
{ "field": "sender_name", "operator": "contains", "value": "ACME PAYROLL" }
]
}
The rule begins enabled. When a matching deposit into the parent account settles, its full
amount moves to the child account as an internal transfer.
4. View transfers created by the rule
GET /v1/transfers?funding_rule_id={funding_rule_id}
Withdraw from a business-owned balance to that account's own external instrument.
1. Register the external bank instrument
POST /v1/accounts/{biz_account_id}/instruments
{
"idempotency_key": "b57ba9a4-0f17-4c5d-99cd-e1467069270e",
"type": "bank_account",
"currency": "USD",
"bank_account": {
"holder_name": "Example Business LLC",
"account_number": "000123456789",
"routing_number": "021000021",
"country": "US"
}
}
2. Check the review status
If a newly registered instrument is in_review, poll it while that status remains:
GET /v1/instruments/{instrument_id}
Proceed only when the instrument is approved. declined is terminal; correct the bank
details and register a new instrument.
3. Create the withdrawal
Use the method-specific endpoint. For ACH:
POST /v1/transfers/ach
{
"idempotency_key": "15dfe9e2-04e2-4e9a-b448-2d71c46c2219",
"source": { "account_id": "biz_..." },
"destination": { "instrument_id": "epi_..." },
"amount": "500.00",
"currency": "USD",
"memo": "PAYROLL"
}
Use POST /v1/transfers/wire instead for a wire withdrawal. ACH and wire have different
memo limits; see the endpoint request schemas.
To withdraw USD converted to PKR, see Withdraw USD as PKR.
Convert USD and withdraw the resolved PKR amount through Pocket's instant IBFT route to the source account's own approved Pakistani bank instrument. V1 does not expose the standard PKR cash-out route and does not promise a delivery time.
1. Find a supported bank
GET /v1/banks?country=PK&method=ibft
Use the returned code when registering the bank account.
2. Register the PKR instrument
POST /v1/accounts/{biz_account_id}/instruments
{
"idempotency_key": "0b57ba9a-4f17-4c5d-99cd-e14670692710",
"type": "bank_account",
"currency": "PKR",
"bank_account": {
"country": "PK",
"bank_code": "hbl",
"account_number": "PK16HABB1234567890123456"
}
}
account_number may be a supported local account number or Pakistani International Bank
Account Number (IBAN). If the instrument is in_review, poll it while that status remains.
Proceed only when it is approved. If it is declined, correct the bank details and
register a new instrument.
3. Request a quote
POST /v1/fx_quotes
{
"idempotency_key": "9f1c2a34-6a3d-4e0b-9c7e-2f8b1d5a7e21",
"source": { "account_id": "biz_..." },
"destination": { "instrument_id": "epi_..." },
"method": "ibft",
"source_amount": "1000.00",
"source_currency": "USD",
"destination_currency": "PKR"
}
The response fixes the rate, fees and PKR amount until expires_at, while the quote remains
open. The quote cannot be accepted at or after expires_at. Creating it does not reserve
USD.
4. Create the transfer
POST /v1/transfers/ibft
{
"idempotency_key": "b2e6d1f0-3c44-4d55-8f66-77a889900abc",
"source": { "account_id": "biz_..." },
"destination": { "instrument_id": "epi_..." },
"amount": "1000.00",
"currency": "USD",
"destination_currency": "PKR",
"pricing": {
"mode": "quote",
"quote_id": "fxq_..."
},
"reference": "cashout-1042"
}
To skip the separate quote request, use pricing.mode=current. Pocket then creates and
accepts an equivalent quote as part of transfer creation. If the request fails, neither the
quote nor the transfer is created. Add minimum_destination_amount when the transfer must
not proceed below a particular PKR amount.
5. Track the withdrawal
Poll GET /v1/transfers/{transfer_id} until the transfer is terminal. amount is the
gross USD debit; fx contains the fee, rate and PKR amount to reconcile. A failed transfer
releases the full USD reservation and is not automatically retried.
Money-movement activity across the account hierarchy associated with the API key. It includes transfers, deposits and the transaction entry for each account-relative view. Pending entries are visible before they post to a balance.
Use the transaction ID to fetch the transfer or deposit object when one exists.
Required scope: transactions:read.
List money-movement activity across the account hierarchy associated with the API key. Rostered customer activity is excluded unless the customer account independently belongs to that hierarchy.
Narrow results with account_id, kind, method, status, amount, reference, created
date, or settled date.
When account_id is supplied, it selects one owned account's viewpoint.
Each item is a transaction (txn_…) seen from one account's side:
(id, account_id).txn_… can appear twice when both sides of an internal move are in the account
hierarchy associated with the API key.kind and id to fetch a transfer or deposit object when one exists.An accepted internal transfer creates both authorized account-relative views at once:
kind=transfer and begins pending.kind=deposit and begins pending.settled, failed, or voided together.A rejected request creates no feed entry, transfer or deposit.
details carries method-specific facts and may gain fields before settlement. Events are
references, not snapshots; fetch the transaction for its current details.
If you sent money to a customer account, your feed shows your transfer and its status, not the customer's resulting balance or unrelated activity. Verification microdeposits, declined card authorizations, and Pocket-internal treasury operations are excluded.
The v1 feed does not model post-settlement returns or reversals. A future return will be a new balance-moving entry, not a change to an already settled status.
| account_id | string Example: account_id=biz_01j8ma3wv3mepwabfxxs0yc395 Select the viewpoint of the account associated with the API key or one of its sub-accounts. Roster membership is not sufficient.
|
| kind | string (TransactionKind) Enum: "transfer" "deposit" Example: kind=deposit Only transfers (outbound) or only deposits (inbound). |
| method | Array of strings (Method) Items Enum: "internal" "ach" "wire" "ibft" "swift" "faster_payments" "payment_link" "card" Example: method=ach,wire Filter transactions by method. Comma-separate to match more than one (e.g. |
| status | string (TransactionStatus) Enum: "pending" "settled" "failed" "voided"
|
| amount_min | string (MoneyAmount) <= 19 characters ^(?:0(?:\.[0-9]{1,2})?|[1-9][0-9]{0,15}(?:\.[... Example: amount_min=100.00 Minimum amount (inclusive), as a decimal string in major units, e.g. |
| amount_max | string (MoneyAmount) <= 19 characters ^(?:0(?:\.[0-9]{1,2})?|[1-9][0-9]{0,15}(?:\.[... Example: amount_max=100.00 Maximum amount (inclusive), as a decimal string in major units, e.g. |
| reference | string Exact match on your opaque |
| created_after | string <date-time> Example: created_after=2026-07-31T09:00:00Z Only items created at/after this time (inclusive). |
| created_before | string <date-time> Example: created_before=2026-07-31T09:00:00Z Only items created at/before this time (inclusive). |
| settled_after | string <date-time> Example: settled_after=2026-07-31T09:00:00Z Only items settled at/after this time (inclusive). Pending, failed, and voided items have no settlement time and are excluded when this filter is used. |
| settled_before | string <date-time> Example: settled_before=2026-07-31T09:00:00Z Only items settled at/before this time (inclusive). Pending, failed, and voided items have no settlement time and are excluded when this filter is used. |
| cursor | string Opaque cursor ( |
| limit | integer [ 1 .. 100 ] Default: 25 |
{- "has_more": true,
- "next_cursor": "string",
- "data": [
- {
- "id": "txn_01jjftqbz0n1vzey0pqrq3qmnn",
- "account_id": "biz_01j8ma3wv3mepwabfxxs0yc395",
- "kind": "deposit",
- "method": "ach",
- "source": null,
- "destination": {
- "account_id": "biz_01j8ma3wv3mepwabfxxs0yc395"
}, - "amount": "2500.00",
- "currency": "USD",
- "status": "settled",
- "fx": null,
- "metadata": { },
- "details": {
- "ach": {
- "sender_name": "PAISMO INC",
- "trace_number": "021000021234567"
}
}, - "created_at": "2026-07-30T14:10:00Z",
- "settled_at": "2026-07-31T09:00:00Z"
}
]
}Required scope: transactions:read.
Fetch one transaction entry by ID, e.g. /v1/transactions/txn_….
A transaction entry is one account's viewpoint on a money movement.
account_id
may be omitted.account_id; omitting it returns 400;
param is account_id.account_id returns 400; param is account_id.404.| transaction_id required | string^txn_ Example: txn_01jjftqbz0n1vzey0pqrq3qmnn |
| account_id | string Example: account_id=biz_01j8ma3wv3mepwabfxxs0yc395 Select one owned account's viewpoint of this transaction.
|
{- "id": "txn_01jjftqbz0n1vzey0pqrq3qmnn",
- "account_id": "biz_01j8ma3wv3mepwabfxxs0yc395",
- "kind": "deposit",
- "method": "ach",
- "source": null,
- "destination": {
- "account_id": "biz_01j8ma3wv3mepwabfxxs0yc395"
}, - "amount": "2500.00",
- "currency": "USD",
- "status": "settled",
- "fx": null,
- "metadata": { },
- "details": {
- "ach": {
- "sender_name": "PAISMO INC",
- "trace_number": "021000021234567"
}
}, - "created_at": "2026-07-30T14:10:00Z",
- "settled_at": "2026-07-31T09:00:00Z"
}Move money out of the account associated with the API key or one of its sub-accounts.
An internal transfer pays another Pocket account. ach and wire withdraw USD to the
source account's own approved external instrument. ibft converts USD and withdraws PKR
through Pocket's instant route to the source account's own approved Pakistani bank
instrument. V1 does not expose the standard PKR cash-out route or promise a delivery time.
Each method has its own write endpoint.
Required scope: transfers:read.
Outbound money movements across the account associated with the API key and its complete owned sub-account hierarchy.
Narrow results with method, source_id, destination_id, status, amount,
funding_rule_id, reference, created date, or settled date.
source_id restricts the list to one owned source account.
destination_id is a counterparty filter. It may identify a non-owned Pocket account or an
external instrument already visible on one of the customer's transfers.
| method | Array of strings (TransferMethod) Items Enum: "internal" "ach" "wire" "ibft" Example: method=ach,wire Filter transfers by method. Comma-separate to match more than one (e.g.
|
| source_id | string Filter by an owned source account ID ( |
| destination_id | string Filter by a Pocket account for internal transfers or an external instrument for withdrawals. The destination may be non-owned.
|
| status | string (TransferStatus) Enum: "pending" "settled" "failed" "voided"
|
| amount_min | string (MoneyAmount) <= 19 characters ^(?:0(?:\.[0-9]{1,2})?|[1-9][0-9]{0,15}(?:\.[... Example: amount_min=100.00 Minimum amount (inclusive), as a decimal string in major units, e.g. |
| amount_max | string (MoneyAmount) <= 19 characters ^(?:0(?:\.[0-9]{1,2})?|[1-9][0-9]{0,15}(?:\.[... Example: amount_max=100.00 Maximum amount (inclusive), as a decimal string in major units, e.g. |
| funding_rule_id | string Only transfers or deposits initiated by this funding rule ( |
| reference | string Exact match on your opaque |
| created_after | string <date-time> Example: created_after=2026-07-31T09:00:00Z Only items created at/after this time (inclusive). |
| created_before | string <date-time> Example: created_before=2026-07-31T09:00:00Z Only items created at/before this time (inclusive). |
| settled_after | string <date-time> Example: settled_after=2026-07-31T09:00:00Z Only items settled at/after this time (inclusive). Pending, failed, and voided items have no settlement time and are excluded when this filter is used. |
| settled_before | string <date-time> Example: settled_before=2026-07-31T09:00:00Z Only items settled at/before this time (inclusive). Pending, failed, and voided items have no settlement time and are excluded when this filter is used. |
| cursor | string Opaque cursor ( |
| limit | integer [ 1 .. 100 ] Default: 25 |
{- "has_more": true,
- "next_cursor": "string",
- "data": [
- {
- "id": "txn_01jhv705whdehqd34b4113r1q8",
- "method": "ach",
- "reference": "payrun-2026-07",
- "memo": "July salary",
- "source": {
- "account_id": "cus_01jm0defbbct46vh2ev5dkkhej"
}, - "destination": {
- "account_id": "cus_01jm0defbbct46vh2ev5dkkhej"
}, - "batch_id": "string",
- "funding_rule_id": "string",
- "amount": "100.00",
- "currency": "USD",
- "status": "pending",
- "failure_code": "string",
- "failure_message": "string",
- "fx": {
- "quote_id": "fxq_01k0f8ma3wv3mepwabfxxs0yc3",
- "fixed_side": "source",
- "source_amount": "100.00",
- "source_currency": "USD",
- "fees": [
- {
- "type": "transfer",
- "amount": "10.00",
- "currency": "USD"
}
], - "net_source_amount": "10.00",
- "rate": "280.00",
- "destination_amount": "277200.00",
- "destination_currency": "PKR"
}, - "details": {
- "ach": {
- "sender_name": "string",
- "description": "string",
- "sender_routing_number": "string",
- "trace_number": "021000021234567"
}
}, - "metadata": {
- "property1": "string",
- "property2": "string"
}, - "transitioned_at": {
- "pending": "2026-07-31T09:00:00Z",
- "settled": "2026-07-31T09:00:00Z",
- "failed": "2026-07-31T09:00:00Z",
- "voided": "2026-07-31T09:00:00Z"
}, - "created_at": "2026-07-31T09:00:00Z",
- "updated_at": "2026-07-31T09:00:00Z"
}
]
}Required scope: transfers:write.
Move funds from one Pocket account to another. source.account_id must be the account
associated with the API key or one of its sub-accounts; destination.account_id must be a
valid account that can receive funds. Sending money to a destination account does not grant
read or other access to it.
At acceptance
kind is transfer, method is internal, and status is pending.kind is deposit, method is internal, and status is pending.available decreases and reserved increases.settled and every destination balance amount remain unchanged.At settlement
Both views become settled. The source reservation posts out, and the destination
settled and available amounts are credited.
On failure or voiding
Both views remain visible with the terminal status. The source reservation is released, and the destination is never credited.
A request rejected before a txn_… is created produces no transfer, deposit, or
transaction resource.
| idempotency_key required | string [ 1 .. 255 ] characters .*\S.* Use a non-blank random value minted once for this create request so retries do not create duplicate transfers. |
required | object (TransferSource) Where a transfer pulls money from. This must be the account associated with the API key or one of its sub-accounts. In v1 this is a Pocket account. Supply exactly one key. |
required | object (AccountReference) A Pocket account ref ( |
| amount required | string (WriteAmount) <= 19 characters ^(?:0\.(?:0[1-9]|[1-9][0-9]?)|[1-9][0-9]{0,15... A positive amount to move, expressed as a JSON decimal string in major units. For example,
An invalid, non-positive or overflowing amount returns |
| currency required | string (Currency) Value: "USD" Currency debited from or credited to the Pocket account.
|
| reference | string <= 255 characters Your private external reference for this transfer (e.g. a pay-run or employee ID). Optional, not unique; filter by it. Counterparties do not see it. |
| memo | string <= 100 characters Payment note carried on the movement and visible to the destination account when the method supports a note. Internal transfer memos can be up to 100 characters; longer values are rejected with |
object (Metadata) <= 50 properties Up to 50 caller-defined string key/value pairs. An empty object is valid. Keys
OpenAPI 3.0 cannot express the key-length limit for arbitrary properties, so Pocket enforces
it at runtime. An invalid key returns Values
An overlong value returns Privacy Metadata is visible only from the account-owner side on which it was set and is not shared with money-movement counterparties. Use it for opaque business identifiers and non-sensitive labels only. Do not include:
Pocket may reject metadata that appears sensitive, but the caller remains responsible for the data it supplies. |
{- "idempotency_key": "d9f80740-7f8e-4f16-b5cc-4fd5bf7d3b21",
- "source": {
- "account_id": "biz_01j8ma3wv3mepwabfxxs0yc395"
}, - "destination": {
- "account_id": "cus_01jm0defbbct46vh2ev5dkkhej"
}, - "amount": "100.00",
- "currency": "USD",
- "reference": "payrun-2026-07",
- "memo": "July salary",
- "metadata": {
- "employee_ref": "emp-001"
}
}{- "id": "txn_01jhv705whdehqd34b4113r1q8",
- "method": "ach",
- "reference": "payrun-2026-07",
- "memo": "July salary",
- "source": {
- "account_id": "cus_01jm0defbbct46vh2ev5dkkhej"
}, - "destination": {
- "account_id": "cus_01jm0defbbct46vh2ev5dkkhej"
}, - "batch_id": "string",
- "funding_rule_id": "string",
- "amount": "100.00",
- "currency": "USD",
- "status": "pending",
- "failure_code": "string",
- "failure_message": "string",
- "fx": {
- "quote_id": "fxq_01k0f8ma3wv3mepwabfxxs0yc3",
- "fixed_side": "source",
- "source_amount": "100.00",
- "source_currency": "USD",
- "fees": [
- {
- "type": "transfer",
- "amount": "10.00",
- "currency": "USD"
}
], - "net_source_amount": "10.00",
- "rate": "280.00",
- "destination_amount": "277200.00",
- "destination_currency": "PKR"
}, - "details": {
- "ach": {
- "sender_name": "string",
- "description": "string",
- "sender_routing_number": "string",
- "trace_number": "021000021234567"
}
}, - "metadata": {
- "property1": "string",
- "property2": "string"
}, - "transitioned_at": {
- "pending": "2026-07-31T09:00:00Z",
- "settled": "2026-07-31T09:00:00Z",
- "failed": "2026-07-31T09:00:00Z",
- "voided": "2026-07-31T09:00:00Z"
}, - "created_at": "2026-07-31T09:00:00Z",
- "updated_at": "2026-07-31T09:00:00Z"
}Required scope: transfers:write.
Withdraw funds to an approved external bank instrument over ACH. This is self-withdrawal only.
epi_….The note (ACH company entry description) rides in memo. A destination instrument that is
not approved returns 403 with code instrument_not_approved.
| idempotency_key required | string [ 1 .. 255 ] characters .*\S.* Use a non-blank random value minted once for this create request so retries do not create duplicate transfers. |
required | object (TransferSource) Where a transfer pulls money from. This must be the account associated with the API key or one of its sub-accounts. In v1 this is a Pocket account. Supply exactly one key. |
required | object (InstrumentReference) An external instrument ref ( |
| amount required | string (WriteAmount) <= 19 characters ^(?:0\.(?:0[1-9]|[1-9][0-9]?)|[1-9][0-9]{0,15... A positive amount to move, expressed as a JSON decimal string in major units. For example,
An invalid, non-positive or overflowing amount returns |
| currency required | string (Currency) Value: "USD" Currency debited from or credited to the Pocket account.
|
| reference | string <= 255 characters Your private external reference for this transfer. Optional, not unique; filter by it. Counterparties do not see it. |
| memo | string <= 10 characters ACH company entry description. Must be 10 characters or fewer; longer values are rejected with |
object (Metadata) <= 50 properties Up to 50 caller-defined string key/value pairs. An empty object is valid. Keys
OpenAPI 3.0 cannot express the key-length limit for arbitrary properties, so Pocket enforces
it at runtime. An invalid key returns Values
An overlong value returns Privacy Metadata is visible only from the account-owner side on which it was set and is not shared with money-movement counterparties. Use it for opaque business identifiers and non-sensitive labels only. Do not include:
Pocket may reject metadata that appears sensitive, but the caller remains responsible for the data it supplies. |
{- "idempotency_key": "15dfe9e2-04e2-4e9a-b448-2d71c46c2219",
- "source": {
- "account_id": "biz_01j8ma3wv3mepwabfxxs0yc395"
}, - "destination": {
- "instrument_id": "epi_01jzjc7rmr2k988mgd9nrk1r1b"
}, - "amount": "500.00",
- "currency": "USD",
- "memo": "PAYROLL"
}{- "id": "txn_01jhv705whdehqd34b4113r1q8",
- "method": "ach",
- "reference": "payrun-2026-07",
- "memo": "July salary",
- "source": {
- "account_id": "cus_01jm0defbbct46vh2ev5dkkhej"
}, - "destination": {
- "account_id": "cus_01jm0defbbct46vh2ev5dkkhej"
}, - "batch_id": "string",
- "funding_rule_id": "string",
- "amount": "100.00",
- "currency": "USD",
- "status": "pending",
- "failure_code": "string",
- "failure_message": "string",
- "fx": {
- "quote_id": "fxq_01k0f8ma3wv3mepwabfxxs0yc3",
- "fixed_side": "source",
- "source_amount": "100.00",
- "source_currency": "USD",
- "fees": [
- {
- "type": "transfer",
- "amount": "10.00",
- "currency": "USD"
}
], - "net_source_amount": "10.00",
- "rate": "280.00",
- "destination_amount": "277200.00",
- "destination_currency": "PKR"
}, - "details": {
- "ach": {
- "sender_name": "string",
- "description": "string",
- "sender_routing_number": "string",
- "trace_number": "021000021234567"
}
}, - "metadata": {
- "property1": "string",
- "property2": "string"
}, - "transitioned_at": {
- "pending": "2026-07-31T09:00:00Z",
- "settled": "2026-07-31T09:00:00Z",
- "failed": "2026-07-31T09:00:00Z",
- "voided": "2026-07-31T09:00:00Z"
}, - "created_at": "2026-07-31T09:00:00Z",
- "updated_at": "2026-07-31T09:00:00Z"
}Required scope: transfers:write.
Withdraw funds to an approved external bank instrument over wire: self-withdrawal only.
The { instrument_id } destination must be the source account's own approved epi_…;
customer-owned instruments are not usable by a business.
The note (Originator-to-Beneficiary Information, or OBI) rides in memo. An unapproved
destination returns 403 with code instrument_not_approved.
| idempotency_key required | string [ 1 .. 255 ] characters .*\S.* Use a non-blank random value minted once for this create request so retries do not create duplicate transfers. |
required | object (TransferSource) Where a transfer pulls money from. This must be the account associated with the API key or one of its sub-accounts. In v1 this is a Pocket account. Supply exactly one key. |
required | object (InstrumentReference) An external instrument ref ( |
| amount required | string (WriteAmount) <= 19 characters ^(?:0\.(?:0[1-9]|[1-9][0-9]?)|[1-9][0-9]{0,15... A positive amount to move, expressed as a JSON decimal string in major units. For example,
An invalid, non-positive or overflowing amount returns |
| currency required | string (Currency) Value: "USD" Currency debited from or credited to the Pocket account.
|
| reference | string <= 255 characters Your private external reference for this transfer. Optional, not unique; filter by it. Counterparties do not see it. |
| memo | string <= 140 characters Wire OBI/remittance information. Must be 140 characters or fewer; longer values are rejected with |
object (Metadata) <= 50 properties Up to 50 caller-defined string key/value pairs. An empty object is valid. Keys
OpenAPI 3.0 cannot express the key-length limit for arbitrary properties, so Pocket enforces
it at runtime. An invalid key returns Values
An overlong value returns Privacy Metadata is visible only from the account-owner side on which it was set and is not shared with money-movement counterparties. Use it for opaque business identifiers and non-sensitive labels only. Do not include:
Pocket may reject metadata that appears sensitive, but the caller remains responsible for the data it supplies. |
{- "idempotency_key": "e829e742-588b-4089-a048-a3d404401f91",
- "source": {
- "account_id": "biz_01j8ma3wv3mepwabfxxs0yc395"
}, - "destination": {
- "instrument_id": "epi_01jzjc7rmr2k988mgd9nrk1r1b"
}, - "amount": "500.00",
- "currency": "USD"
}{- "id": "txn_01jhv705whdehqd34b4113r1q8",
- "method": "ach",
- "reference": "payrun-2026-07",
- "memo": "July salary",
- "source": {
- "account_id": "cus_01jm0defbbct46vh2ev5dkkhej"
}, - "destination": {
- "account_id": "cus_01jm0defbbct46vh2ev5dkkhej"
}, - "batch_id": "string",
- "funding_rule_id": "string",
- "amount": "100.00",
- "currency": "USD",
- "status": "pending",
- "failure_code": "string",
- "failure_message": "string",
- "fx": {
- "quote_id": "fxq_01k0f8ma3wv3mepwabfxxs0yc3",
- "fixed_side": "source",
- "source_amount": "100.00",
- "source_currency": "USD",
- "fees": [
- {
- "type": "transfer",
- "amount": "10.00",
- "currency": "USD"
}
], - "net_source_amount": "10.00",
- "rate": "280.00",
- "destination_amount": "277200.00",
- "destination_currency": "PKR"
}, - "details": {
- "ach": {
- "sender_name": "string",
- "description": "string",
- "sender_routing_number": "string",
- "trace_number": "021000021234567"
}
}, - "metadata": {
- "property1": "string",
- "property2": "string"
}, - "transitioned_at": {
- "pending": "2026-07-31T09:00:00Z",
- "settled": "2026-07-31T09:00:00Z",
- "failed": "2026-07-31T09:00:00Z",
- "voided": "2026-07-31T09:00:00Z"
}, - "created_at": "2026-07-31T09:00:00Z",
- "updated_at": "2026-07-31T09:00:00Z"
}Required scope: transfers:write.
Convert USD and withdraw PKR through Pocket's instant Inter Bank Funds Transfer (IBFT) route. This is self-withdrawal only. V1 does not expose the standard PKR cash-out route or promise a delivery time.
source.account_id.destination_currency must be PKR and must match the instrument.Quoted pricing
Use pricing.mode=quote with an open fxq_…. The request must match the quote's source,
destination, amount and currencies. A mismatch returns 400 quote_mismatch, with param
naming the field. An open firm quote is not repriced, so pricing_unavailable does not
apply.
Current pricing
Use pricing.mode=current to price and accept the transfer in one request. Pocket returns
the quote ID in fx.quote_id. Set minimum_destination_amount to reject a quote below a
chosen PKR amount. If pricing is unavailable, the operation returns
503 pricing_unavailable. A failed request creates neither the quote nor the transfer.
The gross source amount must exceed its source-currency fees. Otherwise, the operation
returns 400 invalid_request with param=amount and creates nothing.
Atomic acceptance
Quote acceptance, transfer creation, the gross USD reservation, quote linkage and
idempotency binding succeed or fail together. Replay is checked before quote state, so a
successful request can be replayed without receiving quote_already_accepted.
Account and portfolio limits are checked when the transfer is created, not when a quote is
created. 409 limit_exceeded creates no transfer and leaves the transfer idempotency key
unbound. In current-pricing mode, it also creates no quote.
A quote-state conflict also creates no transfer and leaves the key unbound. Retry the same request with that key. A replacement quote changes the financial instruction and needs a new key.
At acceptance, the gross USD amount moves from available to reserved and the transfer
begins pending. It becomes settled only when the beneficiary bank accepts the payment;
an uncertain bank outcome remains pending.
The Transfer's amount equals fx.source_amount, and its currency equals
fx.source_currency (USD in v1). fx.destination_amount is the PKR amount delivered to
the destination instrument. FX fees are included within the gross USD amount, not added
on top.
details is omitted until Pocket assigns a Retrieval Reference Number (RRN). Once present,
details.ibft.retrieval_reference_number is always set.
A known failure releases the full gross USD reservation, including fees. Pocket does not retry a failed IBFT transfer. Obtain new pricing and create another transfer.
| idempotency_key required | string [ 1 .. 255 ] characters .*\S.* Use a non-blank random value minted once for this transfer request so retries do not create duplicate transfers. |
required | object (TransferSource) Where a transfer pulls money from. This must be the account associated with the API key or one of its sub-accounts. In v1 this is a Pocket account. Supply exactly one key. |
required | object (InstrumentReference) An external instrument ref ( |
| amount required | string (WriteAmount) <= 19 characters ^(?:0\.(?:0[1-9]|[1-9][0-9]?)|[1-9][0-9]{0,15... A positive amount to move, expressed as a JSON decimal string in major units. For example,
An invalid, non-positive or overflowing amount returns |
| currency required | string (Currency) Value: "USD" Currency debited from or credited to the Pocket account.
|
| destination_currency required | string (DestinationCurrency) Value: "PKR" Currency delivered by a cross-currency transfer. USD-to-PKR IBFT is the only supported cross-currency corridor in v1. |
required | any (TransferPricing) |
| reference | string <= 255 characters Your private external reference for this transfer. Optional, not unique, and not sent to the beneficiary bank. |
object (Metadata) <= 50 properties Up to 50 caller-defined string key/value pairs. An empty object is valid. Keys
OpenAPI 3.0 cannot express the key-length limit for arbitrary properties, so Pocket enforces
it at runtime. An invalid key returns Values
An overlong value returns Privacy Metadata is visible only from the account-owner side on which it was set and is not shared with money-movement counterparties. Use it for opaque business identifiers and non-sensitive labels only. Do not include:
Pocket may reject metadata that appears sensitive, but the caller remains responsible for the data it supplies. |
{- "idempotency_key": "b2e6d1f0-3c44-4d55-8f66-77a889900abc",
- "source": {
- "account_id": "biz_01j8ma3wv3mepwabfxxs0yc395"
}, - "destination": {
- "instrument_id": "epi_01jzjc7rmr2k988mgd9nrk1r1b"
}, - "amount": "1000.00",
- "currency": "USD",
- "destination_currency": "PKR",
- "pricing": {
- "mode": "quote",
- "quote_id": "fxq_01k0f8ma3wv3mepwabfxxs0yc3"
}, - "reference": "cashout-1042"
}{- "id": "txn_01jhv705whdehqd34b4113r1q8",
- "method": "ach",
- "reference": "payrun-2026-07",
- "memo": "July salary",
- "source": {
- "account_id": "cus_01jm0defbbct46vh2ev5dkkhej"
}, - "destination": {
- "account_id": "cus_01jm0defbbct46vh2ev5dkkhej"
}, - "batch_id": "string",
- "funding_rule_id": "string",
- "amount": "100.00",
- "currency": "USD",
- "status": "pending",
- "failure_code": "string",
- "failure_message": "string",
- "fx": {
- "quote_id": "fxq_01k0f8ma3wv3mepwabfxxs0yc3",
- "fixed_side": "source",
- "source_amount": "100.00",
- "source_currency": "USD",
- "fees": [
- {
- "type": "transfer",
- "amount": "10.00",
- "currency": "USD"
}
], - "net_source_amount": "10.00",
- "rate": "280.00",
- "destination_amount": "277200.00",
- "destination_currency": "PKR"
}, - "details": {
- "ach": {
- "sender_name": "string",
- "description": "string",
- "sender_routing_number": "string",
- "trace_number": "021000021234567"
}
}, - "metadata": {
- "property1": "string",
- "property2": "string"
}, - "transitioned_at": {
- "pending": "2026-07-31T09:00:00Z",
- "settled": "2026-07-31T09:00:00Z",
- "failed": "2026-07-31T09:00:00Z",
- "voided": "2026-07-31T09:00:00Z"
}, - "created_at": "2026-07-31T09:00:00Z",
- "updated_at": "2026-07-31T09:00:00Z"
}Required scope: transfers:read.
Fetch one transfer by ID, e.g. /v1/transfers/txn_….
This returns the outbound side when its source account is in the account hierarchy
associated with the API key. If the txn_… has no transfer side in that hierarchy, this
endpoint returns 404.
For an internal movement, the same txn_… may also be retrievable from
GET /v1/deposits/{deposit_id} when the inbound side is in the account hierarchy associated
with the API key. The transfer is retrievable as soon as its txn_… exists and remains
retrievable through its terminal status.
| transfer_id required | string^txn_ Example: txn_01jhv705whdehqd34b4113r1q8 |
{- "id": "txn_01jhv705whdehqd34b4113r1q8",
- "method": "ach",
- "reference": "payrun-2026-07",
- "memo": "July salary",
- "source": {
- "account_id": "cus_01jm0defbbct46vh2ev5dkkhej"
}, - "destination": {
- "account_id": "cus_01jm0defbbct46vh2ev5dkkhej"
}, - "batch_id": "string",
- "funding_rule_id": "string",
- "amount": "100.00",
- "currency": "USD",
- "status": "pending",
- "failure_code": "string",
- "failure_message": "string",
- "fx": {
- "quote_id": "fxq_01k0f8ma3wv3mepwabfxxs0yc3",
- "fixed_side": "source",
- "source_amount": "100.00",
- "source_currency": "USD",
- "fees": [
- {
- "type": "transfer",
- "amount": "10.00",
- "currency": "USD"
}
], - "net_source_amount": "10.00",
- "rate": "280.00",
- "destination_amount": "277200.00",
- "destination_currency": "PKR"
}, - "details": {
- "ach": {
- "sender_name": "string",
- "description": "string",
- "sender_routing_number": "string",
- "trace_number": "021000021234567"
}
}, - "metadata": {
- "property1": "string",
- "property2": "string"
}, - "transitioned_at": {
- "pending": "2026-07-31T09:00:00Z",
- "settled": "2026-07-31T09:00:00Z",
- "failed": "2026-07-31T09:00:00Z",
- "voided": "2026-07-31T09:00:00Z"
}, - "created_at": "2026-07-31T09:00:00Z",
- "updated_at": "2026-07-31T09:00:00Z"
}Money arriving in an account.
Deposits are created for you, never by you:
A pending internal deposit is visible but does not affect the destination balance until settlement. Card refunds are feed-only transactions, not deposit objects.
Required scope: deposits:read.
Inbound money movements across the account associated with the API key and its complete owned sub-account hierarchy.
Narrow results with method, account_id, status, amount, funding_rule_id, reference,
created date, or settled date.
A destination view is listable as soon as its canonical txn_… exists.
For an internal movement:
pending.When account_id is supplied, it selects one owned destination account.
| method | Array of strings (DepositMethod) Items Enum: "internal" "ach" "wire" "swift" "faster_payments" "payment_link" Example: method=ach,wire Filter deposits by method. Comma-separate to match more than one (e.g.
|
| account_id | string Example: account_id=biz_01j8ma3wv3mepwabfxxs0yc395 Select the viewpoint of the account associated with the API key or one of its sub-accounts. Roster membership is not sufficient.
|
| status | string (TransactionStatus) Enum: "pending" "settled" "failed" "voided"
|
| amount_min | string (MoneyAmount) <= 19 characters ^(?:0(?:\.[0-9]{1,2})?|[1-9][0-9]{0,15}(?:\.[... Example: amount_min=100.00 Minimum amount (inclusive), as a decimal string in major units, e.g. |
| amount_max | string (MoneyAmount) <= 19 characters ^(?:0(?:\.[0-9]{1,2})?|[1-9][0-9]{0,15}(?:\.[... Example: amount_max=100.00 Maximum amount (inclusive), as a decimal string in major units, e.g. |
| funding_rule_id | string Only transfers or deposits initiated by this funding rule ( |
| reference | string Exact match on your opaque |
| created_after | string <date-time> Example: created_after=2026-07-31T09:00:00Z Only items created at/after this time (inclusive). |
| created_before | string <date-time> Example: created_before=2026-07-31T09:00:00Z Only items created at/before this time (inclusive). |
| settled_after | string <date-time> Example: settled_after=2026-07-31T09:00:00Z Only items settled at/after this time (inclusive). Pending, failed, and voided items have no settlement time and are excluded when this filter is used. |
| settled_before | string <date-time> Example: settled_before=2026-07-31T09:00:00Z Only items settled at/before this time (inclusive). Pending, failed, and voided items have no settlement time and are excluded when this filter is used. |
| cursor | string Opaque cursor ( |
| limit | integer [ 1 .. 100 ] Default: 25 |
{- "has_more": true,
- "next_cursor": "string",
- "data": [
- {
- "id": "txn_01jjftqbz0n1vzey0pqrq3qmnn",
- "method": "ach",
- "account_id": "biz_01j8ma3wv3mepwabfxxs0yc395",
- "source": null,
- "destination": {
- "account_id": "biz_01j8ma3wv3mepwabfxxs0yc395"
}, - "reference": null,
- "memo": null,
- "funding_rule_id": null,
- "amount": "2500.00",
- "currency": "USD",
- "status": "settled",
- "details": {
- "ach": {
- "sender_name": "PAISMO INC",
- "trace_number": "021000021234567"
}
}, - "metadata": { },
- "created_at": "2026-07-30T14:10:00Z",
- "settled_at": "2026-07-31T09:00:00Z",
- "updated_at": "2026-07-31T09:00:00Z"
}
]
}Required scope: deposits:read.
Fetch one deposit by ID, e.g. /v1/deposits/txn_….
This returns the inbound side when its destination account is in the account hierarchy
associated with the API key. If the txn_… has no deposit side in that hierarchy, this
endpoint returns 404.
For an internal movement:
txn_… may resolve at GET /v1/transfers/{transfer_id} when the outbound side is
in the account hierarchy associated with the API key.pending.failed or voided.| deposit_id required | string^txn_ Example: txn_01jjftqbz0n1vzey0pqrq3qmnn |
{- "id": "txn_01jjftqbz0n1vzey0pqrq3qmnn",
- "method": "ach",
- "account_id": "biz_01j8ma3wv3mepwabfxxs0yc395",
- "source": null,
- "destination": {
- "account_id": "biz_01j8ma3wv3mepwabfxxs0yc395"
}, - "reference": null,
- "memo": null,
- "funding_rule_id": null,
- "amount": "2500.00",
- "currency": "USD",
- "status": "settled",
- "details": {
- "ach": {
- "sender_name": "PAISMO INC",
- "trace_number": "021000021234567"
}
}, - "metadata": { },
- "created_at": "2026-07-30T14:10:00Z",
- "settled_at": "2026-07-31T09:00:00Z",
- "updated_at": "2026-07-31T09:00:00Z"
}Price a cross-currency transfer before creating it.
V1 quotes are source-fixed USD-to-PKR quotes for method=ibft. A quote binds its source
account, destination instrument, method, currencies, gross source amount, fees, rate, and
resolved destination amount.
Lifecycle
open: available for one transfer to accept before expires_at.accepted: linked permanently to the transfer in transfer_id.expired: not accepted before expires_at.canceled: withdrawn by Pocket before acceptance.expires_at is exclusive: the quote cannot be accepted at or after that instant.
Terminal states do not change. An accepted quote never expires and is never reusable. Pocket
may cancel an open quote, but while it remains open its quoted pricing is honored until
expires_at. Acceptance can still fail because funds, authorization, limits, account state,
or instrument approval changed.
Creating a quote does not reserve customer funds or affect balances. Multiple open quotes may coexist, subject to rate and capacity limits; creating one does not cancel another.
Required scope: transfers:write.
Request source-fixed pricing for a USD-to-PKR IBFT withdrawal. The quote binds all routing and pricing fields in the response.
destination_currency must match the instrument's currency.source_amount must exceed the total applicable source-currency fees. Otherwise Pocket
returns 400 invalid_request; param is source_amount.expires_at; it cannot be
accepted at or after that instant.Pocket may cancel an open quote. While it remains open, market movement does not change its
price. Funds, authorization, limits, account state and instrument approval are checked when
the transfer is created. Quote creation does not return limit_exceeded.
| idempotency_key required | string [ 1 .. 255 ] characters .*\S.* Use a non-blank random value minted once for this quote request so retries do not create duplicate quotes. |
required | object (TransferSource) Where a transfer pulls money from. This must be the account associated with the API key or one of its sub-accounts. In v1 this is a Pocket account. Supply exactly one key. |
required | object (InstrumentReference) An external instrument ref ( |
| method required | string Value: "ibft" |
| source_amount required | string (WriteAmount) <= 19 characters ^(?:0\.(?:0[1-9]|[1-9][0-9]?)|[1-9][0-9]{0,15... A positive amount to move, expressed as a JSON decimal string in major units. For example,
An invalid, non-positive or overflowing amount returns |
| source_currency required | string (Currency) Value: "USD" Currency debited from or credited to the Pocket account.
|
| destination_currency required | string (DestinationCurrency) Value: "PKR" Currency delivered by a cross-currency transfer. USD-to-PKR IBFT is the only supported cross-currency corridor in v1. |
{- "idempotency_key": "9f1c2a34-6a3d-4e0b-9c7e-2f8b1d5a7e21",
- "source": {
- "account_id": "biz_01j8ma3wv3mepwabfxxs0yc395"
}, - "destination": {
- "instrument_id": "epi_01jzjc7rmr2k988mgd9nrk1r1b"
}, - "method": "ibft",
- "source_amount": "1000.00",
- "source_currency": "USD",
- "destination_currency": "PKR"
}{- "id": "fxq_01k0f8ma3wv3mepwabfxxs0yc3",
- "status": "open",
- "method": "ibft",
- "source": {
- "account_id": "biz_01j8ma3wv3mepwabfxxs0yc395"
}, - "destination": {
- "instrument_id": "epi_01jzjc7rmr2k988mgd9nrk1r1b"
}, - "fixed_side": "source",
- "source_amount": "1000.00",
- "source_currency": "USD",
- "fees": [
- {
- "type": "transfer",
- "amount": "10.00",
- "currency": "USD"
}
], - "net_source_amount": "990.00",
- "rate": "280.00",
- "destination_amount": "277200.00",
- "destination_currency": "PKR",
- "transfer_id": null,
- "created_at": "2026-07-13T09:00:00Z",
- "expires_at": "2026-07-13T09:05:00Z",
- "accepted_at": null,
- "canceled_at": null
}Required scope: transfers:read.
Retrieve a quote whose source account is in the account hierarchy associated with the API
key. A quote outside that hierarchy returns 404.
At or after expires_at, Pocket returns a stored open quote as expired. An accepted quote
never becomes expired.
Expired and canceled quotes remain retrievable for at least 24 hours after creation, the same minimum period as their idempotency-key binding. Accepted quotes remain retrievable for as long as their accepting transfer.
| quote_id required | string^fxq_ Example: fxq_01k0f8ma3wv3mepwabfxxs0yc3 |
{- "id": "fxq_01k0f8ma3wv3mepwabfxxs0yc3",
- "status": "open",
- "method": "ibft",
- "source": {
- "account_id": "biz_01j8ma3wv3mepwabfxxs0yc395"
}, - "destination": {
- "instrument_id": "epi_01jzjc7rmr2k988mgd9nrk1r1b"
}, - "fixed_side": "source",
- "source_amount": "1000.00",
- "source_currency": "USD",
- "fees": [
- {
- "type": "transfer",
- "amount": "10.00",
- "currency": "USD"
}
], - "net_source_amount": "990.00",
- "rate": "280.00",
- "destination_amount": "277200.00",
- "destination_currency": "PKR",
- "transfer_id": null,
- "created_at": "2026-07-13T09:00:00Z",
- "expires_at": "2026-07-13T09:05:00Z",
- "accepted_at": null,
- "canceled_at": null
}Required scopes: batches:write and transfers:write.
Submit internal transfers from one owned source account as an asynchronous job. Acceptance does not move or reserve money.
Pocket validates the request and may run an optimistic balance check before accepting it.
Recipient policy pre-check
recipient_policy defaults to any_account. Set it to payable_members to check the
complete batch against the source account's roster before acceptance:
source.account_id.capabilities.can_receive_transfers set to
true.This check runs after ordinary validation, including duplicate item_id validation. If any
item fails, one 400 recipient_policy_failed response lists all failures in request order.
Pocket creates nothing and leaves the idempotency key unbound. Correct the request and
retry with the same key.
The recipient check is not repeated during item processing. Ordinary transfer rules still apply.
Track every submitted line with GET /v1/batches/{batch_id}/items.
transfer_id: null.txn_… exists, transfer_id identifies it through settlement, failure or voiding.failure_code: insufficient_funds.item_id does not deduplicate across batches;
resubmitting a settled line can pay twice.Duplicate item ids
Every item_id must be unique within items.
reference and idempotency_key do not identify batch lines.Pocket reports the first repeated value. The request returns 400 invalid_request, with
param set to the second occurrence (items[n].item_id). The index is zero-based.
Pocket creates nothing and leaves the idempotency key unbound. Correct the request and retry with the same key.
Batches cannot be canceled once accepted.
The UTF-8 JSON body may be at most 10 MiB (10,485,760 bytes) instead of the usual 1 MiB.
The whole request must fit, even when every item is valid. An oversized request returns
413 and creates nothing.
| idempotency_key required | string [ 1 .. 255 ] characters .*\S.* Use a non-blank random value minted once for this create request so retries do not create duplicate batches. |
required | object (TransferSource) Where a transfer pulls money from. This must be the account associated with the API key or one of its sub-accounts. In v1 this is a Pocket account. Supply exactly one key. |
| recipient_policy | string (BatchRecipientPolicy) Default: "any_account" Enum: "any_account" "payable_members" One-time destination pre-check applied before Pocket accepts a batch.
The policy is not evaluated again after acceptance or as individual transfers execute.
Omitting the field and explicitly sending |
required | Array of objects (BatchTransferItem) [ 1 .. 4096 ] items Each |
| reference | string <= 255 characters Your external ID for this batch (e.g. a pay-run ID). Optional, filterable. |
object (Metadata) <= 50 properties Up to 50 caller-defined string key/value pairs. An empty object is valid. Keys
OpenAPI 3.0 cannot express the key-length limit for arbitrary properties, so Pocket enforces
it at runtime. An invalid key returns Values
An overlong value returns Privacy Metadata is visible only from the account-owner side on which it was set and is not shared with money-movement counterparties. Use it for opaque business identifiers and non-sensitive labels only. Do not include:
Pocket may reject metadata that appears sensitive, but the caller remains responsible for the data it supplies. |
{- "idempotency_key": "a15e4ae4-52f3-460c-9c1c-5f6b7b90cc44",
- "source": {
- "account_id": "biz_01j8ma3wv3mepwabfxxs0yc395"
}, - "recipient_policy": "payable_members",
- "items": [
- {
- "item_id": "line-001",
- "destination": {
- "account_id": "cus_01jm0defbbct46vh2ev5dkkhej"
}, - "amount": "100.00",
- "currency": "USD",
- "reference": "emp-001"
}, - {
- "item_id": "line-002",
- "destination": {
- "account_id": "cus_01j7qkfn0n4egp6wj30vajew7g"
}, - "amount": "120.00",
- "currency": "USD",
- "reference": "emp-002"
}
], - "reference": "northwind-2026-07",
- "metadata": {
- "pay_period": "2026-07"
}
}{- "id": "batch_01j5gr81vpavng9emxaepf2be3",
- "reference": "northwind-2026-07",
- "source": {
- "account_id": "cus_01jm0defbbct46vh2ev5dkkhej"
}, - "recipient_policy": "any_account",
- "status": "pending",
- "item_counts": {
- "total": 2,
- "pending": 0,
- "settled": 2,
- "failed": 0,
- "voided": 0
}, - "amount_totals": [
- {
- "currency": "USD",
- "total": "100.00",
- "pending": "100.00",
- "settled": "100.00",
- "failed": "100.00",
- "voided": "100.00"
}
], - "metadata": {
- "property1": "string",
- "property2": "string"
}, - "created_at": "2026-07-31T09:00:00Z",
- "finalized_at": "2026-07-31T09:00:00Z"
}Required scope: batches:read.
List batches whose source is the account associated with the API key or one of its sub-accounts, recursively.
Use source_id to restrict the list to one owned source account.
| source_id | string Filter by an owned source account ID ( |
| status | string (BatchStatus) Enum: "pending" "processing" "completed" "partially_completed" "failed" Summary status derived from the batch item counts:
The counts are the source of truth for reconciliation and always satisfy
|
| created_after | string <date-time> Example: created_after=2026-07-31T09:00:00Z Only items created at/after this time (inclusive). |
| created_before | string <date-time> Example: created_before=2026-07-31T09:00:00Z Only items created at/before this time (inclusive). |
| reference | string Exact match on your opaque |
| cursor | string Opaque cursor ( |
| limit | integer [ 1 .. 100 ] Default: 25 |
{- "has_more": true,
- "next_cursor": "string",
- "data": [
- {
- "id": "batch_01j5gr81vpavng9emxaepf2be3",
- "reference": "northwind-2026-07",
- "source": {
- "account_id": "cus_01jm0defbbct46vh2ev5dkkhej"
}, - "recipient_policy": "any_account",
- "status": "pending",
- "item_counts": {
- "total": 2,
- "pending": 0,
- "settled": 2,
- "failed": 0,
- "voided": 0
}, - "amount_totals": [
- {
- "currency": "USD",
- "total": "100.00",
- "pending": "100.00",
- "settled": "100.00",
- "failed": "100.00",
- "voided": "100.00"
}
], - "metadata": {
- "property1": "string",
- "property2": "string"
}, - "created_at": "2026-07-31T09:00:00Z",
- "finalized_at": "2026-07-31T09:00:00Z"
}
]
}Required scope: batches:read.
Retrieve a batch by ID. Use its item counts and amount totals to track progress.
| batch_id required | string Example: batch_01j5gr81vpavng9emxaepf2be3 |
{- "id": "batch_01j5gr81vpavng9emxaepf2be3",
- "reference": "northwind-2026-07",
- "source": {
- "account_id": "cus_01jm0defbbct46vh2ev5dkkhej"
}, - "recipient_policy": "any_account",
- "status": "pending",
- "item_counts": {
- "total": 2,
- "pending": 0,
- "settled": 2,
- "failed": 0,
- "voided": 0
}, - "amount_totals": [
- {
- "currency": "USD",
- "total": "100.00",
- "pending": "100.00",
- "settled": "100.00",
- "failed": "100.00",
- "voided": "100.00"
}
], - "metadata": {
- "property1": "string",
- "property2": "string"
}, - "created_at": "2026-07-31T09:00:00Z",
- "finalized_at": "2026-07-31T09:00:00Z"
}Required scope: batches:read.
List every submitted item in the batch, including items that failed before creating a transfer.
Use item_id to reconcile the response with the line you submitted. When an item creates
a transfer, transfer_id links to the resulting txn_…; otherwise transfer_id is null
and failure_code explains the failure.
Narrow with item_id, status, or reference.
To retry failures, submit the failed lines in a new batch. A new batch creates new
transfers; item_id does not deduplicate across batches, so resubmitting a settled line
can pay the recipient twice.
| batch_id required | string |
| item_id | string [ 1 .. 255 ] characters .*\S.* Only the batch item with this caller-supplied ID. Unique within the batch. |
| status | string (BatchItemStatus) Enum: "pending" "settled" "failed" "voided" Lifecycle of one submitted batch item. When a transfer exists, this mirrors the transfer status. A |
| reference | string Exact match on your opaque |
| cursor | string Opaque cursor ( |
| limit | integer [ 1 .. 100 ] Default: 25 |
{- "has_more": true,
- "next_cursor": "string",
- "data": [
- {
- "item_id": "line-001",
- "batch_id": "batch_01j5gr81vpavng9emxaepf2be3",
- "status": "pending",
- "transfer_id": "txn_01jhv705whdehqd34b4113r1q8",
- "destination": {
- "account_id": "cus_01jm0defbbct46vh2ev5dkkhej"
}, - "amount": "100.00",
- "currency": "USD",
- "reference": "string",
- "memo": "string",
- "failure_code": "string",
- "failure_message": "string",
- "metadata": {
- "property1": "string",
- "property2": "string"
}, - "created_at": "2026-07-31T09:00:00Z",
- "updated_at": "2026-07-31T09:00:00Z"
}
]
}Required scopes: batches:read and transfers:read.
Only items that produced a transfer appear here. Every submitted item appears in
GET /v1/batches/{batch_id}/items. An item that fails before transfer creation, such as for
insufficient funds when it runs, has transfer_id: null.
| batch_id required | string |
| status | string (TransferStatus) Enum: "pending" "settled" "failed" "voided"
|
| cursor | string Opaque cursor ( |
| limit | integer [ 1 .. 100 ] Default: 25 |
{- "has_more": true,
- "next_cursor": "string",
- "data": [
- {
- "id": "txn_01jhv705whdehqd34b4113r1q8",
- "method": "ach",
- "reference": "payrun-2026-07",
- "memo": "July salary",
- "source": {
- "account_id": "cus_01jm0defbbct46vh2ev5dkkhej"
}, - "destination": {
- "account_id": "cus_01jm0defbbct46vh2ev5dkkhej"
}, - "batch_id": "string",
- "funding_rule_id": "string",
- "amount": "100.00",
- "currency": "USD",
- "status": "pending",
- "failure_code": "string",
- "failure_message": "string",
- "fx": {
- "quote_id": "fxq_01k0f8ma3wv3mepwabfxxs0yc3",
- "fixed_side": "source",
- "source_amount": "100.00",
- "source_currency": "USD",
- "fees": [
- {
- "type": "transfer",
- "amount": "10.00",
- "currency": "USD"
}
], - "net_source_amount": "10.00",
- "rate": "280.00",
- "destination_amount": "277200.00",
- "destination_currency": "PKR"
}, - "details": {
- "ach": {
- "sender_name": "string",
- "description": "string",
- "sender_routing_number": "string",
- "trace_number": "021000021234567"
}
}, - "metadata": {
- "property1": "string",
- "property2": "string"
}, - "transitioned_at": {
- "pending": "2026-07-31T09:00:00Z",
- "settled": "2026-07-31T09:00:00Z",
- "failed": "2026-07-31T09:00:00Z",
- "voided": "2026-07-31T09:00:00Z"
}, - "created_at": "2026-07-31T09:00:00Z",
- "updated_at": "2026-07-31T09:00:00Z"
}
]
}Required scope: accounts:write.
Create an active business sub-account. Omit parent_id to create it directly under the
account associated with the API key. Otherwise, parent_id must name a business account in
that hierarchy.
The public API sets no fixed hierarchy depth. Accounts may be nested while their state permits children.
parent_id: 400; param is parent_id.parent_id: 404.409.| idempotency_key required | string [ 1 .. 255 ] characters .*\S.* Use a non-blank random value minted once for this create request so retries do not create duplicate accounts. To carry your own ID for the account, use |
| reference | string <= 255 characters An opaque external reference of your choosing for this account. We don't parse or dedupe it; find accounts and balances by it with the |
| name | string |
| parent_id | string Parent business account ( |
object (Metadata) <= 50 properties Up to 50 caller-defined string key/value pairs. An empty object is valid. Keys
OpenAPI 3.0 cannot express the key-length limit for arbitrary properties, so Pocket enforces
it at runtime. An invalid key returns Values
An overlong value returns Privacy Metadata is visible only from the account-owner side on which it was set and is not shared with money-movement counterparties. Use it for opaque business identifiers and non-sensitive labels only. Do not include:
Pocket may reject metadata that appears sensitive, but the caller remains responsible for the data it supplies. |
{- "idempotency_key": "9ff42f6e-ec45-45ac-8f8b-5f5c2f1d0b4a",
- "reference": "northwind-co",
- "name": "Northwind Trading Co"
}{- "id": "biz_01j8ma3wv3mepwabfxxs0yc395",
- "reference": "northwind-co",
- "name": "string",
- "parent_id": "string",
- "status": "active",
- "metadata": {
- "property1": "string",
- "property2": "string"
}, - "created_at": "2026-07-31T09:00:00Z",
- "updated_at": "2026-07-31T09:00:00Z"
}Required scope: accounts:read.
List the account associated with the API key and all of its sub-accounts. A customer on a business member roster is included only if its account independently belongs to that hierarchy.
When parent_id is supplied, only that owned account's direct children are returned. The
parent and grandchildren are excluded.
| parent_id | string List only the direct children of this owned business account (
|
| status | string (AccountStatus) Enum: "active" "pending" "suspended" "closed" Current account lifecycle state. |
| reference | string Exact match on your opaque |
| created_after | string <date-time> Example: created_after=2026-07-31T09:00:00Z Only items created at/after this time (inclusive). |
| created_before | string <date-time> Example: created_before=2026-07-31T09:00:00Z Only items created at/before this time (inclusive). |
| cursor | string Opaque cursor ( |
| limit | integer [ 1 .. 100 ] Default: 25 |
{- "has_more": true,
- "next_cursor": "string",
- "data": [
- {
- "id": "biz_01j8ma3wv3mepwabfxxs0yc395",
- "reference": "northwind-co",
- "name": "string",
- "parent_id": "string",
- "status": "active",
- "metadata": {
- "property1": "string",
- "property2": "string"
}, - "created_at": "2026-07-31T09:00:00Z",
- "updated_at": "2026-07-31T09:00:00Z"
}
]
}Required scope: accounts:read.
Retrieve the account associated with the API key or one of its sub-accounts. Roster membership alone does not make a customer account retrievable.
| account_id required | string Example: biz_01j8ma3wv3mepwabfxxs0yc395 |
{- "id": "biz_01j8ma3wv3mepwabfxxs0yc395",
- "reference": "northwind-co",
- "name": "string",
- "parent_id": "string",
- "status": "active",
- "metadata": {
- "property1": "string",
- "property2": "string"
}, - "created_at": "2026-07-31T09:00:00Z",
- "updated_at": "2026-07-31T09:00:00Z"
}Required scope: accounts:write.
Update a business sub-account you own.
name, status, and metadata.active and suspended.pending is platform-owned.closed is terminal; closing is not part of v1.cus_…) accounts are not mutable through this API.Supply at least one writable field. An empty body or a body containing only
idempotency_key returns 400 invalid_request.
If every supplied value already matches, Pocket returns the account without changing
updated_at. A supplied idempotency_key is still bound to the response.
An illegal state transition returns 409.
| account_id required | string Example: biz_01j8ma3wv3mepwabfxxs0yc395 |
| name required | string |
| idempotency_key | string [ 1 .. 255 ] characters .*\S.* Optional. When supplied, it must not be blank. Makes this update safe to retry; reusing the same key with a different request fingerprint returns |
| status | string (AccountWritableStatus) Enum: "active" "suspended" Status values callers can set with |
object (Metadata) <= 50 properties Up to 50 caller-defined string key/value pairs. An empty object is valid. Keys
OpenAPI 3.0 cannot express the key-length limit for arbitrary properties, so Pocket enforces
it at runtime. An invalid key returns Values
An overlong value returns Privacy Metadata is visible only from the account-owner side on which it was set and is not shared with money-movement counterparties. Use it for opaque business identifiers and non-sensitive labels only. Do not include:
Pocket may reject metadata that appears sensitive, but the caller remains responsible for the data it supplies. |
{- "metadata": {
- "property1": "string",
- "property2": "string"
}, - "idempotency_key": "string",
- "name": "string",
- "status": "active"
}{- "id": "biz_01j8ma3wv3mepwabfxxs0yc395",
- "reference": "northwind-co",
- "name": "string",
- "parent_id": "string",
- "status": "active",
- "metadata": {
- "property1": "string",
- "property2": "string"
}, - "created_at": "2026-07-31T09:00:00Z",
- "updated_at": "2026-07-31T09:00:00Z"
}Required scope: balances:read.
Return one funding balance per currency for a single account. The account may be the one associated with the API key or any of its sub-accounts. A roster relationship alone does not make a customer account readable.
Only USD is supported in v1, so the response contains at most one item and has_more is
always false.
The balance is the payable pool, not a net position. Funds still moving through an external rail, or otherwise unavailable for payment, are not included. Filtering to a currency the account does not hold returns an empty page, not a 404.
| account_id required | string Example: biz_01j8ma3wv3mepwabfxxs0yc395 |
| currency | string (Currency) Value: "USD" Example: currency=USD Only the balance in this currency. |
{- "has_more": true,
- "next_cursor": "string",
- "data": [
- {
- "account_id": "biz_01j8ma3wv3mepwabfxxs0yc395",
- "type": "funding",
- "reference": "northwind-co",
- "currency": "USD",
- "available": "100.00",
- "settled": "100.00",
- "reserved": "0.00",
- "as_of": "2026-07-31T09:00:00Z"
}
]
}Required scope: balances:read.
One entry per account per currency across the account associated with the API key and its complete owned sub-account hierarchy, recursively. Rostered customer accounts are not included unless they are independently part of that hierarchy.
When parent_id is supplied, only balances for that owned account's direct children are
returned. The parent and grandchildren are excluded.
For a single account, use List an account's balances.
| parent_id | string List balances only for the direct children of this owned business account (
|
| currency | string (Currency) Value: "USD" Example: currency=USD Only balances in this currency. |
| reference | string Exact match on your opaque |
| cursor | string Opaque cursor ( |
| limit | integer [ 1 .. 100 ] Default: 25 |
{- "has_more": true,
- "next_cursor": "string",
- "data": [
- {
- "account_id": "biz_01j8ma3wv3mepwabfxxs0yc395",
- "type": "funding",
- "reference": "northwind-co",
- "currency": "USD",
- "available": "100.00",
- "settled": "100.00",
- "reserved": "0.00",
- "as_of": "2026-07-31T09:00:00Z"
}
]
}External accounts registered to the account associated with the API key or one of its sub-accounts, used as transfer destinations. USD instruments support ACH and wire withdrawals; PKR Pakistani bank instruments support self-withdrawal by IBFT.
Required scope: instruments:read.
List banks Pocket supports for external instruments. Use code as
bank_account.bank_code when registering a Pakistani bank account.
Bank support can change. After registration, store the instrument ID instead of relying on this list as a permanent eligibility guarantee.
This endpoint is unpaginated in v1 but uses the standard list shape. has_more is always
false, and next_cursor is always JSON null.
| country required | string Value: "PK" ISO 3166-1 alpha-2 country code. |
| method | string Value: "ibft" Limit the result to banks that support this transfer method. |
{- "data": [
- {
- "code": "hbl",
- "name": "HBL",
- "country": "PK",
- "supported_methods": [
- "ibft"
]
}
], - "has_more": false,
- "next_cursor": null
}Required scope: instruments:write.
Register an external bank account as a withdrawal destination for account_id.
account_id must be the account associated with the API key or one of its sub-accounts; a
business cannot register instruments on a rostered customer account outside that
hierarchy. The instrument must be approved before a transfer can use it.
For a Pakistani PKR instrument, Pocket verifies the bank account and expected holder identity. It does not expose the bank-returned title, title-match score or decline reason.
Local account-number rules vary by Pakistani bank and are validated during registration.
An invalid local account number or IBAN returns 400 invalid_request; param is
bank_account.account_number.
| account_id required | string Example: biz_01j8ma3wv3mepwabfxxs0yc395 |
| currency required | string Enum: "USD" "PKR" Currency accepted by an external instrument. This is separate from |
required | object US bank account details. Raw account and routing values are accepted only on create and are not returned by read endpoints. |
| idempotency_key required | string [ 1 .. 255 ] characters .*\S.* Use a non-blank random value minted once for this create request so retries do not create duplicate instruments. |
| reference | string <= 255 characters Your external ID for this instrument (optional, filterable). |
| type required | string (InstrumentType) Value: "bank_account" |
object (Metadata) <= 50 properties Up to 50 caller-defined string key/value pairs. An empty object is valid. Keys
OpenAPI 3.0 cannot express the key-length limit for arbitrary properties, so Pocket enforces
it at runtime. An invalid key returns Values
An overlong value returns Privacy Metadata is visible only from the account-owner side on which it was set and is not shared with money-movement counterparties. Use it for opaque business identifiers and non-sensitive labels only. Do not include:
Pocket may reject metadata that appears sensitive, but the caller remains responsible for the data it supplies. |
{- "currency": "USD",
- "bank_account": {
- "holder_name": "string",
- "account_number": "string",
- "routing_number": "string",
- "country": "US"
}, - "idempotency_key": "string",
- "reference": "string",
- "type": "bank_account",
- "metadata": {
- "property1": "string",
- "property2": "string"
}
}{- "id": "epi_01jzjc7rmr2k988mgd9nrk1r1b",
- "account_id": "biz_01j6qvsv30kfq9dq59sxp9aze5",
- "reference": "string",
- "type": "bank_account",
- "status": "in_review",
- "currency": "USD",
- "country": "PK",
- "bank_code": "hbl",
- "bank_name": "HBL",
- "bank_last4": "4242",
- "holder_name": "string",
- "metadata": {
- "property1": "string",
- "property2": "string"
}, - "created_at": "2026-07-31T09:00:00Z",
- "approved_at": "2026-07-31T09:00:00Z"
}Required scope: instruments:read.
List instruments for the account associated with the API key or one of its sub-accounts. Instruments attached to rostered customer accounts outside that hierarchy are private and are not listable by the business.
Soft-deleted instruments are excluded by default. Filter with status=deleted to include
only deleted instruments.
| account_id required | string Example: biz_01j8ma3wv3mepwabfxxs0yc395 |
| status | string (InstrumentStatus) Enum: "in_review" "approved" "declined" "deleted" Instrument lifecycle status. Omit to exclude soft-deleted instruments. |
| reference | string Exact match on your opaque |
| cursor | string Opaque cursor ( |
| limit | integer [ 1 .. 100 ] Default: 25 |
{- "has_more": true,
- "next_cursor": "string",
- "data": [
- {
- "id": "epi_01jzjc7rmr2k988mgd9nrk1r1b",
- "account_id": "biz_01j6qvsv30kfq9dq59sxp9aze5",
- "reference": "string",
- "type": "bank_account",
- "status": "in_review",
- "currency": "USD",
- "country": "PK",
- "bank_code": "hbl",
- "bank_name": "HBL",
- "bank_last4": "4242",
- "holder_name": "string",
- "metadata": {
- "property1": "string",
- "property2": "string"
}, - "created_at": "2026-07-31T09:00:00Z",
- "approved_at": "2026-07-31T09:00:00Z"
}
]
}Required scope: instruments:read.
Retrieve an instrument belonging to the account associated with the API key or one of its sub-accounts. Instruments attached to customer accounts outside that hierarchy remain private.
Direct retrieval continues to return a soft-deleted instrument with status=deleted so
historical transfer references remain resolvable.
| instrument_id required | string Example: epi_01jzjc7rmr2k988mgd9nrk1r1b |
{- "id": "epi_01jzjc7rmr2k988mgd9nrk1r1b",
- "account_id": "biz_01j6qvsv30kfq9dq59sxp9aze5",
- "reference": "string",
- "type": "bank_account",
- "status": "in_review",
- "currency": "USD",
- "country": "PK",
- "bank_code": "hbl",
- "bank_name": "HBL",
- "bank_last4": "4242",
- "holder_name": "string",
- "metadata": {
- "property1": "string",
- "property2": "string"
}, - "created_at": "2026-07-31T09:00:00Z",
- "approved_at": "2026-07-31T09:00:00Z"
}Required scope: instruments:write.
Soft-delete an instrument belonging to the account associated with the API key or one of its sub-accounts. A business cannot remove instruments from a rostered customer account outside that hierarchy.
204.status=deleted.status=deleted to retrieve deleted instruments.| instrument_id required | string |
{- "code": "string",
- "message": "destination.account_id has an unexpected prefix",
- "param": "destination.account_id",
- "request_id": "req_01jj0m9w2k3n5p7q9r1s3t5v7w"
}Members are the customers (cus_…) a business keeps on its payment roster.
Identity inputs are normalized before matching:
customer_id: exact Pocket cus_… ID.phone: E.164 international phone-number format.email: surrounding whitespace trimmed, then compared case-insensitively using Pocket's
canonical form.government_id: a Pakistani Computerized National Identity Card (CNIC), accepted as 13
digits or #####-#######-#.For CNICs, Pocket ignores surrounding whitespace and display hyphens, then compares the 13
digits. A malformed identifier returns 400 with param naming the field.
Required scope: members:write.
Add a customer to this business's payment roster. Name lookup is not supported.
Identifiers
Supply any combination of customer_id, email, phone and government_id. At least one
is required. If several are supplied, they must all resolve to the same customer. A
mismatch returns a generic 400 without revealing which values matched.
Existing customer
Pocket links an existing customer immediately and returns customer_id. The customer does
not need to consent to each business relationship.
active: the customer completed the relevant onboarding.onboarding_required: onboarding is incomplete.In either state, use capabilities.can_receive_transfers to decide whether the member can
be paid.
No existing match
If phone or email is present, Pocket can create a pending customer and the roster
relationship. The response contains a new customer_id, status=onboarding_required and
can_receive_transfers=false.
Invitation delivery is separate from this operation and is not guaranteed by it.
An unmatched government_id alone returns 404 because phone or email is required to
create a new customer. An explicit unknown customer_id also returns 404; Pocket never
substitutes another customer or creates a customer with a caller-supplied ID.
Retries and re-adding
This endpoint takes no idempotency_key. A retry that resolves to the same customer returns
the existing relationship and does not resend an invitation. New relationships return
201 Created; existing relationships return 200 OK.
If the relationship already exists and is not removed, this operation does not update its metadata; use the member update endpoint instead.
Re-adding a removed member restores the relationship and returns 200 OK. Omitted
metadata is preserved; supplied metadata replaces the previous object. The restored
status is active when onboarding is complete and onboarding_required otherwise.
Privacy
The response contains roster data only. It does not grant access to the customer's account or any private customer data.
Pocket may apply additional rate limits to identity resolution and customer creation. Never
log or trace raw identity inputs, and never copy a full government identity value into
metadata.
| account_id required | string Example: biz_01j8ma3wv3mepwabfxxs0yc395 |
| customer_id required | string^cus_ Match by the customer's exact Pocket ID ( |
string <email> (MemberEmailLookup) Match by email after trimming surrounding whitespace and applying Pocket's case-insensitive canonical email normalization. | |
| phone | string (MemberPhoneLookup) ^\+[1-9][0-9]{1,14}$ Match by E.164 phone (e.g. |
| government_id | string (MemberGovernmentIdLookup) ^\s*(?:[0-9]{13}|[0-9]{5}-[0-9]{7}-[0-9])\s*$... Match by Pakistani CNIC, the government identity type supported in v1. Formatted and unformatted values are normalized to the same 13 digits before matching. Responses return only |
object (Metadata) <= 50 properties Up to 50 caller-defined string key/value pairs. An empty object is valid. Keys
OpenAPI 3.0 cannot express the key-length limit for arbitrary properties, so Pocket enforces
it at runtime. An invalid key returns Values
An overlong value returns Privacy Metadata is visible only from the account-owner side on which it was set and is not shared with money-movement counterparties. Use it for opaque business identifiers and non-sensitive labels only. Do not include:
Pocket may reject metadata that appears sensitive, but the caller remains responsible for the data it supplies. |
{- "government_id": "string",
- "phone": "+923228884666",
- "metadata": {
- "employee_ref": "emp-001"
}
}{- "business_id": "biz_01j8ma3wv3mepwabfxxs0yc395",
- "customer_id": "cus_01jm0defbbct46vh2ev5dkkhej",
- "email": "usama@example.com",
- "phone": "+923228884666",
- "government_id_masked": "*********5678",
- "status": "active",
- "capabilities": {
- "can_receive_transfers": true
}, - "metadata": {
- "employee_ref": "emp-001"
}, - "created_at": "2026-07-31T09:00:00Z",
- "updated_at": "2026-07-31T09:00:00Z"
}Required scope: members:read.
The roster of customers this business pays.
Only roster-visible fields are returned; customer account details and internal account status remain private.
status=removed to list removed relationships.status to list only relationships in that state.customer_id from
GET /v1/accounts/{account_id}/members/{customer_id}.| account_id required | string Example: biz_01j8ma3wv3mepwabfxxs0yc395 |
| status | string (MemberStatus) Enum: "onboarding_required" "active" "inactive" "removed" Only relationships in this state. Without this filter, removed relationships are excluded. |
| cursor | string Opaque cursor ( |
| limit | integer [ 1 .. 100 ] Default: 25 |
{- "has_more": true,
- "next_cursor": "string",
- "data": [
- {
- "business_id": "biz_01j8ma3wv3mepwabfxxs0yc395",
- "customer_id": "cus_01jm0defbbct46vh2ev5dkkhej",
- "email": "usama@example.com",
- "phone": "+923228884666",
- "government_id_masked": "*********5678",
- "status": "active",
- "capabilities": {
- "can_receive_transfers": true
}, - "metadata": {
- "employee_ref": "emp-001"
}, - "created_at": "2026-07-31T09:00:00Z",
- "updated_at": "2026-07-31T09:00:00Z"
}
]
}Required scope: members:read.
Look up a roster member by customer_id, email, phone, government_id or any
combination. Identifiers belong in the request body so personally identifiable information
(PII) does not appear in URLs. Name lookup is not supported.
This endpoint searches this business's roster only.
400 without revealing which values matched.404.The response never confirms whether an identifier exists elsewhere in Pocket.
Although this is a POST, it creates nothing, takes no idempotency_key and is safe to
retry. Pocket may apply additional rate limits to identity searches.
Never log or trace raw identity inputs, and never copy a full government identity value
into metadata.
The response contains roster data only. It exposes no private customer or account data.
| account_id required | string Example: biz_01j8ma3wv3mepwabfxxs0yc395 |
| customer_id required | string^cus_ Match by the customer's exact Pocket ID ( |
string <email> (MemberEmailLookup) Match by email after trimming surrounding whitespace and applying Pocket's case-insensitive canonical email normalization. | |
| phone | string (MemberPhoneLookup) ^\+[1-9][0-9]{1,14}$ Match by E.164 phone (e.g. |
| government_id | string (MemberGovernmentIdLookup) ^\s*(?:[0-9]{13}|[0-9]{5}-[0-9]{7}-[0-9])\s*$... Match by Pakistani CNIC, the government identity type supported in v1. Formatted and unformatted values are normalized to the same 13 digits before matching. Responses return only |
{- "government_id": "string",
- "phone": "+923228884666"
}{- "business_id": "biz_01j8ma3wv3mepwabfxxs0yc395",
- "customer_id": "cus_01jm0defbbct46vh2ev5dkkhej",
- "email": "usama@example.com",
- "phone": "+923228884666",
- "government_id_masked": "*********5678",
- "status": "active",
- "capabilities": {
- "can_receive_transfers": true
}, - "metadata": {
- "employee_ref": "emp-001"
}, - "created_at": "2026-07-31T09:00:00Z",
- "updated_at": "2026-07-31T09:00:00Z"
}Required scope: members:read.
Retrieve one roster member by customer_id. Soft-removed relationships are included. The
response contains roster data only, not private customer or account data.
| account_id required | string Example: biz_01j8ma3wv3mepwabfxxs0yc395 |
| customer_id required | string Example: cus_01jm0defbbct46vh2ev5dkkhej The linked customer ( |
{- "business_id": "biz_01j8ma3wv3mepwabfxxs0yc395",
- "customer_id": "cus_01jm0defbbct46vh2ev5dkkhej",
- "email": "usama@example.com",
- "phone": "+923228884666",
- "government_id_masked": "*********5678",
- "status": "active",
- "capabilities": {
- "can_receive_transfers": true
}, - "metadata": {
- "employee_ref": "emp-001"
}, - "created_at": "2026-07-31T09:00:00Z",
- "updated_at": "2026-07-31T09:00:00Z"
}Required scope: members:write.
Update this business's roster relationship. Supply at least one of status or metadata.
status may be active or inactive.metadata replaces the whole metadata object; use {} to clear it.idempotency_key is optional but cannot be the only field.This changes only the roster relationship. It does not change the Pocket customer or customer account.
active means the business considers the roster relationship active. It does not guarantee
that the customer can receive a transfer.
capabilities.can_receive_transfers as the sole current inclusion check for
roster-based payments.active update cannot bypass onboarding_required or private customer-account state.409.| account_id required | string Example: biz_01j8ma3wv3mepwabfxxs0yc395 |
| customer_id required | string Example: cus_01jm0defbbct46vh2ev5dkkhej The linked customer ( |
| status required | string Enum: "active" "inactive" The roster states a business may request. Setting |
| idempotency_key | string [ 1 .. 255 ] characters .*\S.* Optional. When supplied, it must not be blank. Makes this update safe to retry; reusing the same key with a different request fingerprint returns |
object (Metadata) <= 50 properties Up to 50 caller-defined string key/value pairs. An empty object is valid. Keys
OpenAPI 3.0 cannot express the key-length limit for arbitrary properties, so Pocket enforces
it at runtime. An invalid key returns Values
An overlong value returns Privacy Metadata is visible only from the account-owner side on which it was set and is not shared with money-movement counterparties. Use it for opaque business identifiers and non-sensitive labels only. Do not include:
Pocket may reject metadata that appears sensitive, but the caller remains responsible for the data it supplies. |
{- "metadata": {
- "property1": "string",
- "property2": "string",
- "employee_ref": "emp-001"
}, - "status": "inactive"
}{- "business_id": "biz_01j8ma3wv3mepwabfxxs0yc395",
- "customer_id": "cus_01jm0defbbct46vh2ev5dkkhej",
- "email": "usama@example.com",
- "phone": "+923228884666",
- "government_id_masked": "*********5678",
- "status": "active",
- "capabilities": {
- "can_receive_transfers": true
}, - "metadata": {
- "employee_ref": "emp-001"
}, - "created_at": "2026-07-31T09:00:00Z",
- "updated_at": "2026-07-31T09:00:00Z"
}Required scope: members:write.
Soft-remove a member from this business's roster by its customer_id.
removed and can_receive_transfers becomes false.GET .../members?status=removed.Removing a member does not affect the Pocket customer, account or payment history.
| account_id required | string Example: biz_01j8ma3wv3mepwabfxxs0yc395 |
| customer_id required | string Example: cus_01jm0defbbct46vh2ev5dkkhej The linked customer ( |
{- "code": "string",
- "message": "destination.account_id has an unexpected prefix",
- "param": "destination.account_id",
- "request_id": "req_01jj0m9w2k3n5p7q9r1s3t5v7w"
}Auto-route deposits from a parent business account into a sub-account.
Matching
Timing
settled while it is enabled.No match
The funds remain in the parent account. No transfer or balance reservation is created. Any preview or event reporting the result is informational only.
Failed routing transfer
A failure is terminal and Pocket does not retry automatically:
funding_rule_id.Use an explicit internal transfer to move earlier, unmatched, or failed-routing funds.
Required scope: funding_rules:write.
Create a deposit-routing rule.
destination_account_id must be an active direct sub-account of the source.Malformed criteria or an invalid destination return 400 invalid_request, with param
naming the field. A source that is not a parent business returns 403 forbidden.
| account_id required | string Example: biz_01j8ma3wv3mepwabfxxs0yc395 |
| idempotency_key required | string [ 1 .. 255 ] characters .*\S.* Use a non-blank random value minted once for this create request so retries do not create duplicate rules. |
| destination_account_id required | string The sub-account matched deposits move to ( |
required | Array of any (FundingRuleCriterion) non-empty |
{- "idempotency_key": "5af19ee3-f1f2-4147-b1b8-67a9fc80f7e2",
- "destination_account_id": "biz_01j6qvsv30kfq9dq59sxp9aze5",
- "criteria": [
- {
- "field": "sender_name",
- "operator": "contains",
- "value": "ARBISOFT"
}, - {
- "field": "description",
- "operator": "equals",
- "value": "PAYROLL"
}
]
}{- "id": "frule_01jzq3v9k2x8e4w7r5t1n6m0ps",
- "source_account_id": "biz_01j8ma3wv3mepwabfxxs0yc395",
- "destination_account_id": "biz_01j6qvsv30kfq9dq59sxp9aze5",
- "criteria": [
- {
- "field": "sender_name",
- "operator": "contains",
- "value": "ARBISOFT"
}
], - "status": "enabled",
- "version": 0,
- "created_at": "2026-07-31T09:00:00Z",
- "updated_at": "2026-07-31T09:00:00Z"
}Required scope: funding_rules:read.
List rules whose source is account_id. Deleted rules appear only when you filter with
status=deleted.
| account_id required | string Example: biz_01j8ma3wv3mepwabfxxs0yc395 |
| status | string (FundingRuleStatus) Enum: "enabled" "disabled" "deleted" Only DELETE sets the terminal |
| cursor | string Opaque cursor ( |
| limit | integer [ 1 .. 100 ] Default: 25 |
{- "has_more": true,
- "next_cursor": "string",
- "data": [
- {
- "id": "frule_01jzq3v9k2x8e4w7r5t1n6m0ps",
- "source_account_id": "biz_01j8ma3wv3mepwabfxxs0yc395",
- "destination_account_id": "biz_01j6qvsv30kfq9dq59sxp9aze5",
- "criteria": [
- {
- "field": "sender_name",
- "operator": "contains",
- "value": "ARBISOFT"
}
], - "status": "enabled",
- "version": 0,
- "created_at": "2026-07-31T09:00:00Z",
- "updated_at": "2026-07-31T09:00:00Z"
}
]
}Required scopes: funding_rules:read and transactions:read.
Test draft criteria against recent settled deposits. Preview creates nothing and never moves or reserves money.
For a deposit from the SWIFT international payment network, preview values may include
method and sender_name. description is absent, so a criterion on it does not match. A
SWIFT payment reference is not treated as a description.
| account_id required | string Example: biz_01j8ma3wv3mepwabfxxs0yc395 |
required | Array of any (FundingRuleCriterion) non-empty |
{- "criteria": [
- {
- "field": "sender_name",
- "operator": "contains",
- "value": "ARBISOFT"
}
]
}{- "data": [
- {
- "transaction_id": "txn_01jjftqbz0n1vzey0pqrq3qmnn",
- "matched": true,
- "matched_criteria": [
- 0
], - "values": {
- "sender_name": "arbisoft ltd"
}
}
]
}Required scope: funding_rules:read.
Retrieve a rule by ID. Soft-deleted rules are included.
| rule_id required | string Example: frule_01jzq3v9k2x8e4w7r5t1n6m0ps |
{- "id": "frule_01jzq3v9k2x8e4w7r5t1n6m0ps",
- "source_account_id": "biz_01j8ma3wv3mepwabfxxs0yc395",
- "destination_account_id": "biz_01j6qvsv30kfq9dq59sxp9aze5",
- "criteria": [
- {
- "field": "sender_name",
- "operator": "contains",
- "value": "ARBISOFT"
}
], - "status": "enabled",
- "version": 0,
- "created_at": "2026-07-31T09:00:00Z",
- "updated_at": "2026-07-31T09:00:00Z"
}Required scope: funding_rules:write.
Update criteria, or pause/resume the rule with status.
enabled and disabled.deleted.409.criteria or status. An empty body or a body containing only
idempotency_key returns 400 invalid_request.idempotency_key to make the update safe to retry.criteria or status increments version and changes updated_at.version or updated_at. A supplied idempotency_key is still bound.If the rule changes after a deposit matches but before its routing transfer runs, the transfer does not run. Funds stay in the source account, and matching is not retried under the new rule version.
| rule_id required | string Example: frule_01jzq3v9k2x8e4w7r5t1n6m0ps |
required | Array of (FundingRuleTextCriterion (object) or FundingRuleMethodCriterion (object)) or (FundingRuleTextCriterion (object) or FundingRuleMethodCriterion (object)) non-empty |
| idempotency_key | string [ 1 .. 255 ] characters .*\S.* Optional. When supplied, it must not be blank. Makes this update safe to retry; reusing the same key with a different request fingerprint returns |
| status | string (FundingRuleWritableStatus) Enum: "enabled" "disabled" Status values callers can set with |
{- "status": "enabled",
- "idempotency_key": "string",
- "criteria": [
- {
- "field": "sender_name",
- "operator": "contains",
- "value": "ARBISOFT"
}
]
}{- "id": "frule_01jzq3v9k2x8e4w7r5t1n6m0ps",
- "source_account_id": "biz_01j8ma3wv3mepwabfxxs0yc395",
- "destination_account_id": "biz_01j6qvsv30kfq9dq59sxp9aze5",
- "criteria": [
- {
- "field": "sender_name",
- "operator": "contains",
- "value": "ARBISOFT"
}
], - "status": "enabled",
- "version": 0,
- "created_at": "2026-07-31T09:00:00Z",
- "updated_at": "2026-07-31T09:00:00Z"
}Required scope: funding_rules:write.
Stop the rule immediately.
status=deleted.GET /v1/funding_rules/{rule_id} continues to return it with status set to deleted.This soft deletion keeps past transfer funding_rule_id references resolvable.
| rule_id required | string Example: frule_01jzq3v9k2x8e4w7r5t1n6m0ps |
{- "code": "string",
- "message": "destination.account_id has an unexpected prefix",
- "param": "destination.account_id",
- "request_id": "req_01jj0m9w2k3n5p7q9r1s3t5v7w"
}Webhook endpoints and the event log (list, retrieve, replay).
Events are reference-only notifications across the account associated with the API key and its owned sub-account hierarchy. They cover:
An event never embeds a resource snapshot. Use its typed subject and optional related
references to fetch current resource state.
Event type identifiers follow resource.event naming. They are open, opaque strings; clients
must handle unknown values.
Events are retained for 7 days from created_at. Older events are omitted from lists and
return 404 on retrieve or replay.
Required scope: webhooks:write.
Create an endpoint that receives Pocket events.
secret appears only in the original successful response.secret: null.| idempotency_key required | string [ 1 .. 255 ] characters .*\S.* Use a non-blank random value minted once for this create request so retries do not create duplicate webhook endpoints. |
| url required | string <uri> |
| enabled_events | Array of strings non-empty Event types to deliver. Omit or use |
| description | string or null |
{- "idempotency_key": "a1f7f0b4-6c2e-4f0e-a0b1-cd50ea2df001",
- "enabled_events": [
- "*"
]
}{- "id": "we_01j1n5qyj7pq43fvg4c142h9f6",
- "enabled_events": [
- "string"
], - "status": "enabled",
- "secret": "string",
- "description": "string",
- "created_at": "2026-07-31T09:00:00Z"
}Required scope: webhooks:read.
| cursor | string Opaque cursor ( |
| limit | integer [ 1 .. 100 ] Default: 25 |
{- "has_more": true,
- "next_cursor": "string",
- "data": [
- {
- "id": "we_01j1n5qyj7pq43fvg4c142h9f6",
- "enabled_events": [
- "string"
], - "status": "enabled",
- "secret": "string",
- "description": "string",
- "created_at": "2026-07-31T09:00:00Z"
}
]
}Required scope: webhooks:read.
| endpoint_id required | string Example: we_01j1n5qyj7pq43fvg4c142h9f6 |
{- "id": "we_01j1n5qyj7pq43fvg4c142h9f6",
- "enabled_events": [
- "string"
], - "status": "enabled",
- "secret": "string",
- "description": "string",
- "created_at": "2026-07-31T09:00:00Z"
}Required scope: webhooks:write.
Update url, enabled_events, or status.
enabled_events is replaced as a whole, not merged, and cannot be empty.status to disabled to pause delivery without removing the endpoint. Set it back
to enabled to resume delivery.Supply at least one field to update. An empty body or idempotency_key alone returns
400 invalid_request.
| endpoint_id required | string Example: we_01j1n5qyj7pq43fvg4c142h9f6 |
| url required | string <uri> Replacement delivery URL. |
| idempotency_key | string [ 1 .. 255 ] characters .*\S.* Optional. When supplied, it must not be blank. Makes this update safe to retry; reusing the same key with a different request fingerprint returns |
| enabled_events | Array of strings non-empty Replacement event selection. Cannot be empty; use |
| status | string Enum: "enabled" "disabled" Set |
{- "status": "enabled",
- "idempotency_key": "string",
- "enabled_events": [
- "string"
]
}{- "id": "we_01j1n5qyj7pq43fvg4c142h9f6",
- "enabled_events": [
- "string"
], - "status": "enabled",
- "secret": "string",
- "description": "string",
- "created_at": "2026-07-31T09:00:00Z"
}Required scope: webhooks:write.
Permanently remove the endpoint and stop delivery. To pause delivery without removing its
configuration or signing secret, update its status to disabled instead.
Recreating a deleted endpoint creates a new endpoint with a new signing secret.
| endpoint_id required | string Example: we_01j1n5qyj7pq43fvg4c142h9f6 |
{- "code": "string",
- "message": "destination.account_id has an unexpected prefix",
- "param": "destination.account_id",
- "request_id": "req_01jj0m9w2k3n5p7q9r1s3t5v7w"
}Required scope: webhooks:write.
Rotate the endpoint's signing secret.
secret appears only in the original successful response.secret: null.| endpoint_id required | string Example: we_01j1n5qyj7pq43fvg4c142h9f6 |
| idempotency_key required | string [ 1 .. 255 ] characters .*\S.* Use a non-blank random value minted once for this rotation request so retries do not rotate the secret more than once. |
{- "idempotency_key": "c6d78b1f-83f1-4d54-8d8d-7a667865c3f7"
}{- "id": "we_01j1n5qyj7pq43fvg4c142h9f6",
- "enabled_events": [
- "string"
], - "status": "enabled",
- "secret": "string",
- "description": "string",
- "created_at": "2026-07-31T09:00:00Z"
}Required scope: events:read.
List retained events across the account associated with the API key and its complete owned sub-account hierarchy.
created_at.When account_id is supplied, it selects one owned account's portfolio context.
| account_id | string Example: account_id=biz_01j8ma3wv3mepwabfxxs0yc395 Select the viewpoint of the account associated with the API key or one of its sub-accounts. Roster membership is not sufficient.
|
| type | string (EventType) Opaque event type identifier in |
| subject_id | string Only events whose |
| created_after | string <date-time> Example: created_after=2026-07-31T09:00:00Z Only items created at/after this time (inclusive). |
| created_before | string <date-time> Example: created_before=2026-07-31T09:00:00Z Only items created at/before this time (inclusive). |
| cursor | string Opaque cursor ( |
| limit | integer [ 1 .. 100 ] Default: 25 |
{- "has_more": true,
- "next_cursor": "string",
- "data": [
- {
- "id": "evt_01j56eb11k4xtsrjhy22xtbdqx",
- "type": "string",
- "account_id": "biz_01j8ma3wv3mepwabfxxs0yc395",
- "subject": {
- "resource": "string",
- "id": "string"
}, - "related": [
- {
- "relationship": "string",
- "resource": "string",
- "id": "string"
}
], - "created_at": "2026-07-31T09:00:00Z"
}
]
}Required scope: events:read.
Retrieve a retained event. Events expire 7 days after created_at; an expired event
returns 404.
| event_id required | string Example: evt_01j56eb11k4xtsrjhy22xtbdqx |
{- "id": "evt_01j56eb11k4xtsrjhy22xtbdqx",
- "type": "string",
- "account_id": "biz_01j8ma3wv3mepwabfxxs0yc395",
- "subject": {
- "resource": "string",
- "id": "string"
}, - "related": [
- {
- "relationship": "string",
- "resource": "string",
- "id": "string"
}
], - "created_at": "2026-07-31T09:00:00Z"
}Required scope: events:write.
Re-deliver a retained event to all matching webhook endpoints. Manual replay is available
only during the 7-day retention window; an expired event returns 404. This operation
does not define automatic webhook retry or delivery guarantees.
| event_id required | string |
{- "code": "string",
- "message": "destination.account_id has an unexpected prefix",
- "param": "destination.account_id",
- "request_id": "req_01jj0m9w2k3n5p7q9r1s3t5v7w"
}