Formance Ledger API

The programmable, open-source double-entry Ledger (v2). Create ledgers, post immutable transactions with multi-posting sources and destinations, read accounts, balances, aggregated balances and volumes, attach metadata, revert transactions, and model complex money flows with the Numscript DSL. Supports bulk requests and a full transaction/account log.

OpenAPI Specification

formance-openapi.yml Raw ↑
openapi: 3.0.3
info:
  title: Formance Platform API
  description: >-
    Open-source financial infrastructure for money movement. This specification
    describes the REST surface of the Formance Platform across its modules -
    Ledger (v2), Payments, Orchestration / Flows (v2), Wallets, Reconciliation,
    Auth, Webhooks, and Search - as exposed by Formance Cloud. All resource
    modules are served under a per-module path prefix (for example
    `/api/ledger`, `/api/payments`) on a single stack host and are secured with
    OAuth2 client-credentials Bearer tokens issued by the Auth module.
  termsOfService: https://www.formance.com/terms
  contact:
    name: Formance
    url: https://www.formance.com
  license:
    name: MIT
    url: https://github.com/formancehq/ledger/blob/main/LICENSE
  version: 'v1'
servers:
  - url: https://{organization}.{environment}.formance.cloud
    description: Formance Cloud stack host
    variables:
      organization:
        default: sandbox
        description: Your organization / stack slug.
      environment:
        default: eu.sandbox
        description: The Formance Cloud environment / region for the stack.
security:
  - oauth2: []
tags:
  - name: Auth
    description: OAuth2 / OIDC authorization server, clients, and users.
  - name: Ledger
    description: Programmable double-entry ledger (v2).
  - name: Payments
    description: Unified payments connectivity, connectors, and transfers.
  - name: Orchestration
    description: Flows workflows, instances, and triggers (v2).
  - name: Wallets
    description: White-label wallets, balances, and holds.
  - name: Reconciliation
    description: Reconciliation policies and runs.
  - name: Webhooks
    description: Webhook subscription configuration.
  - name: Search
    description: Cross-module search.
