recipients

Recipients (beneficiaries): requirements per currency/country, CRUD, Confirmation/Verification of Payee, approval (customer tier or operator queue, D-14).

Markdown version: recipients.md

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

NameInTypeDescription
X-Tenant-IdrequiredheaderUuid

Tenant context: the operator tenant id (staff operations) or customer tenant id (customer operations). Validated against the caller's memberships; mismatch → 403. For API keys it must equal the key's customer id (customer-level keys are bound to one customer) or, for operator-level keys (P9-T08b), the operator id.

X-Request-Idheaderstring

Client-supplied correlation id. Generated by the server when absent; always echoed in the response and in problem details.

cursorquerystring

Opaque cursor from page.nextCursor or page.prevCursor. Must be used with the same sort and filter as the request that produced it (400 invalid-cursor otherwise).

limitqueryinteger

Page size (max 100).

sortquerystring

Sort order; prefix - for descending. Cursor stability is guaranteed only for the default sort.

filterqueryobject

Filters as filter[field]=value. Multiple values for one field are comma-separated (OR); different fields combine with AND. Date ranges use filter[createdFrom]/filter[createdTo] (inclusive, RFC 3339 or date). P10-T03: filter[metadata.<key>]=<value> matches a metadata attribute exactly (key [A-Za-z0-9_-]{1,40}; at most 5 per request, AND-combined, one value each).

qquerystring

Free-text search (trigram; min 2 characters).

withTotalqueryboolean

Include page.total (may be slower). P12-T07: limit=1&withTotal=true is the count-only form for badges.

Responses

  • 200 OK application/json

    Schema RecipientPage

    Cursor-paginated list of Recipient.

  • 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+json

    Body Problem; see the error catalogue.

  • 401 Missing, expired or invalid credentials (`unauthenticated`, `session-expired` with `reason` `idle` / `revoked` / `expired`, `invalid-api-key`, `mfa-required`). application/problem+json

    Body Problem; see the error catalogue.

  • 403 Authenticated but not allowed: missing capability or scope, tenant not in memberships, `step-up-required`, IP not allow-listed, impersonation restriction. application/problem+json

    Body Problem; see the error catalogue.

  • 429 Rate limit exceeded. application/problem+json

    Body Problem; see the error catalogue.

  • default 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

    Body Problem; see the error catalogue.

Code samples

