payments

Payments, internal transfers, add money, exchanges and quotes, forward contracts and held rates, scheduled payments, direct debits (mandates, collections), bulk payments, approvals and funds requests.

Markdown version: payments.md

Add money (deposit details or conversion order)

POST /v1/add-money

  • addMoney
  • API key scope payments:write
  • Idempotency-Key required
  • Tenant customer

Idempotency: Idempotency-Key is required. Replays within 24 h return the original response with Idempotency-Replayed: true.

API key scope: payments: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 AddMoneyRequest

bank_transfer: returns deposit details (Same currency). conversion: creates a conversion order from fromBalanceId at the locked quoteId rate (Convert currency).

  • method stringrequired

    One of: "bank_transfer", "conversion"

  • balanceId Uuidrequired

  • amount PositiveMoney | null

  • fromBalanceId Uuid | null

  • quoteId Uuid | null

  • fixedSide FixedSide | null

Responses

  • 200 OK application/json

    Schema AddMoneyResult

    • method stringrequired

      One of: "bank_transfer", "conversion"

    • depositDetails array of AccountDetails

    • exchange Exchange | null

  • 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/add-money" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  --data '{
  "method": "conversion",
  "balanceId": "0192a6f1-1111-7000-8000-00000000b003",
  "fromBalanceId": "0192a6f1-1111-7000-8000-00000000b001",
  "amount": {
    "amountMinor": "250000",
    "currency": "EUR"
  },
  "fixedSide": "buy",
  "quoteId": "0192a6f1-4444-7000-8000-00000000d001"
}'

Approvals inbox

GET /v1/approvals

  • listApprovals
  • API key scope payments:read
  • Tenant any

Customer members see their customer's approvals. Operator staff (x-tenant: any): with X-Tenant-Id set to a customer they read that customer; with their operator id they read every customer of the operator (RLS operator scope) (approvals oversight); staff never decide customer approvals, so mine returns nothing for them and canDecide is false. filter[subjectId] lists the approvals of one payment, recipient or bulk upload.

API key scope: payments:read.

Conditional GET (P12-T07): the response carries a weak ETag of its content; send it back as If-None-Match when polling and the API answers 304 without a body while nothing changed.

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).

withTotalqueryboolean

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

If-None-Matchheaderstring

Conditional GET; 304 when unchanged.

Responses

  • 200 OK application/json

    Schema ApprovalPage

    Cursor-paginated list of Approval.

  • 304 Not modified (`If-None-Match` matched).
  • 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/approvals" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Get approval

GET /v1/approvals/{approvalId}

  • getApproval
  • API key scope payments:read
  • Tenant any

Read access as GET /approvals (operator staff: any customer of the operator).

API key scope: payments:read.

Parameters

NameInTypeDescription
approvalIdrequiredpathUuid

Identifier (approvalId).

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 Approval

    • id Uuidrequiredread-only

      Fields of id
    • subjectType ApprovalSubjectTyperequired

    • subjectId Uuidrequired

    • subjectSummary objectrequired

      Fields of subjectSummary
      • title stringrequired

      • amount Money | null

      • recipientName string | null

        Recipient (payments, recipients) or counterparty name.

      • sourceBalanceId Uuid | null

      • sourceBalanceName string | null

      • rail Rail | null

      • itemCount integer | null

        Bulk uploads: payments in the batch.

        min 0

      • recipientMaskedIdentifier string | null

        Masked account identifier of the recipient the approver binds to (payments: the snapshot taken at submission, which the payment is sent to or refused against; recipients: the current details). Null for other subjects (security audit S-01, D-47).

    • tier integerrequired

      min 0

    • status ApprovalStatusrequiredread-only

      Fields of status
    • requiredApprovals integerrequired

      min 1

    • received integerrequiredread-only

      Approvals received so far (approved decisions).

      min 0

    • decisions array of objectrequired

      Fields of decisions
      • by Uuid

      • byName string

      • decision string

        One of: "approved", "rejected"

      • comment string | null

      • at Timestamp

    • requestedBy Uuidrequired

    • requestedByName string

    • canDecide booleanrequiredread-only

      Whether the caller is an eligible approver (not the requester unless self-approval allowed).

    • expiresAt Timestamp | null

    • createdAt Timestamprequiredread-only

      Fields of createdAt
    • policy objectread-only

      The effective policy tier the request is judged against.

      Fields of policy
      • kind ApprovalPolicyKind | null

      • source stringrequired

        snapshot: the tier captured when the request opened; policy: the current policy; default: the built-in single approval; recipient: recipient approval mode.

        One of: "snapshot", "policy", "default", "recipient"

      • tier ApprovalTierrequired

      • issues array of objectrequired

        Fields of issues
        • code stringrequired

        • message stringrequired

  • 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/approvals/{approvalId}" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

List bulk uploads

GET /v1/bulk-payments

  • listBulkPayments
  • API key scope payments:read
  • Tenant customer

API key scope: payments: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.

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).

Responses

  • 200 OK application/json

    Schema BulkPaymentPage

    Cursor-paginated list of BulkPayment.

  • 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/bulk-payments" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Upload bulk payments file for validation

POST /v1/bulk-payments

  • createBulkPayment
  • API key scope payments:write
  • Idempotency-Key required
  • Tenant customer

Idempotency: Idempotency-Key is required. Replays within 24 h return the original response with Idempotency-Replayed: true.

API key scope: payments: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 BulkPaymentCreate

Upload the CSV first via POST /documents (kind=bulk_payments). Validation is asynchronous.

  • documentId Uuidrequired

  • sourceBalanceId Uuidrequired

  • template string

    One of: "wirebloom_csv_v1"

    default "wirebloom_csv_v1"

Responses

  • 202 Accepted application/json

    Schema BulkPayment

    • id Uuidrequiredread-only

      Fields of id
    • customerId Uuidrequiredread-only

      Fields of customerId
    • documentId Uuidrequired

    • sourceBalanceId Uuidrequired

    • status BulkUploadStatusrequiredread-only

      Fields of status
    • rowsTotal integerrequired

    • rowsOk integerrequired

    • rowsFailed integerrequired

    • total Money | null

    • resultsDocumentId string | null (uuid)read-only

      Per-row results file (CSV document, GET /documents/{documentId}/download) written after validation and after submission; null until produced.

    • createdBy Uuidread-only

      Fields of createdBy
    • createdAt Timestamprequiredread-only

      Fields of createdAt
  • 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/bulk-payments" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  --data '{
  "documentId": "0192a6f0-7c1e-7b3a-9d2e-5f4c3b2a1908",
  "sourceBalanceId": "0192a6f0-7c1e-7b3a-9d2e-5f4c3b2a1908"
}'

Bulk upload status

GET /v1/bulk-payments/{bulkPaymentId}

  • getBulkPayment
  • API key scope payments:read
  • Tenant customer

API key scope: payments:read.

Parameters

NameInTypeDescription
bulkPaymentIdrequiredpathUuid

Identifier (bulkPaymentId).

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 BulkPayment

    • id Uuidrequiredread-only

      Fields of id
    • customerId Uuidrequiredread-only

      Fields of customerId
    • documentId Uuidrequired

    • sourceBalanceId Uuidrequired

    • status BulkUploadStatusrequiredread-only

      Fields of status
    • rowsTotal integerrequired

    • rowsOk integerrequired

    • rowsFailed integerrequired

    • total Money | null

    • resultsDocumentId string | null (uuid)read-only

      Per-row results file (CSV document, GET /documents/{documentId}/download) written after validation and after submission; null until produced.

    • createdBy Uuidread-only

      Fields of createdBy
    • createdAt Timestamprequiredread-only

      Fields of createdAt
  • 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/bulk-payments/{bulkPaymentId}" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Cancel bulk upload

POST /v1/bulk-payments/{bulkPaymentId}/cancel

  • cancelBulkPayment
  • API key scope payments:write
  • Tenant customer

API key scope: payments:write.

Stalled submissions (re-review R-05): a batch in submitting whose background run has stopped (no progress for two minutes) can be cancelled: rows not yet submitted become failed with code cancelled, payments already created stay and the batch ends submitted / partially_submitted (or cancelled when none was created, which also closes its batch approval). A batch that is still progressing answers 409 not-cancellable. Batches that stay stalled are closed by the platform after 30 minutes (row code submission_stalled), and rows not yet submitted when the batch approval expires fail with code approval_expired.

Parameters

NameInTypeDescription
bulkPaymentIdrequiredpathUuid

