CorebanqCorebanq Developer Docs
Transfersv1Events

Execute Transfer Event

Executes one DSL event on a transfer. ANSWERS 200, NOT 201, and the body is {transfer, result, question?} — the transfer in the minor-units shape, the raw DSL result, and a question member only for a QUESTION outcome. THE REQUEST BODY IS A FREE-FORM JSON OBJECT. The handler decodes it into map[string]any and passes it through; a structured body with dry_run, force, reason or a nested payload wrapper is read by nothing. Payment rail facts supplied by the caller are ignored as well: they come from the rail. 400 covers an unparseable transfer_id, a missing event_type, an undecodable body, a terminal transfer (transfers_m.cannot_execute_event_terminal_transfer), a repeat of an event the product does not allow to repeat (transfers_m.cannot_execute_same_event_consecutive) and a row that is not a payment — a beneficiary's row, the receiving company's record of an on-us credit linked to the payment through parent_id, is refused with transfers_m.cannot_execute_event_on_beneficiary_row, whose details name the payment the event belongs to under the transfer_id field. THE LIST OF STATUSES BELOW IS NOT CLOSED. runTransferEvent propagates a DSL action's own *errs.AppError unchanged, so an error raised inside a call{} interface or a gl-batch surfaces with whatever status it carried. The three that a gl-batch reaches through the ledgers module are declared below: 402 ledgers.insufficient_funds against an underfunded ledger, 409 ledgers.ledger_inactive / ledgers.ledger_closed from EnsureLedgerPostable on the journal path, and 422 from the transit-ledger currency guards and from the tariff service a tariff{} step calls. A product that calls another interface can surface a status none of them lists. Only a non-AppError failure is flattened to 500 (dsl_m.execution_failed — the DSL catalogue, not the transfers one). An unknown transfer_id never answers 404. The RBAC check runs first, so it is normally a 403; a caller who passes that check reaches loadTransferForEvent, which wraps the storage miss in errs.MsgDatabaseError with no code and so answers 500.

POST
/v1/transfers/{transfer_id}/events/{event_type}/execute

Authorization

BearerAuth
AuthorizationBearer <token>

JWT authentication token

In: header

Path Parameters

transfer_id*string

Transfer UUID

event_type*string

DSL event key, as it appears in the product's DSL.

transfer_id*string

transfer_id path parameter

event_type*string

event_type path parameter

Header Parameters

Accept-Language?string

Language preference for the response

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Free-form. Optional.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/v1/transfers/string/events/string/execute" \  -H "Content-Type: application/json" \  -d '{}'
{
  "transfer": {
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "product_id": "0d012afa-f885-4e65-aeca-37e27701e2d1",
    "product_code": "string",
    "ori_customer_id": "bc70e6eb-7d69-4074-a870-6cf369440f5d",
    "ben_customer_id": "f5b93205-a0f3-4d6a-a411-580dff187bdf",
    "ori_account_id": "93f2cf79-32f9-44a2-ad78-373f29b5514e",
    "ben_account_id": "4d1f2312-f55e-46c1-af1c-97fa399de1d5",
    "type": "string",
    "status": "string",
    "active": true,
    "txn_amt": {
      "amount": "string",
      "currency": "string",
      "precision": 0
    },
    "txn_paymentPurpose": "string",
    "ori_name": "string",
    "ori_iban": "string",
    "ori_bic": "string",
    "ben_name": "string",
    "ben_iban": "string",
    "ben_bic": "string",
    "ben_amt": {
      "amount": "string",
      "currency": "string",
      "precision": 0
    },
    "ori_walletAddress": "string",
    "ben_walletAddress": "string",
    "ben_addressTag": "string",
    "bc_network": "string",
    "bc_txHash": "string",
    "token": "string",
    "txn_netAmt": {
      "amount": "string",
      "currency": "string",
      "precision": 0
    },
    "txn_feeAmt": {
      "amount": "string",
      "currency": "string",
      "precision": 0
    },
    "txn_instructionId": "string",
    "txn_externalId": "string",
    "direction": "string",
    "parent_id": "1c6ca187-e61f-4301-8dcb-0e9749e89eef",
    "metadata": {},
    "context": {},
    "error_code": "string",
    "error_message": "string",
    "created_at": "string",
    "updated_at": "string"
  },
  "result": {},
  "question": {}
}
{
  "status": 0,
  "message": "string",
  "code": "transfers_m.account_not_found",
  "class": "validation",
  "retryable": false,
  "details": [
    {
      "field": "amount",
      "rule": "gt",
      "param": "0",
      "message": "amount must be greater than 0"
    }
  ]
}
{
  "status": 0,
  "message": "string",
  "code": "transfers_m.account_not_found",
  "class": "validation",
  "retryable": false,
  "details": [
    {
      "field": "amount",
      "rule": "gt",
      "param": "0",
      "message": "amount must be greater than 0"
    }
  ]
}
{
  "status": 0,
  "message": "string",
  "code": "transfers_m.account_not_found",
  "class": "validation",
  "retryable": false,
  "details": [
    {
      "field": "amount",
      "rule": "gt",
      "param": "0",
      "message": "amount must be greater than 0"
    }
  ]
}
{
  "status": 0,
  "message": "string",
  "code": "transfers_m.account_not_found",
  "class": "validation",
  "retryable": false,
  "details": [
    {
      "field": "amount",
      "rule": "gt",
      "param": "0",
      "message": "amount must be greater than 0"
    }
  ]
}
{
  "status": 0,
  "message": "string",
  "code": "transfers_m.account_not_found",
  "class": "validation",
  "retryable": false,
  "details": [
    {
      "field": "amount",
      "rule": "gt",
      "param": "0",
      "message": "amount must be greater than 0"
    }
  ]
}
{
  "status": 422,
  "message": "This payee's account cannot accept payments at the moment. Choose another payee, or ask the payee for up-to-date details.",
  "code": "transfers_m.beneficiary_account_not_active",
  "class": "validation"
}
{
  "status": 429,
  "message": "Rate limit exceeded",
  "code": "rate_limits_m.exceeded",
  "class": "temporary",
  "retryable": true
}
{
  "status": 0,
  "message": "string",
  "code": "transfers_m.account_not_found",
  "class": "validation",
  "retryable": false,
  "details": [
    {
      "field": "amount",
      "rule": "gt",
      "param": "0",
      "message": "amount must be greater than 0"
    }
  ]
}

{
  "overall_status": "unhealthy",
  "message": "Service is shutting down",
  "timestamp": "2026-08-27T15:04:05Z"
}