recipients
Recipients (beneficiaries): requirements per currency/country, CRUD, Confirmation/Verification of Payee, approval (customer tier or operator queue, D-14).
List recipients
GET /v1/recipients
- listRecipients
- API key scope recipients:read
- Tenant customer
API key scope: recipients:read.
Metadata filter: filter[metadata.<key>]=<value> (exact match; at most 5; AND).
Batch look-up (P12-T07): filter[id]=<id>,<id>,… (at most 100) returns those rows only, e.g. to resolve names shown next to ids; combine with limit ≥ the number of ids.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
X-Tenant-Idrequired | header | Uuid | Tenant context: the operator tenant id (staff operations) or customer tenant id (customer operations). Validated against the caller's memberships; mismatch → |
X-Request-Id | header | string | Client-supplied correlation id. Generated by the server when absent; always echoed in the response and in problem details. |
cursor | query | string | Opaque cursor from |
limit | query | integer | Page size (max 100). |
sort | query | string | Sort order; prefix |
filter | query | object | Filters as |
q | query | string | Free-text search (trigram; min 2 characters). |
withTotal | query | boolean | Include |
Responses
400 Malformed request: unparseable JSON, or an invalid header, path or query parameter (`errors[].field` is `header.X`, `path.x` or `query.x`). Body validation failures are 422 `validation-error`.
application/problem+json401 Missing, expired or invalid credentials (`unauthenticated`, `session-expired` with `reason` `idle` / `revoked` / `expired`, `invalid-api-key`, `mfa-required`).
application/problem+json403 Authenticated but not allowed: missing capability or scope, tenant not in memberships, `step-up-required`, IP not allow-listed, impersonation restriction.
application/problem+json429 Rate limit exceeded.
application/problem+jsondefault Unexpected error (`500 internal-error`, `501 not-implemented`, `502 provider-error`, `503 service-unavailable`, `504 provider-timeout`). Money operations that time out at the provider are never retried blindly; their state becomes `exception`/unknown and is reconciled.
application/problem+json
Code samples
curl -X GET "https://bank.wirebloom.com/v1/recipients" \
-H "Authorization: Bearer $WIREBLOOM_API_KEY" \
-H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"const response = await fetch("https://bank.wirebloom.com/v1/recipients", {
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.WIREBLOOM_API_KEY}`,
"X-Tenant-Id": process.env.WIREBLOOM_CUSTOMER_ID!,
},
});
if (!response.ok) throw new Error(`${response.status} ${await response.text()}`);
const result = await response.json();import os
import requests
response = requests.request(
"GET",
"https://bank.wirebloom.com/v1/recipients",
headers={
"Authorization": f"Bearer {os.environ['WIREBLOOM_API_KEY']}",
"X-Tenant-Id": os.environ["WIREBLOOM_CUSTOMER_ID"],
},
timeout=30,
)
response.raise_for_status()Add recipient
POST /v1/recipients
- createRecipient
- API key scope recipients:write
- Idempotency-Key required
- Tenant customer
Validates against requirements (IBAN mod-97, BIC, national formats), de-duplicates (409 duplicate-recipient), runs CoP/VoP where available and applies the approval mode (D-14): customer approval tier or operator queue. API keys: no step-up; recipients created by API keys always require approval by a human per the customer policy.
Step-up: requires a verified step-up challenge for action recipient.create within the last 5 minutes (session/bearer only). Otherwise 403 with problem type step-up-required; the step-up check runs before body validation.
Idempotency: Idempotency-Key is required. Replays within 24 h return the original response with Idempotency-Replayed: true.
API key scope: recipients:write.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
X-Tenant-Idrequired | header | Uuid | Tenant context: the operator tenant id (staff operations) or customer tenant id (customer operations). Validated against the caller's memberships; mismatch → |
X-Request-Id | header | string | Client-supplied correlation id. Generated by the server when absent; always echoed in the response and in problem details. |
Idempotency-Keyrequired | header | string | Unique key per logical operation (UUID v4 recommended). Scope: (credential principal, tenant, method, path). Retained 24 h. Same key + same body → original status and body replayed with |
Request body
typeRecipientTyperequirednamestringrequirednicknamestring | nullemailEmail | nulladdressAddress | nullcurrencyCurrencyCoderequiredbankRecipientBankrequireddefaultReferencestring | nullpurposestring | nullverificationOverrideobject | nullProceed despite
close_match/no_matchwhen policy allows.Fields of verificationOverride
acceptOutcomeVerificationOutcomerequiredreasonstringrequired
metadataMetadata
Responses
201 Created
application/jsonRecipient.
approvalis the recipient's review as the caller sees it (null when it was never reviewed). Full bank identifiers are returned only onGET /recipients/{id}(and on create/update); list responses carrybank.ibanandbank.accountNumberasnulland showmaskedIdentifierinstead.idUuidrequiredread-onlyFields of id
customerIdUuidrequiredread-onlyFields of customerId
typeRecipientTyperequirednamestringrequirednicknamestring | nullemailEmail | nulladdressAddress | nullcurrencyCurrencyCoderequiredbankRecipientBankrequiredmaskedIdentifierstringrequiredread-onlyMasked IBAN/account number for lists.
defaultReferencestring | nullpurposestring | nullstatusRecipientStatusrequiredread-onlyFields of status
verificationRecipientVerification | nulllastPaidAtTimestamp | nullcreatedByUuidread-onlyFields of createdBy
createdAtTimestamprequiredread-onlyFields of createdAt
updatedAtTimestampread-onlyFields of updatedAt
approvalRecipientApproval | nullrequiredmetadataMetadata
400 Malformed request: unparseable JSON, or an invalid header, path or query parameter (`errors[].field` is `header.X`, `path.x` or `query.x`). Body validation failures are 422 `validation-error`.
application/problem+json401 Missing, expired or invalid credentials (`unauthenticated`, `session-expired` with `reason` `idle` / `revoked` / `expired`, `invalid-api-key`, `mfa-required`).
application/problem+json403 Authenticated but not allowed: missing capability or scope, tenant not in memberships, `step-up-required`, IP not allow-listed, impersonation restriction.
application/problem+json409 State conflict: `invalid-transition`, `duplicate-recipient`, `quote-expired`, `insufficient-funds`, `idempotency-key-in-use` (with Retry-After), `not-cancellable`.
application/problem+json422 Semantically invalid request; `errors[]` lists field-level problems. Also `idempotency-key-reused` when the key was used with a different payload, `limit-exceeded`, `recipient-not-approved`.
application/problem+json429 Rate limit exceeded.
application/problem+jsondefault Unexpected error (`500 internal-error`, `501 not-implemented`, `502 provider-error`, `503 service-unavailable`, `504 provider-timeout`). Money operations that time out at the provider are never retried blindly; their state becomes `exception`/unknown and is reconciled.
application/problem+json
Code samples
curl -X POST "https://bank.wirebloom.com/v1/recipients" \
-H "Authorization: Bearer $WIREBLOOM_API_KEY" \
-H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
--data '{
"type": "company",
"name": "Acme GmbH",
"currency": "EUR",
"bank": {
"iban": "DE89370400440532013000",
"bic": "COBADEFFXXX",
"bankCountry": "DE"
},
"defaultReference": "INV-2026"
}'const response = await fetch("https://bank.wirebloom.com/v1/recipients", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.WIREBLOOM_API_KEY}`,
"X-Tenant-Id": process.env.WIREBLOOM_CUSTOMER_ID!,
"Idempotency-Key": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({
"type": "company",
"name": "Acme GmbH",
"currency": "EUR",
"bank": {
"iban": "DE89370400440532013000",
"bic": "COBADEFFXXX",
"bankCountry": "DE"
},
"defaultReference": "INV-2026"
}),
});
if (!response.ok) throw new Error(`${response.status} ${await response.text()}`);
const result = await response.json();import os, uuid
import requests
response = requests.request(
"POST",
"https://bank.wirebloom.com/v1/recipients",
headers={
"Authorization": f"Bearer {os.environ['WIREBLOOM_API_KEY']}",
"X-Tenant-Id": os.environ["WIREBLOOM_CUSTOMER_ID"],
"Idempotency-Key": str(uuid.uuid4()),
"Content-Type": "application/json",
},
json={
"type": "company",
"name": "Acme GmbH",
"currency": "EUR",
"bank": {
"iban": "DE89370400440532013000",
"bic": "COBADEFFXXX",
"bankCountry": "DE"
},
"defaultReference": "INV-2026"
},
timeout=30,
)
response.raise_for_status()Get recipient (full details)
GET /v1/recipients/{recipientId}
- getRecipient
- API key scope recipients:read
- Tenant customer
API key scope: recipients:read.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
recipientIdrequired | path | Uuid | Identifier (recipientId). |
X-Tenant-Idrequired | header | Uuid | Tenant context: the operator tenant id (staff operations) or customer tenant id (customer operations). Validated against the caller's memberships; mismatch → |
X-Request-Id | header | string | Client-supplied correlation id. Generated by the server when absent; always echoed in the response and in problem details. |
If-None-Match | header | string | Conditional GET; |
Responses
200 OK
application/jsonRecipient.
approvalis the recipient's review as the caller sees it (null when it was never reviewed). Full bank identifiers are returned only onGET /recipients/{id}(and on create/update); list responses carrybank.ibanandbank.accountNumberasnulland showmaskedIdentifierinstead.idUuidrequiredread-onlyFields of id
customerIdUuidrequiredread-onlyFields of customerId
typeRecipientTyperequirednamestringrequirednicknamestring | nullemailEmail | nulladdressAddress | nullcurrencyCurrencyCoderequiredbankRecipientBankrequiredmaskedIdentifierstringrequiredread-onlyMasked IBAN/account number for lists.
defaultReferencestring | nullpurposestring | nullstatusRecipientStatusrequiredread-onlyFields of status
verificationRecipientVerification | nulllastPaidAtTimestamp | nullcreatedByUuidread-onlyFields of createdBy
createdAtTimestamprequiredread-onlyFields of createdAt
updatedAtTimestampread-onlyFields of updatedAt
approvalRecipientApproval | nullrequiredmetadataMetadata
304 Not modified (`If-None-Match` matched).
401 Missing, expired or invalid credentials (`unauthenticated`, `session-expired` with `reason` `idle` / `revoked` / `expired`, `invalid-api-key`, `mfa-required`).
application/problem+json403 Authenticated but not allowed: missing capability or scope, tenant not in memberships, `step-up-required`, IP not allow-listed, impersonation restriction.
application/problem+json404 Resource does not exist in this tenant (cross-tenant ids also return 404), or feature disabled (`feature-disabled`).
application/problem+json429 Rate limit exceeded.
application/problem+jsondefault Unexpected error (`500 internal-error`, `501 not-implemented`, `502 provider-error`, `503 service-unavailable`, `504 provider-timeout`). Money operations that time out at the provider are never retried blindly; their state becomes `exception`/unknown and is reconciled.
application/problem+json
Code samples
curl -X GET "https://bank.wirebloom.com/v1/recipients/{recipientId}" \
-H "Authorization: Bearer $WIREBLOOM_API_KEY" \
-H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"const response = await fetch("https://bank.wirebloom.com/v1/recipients/{recipientId}", {
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.WIREBLOOM_API_KEY}`,
"X-Tenant-Id": process.env.WIREBLOOM_CUSTOMER_ID!,
},
});
if (!response.ok) throw new Error(`${response.status} ${await response.text()}`);
const result = await response.json();import os
import requests
response = requests.request(
"GET",
"https://bank.wirebloom.com/v1/recipients/{recipientId}",
headers={
"Authorization": f"Bearer {os.environ['WIREBLOOM_API_KEY']}",
"X-Tenant-Id": os.environ["WIREBLOOM_CUSTOMER_ID"],
},
timeout=30,
)
response.raise_for_status()Edit recipient
PATCH /v1/recipients/{recipientId}
- updateRecipient
- API key scope recipients:write
- Tenant customer
Step-up: requires a verified step-up challenge for action recipient.update within the last 5 minutes (session/bearer only). Otherwise 403 with problem type step-up-required; the step-up check runs before body validation.
Concurrency: If-Match with the current ETag is required (428 if absent, 412 if stale).
API key scope: recipients:write.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
recipientIdrequired | path | Uuid | Identifier (recipientId). |
X-Tenant-Idrequired | header | Uuid | Tenant context: the operator tenant id (staff operations) or customer tenant id (customer operations). Validated against the caller's memberships; mismatch → |
X-Request-Id | header | string | Client-supplied correlation id. Generated by the server when absent; always echoed in the response and in problem details. |
If-Matchrequired | header | string | ETag of the representation being modified (from a prior GET/PATCH). |
Request body
Changing bank or name re-triggers verification and approval (FR-REC-05).
namestringnicknamestring | nullemailEmail | nulladdressAddress | nullbankRecipientBankdefaultReferencestring | nullpurposestring | nullmetadataMetadataPatch
Responses
200 OK
application/jsonRecipient.
approvalis the recipient's review as the caller sees it (null when it was never reviewed). Full bank identifiers are returned only onGET /recipients/{id}(and on create/update); list responses carrybank.ibanandbank.accountNumberasnulland showmaskedIdentifierinstead.idUuidrequiredread-onlyFields of id
customerIdUuidrequiredread-onlyFields of customerId
typeRecipientTyperequirednamestringrequirednicknamestring | nullemailEmail | nulladdressAddress | nullcurrencyCurrencyCoderequiredbankRecipientBankrequiredmaskedIdentifierstringrequiredread-onlyMasked IBAN/account number for lists.
defaultReferencestring | nullpurposestring | nullstatusRecipientStatusrequiredread-onlyFields of status
verificationRecipientVerification | nulllastPaidAtTimestamp | nullcreatedByUuidread-onlyFields of createdBy
createdAtTimestamprequiredread-onlyFields of createdAt
updatedAtTimestampread-onlyFields of updatedAt
approvalRecipientApproval | nullrequiredmetadataMetadata
400 Malformed request: unparseable JSON, or an invalid header, path or query parameter (`errors[].field` is `header.X`, `path.x` or `query.x`). Body validation failures are 422 `validation-error`.
application/problem+json401 Missing, expired or invalid credentials (`unauthenticated`, `session-expired` with `reason` `idle` / `revoked` / `expired`, `invalid-api-key`, `mfa-required`).
application/problem+json403 Authenticated but not allowed: missing capability or scope, tenant not in memberships, `step-up-required`, IP not allow-listed, impersonation restriction.
application/problem+json404 Resource does not exist in this tenant (cross-tenant ids also return 404), or feature disabled (`feature-disabled`).
application/problem+json409 State conflict: `invalid-transition`, `duplicate-recipient`, `quote-expired`, `insufficient-funds`, `idempotency-key-in-use` (with Retry-After), `not-cancellable`.
application/problem+json412 `If-Match` does not match the current ETag (resource changed).
application/problem+json422 Semantically invalid request; `errors[]` lists field-level problems. Also `idempotency-key-reused` when the key was used with a different payload, `limit-exceeded`, `recipient-not-approved`.
application/problem+json428 `If-Match` header is required for this operation.
application/problem+json429 Rate limit exceeded.
application/problem+jsondefault Unexpected error (`500 internal-error`, `501 not-implemented`, `502 provider-error`, `503 service-unavailable`, `504 provider-timeout`). Money operations that time out at the provider are never retried blindly; their state becomes `exception`/unknown and is reconciled.
application/problem+json
Code samples
curl -X PATCH "https://bank.wirebloom.com/v1/recipients/{recipientId}" \
-H "Authorization: Bearer $WIREBLOOM_API_KEY" \
-H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID" \
-H "If-Match: \"<etag>\"" \
-H "Content-Type: application/json" \
--data '{}'const response = await fetch("https://bank.wirebloom.com/v1/recipients/{recipientId}", {
method: "PATCH",
headers: {
"Authorization": `Bearer ${process.env.WIREBLOOM_API_KEY}`,
"X-Tenant-Id": process.env.WIREBLOOM_CUSTOMER_ID!,
"If-Match": "\"<etag>\"",
"Content-Type": "application/json",
},
body: JSON.stringify({}),
});
if (!response.ok) throw new Error(`${response.status} ${await response.text()}`);
const result = await response.json();import os
import requests
response = requests.request(
"PATCH",
"https://bank.wirebloom.com/v1/recipients/{recipientId}",
headers={
"Authorization": f"Bearer {os.environ['WIREBLOOM_API_KEY']}",
"X-Tenant-Id": os.environ["WIREBLOOM_CUSTOMER_ID"],
"If-Match": "\"<etag>\"",
"Content-Type": "application/json",
},
json={},
timeout=30,
)
response.raise_for_status()Delete recipient (soft)
DELETE /v1/recipients/{recipientId}
- deleteRecipient
- API key scope recipients:write
- Tenant customer
409 if scheduled payments or pending payments reference it.
Concurrency: If-Match with the current ETag is required (428 if absent, 412 if stale).
API key scope: recipients:write.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
recipientIdrequired | path | Uuid | Identifier (recipientId). |
X-Tenant-Idrequired | header | Uuid | Tenant context: the operator tenant id (staff operations) or customer tenant id (customer operations). Validated against the caller's memberships; mismatch → |
X-Request-Id | header | string | Client-supplied correlation id. Generated by the server when absent; always echoed in the response and in problem details. |
If-Matchrequired | header | string | ETag of the representation being modified (from a prior GET/PATCH). |
Responses
204 No Content
401 Missing, expired or invalid credentials (`unauthenticated`, `session-expired` with `reason` `idle` / `revoked` / `expired`, `invalid-api-key`, `mfa-required`).
application/problem+json403 Authenticated but not allowed: missing capability or scope, tenant not in memberships, `step-up-required`, IP not allow-listed, impersonation restriction.
application/problem+json404 Resource does not exist in this tenant (cross-tenant ids also return 404), or feature disabled (`feature-disabled`).
application/problem+json409 State conflict: `invalid-transition`, `duplicate-recipient`, `quote-expired`, `insufficient-funds`, `idempotency-key-in-use` (with Retry-After), `not-cancellable`.
application/problem+json412 `If-Match` does not match the current ETag (resource changed).
application/problem+json428 `If-Match` header is required for this operation.
application/problem+json429 Rate limit exceeded.
application/problem+jsondefault Unexpected error (`500 internal-error`, `501 not-implemented`, `502 provider-error`, `503 service-unavailable`, `504 provider-timeout`). Money operations that time out at the provider are never retried blindly; their state becomes `exception`/unknown and is reconciled.
application/problem+json
Code samples
curl -X DELETE "https://bank.wirebloom.com/v1/recipients/{recipientId}" \
-H "Authorization: Bearer $WIREBLOOM_API_KEY" \
-H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID" \
-H "If-Match: \"<etag>\""const response = await fetch("https://bank.wirebloom.com/v1/recipients/{recipientId}", {
method: "DELETE",
headers: {
"Authorization": `Bearer ${process.env.WIREBLOOM_API_KEY}`,
"X-Tenant-Id": process.env.WIREBLOOM_CUSTOMER_ID!,
"If-Match": "\"<etag>\"",
},
});
if (!response.ok) throw new Error(`${response.status} ${await response.text()}`);import os
import requests
response = requests.request(
"DELETE",
"https://bank.wirebloom.com/v1/recipients/{recipientId}",
headers={
"Authorization": f"Bearer {os.environ['WIREBLOOM_API_KEY']}",
"X-Tenant-Id": os.environ["WIREBLOOM_CUSTOMER_ID"],
"If-Match": "\"<etag>\"",
},
timeout=30,
)
response.raise_for_status()Run Confirmation / Verification of Payee
POST /v1/recipients/{recipientId}/verify
- verifyRecipient
- API key scope recipients:write
- Tenant customer
422 verification-unavailable if no routed provider supports CoP/VoP for this currency/country.
API key scope: recipients:write.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
recipientIdrequired | path | Uuid | Identifier (recipientId). |
X-Tenant-Idrequired | header | Uuid | Tenant context: the operator tenant id (staff operations) or customer tenant id (customer operations). Validated against the caller's memberships; mismatch → |
X-Request-Id | header | string | Client-supplied correlation id. Generated by the server when absent; always echoed in the response and in problem details. |
Responses
200 OK
application/jsonschemestringrequiredoutcomeVerificationOutcomerequiredmatchedNamestring | nullreasonCodestring | nullproviderProviderIdrequiredverifiedAtTimestamprequiredoverriddenByUuid | nulloverrideReasonstring | null
401 Missing, expired or invalid credentials (`unauthenticated`, `session-expired` with `reason` `idle` / `revoked` / `expired`, `invalid-api-key`, `mfa-required`).
application/problem+json403 Authenticated but not allowed: missing capability or scope, tenant not in memberships, `step-up-required`, IP not allow-listed, impersonation restriction.
application/problem+json404 Resource does not exist in this tenant (cross-tenant ids also return 404), or feature disabled (`feature-disabled`).
application/problem+json409 State conflict: `invalid-transition`, `duplicate-recipient`, `quote-expired`, `insufficient-funds`, `idempotency-key-in-use` (with Retry-After), `not-cancellable`.
application/problem+json429 Rate limit exceeded.
application/problem+jsondefault Unexpected error (`500 internal-error`, `501 not-implemented`, `502 provider-error`, `503 service-unavailable`, `504 provider-timeout`). Money operations that time out at the provider are never retried blindly; their state becomes `exception`/unknown and is reconciled.
application/problem+json
Code samples
curl -X POST "https://bank.wirebloom.com/v1/recipients/{recipientId}/verify" \
-H "Authorization: Bearer $WIREBLOOM_API_KEY" \
-H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"const response = await fetch("https://bank.wirebloom.com/v1/recipients/{recipientId}/verify", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.WIREBLOOM_API_KEY}`,
"X-Tenant-Id": process.env.WIREBLOOM_CUSTOMER_ID!,
},
});
if (!response.ok) throw new Error(`${response.status} ${await response.text()}`);
const result = await response.json();import os
import requests
response = requests.request(
"POST",
"https://bank.wirebloom.com/v1/recipients/{recipientId}/verify",
headers={
"Authorization": f"Bearer {os.environ['WIREBLOOM_API_KEY']}",
"X-Tenant-Id": os.environ["WIREBLOOM_CUSTOMER_ID"],
},
timeout=30,
)
response.raise_for_status()Field requirements per currency and country
GET /v1/recipients/requirements
- getRecipientRequirements
- API key scope recipients:read
- Tenant customer
API key scope: recipients:read.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
X-Tenant-Idrequired | header | Uuid | Tenant context: the operator tenant id (staff operations) or customer tenant id (customer operations). Validated against the caller's memberships; mismatch → |
X-Request-Id | header | string | Client-supplied correlation id. Generated by the server when absent; always echoed in the response and in problem details. |
currencyrequired | query | CurrencyCode | Recipient currency. |
countryrequired | query | CountryCode | Bank country. |
type | query | RecipientType | Recipient type. |
Responses
200 OK
application/jsonDynamic form definition for the Add-recipient wizard, derived from routing and the routed provider (FR-REC-01).
currencyCurrencyCoderequiredbankCountryCountryCoderequiredrecipientTypeRecipientTyperequiredrailsarray of Railrequiredfieldsarray of RecipientRequirementFieldrequiredverificationAvailablestring | nullalternativesarray of array of stringAlternative sets of required field paths: the recipient is complete when every path of at least one set is present (e.g.
[["bank.iban"], ["bank.accountNumber", "bank.routingCodes.sortCode"]]).
400 Malformed request: unparseable JSON, or an invalid header, path or query parameter (`errors[].field` is `header.X`, `path.x` or `query.x`). Body validation failures are 422 `validation-error`.
application/problem+json401 Missing, expired or invalid credentials (`unauthenticated`, `session-expired` with `reason` `idle` / `revoked` / `expired`, `invalid-api-key`, `mfa-required`).
application/problem+json403 Authenticated but not allowed: missing capability or scope, tenant not in memberships, `step-up-required`, IP not allow-listed, impersonation restriction.
application/problem+json429 Rate limit exceeded.
application/problem+jsondefault Unexpected error (`500 internal-error`, `501 not-implemented`, `502 provider-error`, `503 service-unavailable`, `504 provider-timeout`). Money operations that time out at the provider are never retried blindly; their state becomes `exception`/unknown and is reconciled.
application/problem+json
Code samples
curl -X GET "https://bank.wirebloom.com/v1/recipients/requirements?currency=GBP&country=GB" \
-H "Authorization: Bearer $WIREBLOOM_API_KEY" \
-H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"const response = await fetch("https://bank.wirebloom.com/v1/recipients/requirements?currency=GBP&country=GB", {
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.WIREBLOOM_API_KEY}`,
"X-Tenant-Id": process.env.WIREBLOOM_CUSTOMER_ID!,
},
});
if (!response.ok) throw new Error(`${response.status} ${await response.text()}`);
const result = await response.json();import os
import requests
response = requests.request(
"GET",
"https://bank.wirebloom.com/v1/recipients/requirements?currency=GBP&country=GB",
headers={
"Authorization": f"Bearer {os.environ['WIREBLOOM_API_KEY']}",
"X-Tenant-Id": os.environ["WIREBLOOM_CUSTOMER_ID"],
},
timeout=30,
)
response.raise_for_status()