Identifier (bulkPaymentId).

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 BulkPayment

    • id Uuidrequiredread-only

      Fields of id
    • customerId Uuidrequiredread-only

      Fields of customerId
    • documentId Uuidrequired

    • sourceBalanceId Uuidrequired

    • status BulkUploadStatusrequiredread-only

      Fields of status
    • rowsTotal integerrequired

    • rowsOk integerrequired

    • rowsFailed integerrequired

    • total Money | null

    • resultsDocumentId string | null (uuid)read-only

      Per-row results file (CSV document, GET /documents/{documentId}/download) written after validation and after submission; null until produced.

    • createdBy Uuidread-only

      Fields of createdBy
    • createdAt Timestamprequiredread-only

      Fields of createdAt
  • 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/bulk-payments/{bulkPaymentId}/cancel" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Per-row validation results

GET /v1/bulk-payments/{bulkPaymentId}/rows

  • listBulkPaymentRows
  • API key scope payments:read
  • Tenant customer

API key scope: payments:read.

Parameters

NameInTypeDescription
bulkPaymentIdrequiredpathUuid

Identifier (bulkPaymentId).

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).

Responses

  • 200 OK application/json

    Schema BulkPaymentRowPage

    Cursor-paginated list of BulkPaymentRow.

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

  • 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/bulk-payments/{bulkPaymentId}/rows" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Submit validated rows as payments

POST /v1/bulk-payments/{bulkPaymentId}/submit

  • submitBulkPayment
  • API key scope payments:write
  • Idempotency-Key required
  • Tenant customer

Asynchronous (scalability audit X-12): moves the batch to submitting, opens the batch approval when the total falls in an approval tier, and returns 202 with the job (Location: /v1/jobs/{jobId}). Every valid row then becomes a payment through the single-payment path, each with its row status in one transaction, so an interrupted run resumes without duplicates. Submitting a batch that is already submitting returns the same job (and resumes it when it stalled, for the original submitter). 429 rate-limited when too many batches of the operator are being submitted. Decisions on the batch approval are refused (409) until the batch leaves submitting.

Step-up: requires a verified step-up challenge for action payment.above_threshold 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: payments:write.

Expired batch approval (re-review R-05): re-submitting a batch in submitting whose batch approval is no longer pending answers 409 invalid-transition; the remaining rows are closed as failed (approval_expired).

Parameters

NameInTypeDescription
bulkPaymentIdrequiredpathUuid

Identifier (bulkPaymentId).

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.

Responses

  • 202 Accepted application/json

    Schema BulkPaymentSubmitAccepted

    202 of submit: the job that creates the payments in the background (kind bulk_validation, poll GET /jobs/{jobId} for progress) and the batch as it stands (status submitting; poll GET /bulk-payments/{bulkPaymentId} for the final submitted / partially_submitted and the row results).

    • id Uuidrequiredread-only

      Fields of id
    • kind stringrequired

      One of: "export", "statement", "report", "bulk_validation", "billing_run", "reconciliation", "replay"

    • status stringrequired

      One of: "queued", "running", "succeeded", "failed", "cancelled"

    • progress integer

      min 0 · max 100

    • resultUrl string | null (uri)

      Pre-signed download URL (valid 15 minutes) when status=succeeded.

    • error Problem | null

    • createdAt Timestamprequiredread-only

      Fields of createdAt
    • finishedAt Timestamp | null

    • bulkPayment BulkPaymentrequired

  • 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/bulk-payments/{bulkPaymentId}/submit" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID" \
  -H "Idempotency-Key: $(uuidgen)"

List direct debit collections

GET /v1/collections

  • listCollections
  • API key scope payments:read
  • Tenant customer

Feature flag: payments.direct_debits; returns 404 with problem type feature-disabled when the flag is off for the operator.

API key scope: payments: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.

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).

Responses

  • 200 OK application/json

    Schema CollectionPage

    Cursor-paginated list of Collection.

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

  • 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/collections" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Request a collection on a mandate

POST /v1/collections

  • createCollection
  • API key scope payments:write
  • Idempotency-Key required
  • Tenant customer

Idempotency: Idempotency-Key is required. Replays within 24 h return the original response with Idempotency-Replayed: true.

Feature flag: payments.direct_debits; returns 404 with problem type feature-disabled when the flag is off for the operator.

API key scope: payments: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 CollectionCreate

  • mandateId Uuidrequired

  • amount PositiveMoneyrequired

  • dueDate Daterequired

  • reference string | null

    max length 35

Responses

  • 201 Created application/json

    Schema Collection

    • id Uuidrequiredread-only

      Fields of id
    • mandateId Uuidrequired

    • amount Moneyrequired

    • dueDate Daterequired

    • status CollectionStatusrequiredread-only

      Fields of status
    • providerRef string | nullread-only

    • transactionId Uuid | null

    • failureReason string | nullread-only

    • createdAt Timestamprequiredread-only

      Fields of createdAt
    • reference string | null

    • sequenceType stringread-only

      One of: "FRST", "RCUR", "OOFF", "FNAL"

    • submitOn Date | null

    • collectedAt Timestamp | null

    • returnReasonCode string | nullread-only

      R-transaction reason code (SEPA / Bacs ARUDD).

    • returnedAt Timestamp | null

    • scheduledPaymentId Uuid | null

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

  • 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/collections" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  --data '{
  "mandateId": "0192a6f0-7c1e-7b3a-9d2e-5f4c3b2a1908",
  "amount": {
    "amountMinor": "125050",
    "currency": "GBP"
  },
  "dueDate": "2026-09-30"
}'

Get collection

GET /v1/collections/{collectionId}

  • getCollection
  • API key scope payments:read
  • Tenant customer

Feature flag: payments.direct_debits; returns 404 with problem type feature-disabled when the flag is off for the operator.

API key scope: payments:read.

Parameters

NameInTypeDescription
collectionIdrequiredpathUuid

Identifier (collectionId).

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 Collection

    • id Uuidrequiredread-only

      Fields of id
    • mandateId Uuidrequired

    • amount Moneyrequired

    • dueDate Daterequired

    • status CollectionStatusrequiredread-only

      Fields of status
    • providerRef string | nullread-only

    • transactionId Uuid | null

    • failureReason string | nullread-only

    • createdAt Timestamprequiredread-only

      Fields of createdAt
    • reference string | null

    • sequenceType stringread-only

      One of: "FRST", "RCUR", "OOFF", "FNAL"

    • submitOn Date | null

    • collectedAt Timestamp | null

    • returnReasonCode string | nullread-only

      R-transaction reason code (SEPA / Bacs ARUDD).

    • returnedAt Timestamp | null

    • scheduledPaymentId Uuid | 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.

  • 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/collections/{collectionId}" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Cancel collection (before submission)

POST /v1/collections/{collectionId}/cancel

  • cancelCollection
  • API key scope payments:write
  • Tenant customer

Feature flag: payments.direct_debits; returns 404 with problem type feature-disabled when the flag is off for the operator.

API key scope: payments:write.

Parameters

NameInTypeDescription
collectionIdrequiredpathUuid

Identifier (collectionId).

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 Collection

    • id Uuidrequiredread-only

      Fields of id
    • mandateId Uuidrequired

    • amount Moneyrequired

    • dueDate Daterequired

    • status CollectionStatusrequiredread-only

      Fields of status
    • providerRef string | nullread-only

    • transactionId Uuid | null

    • failureReason string | nullread-only

    • createdAt Timestamprequiredread-only

      Fields of createdAt
    • reference string | null

    • sequenceType stringread-only

      One of: "FRST", "RCUR", "OOFF", "FNAL"

    • submitOn Date | null

    • collectedAt Timestamp | null

    • returnReasonCode string | nullread-only

      R-transaction reason code (SEPA / Bacs ARUDD).

    • returnedAt Timestamp | null

    • scheduledPaymentId Uuid | 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/collections/{collectionId}/cancel" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

List exchanges

GET /v1/exchanges

  • listExchanges
  • API key scope exchanges:read
  • Tenant customer

API key scope: exchanges: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.

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).

qquerystring

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

Responses

  • 200 OK application/json

    Schema ExchangePage

    Cursor-paginated list of Exchange.

  • 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/exchanges" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Execute exchange from a quote

POST /v1/exchanges

  • createExchange
  • API key scope exchanges:write
  • Idempotency-Key required
  • Tenant customer

Exchanges are subject to payment approval policies when enabled.

Idempotency: Idempotency-Key is required. Replays within 24 h return the original response with Idempotency-Replayed: true.

API key scope: exchanges: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 ExchangeCreate

Execute a live quote. Expired quote → 409 quote-expired.

  • quoteId Uuidrequired

  • sellBalanceId Uuidrequired

  • buyBalanceId Uuidrequired