paths:
  # ------------------------------------------------------------------ Auth
  /api/auth/oauth/token:
    post:
      operationId: createToken
      tags: [Auth]
      summary: Request an OAuth2 access token
      description: >-
        Exchange a client id and secret for a Bearer access token using the
        `client_credentials` grant. The returned token is used in the
        `Authorization` header for every other Formance API call.
      security: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required: [grant_type, client_id, client_secret]
              properties:
                grant_type:
                  type: string
                  example: client_credentials
                client_id:
                  type: string
                client_secret:
                  type: string
                scope:
                  type: string
      responses:
        '200':
          description: Access token issued.
          content:
            application/json:
              schema:
                type: object
                properties:
                  access_token:
                    type: string
                  token_type:
                    type: string
                    example: bearer
                  expires_in:
                    type: integer
                    example: 3600
                  scope:
                    type: string
  /api/auth/.well-known/openid-configuration:
    get:
      operationId: getOIDCWellKnowns
      tags: [Auth]
      summary: Retrieve OpenID Connect configuration
      responses:
        '200':
          description: OIDC configuration document.
  /api/auth/clients:
    get:
      operationId: listClients
      tags: [Auth]
      summary: List OAuth clients
      responses:
        '200': { description: List of clients. }
    post:
      operationId: createClient
      tags: [Auth]
      summary: Create an OAuth client
      requestBody:
        content:
          application/json:
            schema: { $ref: '#/components/schemas/ClientOptions' }
      responses:
        '201': { description: Client created. }
  /api/auth/clients/{clientId}:
    parameters:
      - { name: clientId, in: path, required: true, schema: { type: string } }
    get:
      operationId: readClient
      tags: [Auth]
      summary: Read an OAuth client
      responses:
        '200': { description: Client. }
    put:
      operationId: updateClient
      tags: [Auth]
      summary: Update an OAuth client
      responses:
        '200': { description: Client updated. }
    delete:
      operationId: deleteClient
      tags: [Auth]
      summary: Delete an OAuth client
      responses:
        '204': { description: Client deleted. }
  /api/auth/clients/{clientId}/secrets:
    parameters:
      - { name: clientId, in: path, required: true, schema: { type: string } }
    post:
      operationId: createSecret
      tags: [Auth]
      summary: Add a secret to a client
      responses:
        '200': { description: Secret created. }
  /api/auth/clients/{clientId}/secrets/{secretId}:
    parameters:
      - { name: clientId, in: path, required: true, schema: { type: string } }
      - { name: secretId, in: path, required: true, schema: { type: string } }
    delete:
      operationId: deleteSecret
      tags: [Auth]
      summary: Delete a client secret
      responses:
        '204': { description: Secret deleted. }
  /api/auth/users:
    get:
      operationId: listUsers
      tags: [Auth]
      summary: List users
      responses:
        '200': { description: List of users. }
  /api/auth/users/{userId}:
    parameters:
      - { name: userId, in: path, required: true, schema: { type: string } }
    get:
      operationId: readUser
      tags: [Auth]
      summary: Read a user
      responses:
        '200': { description: User. }

  # ------------------------------------------------------------------ Ledger v2
  /api/ledger/v2:
    get:
      operationId: v2ListLedgers
      tags: [Ledger]
      summary: List ledgers
      responses:
        '200': { description: List of ledgers. }
  /api/ledger/v2/{ledger}:
    parameters:
      - { name: ledger, in: path, required: true, schema: { type: string } }
    get:
      operationId: v2GetLedger
      tags: [Ledger]
      summary: Get a ledger
      responses:
        '200': { description: Ledger. }
    post:
      operationId: v2CreateLedger
      tags: [Ledger]
      summary: Create a ledger
      responses:
        '204': { description: Ledger created. }
  /api/ledger/v2/{ledger}/_info:
    parameters:
      - { name: ledger, in: path, required: true, schema: { type: string } }
    get:
      operationId: v2GetLedgerInfo
      tags: [Ledger]
      summary: Get information about a ledger
      responses:
        '200': { description: Ledger info. }
  /api/ledger/v2/{ledger}/_bulk:
    parameters:
      - { name: ledger, in: path, required: true, schema: { type: string } }
    post:
      operationId: v2CreateBulk
      tags: [Ledger]
      summary: Bulk request
      responses:
        '200': { description: Bulk result. }
  /api/ledger/v2/{ledger}/accounts:
    parameters:
      - { name: ledger, in: path, required: true, schema: { type: string } }
    get:
      operationId: v2ListAccounts
      tags: [Ledger]
      summary: List accounts from a ledger
      responses:
        '200': { description: Cursor of accounts. }
    head:
      operationId: v2CountAccounts
      tags: [Ledger]
      summary: Count the accounts from a ledger
      responses:
        '204': { description: Count returned in Count header. }
  /api/ledger/v2/{ledger}/accounts/{address}:
    parameters:
      - { name: ledger, in: path, required: true, schema: { type: string } }
      - { name: address, in: path, required: true, schema: { type: string } }
    get:
      operationId: v2GetAccount
      tags: [Ledger]
      summary: Get account by its address
      responses:
        '200': { description: Account. }
  /api/ledger/v2/{ledger}/accounts/{address}/metadata:
    parameters:
      - { name: ledger, in: path, required: true, schema: { type: string } }
      - { name: address, in: path, required: true, schema: { type: string } }
    post:
      operationId: v2AddMetadataToAccount
      tags: [Ledger]
      summary: Add metadata to an account
      responses:
        '204': { description: Metadata added. }
  /api/ledger/v2/{ledger}/transactions:
    parameters:
      - { name: ledger, in: path, required: true, schema: { type: string } }
    get:
      operationId: v2ListTransactions
      tags: [Ledger]
      summary: List transactions from a ledger
      responses:
        '200': { description: Cursor of transactions. }
    post:
      operationId: v2CreateTransaction
      tags: [Ledger]
      summary: Create a new transaction
      description: >-
        Post a double-entry transaction to the ledger. Provide either explicit
        `postings` (source, destination, amount, asset) or a `script`
        expressed in Numscript to compute complex multi-party money flows.
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/V2PostTransaction' }
      responses:
        '200': { description: Transaction created. }
    head:
      operationId: v2CountTransactions
      tags: [Ledger]
      summary: Count the transactions from a ledger
      responses:
        '204': { description: Count returned in Count header. }
  /api/ledger/v2/{ledger}/transactions/{id}:
    parameters:
      - { name: ledger, in: path, required: true, schema: { type: string } }
      - { name: id, in: path, required: true, schema: { type: integer, format: bigint } }
    get:
      operationId: v2GetTransaction
      tags: [Ledger]
      summary: Get transaction by its ID
      responses:
        '200': { description: Transaction. }
  /api/ledger/v2/{ledger}/transactions/{id}/metadata:
    parameters:
      - { name: ledger, in: path, required: true, schema: { type: string } }
      - { name: id, in: path, required: true, schema: { type: integer, format: bigint } }
    post:
      operationId: v2AddMetadataOnTransaction
      tags: [Ledger]
      summary: Set the metadata of a transaction by its ID
      responses:
        '204': { description: Metadata set. }
  /api/ledger/v2/{ledger}/transactions/{id}/revert:
    parameters:
      - { name: ledger, in: path, required: true, schema: { type: string } }
      - { name: id, in: path, required: true, schema: { type: integer, format: bigint } }
    post:
      operationId: v2RevertTransaction
      tags: [Ledger]
      summary: Revert a ledger transaction by its ID
      responses:
        '201': { description: Reverting transaction created. }
  /api/ledger/v2/{ledger}/aggregate/balances:
    parameters:
      - { name: ledger, in: path, required: true, schema: { type: string } }
    get:
      operationId: v2GetBalancesAggregated
      tags: [Ledger]
      summary: Get the aggregated balances from selected accounts
      responses:
        '200': { description: Aggregated balances. }
  /api/ledger/v2/{ledger}/volumes:
    parameters:
      - { name: ledger, in: path, required: true, schema: { type: string } }
    get:
      operationId: v2GetVolumesWithBalances
      tags: [Ledger]
      summary: Get list of volumes with balances for (account/asset)
      responses:
        '200': { description: Cursor of volumes with balances. }
  /api/ledger/v2/{ledger}/logs:
    parameters:
      - { name: ledger, in: path, required: true, schema: { type: string } }
    get:
      operationId: v2ListLogs
      tags: [Ledger]
      summary: List the logs from a ledger
      responses:
        '200': { description: Cursor of logs. }

  # ------------------------------------------------------------------ Payments
  /api/payments/v1/connectors:
    get:
      operationId: listAllConnectors
      tags: [Payments]
      summary: List all installed connectors
      responses:
        '200': { description: List of connectors. }
  /api/payments/v1/connectors/configs:
    get:
      operationId: listConfigsAvailableConnectors
      tags: [Payments]
      summary: List the configs of each available connector
      responses:
        '200': { description: Available connector configs. }
  /api/payments/v1/connectors/{connector}:
    parameters:
      - { name: connector, in: path, required: true, schema: { type: string } }
    post:
      operationId: installConnector
      tags: [Payments]
      summary: Install a connector
      responses:
        '201': { description: Connector installed. }
  /api/payments/v1/connectors/{connector}/{connectorId}:
    parameters:
      - { name: connector, in: path, required: true, schema: { type: string } }
      - { name: connectorId, in: path, required: true, schema: { type: string } }
    delete:
      operationId: uninstallConnectorV1
      tags: [Payments]
      summary: Uninstall a connector
      responses:
        '204': { description: Connector uninstalled. }
  /api/payments/v1/connectors/transfers:
    post:
      operationId: connectorsTransfer
      tags: [Payments]
      summary: Transfer funds between accounts on a connector
      responses:
        '200': { description: Transfer created. }
  /api/payments/v1/accounts:
    get:
      operationId: listAccountsPayments
      tags: [Payments]
      summary: List accounts
      responses:
        '200': { description: Cursor of accounts. }
    post:
      operationId: createAccount
      tags: [Payments]
      summary: Create an account
      responses:
        '200': { description: Account created. }
  /api/payments/v1/accounts/{accountId}/balances:
    parameters:
      - { name: accountId, in: path, required: true, schema: { type: string } }
    get:
      operationId: getAccountBalances
      tags: [Payments]
      summary: Get account balances
      responses:
        '200': { description: Balances. }
  /api/payments/v1/payments:
    get:
      operationId: listPayments
      tags: [Payments]
      summary: List payments
      responses:
        '200': { description: Cursor of payments. }
    post:
      operationId: createPayment
      tags: [Payments]
      summary: Create a payment
      responses:
        '200': { description: Payment created. }
  /api/payments/v1/payments/{paymentId}:
    parameters:
      - { name: paymentId, in: path, required: true, schema: { type: string } }
    get:
      operationId: getPayment
      tags: [Payments]
      summary: Get a payment
      responses:
        '200': { description: Payment. }
  /api/payments/v1/bank-accounts:
    get:
      operationId: listBankAccounts
      tags: [Payments]
      summary: List bank accounts
      responses:
        '200': { description: Cursor of bank accounts. }
    post:
      operationId: createBankAccount
      tags: [Payments]
      summary: Create a bank account
      responses:
        '200': { description: Bank account created. }
  /api/payments/v1/bank-accounts/{bankAccountId}:
    parameters:
      - { name: bankAccountId, in: path, required: true, schema: { type: string } }
    get:
      operationId: getBankAccount
      tags: [Payments]
      summary: Get a bank account
      responses:
        '200': { description: Bank account. }
  /api/payments/v1/transfer-initiations:
    get:
      operationId: listTransferInitiations
      tags: [Payments]
      summary: List transfer initiations
      responses:
        '200': { description: Cursor of transfer initiations. }
    post:
      operationId: createTransferInitiation
      tags: [Payments]
      summary: Create a transfer initiation
      responses:
        '200': { description: Transfer initiation created. }
  /api/payments/v1/transfer-initiations/{transferId}:
    parameters:
      - { name: transferId, in: path, required: true, schema: { type: string } }
    get:
      operationId: getTransferInitiation
      tags: [Payments]
      summary: Get a transfer initiation
      responses:
        '200': { description: Transfer initiation. }
    delete:
      operationId: deleteTransferInitiation
      tags: [Payments]
      summary: Delete a transfer initiation
      responses:
        '204': { description: Deleted. }
  /api/payments/v1/transfer-initiations/{transferId}/status:
    parameters:
      - { name: transferId, in: path, required: true, schema: { type: string } }
    post:
      operationId: updateTransferInitiationStatus
      tags: [Payments]
      summary: Update the status of a transfer initiation
      responses:
        '204': { description: Status updated. }
  /api/payments/v1/pools:
    get:
      operationId: listPools
      tags: [Payments]
      summary: List pools
      responses:
        '200': { description: Cursor of pools. }
    post:
      operationId: createPool
      tags: [Payments]
      summary: Create a pool
      responses:
        '200': { description: Pool created. }
  /api/payments/v1/pools/{poolId}:
    parameters:
      - { name: poolId, in: path, required: true, schema: { type: string } }
    get:
      operationId: getPool
      tags: [Payments]
      summary: Get a pool
      responses:
        '200': { description: Pool. }
    delete:
      operationId: deletePool
      tags: [Payments]
      summary: Delete a pool
      responses:
        '204': { description: Deleted. }
  /api/payments/v1/pools/{poolId}/balances:
    parameters:
      - { name: poolId, in: path, required: true, schema: { type: string } }
    get:
      operationId: getPoolBalances
      tags: [Payments]
      summary: Get pool balances
      responses:
        '200': { description: Pool balances. }

  # ------------------------------------------------------------------ Orchestration v2
  /api/orchestration/v2/workflows:
    get:
      operationId: listWorkflows
      tags: [Orchestration]
      summary: List registered workflows
      responses:
        '200': { description: List of workflows. }
    post:
      operationId: createWorkflow
      tags: [Orchestration]
      summary: Create a workflow
      responses:
        '201': { description: Workflow created. }
  /api/orchestration/v2/workflows/{flowId}:
    parameters:
      - { name: flowId, in: path, required: true, schema: { type: string } }
    get:
      operationId: getWorkflow
      tags: [Orchestration]
      summary: Get a workflow by id
      responses:
        '200': { description: Workflow. }
    delete:
      operationId: deleteWorkflow
      tags: [Orchestration]
      summary: Delete a workflow by id
      responses:
        '204': { description: Deleted. }
  /api/orchestration/v2/workflows/{flowId}/instances:
    parameters:
      - { name: flowId, in: path, required: true, schema: { type: string } }
    post:
      operationId: runWorkflow
      tags: [Orchestration]
      summary: Run a workflow
      responses:
        '201': { description: Workflow instance started. }
  /api/orchestration/v2/instances:
    get:
      operationId: listInstances
      tags: [Orchestration]
      summary: List workflow instances
      responses:
        '200': { description: List of instances. }
  /api/orchestration/v2/instances/{instanceId}:
    parameters:
      - { name: instanceId, in: path, required: true, schema: { type: string } }
    get:
      operationId: getInstance
      tags: [Orchestration]
      summary: Get a workflow instance by id
      responses:
        '200': { description: Instance. }
  /api/orchestration/v2/instances/{instanceId}/history:
    parameters:
      - { name: instanceId, in: path, required: true, schema: { type: string } }
    get:
      operationId: getInstanceHistory
      tags: [Orchestration]
      summary: Get a workflow instance history by id
      responses:
        '200': { description: Instance history. }
  /api/orchestration/v2/triggers:
    get:
      operationId: listTriggers
      tags: [Orchestration]
      summary: List triggers
      responses:
        '200': { description: List of triggers. }
    post:
      operationId: createTrigger
      tags: [Orchestration]
      summary: Create a trigger
      responses:
        '201': { description: Trigger created. }
  /api/orchestration/v2/triggers/{triggerId}:
    parameters:
      - { name: triggerId, in: path, required: true, schema: { type: string } }
    get:
      operationId: readTrigger
      tags: [Orchestration]
      summary: Read a trigger
      responses:
        '200': { description: Trigger. }
    delete:
      operationId: deleteTrigger
      tags: [Orchestration]
      summary: Delete a trigger
      responses:
        '204': { description: Deleted. }
  /api/orchestration/v2/events:
    post:
      operationId: sendEvent
      tags: [Orchestration]
      summary: Send an event to a running workflow instance
      responses:
        '204': { description: Event sent. }

  # ------------------------------------------------------------------ Wallets
  /api/wallets/v1/wallets:
    get:
      operationId: listWallets
      tags: [Wallets]
      summary: List all wallets
      responses:
        '200': { description: Cursor of wallets. }
    post:
      operationId: createWallet
      tags: [Wallets]
      summary: Create a new wallet
      responses:
        '201': { description: Wallet created. }
  /api/wallets/v1/wallets/{id}:
    parameters:
      - { name: id, in: path, required: true, schema: { type: string } }
    get:
      operationId: getWallet
      tags: [Wallets]
      summary: Get a wallet
      responses:
        '200': { description: Wallet. }
    patch:
      operationId: updateWallet
      tags: [Wallets]
      summary: Update a wallet
      responses:
        '204': { description: Wallet updated. }
  /api/wallets/v1/wallets/{id}/summary:
    parameters:
      - { name: id, in: path, required: true, schema: { type: string } }
    get:
      operationId: getWalletSummary
      tags: [Wallets]
      summary: Get a wallet summary
      responses:
        '200': { description: Wallet summary. }
  /api/wallets/v1/wallets/{id}/balances:
    parameters:
      - { name: id, in: path, required: true, schema: { type: string } }
    get:
      operationId: listBalances
      tags: [Wallets]
      summary: List balances of a wallet
      responses:
        '200': { description: Balances. }
    post:
      operationId: createBalance
      tags: [Wallets]
      summary: Create a balance
      responses:
        '201': { description: Balance created. }
  /api/wallets/v1/wallets/{id}/credit:
    parameters:
      - { name: id, in: path, required: true, schema: { type: string } }
    post:
      operationId: creditWallet
      tags: [Wallets]
      summary: Credit a wallet
      responses:
        '204': { description: Wallet credited. }
  /api/wallets/v1/wallets/{id}/debit:
    parameters:
      - { name: id, in: path, required: true, schema: { type: string } }
    post:
      operationId: debitWallet
      tags: [Wallets]
      summary: Debit a wallet
      description: >-
        Debit a wallet. When `pending` is true a hold is created that must be
        later confirmed or voided (authorization then capture).
      responses:
        '200': { description: Debit / hold created. }
  /api/wallets/v1/holds:
    get:
      operationId: getHolds
      tags: [Wallets]
      summary: Get all holds for a wallet
      responses:
        '200': { description: Cursor of holds. }
  /api/wallets/v1/holds/{holdId}:
    parameters:
      - { name: holdId, in: path, required: true, schema: { type: string } }
    get:
      operationId: getHold
      tags: [Wallets]
      summary: Get a hold
      responses:
        '200': { description: Hold. }
  /api/wallets/v1/holds/{holdId}/confirm:
    parameters:
      - { name: holdId, in: path, required: true, schema: { type: string } }
    post:
      operationId: confirmHold
      tags: [Wallets]
      summary: Confirm a hold
      responses:
        '204': { description: Hold confirmed (captured). }
  /api/wallets/v1/holds/{holdId}/void:
    parameters:
      - { name: holdId, in: path, required: true, schema: { type: string } }
    post:
      operationId: voidHold
      tags: [Wallets]
      summary: Cancel a hold
      responses:
        '204': { description: Hold voided. }

  # ------------------------------------------------------------------ Reconciliation
  /api/reconciliation/v1/policies:
    get:
      operationId: listPolicies
      tags: [Reconciliation]
      summary: List reconciliation policies
      responses:
        '200': { description: Cursor of policies. }
    post:
      operationId: createPolicy
      tags: [Reconciliation]
      summary: Create a reconciliation policy
      responses:
        '201': { description: Policy created. }
  /api/reconciliation/v1/policies/{policyID}:
    parameters:
      - { name: policyID, in: path, required: true, schema: { type: string } }
    get:
      operationId: getPolicy
      tags: [Reconciliation]
      summary: Get a policy
      responses:
        '200': { description: Policy. }
    delete:
      operationId: deletePolicy
      tags: [Reconciliation]
      summary: Delete a policy
      responses:
        '204': { description: Deleted. }
  /api/reconciliation/v1/policies/{policyID}/reconciliation:
    parameters:
      - { name: policyID, in: path, required: true, schema: { type: string } }
    post:
      operationId: reconcile
      tags: [Reconciliation]
      summary: Reconcile using a policy
      responses:
        '200': { description: Reconciliation result. }
  /api/reconciliation/v1/reconciliations:
    get:
      operationId: listReconciliations
      tags: [Reconciliation]
      summary: List reconciliations
      responses:
        '200': { description: Cursor of reconciliations. }
  /api/reconciliation/v1/reconciliations/{reconciliationID}:
    parameters:
      - { name: reconciliationID, in: path, required: true, schema: { type: string } }
    get:
      operationId: getReconciliation
      tags: [Reconciliation]
      summary: Get a reconciliation
      responses:
        '200': { description: Reconciliation. }

  # ------------------------------------------------------------------ Webhooks
  /api/webhooks/configs:
    get:
      operationId: getManyConfigs
      tags: [Webhooks]
      summary: Get many configs
      responses:
        '200': { description: Cursor of configs. }
    post:
      operationId: insertConfig
      tags: [Webhooks]
      summary: Insert a new config
      responses:
        '200': { description: Config created. }
  /api/webhooks/configs/{id}:
    parameters:
      - { name: id, in: path, required: true, schema: { type: string } }
    put:
      operationId: updateConfig
      tags: [Webhooks]
      summary: Update one config
      responses:
        '200': { description: Config updated. }
    delete:
      operationId: deleteConfig
      tags: [Webhooks]
      summary: Delete one config
      responses:
        '200': { description: Config deleted. }
  /api/webhooks/configs/{id}/activate:
    parameters:
      - { name: id, in: path, required: true, schema: { type: string } }
    put:
      operationId: activateConfig
      tags: [Webhooks]
      summary: Activate one config
      responses:
        '200': { description: Config activated. }
  /api/webhooks/configs/{id}/deactivate:
    parameters:
      - { name: id, in: path, required: true, schema: { type: string } }
    put:
      operationId: deactivateConfig
      tags: [Webhooks]
      summary: Deactivate one config
      responses:
        '200': { description: Config deactivated. }
  /api/webhooks/configs/{id}/secret/change:
    parameters:
      - { name: id, in: path, required: true, schema: { type: string } }
    put:
      operationId: changeConfigSecret
      tags: [Webhooks]
      summary: Change the signing secret of a config
      responses:
        '200': { description: Secret changed. }
  /api/webhooks/configs/{id}/test:
    parameters:
      - { name: id, in: path, required: true, schema: { type: string } }
    get:
      operationId: testConfig
      tags: [Webhooks]
      summary: Test one config
      responses:
        '200': { description: Test result. }

  # ------------------------------------------------------------------ Search
  /api/search/:
    post:
      operationId: search
      tags: [Search]
      summary: Search across the platform
      description: >-
        Query indexed resources (ledger transactions and accounts, payments,
        and more) by target and terms across all modules.
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                target:
                  type: string
                  example: TRANSACTION
                terms:
                  type: array
                  items: { type: string }
                pageSize:
                  type: integer
      responses:
        '200': { description: Search response. }
