CorebanqCorebanq Developer Docs
Preflightv1Pre flight

Pre-flight check

Given a partial transfer context for a **target customer** (`customer_id`), returns eligible active products, active counterparty-shaped source rows, active counterparty-shaped destination rows, viable active routes, and optional limits/fees/FX. The target customer itself is represented as a counterparty row, matching the counterparties domain model. Selectable nested payment-source rows expose `cp_account_type` (`account`, `bank_account`, `crypto_wallet`), `cp_account_id`, and `products_allowed`. Inactive catalogue products, inactive matrix rules, inactive transaction channels, inactive source accounts, inactive destination counterparties, inactive bank accounts, and inactive crypto wallets are not returned. Modern finalize clients build selectors from the parent counterparty row `id` plus the chosen nested `cp_account_id`, then send them as `source.counterparty_id` / `source.cp_account_id` and `destination.counterparty_id` / `destination.cp_account_id`. The optional `finalize_recipient` hint is legacy convenience data for older recipient-shaped finalize clients. When a product is pinned via a single effective `product_ids[]` selection and enough route context is provided, `transfer_params` includes the allow/deny verdict, normalized amount, calculated fees, advisory FX, velocity hints, and optional quote state. Requires JWT and **RBAC read** on that customer.

POST
/v1/products/pre-flight

Authorization

BearerAuth
AuthorizationBearer <token>

HTTP bearer JWT from the Corebanq auth service.

Authorization is enforced with RBAC (record-level permissions), not ad-hoc OAuth-style scopes in this spec. See each tag description and operation summaries for which record grants apply.

In: header

Header Parameters

Accept-Language?string

BCP 47 language tag. Selects locale for product name/description. Falls back to the tenant's default locale when absent or unsupported.

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Partial transfer context for the target customer_id. Matrix filter fields are optional: when only customer_id is set, the API returns the full eligible matrix (products, sources with allowed_products, destinations). product_ids[] is the pre-flight product filter; send one UUID to pin one product or multiple UUIDs to constrain discovery to a subset. product_code is not part of the pre-flight request contract; clients should resolve products through the catalog/list APIs and send product UUIDs. destination_account_id and destination_counterparty_id are mutually exclusive. destination_account_id is the universal exact destination selector (counterparties.cp_accounts.id) for own accounts, saved bank accounts, and saved crypto wallets; destination_counterparty_id is a broader counterparty filter that expands linked destination accounts. For deposit route products, pin destination_account_id to check incoming restrictions for the credited account; the source side is evaluated as an external/foreign incoming probe by the product matrix. customer_id is required in JSON unless the route defines {customer_id} (URL wins when both are present). fee_bearer lets the client declare who is willing to bear fees using pre-flight fee-mode semantics (OUR, SHA, BEN). amount.precision is optional metadata; amount.amount is always interpreted as minor units. quote is optional: omit it (or use mode=none) for normal discovery, use mode=intent to ask whether finalize will require a locked quote, and use mode=lock on final review to create or reuse a short-lived locked quote when the transfer is fully determined and allowed.

For execution, the client sends POST /v1/transfers/finalize with CreatePaymentRequest; the server maps that body to this shape, including fee-bearer normalization from DEBT/CRED/SHAR to OUR/BEN/SHA (see products.mdx Client journey mapping table).

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/v1/products/pre-flight" \  -H "Content-Type: application/json" \  -d '{    "customer_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",    "source_account_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"  }'

{
  "context": {
    "customer_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "source_account_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
  },
  "products": [
    {
      "id": "288629b6-c41f-5206-bfd4-becb828ae1ac",
      "code": "OWT",
      "name": "Outbound Wire Transfer",
      "description": "Send funds to external bank accounts via wire transfer.",
      "type": "transfers",
      "route": "payment"
    }
  ],
  "sources": [
    {
      "id": "11111111-1111-4111-8111-111111111111",
      "customer_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
      "legal_name": "My Company",
      "type": "business",
      "name": "My Company",
      "owner_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
      "is_visible_to_others": false,
      "ownership": "own",
      "contacts": [],
      "addresses": [],
      "bank_accounts": [],
      "crypto_wallets": [],
      "own_accounts": [
        {
          "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
          "customer_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
          "cp_account_id": "3fa85f64-5717-4562-b3fc-2c963f66afa7",
          "cp_account_type": "account",
          "currency": "EUR",
          "balance": 125000,
          "iban": "DE89370400440532013000",
          "description": "EUR Current Account",
          "status": "active",
          "account_scope": "internal",
          "products_allowed": [
            {
              "id": "288629b6-c41f-5206-bfd4-becb828ae1ac",
              "code": "OWT",
              "name": "Outbound Wire Transfer",
              "description": "Send funds to external bank accounts via wire transfer.",
              "type": "transfers",
              "route": "payment"
            }
          ]
        }
      ]
    }
  ],
  "destinations": [
    {
      "id": "8ce85f64-5717-4562-b3fc-2c963f66afa6",
      "legal_name": "ACME Corp GmbH",
      "name": "ACME Corp GmbH",
      "owner_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
      "is_visible_to_others": true,
      "ownership": "foreign",
      "contacts": [],
      "addresses": [],
      "own_accounts": [],
      "crypto_wallets": [],
      "bank_accounts": [
        {
          "id": "7de85f64-5717-4562-b3fc-2c963f66afa6",
          "recipient_id": "6de85f64-5717-4562-b3fc-2c963f66afa6",
          "cp_account_id": "7de85f64-5717-4562-b3fc-2c963f66afa7",
          "cp_account_type": "bank_account",
          "iban": "DE75201207000009248525",
          "bic": "DEUTDEDB",
          "bank": "Deutsche Bank",
          "is_primary": true,
          "is_validated": true,
          "currency": "EUR",
          "products_allowed": [
            {
              "id": "288629b6-c41f-5206-bfd4-becb828ae1ac",
              "code": "OWT",
              "name": "Outbound Wire Transfer",
              "description": "Send funds to external bank accounts via wire transfer.",
              "type": "transfers",
              "route": "payment"
            }
          ],
          "finalize_recipient": {
            "type": "recipient",
            "id": "8ce85f64-5717-4562-b3fc-2c963f66afa6",
            "identifier_type": "bank_account",
            "identifier_id": "7de85f64-5717-4562-b3fc-2c963f66afa6"
          }
        }
      ]
    }
  ],
  "routes": [
    {
      "source_account_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "destination_account_id": "7de85f64-5717-4562-b3fc-2c963f66afa7",
      "channels": [
        {
          "name": "wire",
          "estimated_delivery": "P1D"
        }
      ]
    }
  ],
  "foreign_counterparties_allowed": true,
  "transfer_params": null
}

{
  "code": "validation_error",
  "message": "At least one of product_ids, source_account_id, destination_account_id, or destination_counterparty_id is required.",
  "details": {}
}
{
  "code": "validation_error",
  "message": "At least one of product_ids, source_account_id, destination_account_id, or destination_counterparty_id is required.",
  "details": {}
}
{
  "code": "validation_error",
  "message": "At least one of product_ids, source_account_id, destination_account_id, or destination_counterparty_id is required.",
  "details": {}
}
{
  "code": "validation_error",
  "message": "At least one of product_ids, source_account_id, destination_account_id, or destination_counterparty_id is required.",
  "details": {}
}
{
  "code": "validation_error",
  "message": "At least one of product_ids, source_account_id, destination_account_id, or destination_counterparty_id is required.",
  "details": {}
}