Responses

  • 201 Created application/json

    Schema Exchange

    • id Uuidrequiredread-only

      Fields of id
    • customerId Uuidrequiredread-only

      Fields of customerId
    • kind ExchangeKindrequired

    • status ExchangeStatusrequiredread-only

      Fields of status
    • sellBalanceId Uuidrequired

    • buyBalanceId Uuidrequired

    • sellAmount Moneyrequired

    • buyAmount Moneyrequired

    • rate Raterequired

    • fixedSide FixedSiderequired

    • quoteId Uuidrequired

    • fee Money | null

    • settlementDate Date | null

    • deposit Money | null

    • remaining Money | null

    • orderId stringrequiredread-only

      Human order id shown on confirmations.

    • providerRef string | nullread-only

    • createdBy Uuid | null

    • createdAt Timestamprequiredread-only

      Fields of createdAt
    • completedAt Timestamp | null

    • purpose stringread-only

      What the conversion is for: a direct exchange, an add-money conversion order or the funding of a cross-currency payment.

      One of: "exchange", "add_money", "payment"

    • statusReason string | nullread-only

      Why the exchange failed or was cancelled.

    • marginCall object | nullread-only

      Open margin call on a forward: deposit top-up required (POST /forward-contracts/{exchangeId}/deposit).

      Fields of marginCall
    • drawdownCount integerread-only

      Drawdowns requested on a forward or held-rate contract.

      min 0

  • 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/exchanges" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  --data '{
  "quoteId": "0192a6f1-4444-7000-8000-00000000d001",
  "sellBalanceId": "0192a6f1-1111-7000-8000-00000000b001",
  "buyBalanceId": "0192a6f1-1111-7000-8000-00000000b003"
}'

Get exchange

GET /v1/exchanges/{exchangeId}

  • getExchange
  • API key scope exchanges:read
  • Tenant customer

API key scope: exchanges:read.

Parameters

NameInTypeDescription
exchangeIdrequiredpathUuid

Identifier (exchangeId).

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 Exchange

    • id Uuidrequiredread-only

      Fields of id
    • customerId Uuidrequiredread-only

      Fields of customerId
    • kind ExchangeKindrequired

    • status ExchangeStatusrequiredread-only

      Fields of status
    • sellBalanceId Uuidrequired

    • buyBalanceId Uuidrequired

    • sellAmount Moneyrequired

    • buyAmount Moneyrequired

    • rate Raterequired

    • fixedSide FixedSiderequired

    • quoteId Uuidrequired

    • fee Money | null

    • settlementDate Date | null

    • deposit Money | null

    • remaining Money | null

    • orderId stringrequiredread-only

      Human order id shown on confirmations.

    • providerRef string | nullread-only

    • createdBy Uuid | null

    • createdAt Timestamprequiredread-only

      Fields of createdAt
    • completedAt Timestamp | null

    • purpose stringread-only

      What the conversion is for: a direct exchange, an add-money conversion order or the funding of a cross-currency payment.

      One of: "exchange", "add_money", "payment"

    • statusReason string | nullread-only

      Why the exchange failed or was cancelled.

    • marginCall object | nullread-only

      Open margin call on a forward: deposit top-up required (POST /forward-contracts/{exchangeId}/deposit).

      Fields of marginCall
    • drawdownCount integerread-only

      Drawdowns requested on a forward or held-rate contract.

      min 0

  • 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/exchanges/{exchangeId}" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Exchange order confirmation (PDF)

GET /v1/exchanges/{exchangeId}/confirmation

  • getExchangeConfirmation
  • API key scope statements:read
  • Tenant customer

The branded confirmation PDF, rendered on first request and cached (same behaviour as GET /payments/{paymentId}/confirmation).

API key scope: statements:read.

Parameters

NameInTypeDescription
exchangeIdrequiredpathUuid

Identifier (exchangeId).

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/pdf

    string

  • 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/exchanges/{exchangeId}/confirmation" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Create FX quote

POST /v1/exchanges/quotes

  • createQuote
  • API key scope exchanges:write
  • Tenant customer

API key scope: exchanges: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-Keyheaderstring

Optional idempotency key; same semantics as on money operations.

Request body

Required. application/json

Schema QuoteCreate

amount.currency must equal the fixed side currency. settlementDate required for forward.

  • sellCurrency CurrencyCoderequired

  • buyCurrency CurrencyCoderequired

  • amount PositiveMoneyrequired

  • fixedSide FixedSiderequired

  • kind ExchangeKind

  • settlementDate Date | null

  • sellBalanceId Uuid | null

  • buyBalanceId Uuid | null

  • holdMinutes integer | null

    Held rates: how long the rate is held (default: operator setting exchange.heldRateDefaultMinutes).

    min 1 · max 1440

Responses

  • 201 Created application/json

    Schema Quote

    Firm quote; typically valid 30 seconds (countdown in the UI). Refresh to get a new rate.

  • 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/exchanges/quotes" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID" \
  -H "Content-Type: application/json" \
  --data '{
  "sellCurrency": "GBP",
  "buyCurrency": "EUR",
  "amount": {
    "amountMinor": "100000",
    "currency": "EUR"
  },
  "fixedSide": "buy",
  "kind": "spot"
}'

Get quote

GET /v1/exchanges/quotes/{quoteId}

  • getQuote
  • API key scope exchanges:read
  • Tenant customer

API key scope: exchanges:read.

Parameters

NameInTypeDescription
quoteIdrequiredpathUuid

Identifier (quoteId).

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 Quote

    Firm quote; typically valid 30 seconds (countdown in the UI). Refresh to get a new rate.

  • 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/exchanges/quotes/{quoteId}" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Refresh an expired quote (new quote, same terms)

POST /v1/exchanges/quotes/{quoteId}/refresh

  • refreshQuote
  • API key scope exchanges:write
  • Tenant customer

API key scope: exchanges:write.

Parameters

NameInTypeDescription
quoteIdrequiredpathUuid

Identifier (quoteId).

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-Keyheaderstring

Optional idempotency key; same semantics as on money operations.

Responses

  • 201 Created application/json

    Schema Quote

    Firm quote; typically valid 30 seconds (countdown in the UI). Refresh to get a new rate.

  • 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/exchanges/quotes/{quoteId}/refresh" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

List forward contracts and held rates

GET /v1/forward-contracts

  • listForwardContracts
  • API key scope exchanges:read
  • Tenant customer

Forwards and held rates (filter[kind]=held_rate): there is no separate /held-rates resource; held rates are booked, listed and drawn down here.

Feature flag: fx.forwards; returns 404 with problem type feature-disabled when the flag is off for the operator.

API key scope: exchanges: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.

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).

qquerystring

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

Responses

  • 200 OK application/json

    Schema ExchangePage

    Cursor-paginated list of Exchange.

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

  • 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/forward-contracts" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Book forward contract / held rate

POST /v1/forward-contracts

  • createForwardContract
  • API key scope exchanges:write
  • Idempotency-Key required
  • Tenant customer

Idempotency: Idempotency-Key is required. Replays within 24 h return the original response with Idempotency-Replayed: true.

Feature flag: fx.forwards; returns 404 with problem type feature-disabled when the flag is off for the operator.

API key scope: exchanges: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 ForwardContractCreate

Book a forward or held-rate contract from a forward/held_rate quote. Deposit is taken from depositBalanceId when required.

  • quoteId Uuidrequired

  • sellBalanceId Uuidrequired

  • buyBalanceId Uuidrequired

  • depositBalanceId Uuid | null

Responses

  • 201 Created application/json

    Schema Exchange

    • id Uuidrequiredread-only

      Fields of id
    • customerId Uuidrequiredread-only

      Fields of customerId
    • kind ExchangeKindrequired

    • status ExchangeStatusrequiredread-only

      Fields of status
    • sellBalanceId Uuidrequired

    • buyBalanceId Uuidrequired

    • sellAmount Moneyrequired

    • buyAmount Moneyrequired

    • rate Raterequired

    • fixedSide FixedSiderequired

    • quoteId Uuidrequired

    • fee Money | null

    • settlementDate Date | null

    • deposit Money | null

    • remaining Money | null

    • orderId stringrequiredread-only

      Human order id shown on confirmations.

    • providerRef string | nullread-only

    • createdBy Uuid | null

    • createdAt Timestamprequiredread-only

      Fields of createdAt
    • completedAt Timestamp | null

    • purpose stringread-only

      What the conversion is for: a direct exchange, an add-money conversion order or the funding of a cross-currency payment.

      One of: "exchange", "add_money", "payment"

    • statusReason string | nullread-only

      Why the exchange failed or was cancelled.

    • marginCall object | nullread-only

      Open margin call on a forward: deposit top-up required (POST /forward-contracts/{exchangeId}/deposit).

      Fields of marginCall
    • drawdownCount integerread-only

      Drawdowns requested on a forward or held-rate contract.

      min 0

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

  • 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/forward-contracts" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  --data '{
  "quoteId": "0192a6f0-7c1e-7b3a-9d2e-5f4c3b2a1908",
  "sellBalanceId": "0192a6f0-7c1e-7b3a-9d2e-5f4c3b2a1908",
  "buyBalanceId": "0192a6f0-7c1e-7b3a-9d2e-5f4c3b2a1908"
}'

Get forward contract

GET /v1/forward-contracts/{exchangeId}

  • getForwardContract
  • API key scope exchanges:read
  • Tenant customer

