# `create_transfers` Create one or more [`Transfer`](../transfers.md)s. A successfully created transfer will modify the amount fields of its [debit](../transfers.md#debit_account_id) and [credit](../transfers.md#credit_account_id) accounts. ## Event The transfer to create. See [`Transfer`](../transfers.md) for constraints. ## Result Results are listed in this section in order of descending precedence — that is, if more than one error is applicable to the transfer being created, only the result listed first is returned. ### `ok` The transfer was successfully created; did not previously exist. Note that `ok` is generated by the client implementation; the network protocol does not include a result when the transfer was successfully created. ### `linked_event_failed` The transfer was not created. One or more of the other transfers in the [linked chain](../transfers.md#flagslinked) is invalid, so the whole chain failed. ### `linked_event_chain_open` The transfer was not created. The [`Transfer.flags.linked`](../transfers.md#flagslinked) flag was set on the last event in the batch, which is not legal. (`flags.linked` indicates that the chain continues to the next operation). ### `timestamp_must_be_zero` The transfer was not created. The [`Transfer.timestamp`](../accounts.md#timestamp) is nonzero, but must be zero. The cluster is responsible for setting this field. ### `reserved_flag` The transfer was not created. `Transfer.flags.reserved` is nonzero, but must be zero. ### `id_must_not_be_zero` The transfer was not created. [`Transfer.id`](../transfers.md#id) is zero, which is a reserved value. ### `id_must_not_be_int_max` The transfer was not created. [`Transfer.id`](../transfers.md#id) is `2^128 - 1`, which is a reserved value. ### `flags_are_mutually_exclusive` The transfer was not created. An account cannot be created with the specified combination of [`Transfer.flags`](../transfers.md#flags). Flag compatibility (✓ = compatible, ✗ = mutually exclusive): - [`flags.pending`](../transfers.md#flagspending) - ✗ [`flags.post_pending_transfer`](../transfers.md#flagspost_pending_transfer) - ✗ [`flags.void_pending_transfer`](../transfers.md#flagsvoid_pending_transfer) - ✓ [`flags.balancing_debit`](../transfers.md#flagsbalancing_debit) - ✓ [`flags.balancing_credit`](../transfers.md#flagsbalancing_credit) - [`flags.post_pending_transfer`](../transfers.md#flagspost_pending_transfer) - ✗ [`flags.pending`](../transfers.md#flagspending) - ✗ [`flags.void_pending_transfer`](../transfers.md#flagsvoid_pending_transfer) - ✗ [`flags.balancing_debit`](../transfers.md#flagsbalancing_debit) - ✗ [`flags.balancing_credit`](../transfers.md#flagsbalancing_credit) - [`flags.void_pending_transfer`](../transfers.md#flagsvoid_pending_transfer) - ✗ [`flags.pending`](../transfers.md#flagspending) - ✗ [`flags.post_pending_transfer`](../transfers.md#flagspost_pending_transfer) - ✗ [`flags.balancing_debit`](../transfers.md#flagsbalancing_debit) - ✗ [`flags.balancing_credit`](../transfers.md#flagsbalancing_credit) - [`flags.balancing_debit`](../transfers.md#flagsbalancing_debit) - ✓ [`flags.pending`](../transfers.md#flagspending) - ✗ [`flags.void_pending_transfer`](../transfers.md#flagsvoid_pending_transfer) - ✗ [`flags.post_pending_transfer`](../transfers.md#flagspost_pending_transfer) - ✓ [`flags.balancing_credit`](../transfers.md#flagsbalancing_credit) - [`flags.balancing_credit`](../transfers.md#flagsbalancing_credit) - ✓ [`flags.pending`](../transfers.md#flagspending) - ✗ [`flags.void_pending_transfer`](../transfers.md#flagsvoid_pending_transfer) - ✗ [`flags.post_pending_transfer`](../transfers.md#flagspost_pending_transfer) - ✓ [`flags.balancing_debit`](../transfers.md#flagsbalancing_debit) ### `debit_account_id_must_not_be_zero` The transfer was not created. [`Transfer.debit_account_id`](../transfers.md#debit_account_id) is zero, but must be a valid account id. ### `debit_account_id_must_not_be_int_max` The transfer was not created. [`Transfer.debit_account_id`](../transfers.md#debit_account_id) is `2^128 - 1`, but must be a valid account id. ### `credit_account_id_must_not_be_zero` The transfer was not created. [`Transfer.credit_account_id`](../transfers.md#credit_account_id) is zero, but must be a valid account id. ### `credit_account_id_must_not_be_int_max` The transfer was not created. [`Transfer.credit_account_id`](../transfers.md#credit_account_id) is `2^128 - 1`, but must be a valid account id. ### `accounts_must_be_different` The transfer was not created. [`Transfer.debit_account_id`](../transfers.md#debit_account_id) and [`Transfer.credit_account_id`](../transfers.md#credit_account_id) must not be equal. That is, an account cannot transfer money to itself. ### `pending_id_must_be_zero` The transfer was not created. Only post/void transfers can reference a pending transfer. Either: - [`Transfer.flags.post_pending_transfer`](../transfers.md#flagspost_pending_transfer) must be set, or - [`Transfer.flags.void_pending_transfer`](../transfers.md#flagsvoid_pending_transfer) must be set, or - [`Transfer.pending_id`](../transfers.md#pending_id) must be zero. ### `pending_id_must_not_be_zero` The transfer was not created. [`Transfer.flags.post_pending_transfer`](../transfers.md#flagspost_pending_transfer) or [`Transfer.flags.void_pending_transfer`](../transfers.md#flagsvoid_pending_transfer) is set, but [`Transfer.pending_id`](../transfers.md#pending_id) is zero. A posting or voiding transfer must reference a [`pending`](../transfers.md#flagspending) transfer. ### `pending_id_must_not_be_int_max` The transfer was not created. [`Transfer.pending_id`](../transfers.md#pending_id) is `2^128 - 1`, which is a reserved value. ### `pending_id_must_be_different` The transfer was not created. [`Transfer.pending_id`](../transfers.md#pending_id) is set to the same id as [`Transfer.id`](../transfers.md#id). Instead it should refer to a different (existing) transfer. ### `timeout_reserved_for_pending_transfer` The transfer was not created. [`Transfer.timeout`](../transfers.md#timeout) is nonzero, but only [pending](../transfers.md#flagspending) transfers have nonzero timeouts. ### `amount_must_not_be_zero` The transfer was not created. [`Transfer.amount`](../transfers.md#amount) is zero, but must be nonzero. Every transfer must move value. Only posting and voiding transfer amounts may be zero — when zero, they will move the full pending amount. ### `ledger_must_not_be_zero` The transfer was not created. [`Transfer.ledger`](../transfers.md#ledger) is zero, but must be nonzero. ### `code_must_not_be_zero` The transfer was not created. [`Transfer.code`](../transfers.md#code) is zero, but must be nonzero. ### `debit_account_not_found` The transfer was not created. [`Transfer.debit_account_id`](../transfers.md#debit_account_id) must refer to an existing `Account`. ### `credit_account_not_found` The transfer was not created. [`Transfer.credit_account_id`](../transfers.md#credit_account_id) must refer to an existing `Account`. ### `accounts_must_have_the_same_ledger` The transfer was not created. The accounts referred to by [`Transfer.debit_account_id`](../transfers.md#debit_account_id) and [`Transfer.credit_account_id`](../transfers.md#credit_account_id) must have an identical [`ledger`](../accounts.md#ledger). [Currency exchange](../../recipes/currency-exchange.md) is implemented with multiple transfers. ### `transfer_must_have_the_same_ledger_as_accounts` The transfer was not created. The accounts referred to by [`Transfer.debit_account_id`](../transfers.md#debit_account_id) and [`Transfer.credit_account_id`](../transfers.md#credit_account_id) are equivalent, but differ from the [`Transfer.ledger`](../transfers.md#ledger). ### `pending_transfer_not_found` The transfer was not created. The transfer referenced by [`Transfer.pending_id`](../transfers.md#pending_id) does not exist. ### `pending_transfer_not_pending` The transfer was not created. The transfer referenced by [`Transfer.pending_id`](../transfers.md#pending_id) exists, but does not have [`flags.pending`](../transfers.md#flagspending) set. ### `pending_transfer_has_different_debit_account_id` The transfer was not created. The transfer referenced by [`Transfer.pending_id`](../transfers.md#pending_id) exists, but with a different [`debit_account_id`](../transfers.md#debit_account_id). The post/void transfer's `debit_account_id` must either be `0` or identical to the pending transfer's `debit_account_id`. ### `pending_transfer_has_different_credit_account_id` The transfer was not created. The transfer referenced by [`Transfer.pending_id`](../transfers.md#pending_id) exists, but with a different [`credit_account_id`](../transfers.md#credit_account_id). The post/void transfer's `credit_account_id` must either be `0` or identical to the pending transfer's `credit_account_id`. ### `pending_transfer_has_different_ledger` The transfer was not created. The transfer referenced by [`Transfer.pending_id`](../transfers.md#pending_id) exists, but with a different [`ledger`](../transfers.md#ledger). The post/void transfer's `ledger` must either be `0` or identical to the pending transfer's `ledger`. ### `pending_transfer_has_different_code` The transfer was not created. The transfer referenced by [`Transfer.pending_id`](../transfers.md#pending_id) exists, but with a different [`code`](../transfers.md#code). The post/void transfer's `code` must either be `0` or identical to the pending transfer's `code`. ### `exceeds_pending_transfer_amount` The transfer was not created. The transfer's [`amount`](../transfers.md#amount) exceeds the `amount` of its [pending](../transfers.md#pending_id) transfer. ### `pending_transfer_has_different_amount` The transfer was not created. The transfer is attempting to [void](../transfers.md#flagsvoid_pending_transfer) a pending transfer. The voiding transfer's [`amount`](../transfers.md#amount) must be either `0` or exactly the `amount` of the pending transfer. To partially void a transfer, create a [posting transfer](../transfers.md#flagspost_pending_transfer) with an amount between `0` and the pending transfer's `amount`. ### `pending_transfer_already_posted` The transfer was not created. The referenced [pending](../transfers.md#pending_id) transfer was already posted by a [`post_pending_transfer`](../transfers.md#flagspost_pending_transfer). ### `pending_transfer_already_voided` The transfer was not created. The referenced [pending](../transfers.md#pending_id) transfer was already voided by a [`void_pending_transfer`](../transfers.md#flagsvoid_pending_transfer). ### `pending_transfer_expired` The transfer was not created. The referenced [pending](../transfers.md#pending_id) transfer was already voided because its [timeout](../transfers.md#timeout) has passed. ### `exists_with_different_flags` A transfer with the same `id` already exists, but with different [`flags`](../transfers.md#flags). ### `exists_with_different_debit_account_id` A transfer with the same `id` already exists, but with a different [`debit_account_id`](../transfers.md#debit_account_id). ### `exists_with_different_credit_account_id` A transfer with the same `id` already exists, but with a different [`credit_account_id`](../transfers.md#credit_account_id). ### `exists_with_different_amount` A transfer with the same `id` already exists, but with a different [`amount`](../transfers.md#amount). If the transfer has `flags.balancing_debit` or `flags.balancing_credit` set, this error refers to the actual amount transferred, not the original (possibly higher) balancing amount. ### `exists_with_different_pending_id` A transfer with the same `id` already exists, but with a different [`pending_id`](../transfers.md#pending_id). ### `exists_with_different_user_data_128` A transfer with the same `id` already exists, but with a different [`user_data_128`](../transfers.md#user_data_128). ### `exists_with_different_user_data_64` A transfer with the same `id` already exists, but with a different [`user_data_64`](../transfers.md#user_data_64). ### `exists_with_different_user_data_32` A transfer with the same `id` already exists, but with a different [`user_data_32`](../transfers.md#user_data_32). ### `exists_with_different_timeout` A transfer with the same `id` already exists, but with a different [`timeout`](../transfers.md#timeout). ### `exists_with_different_code` A transfer with the same `id` already exists, but with a different [`code`](../transfers.md#code). ### `exists` A transfer with the same `id` already exists, and is identical to the transfer in the request. To correctly recover from application crashes [many applications](../../design/consistency.md#consistency-with-foreign-databases) should handle `exists` exactly as [`ok`](#ok). ### `overflows_debits_pending` The transfer was not created. `debit_account.debits_pending + transfer.amount` would overflow a 128-bit unsigned integer. ### `overflows_credits_pending` The transfer was not created. `credit_account.credits_pending + transfer.amount` would overflow a 128-bit unsigned integer. ### `overflows_debits_posted` The transfer was not created. `debit_account.debits_posted + transfer.amount` would overflow a 128-bit unsigned integer. ### `overflows_credits_posted` The transfer was not created. `debit_account.credits_posted + transfer.amount` would overflow a 128-bit unsigned integer. ### `overflows_debits` The transfer was not created. `debit_account.debits_pending + debit_account.debits_posted + transfer.amount` would overflow a 128-bit unsigned integer. ### `overflows_credits` The transfer was not created. `credit_account.credits_pending + credit_account.credits_posted + transfer.amount` would overflow a 128-bit unsigned integer. ### `overflows_timeout` The transfer was not created. `transfer.timestamp + (transfer.timeout * 1_000_000_000)` would overflow a 64-bit unsigned integer. [`Transfer.timeout`](../transfers.md#timeout) is converted to nanoseconds. This computation uses the [`Transfer.timestamp`](../transfers.md#timestamp) value assigned by the replica, not the `0` value sent by the client. ### `exceeds_credits` The transfer was not created. If [`flags.balancing_debit`](../transfers.md#flagsbalancing_debit) is set, then `debit_account.debits_pending + debit_account.debits_posted + 1` would exceed `debit_account.credits_posted`. Otherwise, the [debit account](../transfers.md#debit_account_id) has [`flags.debits_must_not_exceed_credits`](../accounts.md#flagsdebits_must_not_exceed_credits) set, but `debit_account.debits_pending + debit_account.debits_posted + transfer.amount` would exceed `debit_account.credits_posted`. ### `exceeds_debits` The transfer was not created. If [`flags.balancing_credit`](../transfers.md#flagsbalancing_credit) is set, then `credit_account.credits_pending + credit_account.credits_posted + 1` would exceed `credit_account.debits_posted`. Otherwise, the [credit account](../transfers.md#credit_account_id) has [`flags.credits_must_not_exceed_debits`](../accounts.md#flagscredits_must_not_exceed_debits) set, but `credit_account.credits_pending + credit_account.credits_posted + transfer.amount` would exceed `credit_account.debits_posted`. ## Client libraries For language-specific docs see: * [.NET library](/src/clients/dotnet/README.md#create-transfers) * [Java library](/src/clients/java/README.md#create-transfers) * [Go library](/src/clients/go/README.md#create-transfers) * [Node.js library](/src/clients/node/README.md#create-transfers) ## Internals If you're curious and want to learn more, you can find the source code for creating a transfer in [src/state_machine.zig](https://github.com/tigerbeetle/tigerbeetle/blob/main/src/state_machine.zig). Search for `fn create_transfer(` and `fn execute(`.