POST
/strings/{stringCode}/transferPost an atomic same-currency transfer between two member ledgers of a string
Moves an equal amount of a customer account from the source member ledger to the target member ledger (same currency, no rate). BOTH legs post atomically in one database transaction. Requires an api key whose ledger is a member of the string and which carries the strings:participate:{stringCode} capability. Supply a first-class idempotency key via the Idempotency-Key header (or an idempotency_key body field); replaying it returns the original result without double-posting.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
stringCoderequired | path | string | String code (unique within the tenant). |
Idempotency-Key | header | string max length: 255 | First-class idempotency key (canonical). Falls back to the body idempotency_key when absent. |
Request bodyrequired
| Field | Type | Description |
|---|---|---|
source_ledger_coderequired | string | Code of the member ledger value leaves. |
target_ledger_coderequired | string | Code of the member ledger value arrives in (must differ from the source). |
account_coderequired | string max length: 36 | The logical customer account, present across the string. |
amountrequired | string | Amount to move, in the shared currency (major units). |
referencerequired | string max length: 100 | The per-ledger transaction reference stamped on both legs. |
effective_date | string date · nullable | Posting effective date (Y-m-d). Defaults to today when omitted. |
description | string max length: 255 · nullable | Optional human description recorded on both legs. |
attributes | object nullable | Optional searchable business dimensions — a flat map of key => value string pairs (e.g. {"customer_id": "C-123", "loan_id": "L-42"}) stamped on BOTH legs (each leg is independently searchable). Keys must be lowercase snake_case (max 64 chars) and not shadow a reserved field; values are strings (max 128 chars). Subject to per-transaction (default 20) and per-tenant distinct-key caps, and, when the tenant runs strict mode, must be declared in the attribute catalog first — a violation returns 422 with an ATTRIBUTE_* code synchronously at the gate. Written atomically with both legs and immutable thereafter. |
idempotency_key | string max length: 255 · nullable | Body fallback for the idempotency key when the Idempotency-Key header is not sent. |
Responses
200Idempotent replay: the original result is returned
{
"success": true,
"data": {
"operation": "transfer",
"string_code": "treasury-fx",
"correlation_id": "01997c1e-4d2a-7c3e-9a1b-2f0e8c6d4b5a",
"replayed": false,
"source": {
"ledger_code": "usd-main",
"ledger_id": "01997c1e-4d2a-7c3e-9a1b-2f0e8c6d4b5a",
"transaction_id": "01997c1e-4d2a-7c3e-9a1b-2f0e8c6d4b5a",
"reference": "FX-2026-0001",
"amount": "100.00"
},
"target": {
"ledger_code": "eur-main",
"ledger_id": "01997c1e-4d2a-7c3e-9a1b-2f0e8c6d4b5a",
"transaction_id": "01997c1e-4d2a-7c3e-9a1b-2f0e8c6d4b5a",
"reference": "FX-2026-0001",
"amount": "92.00"
},
"rate": "0.92"
}
} 201Transfer posted (both legs committed)
{
"success": true,
"data": {
"operation": "transfer",
"string_code": "treasury-fx",
"correlation_id": "01997c1e-4d2a-7c3e-9a1b-2f0e8c6d4b5a",
"replayed": false,
"source": {
"ledger_code": "usd-main",
"ledger_id": "01997c1e-4d2a-7c3e-9a1b-2f0e8c6d4b5a",
"transaction_id": "01997c1e-4d2a-7c3e-9a1b-2f0e8c6d4b5a",
"reference": "FX-2026-0001",
"amount": "100.00"
},
"target": {
"ledger_code": "eur-main",
"ledger_id": "01997c1e-4d2a-7c3e-9a1b-2f0e8c6d4b5a",
"transaction_id": "01997c1e-4d2a-7c3e-9a1b-2f0e8c6d4b5a",
"reference": "FX-2026-0001",
"amount": "92.00"
},
"rate": "0.92"
}
} 401Unauthenticated
{
"success": false,
"message": "Validation failed",
"code": "VALIDATION_ERROR"
} 403Forbidden (STRING_KEY_NOT_IN_STRING / STRING_KEY_MISSING_CAPABILITY / STRING_FOREIGN_LEDGER / STRING_OP_NOT_ALLOWED)
{
"success": false,
"message": "Validation failed",
"code": "VALIDATION_ERROR"
} 409Conflict (STRING_PERIOD_LOCKED / STRING_INACTIVE / STRING_NOT_FOUND)
{
"success": false,
"message": "Validation failed",
"code": "VALIDATION_ERROR"
} 422Validation error (STRING_CURRENCY_MISMATCH / STRING_OPERATION_INVALID)
{
"success": false,
"message": "Validation failed",
"code": "VALIDATION_ERROR"
} Examples
curl -X POST https://ledga.io/api/v1/strings/{stringCode}/transfer \
-H "Authorization: Bearer sk_xxxxxxxx_your_secret" \
-H "Content-Type: application/json" \
-d '{
"source_ledger_code": "usd-main",
"target_ledger_code": "usd-ops",
"account_code": "1000",
"amount": "100.00",
"reference": "XFER-2026-0001",
"effective_date": "2026-06-30",
"description": "Treasury sweep",
"attributes": {
"customer_id": "C-123",
"loan_id": "L-42"
},
"idempotency_key": "transfer-2026-0001"
}'