Feature flag: fx.forwards; returns 404 with problem type feature-disabled when the flag is off for the operator.

API key scope: exchanges:read.

Parameters

NameInTypeDescription
exchangeIdrequiredpathUuid

Identifier (exchangeId).

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 Exchange

    • id Uuidrequiredread-only

      Fields of id
    • customerId Uuidrequiredread-only

      Fields of customerId
    • kind ExchangeKindrequired

    • status ExchangeStatusrequiredread-only

      Fields of status
    • sellBalanceId Uuidrequired

    • buyBalanceId Uuidrequired

    • sellAmount Moneyrequired

    • buyAmount Moneyrequired

    • rate Raterequired

    • fixedSide FixedSiderequired

    • quoteId Uuidrequired

    • fee Money | null

    • settlementDate Date | null

    • deposit Money | null

    • remaining Money | null

    • orderId stringrequiredread-only

      Human order id shown on confirmations.

    • providerRef string | nullread-only

    • createdBy Uuid | null

    • createdAt Timestamprequiredread-only

      Fields of createdAt
    • completedAt Timestamp | null

    • purpose stringread-only

      What the conversion is for: a direct exchange, an add-money conversion order or the funding of a cross-currency payment.

      One of: "exchange", "add_money", "payment"

    • statusReason string | nullread-only

      Why the exchange failed or was cancelled.

    • marginCall object | nullread-only

      Open margin call on a forward: deposit top-up required (POST /forward-contracts/{exchangeId}/deposit).

      Fields of marginCall
    • drawdownCount integerread-only

      Drawdowns requested on a forward or held-rate contract.

      min 0

  • 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/forward-contracts/{exchangeId}" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Top up a forward deposit (margin call)

POST /v1/forward-contracts/{exchangeId}/deposit

  • topUpForwardDeposit
  • API key scope exchanges:write
  • Idempotency-Key required
  • Tenant customer

Idempotency: Idempotency-Key is required. Replays within 24 h return the original response with Idempotency-Replayed: true.

Feature flag: fx.forwards; returns 404 with problem type feature-disabled when the flag is off for the operator.

API key scope: exchanges:write.

Parameters

NameInTypeDescription
exchangeIdrequiredpathUuid

Identifier (exchangeId).

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 ForwardDepositTopUp

Deposit top-up for an open forward (margin call), in the contract's sell currency; taken from fromBalanceId (default: the sell balance). Clears the margin call when it covers it.

Responses

  • 200 OK application/json

    Schema Exchange

    • id Uuidrequiredread-only

      Fields of id
    • customerId Uuidrequiredread-only

      Fields of customerId
    • kind ExchangeKindrequired

    • status ExchangeStatusrequiredread-only

      Fields of status
    • sellBalanceId Uuidrequired

    • buyBalanceId Uuidrequired

    • sellAmount Moneyrequired

    • buyAmount Moneyrequired

    • rate Raterequired

    • fixedSide FixedSiderequired

    • quoteId Uuidrequired

    • fee Money | null

    • settlementDate Date | null

    • deposit Money | null

    • remaining Money | null

    • orderId stringrequiredread-only

      Human order id shown on confirmations.

    • providerRef string | nullread-only

    • createdBy Uuid | null

    • createdAt Timestamprequiredread-only

      Fields of createdAt
    • completedAt Timestamp | null

    • purpose stringread-only

      What the conversion is for: a direct exchange, an add-money conversion order or the funding of a cross-currency payment.

      One of: "exchange", "add_money", "payment"

    • statusReason string | nullread-only

      Why the exchange failed or was cancelled.

    • marginCall object | nullread-only

      Open margin call on a forward: deposit top-up required (POST /forward-contracts/{exchangeId}/deposit).

      Fields of marginCall
    • drawdownCount integerread-only

      Drawdowns requested on a forward or held-rate contract.

      min 0

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

  • 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/forward-contracts/{exchangeId}/deposit" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  --data '{
  "amount": {
    "amountMinor": "125050",
    "currency": "GBP"
  }
}'

Draw down a forward contract

POST /v1/forward-contracts/{exchangeId}/drawdowns

  • drawdownForwardContract
  • API key scope exchanges:write
  • Idempotency-Key required
  • Tenant customer

Idempotency: Idempotency-Key is required. Replays within 24 h return the original response with Idempotency-Replayed: true.

Feature flag: fx.forwards; returns 404 with problem type feature-disabled when the flag is off for the operator.

API key scope: exchanges:write.

Parameters

NameInTypeDescription
exchangeIdrequiredpathUuid

Identifier (exchangeId).

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 Drawdown

Use part of the remaining forward balance (settle to buy balance or fund a payment).

Responses

  • 200 OK application/json

    Schema Exchange

    • id Uuidrequiredread-only

      Fields of id
    • customerId Uuidrequiredread-only

      Fields of customerId
    • kind ExchangeKindrequired

    • status ExchangeStatusrequiredread-only

      Fields of status
    • sellBalanceId Uuidrequired

    • buyBalanceId Uuidrequired

    • sellAmount Moneyrequired

    • buyAmount Moneyrequired

    • rate Raterequired

    • fixedSide FixedSiderequired

    • quoteId Uuidrequired

    • fee Money | null

    • settlementDate Date | null

    • deposit Money | null

    • remaining Money | null

    • orderId stringrequiredread-only

      Human order id shown on confirmations.

    • providerRef string | nullread-only

    • createdBy Uuid | null

    • createdAt Timestamprequiredread-only

      Fields of createdAt
    • completedAt Timestamp | null

    • purpose stringread-only

      What the conversion is for: a direct exchange, an add-money conversion order or the funding of a cross-currency payment.

      One of: "exchange", "add_money", "payment"

    • statusReason string | nullread-only

      Why the exchange failed or was cancelled.

    • marginCall object | nullread-only

      Open margin call on a forward: deposit top-up required (POST /forward-contracts/{exchangeId}/deposit).

      Fields of marginCall
    • drawdownCount integerread-only

      Drawdowns requested on a forward or held-rate contract.

      min 0

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

  • 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/forward-contracts/{exchangeId}/drawdowns" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  --data '{
  "amount": {
    "amountMinor": "125050",
    "currency": "GBP"
  }
}'

Deposit balance held for forwards

GET /v1/forward-contracts/deposit-balance

  • getForwardDepositBalance
  • API key scope exchanges:read
  • Tenant customer

Feature flag: fx.forwards; returns 404 with problem type feature-disabled when the flag is off for the operator.

API key scope: exchanges: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.

Responses

  • 200 OK application/json

    Schema DepositBalance

    Deposits held against open forward contracts (Equals "View deposit balance").

    • balances array of objectrequired

      Fields of balances
  • 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/forward-contracts/deposit-balance" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

List funds requests

GET /v1/funds-requests

  • listFundsRequests
  • API key scope payments:read
  • Tenant customer

API key scope: payments: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.

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).

Responses

  • 200 OK application/json

    Schema FundsRequestPage

    Cursor-paginated list of FundsRequest.

  • 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/funds-requests" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Request funds

POST /v1/funds-requests

  • createFundsRequest
  • API key scope payments:write
  • Idempotency-Key required
  • Tenant customer

409 funds-requests-disabled when the customer setting is off.

Idempotency: Idempotency-Key is required. Replays within 24 h return the original response with Idempotency-Replayed: true.

API key scope: payments: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 FundsRequestCreate

  • balanceId Uuidrequired

  • amount PositiveMoneyrequired

  • reason stringrequired

    min length 3 · max length 500

  • fromBalanceId Uuid | null

Responses

  • 201 Created application/json

    Schema FundsRequest

    Equals "Requests": a member asks balance holders for funds (e.g. to a sub-balance or card). Fulfilment is an internal transfer (transferId) into balanceId from the approver's chosen source.

  • 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/funds-requests" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  --data '{
  "balanceId": "0192a6f0-7c1e-7b3a-9d2e-5f4c3b2a1908",
  "amount": {
    "amountMinor": "125050",
    "currency": "GBP"
  },
  "reason": "string"
}'

Get funds request

GET /v1/funds-requests/{fundsRequestId}

  • getFundsRequest
  • API key scope payments:read
  • Tenant customer

API key scope: payments:read.

Parameters

NameInTypeDescription
fundsRequestIdrequiredpathUuid

Identifier (fundsRequestId).

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 FundsRequest

    Equals "Requests": a member asks balance holders for funds (e.g. to a sub-balance or card). Fulfilment is an internal transfer (transferId) into balanceId from the approver's chosen source.

  • 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/funds-requests/{fundsRequestId}" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Cancel funds request

POST /v1/funds-requests/{fundsRequestId}/cancel

  • cancelFundsRequest
  • API key scope payments:write
  • Tenant customer

API key scope: payments:write.

Parameters

NameInTypeDescription
fundsRequestIdrequiredpathUuid