Against the sandbox (https://bank.wirebloom.com/v1).

curl -X GET "https://bank.wirebloom.com/v1/recipients" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

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

NameInTypeDescription
X-Tenant-IdrequiredheaderUuid

Tenant context: the operator tenant id (staff operations) or customer tenant id (customer operations). Validated against the caller's memberships; mismatch → 403. For API keys it must equal the key's customer id (customer-level keys are bound to one customer) or, for operator-level keys (P9-T08b), the operator id.

X-Request-Idheaderstring

Client-supplied correlation id. Generated by the server when absent; always echoed in the response and in problem details.

Idempotency-Keyrequiredheaderstring

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 Idempotency-Replayed: true. Same key + different body → 422 idempotency-key-reused. Concurrent request with a key still in progress → 409 idempotency-key-in-use + Retry-After. 5xx, 401, 403 (incl. step-up-required) and 429 responses are not stored: the key is released, so the retry (after re-authentication, step-up or back-off) may use the same key.

Request body

Required. application/json

Schema RecipientCreate

  • type RecipientTyperequired

  • name stringrequired

    min length 1 · max length 140

  • nickname string | null

    max length 50

  • email Email | null

  • address Address | null

  • currency CurrencyCoderequired

  • bank RecipientBankrequired

  • defaultReference string | null

    max length 35

  • purpose string | null

    max length 140

  • verificationOverride object | null

    Proceed despite close_match/no_match when policy allows.

    Fields of verificationOverride
  • metadata Metadata

Responses

  • 201 Created application/json

    Schema Recipient

    Recipient. approval is the recipient's review as the caller sees it (null when it was never reviewed). Full bank identifiers are returned only on GET /recipients/{id} (and on create/update); list responses carry bank.iban and bank.accountNumber as null and show maskedIdentifier instead.

  • 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+json

    Body Problem; see the error catalogue.

  • 401 Missing, expired or invalid credentials (`unauthenticated`, `session-expired` with `reason` `idle` / `revoked` / `expired`, `invalid-api-key`, `mfa-required`). application/problem+json

    Body Problem; see the error catalogue.

  • 403 Authenticated but not allowed: missing capability or scope, tenant not in memberships, `step-up-required`, IP not allow-listed, impersonation restriction. application/problem+json

    Body Problem; see the error catalogue.

  • 409 State conflict: `invalid-transition`, `duplicate-recipient`, `quote-expired`, `insufficient-funds`, `idempotency-key-in-use` (with Retry-After), `not-cancellable`. application/problem+json

    Body Problem; see the error catalogue.

  • 422 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+json

    Body Problem; see the error catalogue.

  • 429 Rate limit exceeded. application/problem+json

    Body Problem; see the error catalogue.

  • default 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

    Body Problem; see the error catalogue.

Code samples

Against the sandbox (https://bank.wirebloom.com/v1).

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"
}'

Get recipient (full details)

GET /v1/recipients/{recipientId}

  • getRecipient
  • API key scope recipients:read
  • Tenant customer

API key scope: recipients:read.

Parameters

NameInTypeDescription
recipientIdrequiredpathUuid

Identifier (recipientId).

X-Tenant-IdrequiredheaderUuid

Tenant context: the operator tenant id (staff operations) or customer tenant id (customer operations). Validated against the caller's memberships; mismatch → 403. For API keys it must equal the key's customer id (customer-level keys are bound to one customer) or, for operator-level keys (P9-T08b), the operator id.

X-Request-Idheaderstring

Client-supplied correlation id. Generated by the server when absent; always echoed in the response and in problem details.

If-None-Matchheaderstring

Conditional GET; 304 when unchanged.

Responses

  • 200 OK application/json

    Schema Recipient

    Recipient. approval is the recipient's review as the caller sees it (null when it was never reviewed). Full bank identifiers are returned only on GET /recipients/{id} (and on create/update); list responses carry bank.iban and bank.accountNumber as null and show maskedIdentifier instead.

  • 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+json

    Body Problem; see the error catalogue.

  • 403 Authenticated but not allowed: missing capability or scope, tenant not in memberships, `step-up-required`, IP not allow-listed, impersonation restriction. application/problem+json

    Body Problem; see the error catalogue.

  • 404 Resource does not exist in this tenant (cross-tenant ids also return 404), or feature disabled (`feature-disabled`). application/problem+json

    Body Problem; see the error catalogue.

  • 429 Rate limit exceeded. application/problem+json

    Body Problem; see the error catalogue.

  • default 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

    Body Problem; see the error catalogue.

Code samples

Against the sandbox (https://bank.wirebloom.com/v1).

curl -X GET "https://bank.wirebloom.com/v1/recipients/{recipientId}" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

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

NameInTypeDescription
recipientIdrequiredpathUuid

Identifier (recipientId).

X-Tenant-IdrequiredheaderUuid

Tenant context: the operator tenant id (staff operations) or customer tenant id (customer operations). Validated against the caller's memberships; mismatch → 403. For API keys it must equal the key's customer id (customer-level keys are bound to one customer) or, for operator-level keys (P9-T08b), the operator id.

X-Request-Idheaderstring

Client-supplied correlation id. Generated by the server when absent; always echoed in the response and in problem details.

If-Matchrequiredheaderstring

ETag of the representation being modified (from a prior GET/PATCH).

Request body

Required. application/json

Schema RecipientUpdate

Changing bank or name re-triggers verification and approval (FR-REC-05).

  • name string

    min length 1 · max length 140

  • nickname string | null

    max length 50

  • email Email | null

  • address Address | null

  • bank RecipientBank

  • defaultReference string | null

    max length 35

  • purpose string | null

    max length 140

  • metadata MetadataPatch

Responses

  • 200 OK application/json

    Schema Recipient

    Recipient. approval is the recipient's review as the caller sees it (null when it was never reviewed). Full bank identifiers are returned only on GET /recipients/{id} (and on create/update); list responses carry bank.iban and bank.accountNumber as null and show maskedIdentifier instead.

  • 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+json

    Body Problem; see the error catalogue.

  • 401 Missing, expired or invalid credentials (`unauthenticated`, `session-expired` with `reason` `idle` / `revoked` / `expired`, `invalid-api-key`, `mfa-required`). application/problem+json

    Body Problem; see the error catalogue.

  • 403 Authenticated but not allowed: missing capability or scope, tenant not in memberships, `step-up-required`, IP not allow-listed, impersonation restriction. application/problem+json

    Body Problem; see the error catalogue.

  • 404 Resource does not exist in this tenant (cross-tenant ids also return 404), or feature disabled (`feature-disabled`). application/problem+json

    Body Problem; see the error catalogue.

  • 409 State conflict: `invalid-transition`, `duplicate-recipient`, `quote-expired`, `insufficient-funds`, `idempotency-key-in-use` (with Retry-After), `not-cancellable`. application/problem+json

    Body Problem; see the error catalogue.

  • 412 `If-Match` does not match the current ETag (resource changed). application/problem+json

    Body Problem; see the error catalogue.

  • 422 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+json

    Body Problem; see the error catalogue.

  • 428 `If-Match` header is required for this operation. application/problem+json

    Body Problem; see the error catalogue.

  • 429 Rate limit exceeded. application/problem+json

    Body Problem; see the error catalogue.

  • default 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

    Body Problem; see the error catalogue.

Code samples

Against the sandbox (https://bank.wirebloom.com/v1).

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 '{}'

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

NameInTypeDescription
recipientIdrequiredpathUuid

Identifier (recipientId).

X-Tenant-IdrequiredheaderUuid

Tenant context: the operator tenant id (staff operations) or customer tenant id (customer operations). Validated against the caller's memberships; mismatch → 403. For API keys it must equal the key's customer id (customer-level keys are bound to one customer) or, for operator-level keys (P9-T08b), the operator id.

X-Request-Idheaderstring

Client-supplied correlation id. Generated by the server when absent; always echoed in the response and in problem details.

If-Matchrequiredheaderstring

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+json

    Body Problem; see the error catalogue.

  • 403 Authenticated but not allowed: missing capability or scope, tenant not in memberships, `step-up-required`, IP not allow-listed, impersonation restriction. application/problem+json

    Body Problem; see the error catalogue.

  • 404 Resource does not exist in this tenant (cross-tenant ids also return 404), or feature disabled (`feature-disabled`). application/problem+json

    Body Problem; see the error catalogue.

  • 409 State conflict: `invalid-transition`, `duplicate-recipient`, `quote-expired`, `insufficient-funds`, `idempotency-key-in-use` (with Retry-After), `not-cancellable`. application/problem+json

    Body Problem; see the error catalogue.

  • 412 `If-Match` does not match the current ETag (resource changed). application/problem+json

    Body Problem; see the error catalogue.

  • 428 `If-Match` header is required for this operation. application/problem+json

    Body Problem; see the error catalogue.

  • 429 Rate limit exceeded. application/problem+json

    Body Problem; see the error catalogue.

  • default 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

    Body Problem; see the error catalogue.

Code samples

Against the sandbox (https://bank.wirebloom.com/v1).

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>\""

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

NameInTypeDescription
recipientIdrequiredpathUuid

Identifier (recipientId).

X-Tenant-IdrequiredheaderUuid

Tenant context: the operator tenant id (staff operations) or customer tenant id (customer operations). Validated against the caller's memberships; mismatch → 403. For API keys it must equal the key's customer id (customer-level keys are bound to one customer) or, for operator-level keys (P9-T08b), the operator id.

X-Request-Idheaderstring

Client-supplied correlation id. Generated by the server when absent; always echoed in the response and in problem details.

Responses

  • 200 OK application/json

    Schema RecipientVerification

    • scheme stringrequired

      One of: "cop", "vop"

    • outcome VerificationOutcomerequired

    • matchedName string | null

    • reasonCode string | null

    • provider ProviderIdrequired

    • verifiedAt Timestamprequired

    • overriddenBy Uuid | null

    • overrideReason string | null

  • 401 Missing, expired or invalid credentials (`unauthenticated`, `session-expired` with `reason` `idle` / `revoked` / `expired`, `invalid-api-key`, `mfa-required`). application/problem+json

    Body Problem; see the error catalogue.

  • 403 Authenticated but not allowed: missing capability or scope, tenant not in memberships, `step-up-required`, IP not allow-listed, impersonation restriction. application/problem+json

    Body Problem; see the error catalogue.

  • 404 Resource does not exist in this tenant (cross-tenant ids also return 404), or feature disabled (`feature-disabled`). application/problem+json

    Body Problem; see the error catalogue.

  • 409 State conflict: `invalid-transition`, `duplicate-recipient`, `quote-expired`, `insufficient-funds`, `idempotency-key-in-use` (with Retry-After), `not-cancellable`. application/problem+json

    Body Problem; see the error catalogue.

  • 429 Rate limit exceeded. application/problem+json

    Body Problem; see the error catalogue.

  • default 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

    Body Problem; see the error catalogue.

Code samples

Against the sandbox (https://bank.wirebloom.com/v1).

curl -X POST "https://bank.wirebloom.com/v1/recipients/{recipientId}/verify" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Field requirements per currency and country

GET /v1/recipients/requirements

  • getRecipientRequirements
  • API key scope recipients:read
  • Tenant customer

API key scope: recipients:read.

Parameters

NameInTypeDescription
X-Tenant-IdrequiredheaderUuid

Tenant context: the operator tenant id (staff operations) or customer tenant id (customer operations). Validated against the caller's memberships; mismatch → 403. For API keys it must equal the key's customer id (customer-level keys are bound to one customer) or, for operator-level keys (P9-T08b), the operator id.

X-Request-Idheaderstring

Client-supplied correlation id. Generated by the server when absent; always echoed in the response and in problem details.

currencyrequiredqueryCurrencyCode

Recipient currency.

countryrequiredqueryCountryCode

Bank country.

typequeryRecipientType

Recipient type.

Responses

  • 200 OK application/json

    Schema RecipientRequirements

    Dynamic form definition for the Add-recipient wizard, derived from routing and the routed provider (FR-REC-01).

    • currency CurrencyCoderequired

    • bankCountry CountryCoderequired

    • recipientType RecipientTyperequired

    • rails array of Railrequired

    • fields array of RecipientRequirementFieldrequired

    • verificationAvailable string | null

      One of: "cop", "vop"

    • alternatives array of array of string

      Alternative 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+json

    Body Problem; see the error catalogue.

  • 401 Missing, expired or invalid credentials (`unauthenticated`, `session-expired` with `reason` `idle` / `revoked` / `expired`, `invalid-api-key`, `mfa-required`). application/problem+json

    Body Problem; see the error catalogue.

  • 403 Authenticated but not allowed: missing capability or scope, tenant not in memberships, `step-up-required`, IP not allow-listed, impersonation restriction. application/problem+json

    Body Problem; see the error catalogue.

  • 429 Rate limit exceeded. application/problem+json

    Body Problem; see the error catalogue.

  • default 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

    Body Problem; see the error catalogue.

Code samples

Against the sandbox (https://bank.wirebloom.com/v1).

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"