OperationsSend a transfer

Send a transfer

The full outgoing transfer flow (demo invariant: a successful broadcast = confirmed):

  1. Resolve fromAddress and the token (network match), convert amount by decimals
  2. Balance check (raw units)
  3. evaluatePolicy (action=transfer): 403 on deny/block
  4. Record + reserve ledger entry (available → reserved, an atomic batch with a sufficiency guard): funds are locked FOR BOTH branches
  5. allow → executed immediately: GasStation → 2s → broadcast → confirm | release+failed → 201 response
  6. requireApproval → status=awaiting_approval, 202 response; then votes via POST /transfers/{id}/approvals, and the final approve executes the transfer

Idempotency: pass an idempotencyKey (unique for each transfer attempt): the record reserves the key and funds BEFORE broadcast; a repeated request with the same key returns 200 with the existing transaction instead of a second transfer. The reserve is atomic (concurrent requests can't drive the balance negative); after failed/rejected, retry with a new key.

curl -X POST "https://policy-engine-rest.ezig.workers.dev/api/v1/vaults/demo_vault/transfers" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -d '{
  "fromAddressId": "123 Main St",
  "toAddress": "123 Main St",
  "amount": "1.5",
  "asset": "usdt",
  "idempotencyKey": "3f2c1e58-7b0a-4d2c-9a41-8a1f0e6b2d90"
}'
{
  "transaction": {
    "id": "cmr3f41z20001psp7phmyapw3",
    "fromAddress": "123 Main St",
    "toAddress": "123 Main St",
    "amount": "example_string",
    "amountDecimal": "example_string",
    "asset": "example_string",
    "network": "example_string",
    "status": "confirmed",
    "txHash": "example_string",
    "fee": "example_string",
    "counterpartyId": "example_string",
    "approvalThreshold": 42,
    "createdAt": "2026-07-02T11:25:15.134000Z"
  }
}
POST
/api/v1/vaults/{code}/transfers
POST
Base URLstring

Target server for requests. Edit to use your own host.

Bearer Token
Bearer Tokenstring
Required

Session token. Mobile/services. The web uses a cookie.

Session token. Mobile/services. The web uses a cookie.
API Key (cookie: session_token)
session_tokenstring
Required

API key (sent in cookie)

path
codestring
Required

Unique Vault code (slug)

Content-Typestring
Required

The media type of the request body

Options: application/json
amountstring
Required

DECIMAL string, converted by token.decimals

idempotencyKeystring

A unique key for the transfer attempt (recommended: uuid). A repeated request with the same key returns the existing transaction without a second broadcast. For a new attempt after failed, use a new key.

Min length: 8 • Max length: 128
Request Preview
Response

Response will appear here after sending the request

Authentication

header
Authorizationstring
Required

Bearer token. Session token. Mobile/services. The web uses a cookie.

path
parameterstring
Required

API Key for authentication. Provide your API key in the cookie.

Path Parameters

codestring
Required

Unique Vault code (slug)

Example:
demo_vault

Body

application/json
amountstring
Required

DECIMAL string, converted by token.decimals

Example:
1.5
idempotencyKeystring

A unique key for the transfer attempt (recommended: uuid). A repeated request with the same key returns the existing transaction without a second broadcast. For a new attempt after failed, use a new key.

Example:
3f2c1e58-7b0a-4d2c-9a41-8a1f0e6b2d90

Responses

transactionobject
Required