Identifier (fundsRequestId).

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 FundsRequest

    Equals "Requests": a member asks balance holders for funds (e.g. to a sub-balance or card). Fulfilment is an internal transfer (transferId) into balanceId from the approver's chosen source.

  • 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/funds-requests/{fundsRequestId}/cancel" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

List direct debit mandates

GET /v1/mandates

  • listMandates
  • API key scope payments:read
  • Tenant customer

Feature flag: payments.direct_debits; returns 404 with problem type feature-disabled when the flag is off for the operator.

API key scope: payments: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.

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).

Responses

  • 200 OK application/json

    Schema MandatePage

    Cursor-paginated list of Mandate.

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

  • 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/mandates" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Create mandate

POST /v1/mandates

  • createMandate
  • API key scope payments:write
  • Idempotency-Key required
  • Tenant customer

Idempotency: Idempotency-Key is required. Replays within 24 h return the original response with Idempotency-Replayed: true.

Feature flag: payments.direct_debits; returns 404 with problem type feature-disabled when the flag is off for the operator.

API key scope: payments: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 MandateCreate

  • direction MandateDirectionrequired

  • scheme MandateSchemerequired

  • reference stringrequired

    Mandate reference (UMR); empty generates one (WB + 14 characters).

    max length 35

  • balanceId Uuidrequired

  • counterparty objectrequired

    Fields of counterparty
    • name stringrequired

    • iban string | null

    • accountNumber string | null

    • sortCode string | null

    • bic string | null

    • creditorId string | null

    • address Address | null

  • signedAt Date | null

  • mandateDocumentId Uuid | null

Responses

  • 201 Created application/json

    Schema Mandate

    Counterparty account identifiers are returned masked.

    • id Uuidrequiredread-only

      Fields of id
    • customerId Uuidrequiredread-only

      Fields of customerId
    • direction MandateDirectionrequired

    • scheme MandateSchemerequired

    • reference stringrequired

      max length 35

    • balanceId Uuidrequired

    • counterparty objectrequired

      Fields of counterparty
      • name stringrequired

      • iban string | null

      • accountNumber string | null

      • sortCode string | null

      • bic string | null

      • creditorId string | null

      • address Address | null

    • status MandateStatusrequiredread-only

      Fields of status
    • signedAt Timestamp | null

    • cancelledAt Timestamp | null

    • providerRef string | nullread-only

    • createdAt Timestamprequiredread-only

      Fields of createdAt
    • management stringread-only

      client: WireBloom generates collection files / status reports are entered by staff; provider: the partner manages the mandate.

      One of: "client", "provider"

    • statusReason string | nullread-only

    • lastCollectionAt Timestamp | null

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

  • 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/mandates" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  --data '{
  "direction": "collect",
  "scheme": "sepa_dd_core",
  "reference": "string",
  "balanceId": "0192a6f0-7c1e-7b3a-9d2e-5f4c3b2a1908",
  "counterparty": {
    "name": "string"
  }
}'

Get mandate

GET /v1/mandates/{mandateId}

  • getMandate
  • API key scope payments:read
  • Tenant customer

Feature flag: payments.direct_debits; returns 404 with problem type feature-disabled when the flag is off for the operator.

API key scope: payments:read.

Parameters

NameInTypeDescription
mandateIdrequiredpathUuid

Identifier (mandateId).

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 Mandate

    Counterparty account identifiers are returned masked.

    • id Uuidrequiredread-only

      Fields of id
    • customerId Uuidrequiredread-only

      Fields of customerId
    • direction MandateDirectionrequired

    • scheme MandateSchemerequired

    • reference stringrequired

      max length 35

    • balanceId Uuidrequired

    • counterparty objectrequired

      Fields of counterparty
      • name stringrequired

      • iban string | null

      • accountNumber string | null

      • sortCode string | null

      • bic string | null

      • creditorId string | null

      • address Address | null

    • status MandateStatusrequiredread-only

      Fields of status
    • signedAt Timestamp | null

    • cancelledAt Timestamp | null

    • providerRef string | nullread-only

    • createdAt Timestamprequiredread-only

      Fields of createdAt
    • management stringread-only

      client: WireBloom generates collection files / status reports are entered by staff; provider: the partner manages the mandate.

      One of: "client", "provider"

    • statusReason string | nullread-only

    • lastCollectionAt Timestamp | 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.

  • 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/mandates/{mandateId}" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Cancel mandate

POST /v1/mandates/{mandateId}/cancel

  • cancelMandate
  • API key scope payments:write
  • Tenant customer

Feature flag: payments.direct_debits; returns 404 with problem type feature-disabled when the flag is off for the operator.

API key scope: payments:write.

Parameters

NameInTypeDescription
mandateIdrequiredpathUuid

Identifier (mandateId).

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.

Request body

Optional. application/json

Schema CancelRequest

  • reason string | null

    max length 500

Responses

  • 200 OK application/json

    Schema Mandate

    Counterparty account identifiers are returned masked.

    • id Uuidrequiredread-only

      Fields of id
    • customerId Uuidrequiredread-only

      Fields of customerId
    • direction MandateDirectionrequired

    • scheme MandateSchemerequired

    • reference stringrequired

      max length 35

    • balanceId Uuidrequired

    • counterparty objectrequired

      Fields of counterparty
      • name stringrequired

      • iban string | null

      • accountNumber string | null

      • sortCode string | null

      • bic string | null

      • creditorId string | null

      • address Address | null

    • status MandateStatusrequiredread-only

      Fields of status
    • signedAt Timestamp | null

    • cancelledAt Timestamp | null

    • providerRef string | nullread-only

    • createdAt Timestamprequiredread-only

      Fields of createdAt
    • management stringread-only

      client: WireBloom generates collection files / status reports are entered by staff; provider: the partner manages the mandate.

      One of: "client", "provider"

    • statusReason string | nullread-only

    • lastCollectionAt Timestamp | null

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

  • 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/mandates/{mandateId}/cancel" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID" \
  -H "Content-Type: application/json" \
  --data '{}'

Collection schedules of a mandate

GET /v1/mandates/{mandateId}/schedules

  • listMandateSchedules
  • API key scope payments:read
  • Tenant customer

Activate, deactivate or end them through /scheduled-payments/{scheduledPaymentId}.

Feature flag: payments.direct_debits; returns 404 with problem type feature-disabled when the flag is off for the operator.

API key scope: payments:read.

Parameters

NameInTypeDescription
mandateIdrequiredpathUuid

Identifier (mandateId).

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
  • 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/mandates/{mandateId}/schedules" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Create a collection schedule

POST /v1/mandates/{mandateId}/schedules

  • createMandateSchedule
  • API key scope payments:write
  • Idempotency-Key required
  • Tenant customer

Idempotency: Idempotency-Key is required. Replays within 24 h return the original response with Idempotency-Replayed: true.

Feature flag: payments.direct_debits; returns 404 with problem type feature-disabled when the flag is off for the operator.

API key scope: payments:write.

Parameters

NameInTypeDescription
mandateIdrequiredpathUuid

Identifier (mandateId).

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 CollectionScheduleCreate

  • name string | null

    max length 100

  • amount PositiveMoneyrequired

  • reference string | null

    max length 35

  • schedule objectrequired

    Fields of schedule
    • rrule stringrequired

    • startDate Daterequired

    • endDate Date | null

    • timezone string

Responses

  • 201 Created application/json

    Schema ScheduledPayment

    • id Uuidrequiredread-only

      Fields of id
    • customerId Uuidrequiredread-only

      Fields of customerId
    • name string | null

      max length 100

    • template ScheduledPaymentTemplate | CollectionScheduleTemplaterequired

    • schedule objectrequired

      Fields of schedule
      • rrule stringrequired

        RFC 5545 RRULE.

      • startDate Daterequired

      • endDate Date | null

      • timezone string

    • status ScheduledPaymentStatusrequiredread-only

      Fields of status
    • nextRunAt Timestamp | null

    • lastPaymentId Uuid | null

    • createdAt Timestamprequiredread-only

      Fields of createdAt
    • updatedAt Timestampread-only

      Fields of updatedAt
    • kind stringread-only

      One of: "payment", "collection"

    • nextExecutionDate Date | null

    • consecutiveFailures integerread-only

      Failed runs in a row; three deactivate the schedule.

      min 0

    • preApproved booleanread-only

      Runs skip the approval tier (operator setting payments.scheduled.preApproveStandingOrders, approved at creation).

    • statusReason string | nullread-only

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

  • 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/mandates/{mandateId}/schedules" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  --data '{
  "amount": {
    "amountMinor": "125050",
    "currency": "GBP"
  },
  "schedule": {
    "rrule": "string",
    "startDate": "2026-09-30"
  }
}'

Record the mandate signature

POST /v1/mandates/{mandateId}/sign

  • signMandate
  • API key scope payments:write
  • Tenant customer