components:
  securitySchemes:
    oauth2:
      type: oauth2
      description: >-
        OAuth2 client-credentials flow. Exchange a client id and secret at
        `/api/auth/oauth/token` for a Bearer access token, then send it as
        `Authorization: Bearer <token>`.
      flows:
        clientCredentials:
          tokenUrl: https://{organization}.{environment}.formance.cloud/api/auth/oauth/token
          scopes:
            ledger:read: Read ledger resources
            ledger:write: Write ledger resources
            payments:read: Read payments resources
            payments:write: Write payments resources
            wallets:read: Read wallets resources
            wallets:write: Write wallets resources
  schemas:
    V2Posting:
      type: object
      required: [amount, asset, destination, source]
      properties:
        amount:
          type: integer
          format: bigint
          example: 100
        asset:
          type: string
          example: USD/2
        destination:
          type: string
          example: users:001
        source:
          type: string
          example: world
    V2PostTransaction:
      type: object
      properties:
        timestamp:
          type: string
          format: date-time
        postings:
          type: array
          items: { $ref: '#/components/schemas/V2Posting' }
        script:
          type: object
          description: A Numscript program and its variables.
          properties:
            plain:
              type: string
              example: |
                send [USD/2 100] (
                  source = @world
                  destination = @users:001
                )
            vars:
              type: object
              additionalProperties: true
        reference:
          type: string
        metadata:
          type: object
          additionalProperties:
            type: string
    ClientOptions:
      type: object
      properties:
        name:
          type: string
        public:
          type: boolean
        redirectUris:
          type: array
          items: { type: string }
        scopes:
          type: array
          items: { type: string }