Feature flag: payments.direct_debits; returns 404 with problem type feature-disabled when the flag is off for the operator.

API key scope: payments:write.

Parameters

NameInTypeDescription
mandateIdrequiredpathUuid

Identifier (mandateId).

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.

Request body

Required. application/json

Schema MandateSign

Records the debtor's signature of a pending mandate (pending → active).

  • signedAt Daterequired

  • mandateDocumentId Uuid | null

Responses

  • 200 OK application/json

    Schema Mandate

    Counterparty account identifiers are returned masked.

    • id Uuidrequiredread-only

      Fields of id
    • customerId Uuidrequiredread-only

      Fields of customerId
    • direction MandateDirectionrequired

    • scheme MandateSchemerequired

    • reference stringrequired

      max length 35

    • balanceId Uuidrequired

    • counterparty objectrequired

      Fields of counterparty
      • name stringrequired

      • iban string | null

      • accountNumber string | null

      • sortCode string | null

      • bic string | null

      • creditorId string | null

      • address Address | null

    • status MandateStatusrequiredread-only

      Fields of status
    • signedAt Timestamp | null

    • cancelledAt Timestamp | null

    • providerRef string | nullread-only

    • createdAt Timestamprequiredread-only

      Fields of createdAt
    • management stringread-only

      client: WireBloom generates collection files / status reports are entered by staff; provider: the partner manages the mandate.

      One of: "client", "provider"

    • statusReason string | nullread-only

    • lastCollectionAt Timestamp | null

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

  • 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/mandates/{mandateId}/sign" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID" \
  -H "Content-Type: application/json" \
  --data '{
  "signedAt": "2026-09-30"
}'

List payments

GET /v1/payments

  • listPayments
  • API key scope payments:read
  • Tenant customer

API key scope: payments:read.

Metadata filter: filter[metadata.<key>]=<value> (exact match; at most 5; AND).

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).

Responses

  • 200 OK application/json

    Schema PaymentPage

    Cursor-paginated list of Payment.

  • 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/payments" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Create payment (single-payment wizard)

POST /v1/payments

  • createPayment
  • API key scope payments:write
  • Idempotency-Key required
  • Tenant customer

Validates limits and balance, computes fees, places a hold, applies approval tiers (→ pending_approval) or routes and submits. Conditional step-up: x-step-up names payment.first_to_recipient, but the requirement is evaluated after validation: the first payment to a recipient needs payment.first_to_recipient, a payment at or above the threshold (customer settings.payments.stepUpThreshold, else operator payments.stepUpThreshold) needs payment.above_threshold; drafts (submit: false) need none. POST /payments/dry-run returns requiresStepUp / stepUpAction. API-key requests skip step-up but are always subject to approval tiers (D-24). Recipient must be approved. Cross-currency payments (amount.currency ≠ source currency) need a live spot quoteId selling the source currency for exactly amount (422 quote_required / quote_mismatch, 409 quote-expired); the conversion executes before submission.

Step-up: requires a verified step-up challenge for action payment.first_to_recipient 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: payments: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 PaymentCreate

Single-payment wizard: recipient → amount/currency → reference/purpose/attachments → date → review → submit. When amount.currency differs from the source balance, pass a live quoteId (or fixedSide to let the server quote).

  • sourceBalanceId Uuidrequired

  • recipientId Uuidrequired

  • amount PositiveMoneyrequired

  • fixedSide FixedSide

  • quoteId Uuid | null

  • reference stringrequired

    min length 1 · max length 140

  • purposeCode string | null

    Purpose / transfer reason from GET /payments/purpose-codes (ISO 20022 ExternalPurpose1Code; CNH needs GOD, STR, CTF or OTF: 422 purpose_required / invalid_purpose).

    max length 35

  • chargeBearer ChargeBearer | null

  • urgent boolean

    default false

  • scheduledFor Date | null

  • attachmentDocumentIds array of Uuid

  • submit boolean

    false saves a draft; true submits (approval, holds, routing).

    default true

  • note string | null

    max length 500

  • metadata Metadata

Responses

  • 201 Created application/json

    Schema Payment

    Outgoing payment. amount is what the recipient receives (recipient currency); sendAmount is debited from the source balance when currencies differ.

  • 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/payments" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  --data '{
  "sourceBalanceId": "0192a6f1-1111-7000-8000-00000000b001",
  "recipientId": "0192a6f1-2222-7000-8000-00000000a001",
  "amount": {
    "amountMinor": "100000",
    "currency": "EUR"
  },
  "fixedSide": "buy",
  "quoteId": "0192a6f1-4444-7000-8000-00000000d001",
  "reference": "INV-2026-0042",
  "submit": true
}'

Get payment

GET /v1/payments/{paymentId}

  • getPayment
  • API key scope payments:read
  • Tenant customer

API key scope: payments:read.

Processing with ETA (D-50): while an approved payment waits in the submission queue behind other payments of the operator, processing gives its queue position and an estimated hand-off time; it is absent once the payment is submitted (and for scheduled payments before their execution date).

Parameters

NameInTypeDescription
paymentIdrequiredpathUuid

Identifier (paymentId).

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 Payment

    Outgoing payment. amount is what the recipient receives (recipient currency); sendAmount is debited from the source balance when currencies differ.

  • 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/payments/{paymentId}" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Edit draft payment

PATCH /v1/payments/{paymentId}

  • updatePaymentDraft
  • API key scope payments:write
  • Tenant customer

Concurrency: If-Match with the current ETag is required (428 if absent, 412 if stale).

API key scope: payments:write.

Parameters

NameInTypeDescription
paymentIdrequiredpathUuid

Identifier (paymentId).

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 PaymentUpdate

Only draft payments are editable.

  • amount PositiveMoney

  • quoteId Uuid | null

  • reference string

    max length 140

  • purposeCode string | null

    Purpose / transfer reason from GET /payments/purpose-codes (ISO 20022 ExternalPurpose1Code; CNH needs GOD, STR, CTF or OTF: 422 purpose_required / invalid_purpose).

    max length 35

  • chargeBearer ChargeBearer | null

  • urgent boolean

  • scheduledFor Date | null

  • attachmentDocumentIds array of Uuid

  • metadata MetadataPatch

Responses

  • 200 OK application/json

    Schema Payment

    Outgoing payment. amount is what the recipient receives (recipient currency); sendAmount is debited from the source balance when currencies differ.

  • 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/payments/{paymentId}" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID" \
  -H "If-Match: \"<etag>\"" \
  -H "Content-Type: application/json" \
  --data '{}'

Cancel payment (before submission)

POST /v1/payments/{paymentId}/cancel

  • cancelPayment
  • API key scope payments:write
  • Tenant customer

Allowed in draft, pending_approval, approved and scheduled; releases the hold. After submission use a recall via operator support (409 not-cancellable).

API key scope: payments:write.

Parameters

NameInTypeDescription
paymentIdrequiredpathUuid

Identifier (paymentId).

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-Keyheaderstring

Optional idempotency key; same semantics as on money operations.

Request body

Optional. application/json

Schema CancelRequest

  • reason string | null

    max length 500

Responses

  • 200 OK application/json

    Schema Payment

    Outgoing payment. amount is what the recipient receives (recipient currency); sendAmount is debited from the source balance when currencies differ.

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

  • 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/payments/{paymentId}/cancel" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID" \
  -H "Content-Type: application/json" \
  --data '{}'

Payment order confirmation (PDF)

GET /v1/payments/{paymentId}/confirmation

  • getPaymentConfirmation
  • API key scope statements:read
  • Tenant customer

API key scope: statements:read.

Parameters

NameInTypeDescription
paymentIdrequiredpathUuid

Identifier (paymentId).

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/pdf

    string

  • 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/payments/{paymentId}/confirmation" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Payment status history

GET /v1/payments/{paymentId}/events

  • listPaymentEvents
  • API key scope payments:read
  • Tenant any

Payment timeline. Operator staff (x-tenant: any): with X-Tenant-Id set to a customer they read that customer; with their operator id they read every customer of the operator (RLS operator scope); 404 when the payment is outside the tenant.

API key scope: payments:read.

Parameters

NameInTypeDescription
paymentIdrequiredpathUuid

Identifier (paymentId).

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

    Array of PaymentEvent

  • 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/payments/{paymentId}/events" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Submit draft payment

POST /v1/payments/{paymentId}/submit

  • submitPayment
  • API key scope payments:write
  • Idempotency-Key required
  • Tenant customer

Same checks as a direct submit; step-up is conditional as on createPayment (payment.first_to_recipient or payment.above_threshold).

Step-up: requires a verified step-up challenge for action payment.first_to_recipient 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: payments:write.

Parameters

NameInTypeDescription
paymentIdrequiredpathUuid

Identifier (paymentId).

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.

Responses

  • 200 OK application/json

    Schema Payment

    Outgoing payment. amount is what the recipient receives (recipient currency); sendAmount is debited from the source balance when currencies differ.

  • 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/payments/{paymentId}/submit" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID" \
  -H "Idempotency-Key: $(uuidgen)"

Preview fees, rate, route and checks

POST /v1/payments/dry-run

  • dryRunPayment
  • API key scope payments:write
  • Tenant customer

API key scope: payments: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.

Request body

Required. application/json

Schema PaymentCreate

Single-payment wizard: recipient → amount/currency → reference/purpose/attachments → date → review → submit. When amount.currency differs from the source balance, pass a live quoteId (or fixedSide to let the server quote).

  • sourceBalanceId Uuidrequired

  • recipientId Uuidrequired

  • amount PositiveMoneyrequired

  • fixedSide FixedSide

  • quoteId Uuid | null

  • reference stringrequired

    min length 1 · max length 140

  • purposeCode string | null

    Purpose / transfer reason from GET /payments/purpose-codes (ISO 20022 ExternalPurpose1Code; CNH needs GOD, STR, CTF or OTF: 422 purpose_required / invalid_purpose).

    max length 35

  • chargeBearer ChargeBearer | null

  • urgent boolean

    default false

  • scheduledFor Date | null

  • attachmentDocumentIds array of Uuid

  • submit boolean

    false saves a draft; true submits (approval, holds, routing).

    default true

  • note string | null

    max length 500

  • metadata Metadata

Responses

  • 200 OK application/json

    Schema PaymentDryRun

    Fees, route and checks preview for the Review step. No holds, no side effects.

    • rail Railrequired

    • connectionName string | null

      Shown to staff only.

    • amount Moneyrequired

    • sendAmount Moneyrequired

    • rate Rate | null

    • quoteId Uuid | null

    • quoteExpiresAt Timestamp | null

    • fees array of FeeLinerequired

    • totalDebit Moneyrequired

    • estimatedArrival Timestamprequired

    • earliestExecutionDate Daterequired

    • cutOff Timestamp | null

    • requiresApproval booleanrequired

    • requiresStepUp booleanrequired

    • stepUpAction StepUpAction | null

    • limitCheck objectrequired

      Fields of limitCheck
      • withinLimits boolean

      • breaches array of object

        Fields of breaches
        • limit string

        • remaining Money

    • warnings array of objectrequired

      Fields of warnings
      • code string

      • message string

  • 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/payments/dry-run" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID" \
  -H "Content-Type: application/json" \
  --data '{
  "sourceBalanceId": "0192a6f1-1111-7000-8000-00000000b001",
  "recipientId": "0192a6f1-2222-7000-8000-00000000a001",
  "amount": {
    "amountMinor": "100000",
    "currency": "EUR"
  },
  "fixedSide": "buy",
  "quoteId": "0192a6f1-4444-7000-8000-00000000d001",
  "reference": "INV-2026-0042",
  "purposeCode": "SUPP",
  "urgent": false,
  "submit": true
}'

Purpose codes for a payment

GET /v1/payments/purpose-codes

  • listPurposeCodes
  • API key scope payments:read
  • Tenant any

Purpose / transfer-reason catalogue (P10-T03, FR-PAY-13, parity P-50) for a currency, destination and rail: the accepted codes and whether one is required. Payment creation applies the same rule.

API key scope: payments: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

Payment currency.

countryqueryCountryCode

Bank country of the recipient.

railqueryRail

Rail, when known.

Responses

  • 200 OK application/json

    Schema PurposeCodeCatalogue

    • currency CurrencyCoderequired

    • country CountryCode | nullrequired

    • rail Rail | nullrequired

    • required booleanrequired

      A purpose code must be sent with payments in this context (e.g. CNH).

    • reason string | nullrequired

    • codes array of PurposeCoderequired

    • routingCode string | nullrequired

      Domestic routing code the destination needs (aba, transit, clabe, bsb, ifsc, cnaps, sortCode); null for IBAN countries.

    • railLabel string | nullrequired

  • 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/payments/purpose-codes?currency=GBP" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

List scheduled payments (Active / Inactive)

GET /v1/scheduled-payments

  • listScheduledPayments
  • API key scope payments:read
  • Tenant customer

API key scope: payments: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.

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).

withTotalqueryboolean

Include page.total (may be slower). Computed on the first page only (a request without cursor); later pages omit page.total (scalability audit X-32).

Responses

  • 200 OK application/json

    Schema ScheduledPaymentPage

    Cursor-paginated list of ScheduledPayment.

  • 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/scheduled-payments" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Create scheduled payment / standing order

POST /v1/scheduled-payments

  • createScheduledPayment
  • API key scope payments:write
  • Idempotency-Key required
  • Tenant customer

Step-up: requires a verified step-up challenge for action payment.first_to_recipient 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: payments: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 ScheduledPaymentWrite

  • name string | null

    max length 100

  • template objectrequired

    Fields of template
    • sourceBalanceId Uuidrequired

    • recipientId Uuidrequired

    • amount PositiveMoneyrequired

    • reference stringrequired

      max length 140

    • purposeCode string | null

  • schedule objectrequired

    Fields of schedule
    • rrule stringrequired

    • startDate Daterequired

    • endDate Date | null

    • timezone string

Responses

  • 201 Created application/json

    Schema ScheduledPayment

    • id Uuidrequiredread-only

      Fields of id
    • customerId Uuidrequiredread-only

      Fields of customerId
    • name string | null

      max length 100

    • template ScheduledPaymentTemplate | CollectionScheduleTemplaterequired

    • schedule objectrequired

      Fields of schedule
      • rrule stringrequired

        RFC 5545 RRULE.

      • startDate Daterequired

      • endDate Date | null

      • timezone string

    • status ScheduledPaymentStatusrequiredread-only

      Fields of status
    • nextRunAt Timestamp | null

    • lastPaymentId Uuid | null

    • createdAt Timestamprequiredread-only

      Fields of createdAt
    • updatedAt Timestampread-only

      Fields of updatedAt
    • kind stringread-only

      One of: "payment", "collection"

    • nextExecutionDate Date | null

    • consecutiveFailures integerread-only

      Failed runs in a row; three deactivate the schedule.

      min 0

    • preApproved booleanread-only

      Runs skip the approval tier (operator setting payments.scheduled.preApproveStandingOrders, approved at creation).

    • statusReason string | nullread-only

  • 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/scheduled-payments" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  --data '{
  "template": {
    "sourceBalanceId": "0192a6f0-7c1e-7b3a-9d2e-5f4c3b2a1908",
    "recipientId": "0192a6f0-7c1e-7b3a-9d2e-5f4c3b2a1908",
    "amount": {
      "amountMinor": "125050",
      "currency": "GBP"
    },
    "reference": "string"
  },
  "schedule": {
    "rrule": "string",
    "startDate": "2026-09-30"
  }
}'

Get scheduled payment

GET /v1/scheduled-payments/{scheduledPaymentId}

  • getScheduledPayment
  • API key scope payments:read
  • Tenant customer

API key scope: payments:read.

Parameters

NameInTypeDescription
scheduledPaymentIdrequiredpathUuid

Identifier (scheduledPaymentId).

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 ScheduledPayment

    • id Uuidrequiredread-only

      Fields of id
    • customerId Uuidrequiredread-only

      Fields of customerId
    • name string | null

      max length 100

    • template ScheduledPaymentTemplate | CollectionScheduleTemplaterequired

    • schedule objectrequired

      Fields of schedule
      • rrule stringrequired

        RFC 5545 RRULE.

      • startDate Daterequired

      • endDate Date | null

      • timezone string

    • status ScheduledPaymentStatusrequiredread-only

      Fields of status
    • nextRunAt Timestamp | null

    • lastPaymentId Uuid | null

    • createdAt Timestamprequiredread-only

      Fields of createdAt
    • updatedAt Timestampread-only

      Fields of updatedAt
    • kind stringread-only

      One of: "payment", "collection"

    • nextExecutionDate Date | null

    • consecutiveFailures integerread-only

      Failed runs in a row; three deactivate the schedule.

      min 0

    • preApproved booleanread-only

      Runs skip the approval tier (operator setting payments.scheduled.preApproveStandingOrders, approved at creation).

    • statusReason string | nullread-only

  • 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/scheduled-payments/{scheduledPaymentId}" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Edit scheduled payment

PATCH /v1/scheduled-payments/{scheduledPaymentId}

  • updateScheduledPayment
  • API key scope payments:write
  • Tenant customer

Concurrency: If-Match with the current ETag is required (428 if absent, 412 if stale).

API key scope: payments:write.

Parameters

NameInTypeDescription
scheduledPaymentIdrequiredpathUuid

Identifier (scheduledPaymentId).

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 ScheduledPaymentWrite

  • name string | null

    max length 100

  • template objectrequired

    Fields of template
    • sourceBalanceId Uuidrequired

    • recipientId Uuidrequired

    • amount PositiveMoneyrequired

    • reference stringrequired

      max length 140

    • purposeCode string | null

  • schedule objectrequired

    Fields of schedule
    • rrule stringrequired

    • startDate Daterequired

    • endDate Date | null

    • timezone string

Responses

  • 200 OK application/json

    Schema ScheduledPayment

    • id Uuidrequiredread-only

      Fields of id
    • customerId Uuidrequiredread-only

      Fields of customerId
    • name string | null

      max length 100

    • template ScheduledPaymentTemplate | CollectionScheduleTemplaterequired

    • schedule objectrequired

      Fields of schedule
      • rrule stringrequired

        RFC 5545 RRULE.

      • startDate Daterequired

      • endDate Date | null

      • timezone string

    • status ScheduledPaymentStatusrequiredread-only

      Fields of status
    • nextRunAt Timestamp | null

    • lastPaymentId Uuid | null

    • createdAt Timestamprequiredread-only

      Fields of createdAt
    • updatedAt Timestampread-only

      Fields of updatedAt
    • kind stringread-only

      One of: "payment", "collection"

    • nextExecutionDate Date | null

    • consecutiveFailures integerread-only

      Failed runs in a row; three deactivate the schedule.

      min 0

    • preApproved booleanread-only

      Runs skip the approval tier (operator setting payments.scheduled.preApproveStandingOrders, approved at creation).

    • statusReason string | nullread-only

  • 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/scheduled-payments/{scheduledPaymentId}" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID" \
  -H "If-Match: \"<etag>\"" \
  -H "Content-Type: application/json" \
  --data '{
  "template": {
    "sourceBalanceId": "0192a6f0-7c1e-7b3a-9d2e-5f4c3b2a1908",
    "recipientId": "0192a6f0-7c1e-7b3a-9d2e-5f4c3b2a1908",
    "amount": {
      "amountMinor": "125050",
      "currency": "GBP"
    },
    "reference": "string"
  },
  "schedule": {
    "rrule": "string",
    "startDate": "2026-09-30"
  }
}'

End scheduled payment

DELETE /v1/scheduled-payments/{scheduledPaymentId}

  • deleteScheduledPayment
  • API key scope payments:write
  • Tenant customer

Concurrency: If-Match with the current ETag is required (428 if absent, 412 if stale).

API key scope: payments:write.

Parameters

NameInTypeDescription
scheduledPaymentIdrequiredpathUuid

Identifier (scheduledPaymentId).

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/scheduled-payments/{scheduledPaymentId}" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID" \
  -H "If-Match: \"<etag>\""

Reactivate

POST /v1/scheduled-payments/{scheduledPaymentId}/activate

  • activateScheduledPayment
  • API key scope payments:write
  • Tenant customer

API key scope: payments:write.

Parameters

NameInTypeDescription
scheduledPaymentIdrequiredpathUuid

Identifier (scheduledPaymentId).

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 ScheduledPayment

    • id Uuidrequiredread-only

      Fields of id
    • customerId Uuidrequiredread-only

      Fields of customerId
    • name string | null

      max length 100

    • template ScheduledPaymentTemplate | CollectionScheduleTemplaterequired

    • schedule objectrequired

      Fields of schedule
      • rrule stringrequired

        RFC 5545 RRULE.

      • startDate Daterequired

      • endDate Date | null

      • timezone string

    • status ScheduledPaymentStatusrequiredread-only

      Fields of status
    • nextRunAt Timestamp | null

    • lastPaymentId Uuid | null

    • createdAt Timestamprequiredread-only

      Fields of createdAt
    • updatedAt Timestampread-only

      Fields of updatedAt
    • kind stringread-only

      One of: "payment", "collection"

    • nextExecutionDate Date | null

    • consecutiveFailures integerread-only

      Failed runs in a row; three deactivate the schedule.

      min 0

    • preApproved booleanread-only

      Runs skip the approval tier (operator setting payments.scheduled.preApproveStandingOrders, approved at creation).

    • statusReason string | nullread-only

  • 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/scheduled-payments/{scheduledPaymentId}/activate" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Deactivate

POST /v1/scheduled-payments/{scheduledPaymentId}/deactivate

  • deactivateScheduledPayment
  • API key scope payments:write
  • Tenant customer

API key scope: payments:write.

Parameters

NameInTypeDescription
scheduledPaymentIdrequiredpathUuid

Identifier (scheduledPaymentId).

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 ScheduledPayment

    • id Uuidrequiredread-only

      Fields of id
    • customerId Uuidrequiredread-only

      Fields of customerId
    • name string | null

      max length 100

    • template ScheduledPaymentTemplate | CollectionScheduleTemplaterequired

    • schedule objectrequired

      Fields of schedule
      • rrule stringrequired

        RFC 5545 RRULE.

      • startDate Daterequired

      • endDate Date | null

      • timezone string

    • status ScheduledPaymentStatusrequiredread-only

      Fields of status
    • nextRunAt Timestamp | null

    • lastPaymentId Uuid | null

    • createdAt Timestamprequiredread-only

      Fields of createdAt
    • updatedAt Timestampread-only

      Fields of updatedAt
    • kind stringread-only

      One of: "payment", "collection"

    • nextExecutionDate Date | null

    • consecutiveFailures integerread-only

      Failed runs in a row; three deactivate the schedule.

      min 0

    • preApproved booleanread-only

      Runs skip the approval tier (operator setting payments.scheduled.preApproveStandingOrders, approved at creation).

    • statusReason string | nullread-only

  • 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/scheduled-payments/{scheduledPaymentId}/deactivate" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Upcoming and past runs

GET /v1/scheduled-payments/{scheduledPaymentId}/occurrences

  • listScheduledPaymentOccurrences
  • API key scope payments:read
  • Tenant customer

API key scope: payments:read.

Parameters

NameInTypeDescription
scheduledPaymentIdrequiredpathUuid

Identifier (scheduledPaymentId).

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.

limitqueryinteger

Upcoming runs to plan.

Responses

  • 200 OK application/json

    Schema ScheduledOccurrences

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

  • 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/scheduled-payments/{scheduledPaymentId}/occurrences" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Preview the runs of a schedule

POST /v1/scheduled-payments/preview

  • previewScheduledPayment
  • API key scope payments:read
  • Tenant customer

Canonical RRULE and the next runs (nominal and execution dates, run instant). No writes.

API key scope: payments: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.

Request body

Required. application/json

Schema SchedulePreviewRequest

  • schedule objectrequired

    Fields of schedule
    • rrule stringrequired

    • startDate Daterequired

    • endDate Date | null

    • timezone string

  • currency CurrencyCoderequired

  • rail Rail

  • limit integer

    min 1 · max 60 · default 12

Responses

  • 200 OK application/json

    Schema SchedulePreview

    • rrule stringrequired

      Canonical RRULE.

    • runs array of PlannedRunrequired

  • 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/scheduled-payments/preview" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID" \
  -H "Content-Type: application/json" \
  --data '{
  "schedule": {
    "rrule": "string",
    "startDate": "2026-09-30"
  },
  "currency": "GBP"
}'

List internal transfers

GET /v1/transfers

  • listTransfers
  • API key scope payments:read
  • Tenant customer

API key scope: payments: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.

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).

Responses

  • 200 OK application/json

    Schema TransferPage

    Cursor-paginated list of Transfer.

  • 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/transfers" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"

Internal transfer between own balances

POST /v1/transfers

  • createTransfer
  • API key scope payments:write
  • Idempotency-Key required
  • Tenant customer

Idempotency: Idempotency-Key is required. Replays within 24 h return the original response with Idempotency-Replayed: true.

API key scope: payments: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 TransferCreate

  • fromBalanceId Uuidrequired

  • toBalanceId Uuidrequired

  • amount PositiveMoneyrequired

  • reference string | null

    max length 140

Responses

  • 201 Created application/json

    Schema Transfer

    Internal transfer between own balances of the same currency (payment kind=internal, ledger-only).

  • 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/transfers" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  --data '{
  "fromBalanceId": "0192a6f1-1111-7000-8000-00000000b001",
  "toBalanceId": "0192a6f1-1111-7000-8000-00000000b002",
  "amount": {
    "amountMinor": "50000",
    "currency": "GBP"
  },
  "reference": "Payroll top-up"
}'

Get transfer

GET /v1/transfers/{transferId}

  • getTransfer
  • API key scope payments:read
  • Tenant customer

API key scope: payments:read.

Parameters

NameInTypeDescription
transferIdrequiredpathUuid

Identifier (transferId).

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 Transfer

    Internal transfer between own balances of the same currency (payment kind=internal, ledger-only).

  • 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/transfers/{transferId}" \
  -H "Authorization: Bearer $WIREBLOOM_API_KEY" \
  -H "X-Tenant-Id: $WIREBLOOM_CUSTOMER_ID"