Workspace
The collaboration and commercial boundary. A workspace contains members, roles, ledger access, billing, traffic limits, transfer shape, and plan-based capacity for new ledgers and ledger configuration.
Core concepts
XferAPI gives your product a durable balance API without taking ownership of your business rules. Learn which boundary owns what before you send the first transfer.
The collaboration and commercial boundary. A workspace contains members, roles, ledger access, billing, traffic limits, transfer shape, and plan-based capacity for new ledgers and ledger configuration.
The isolated accounting boundary for one product, environment, or balance domain. Accounts, vocabulary, platform accounts, transfers, records, and service keys belong to one ledger and do not cross it.
A backend credential that selects exactly one ledger. The public /v1 API derives the ledger from the key, so integrations do not put an internal ledger ID in a URL or request body.
The exact points asset and built-in -1 and -2 platform account definitions do not consume additional allowances. If a ledger does not contain points, it does not receive a hidden free asset slot. System account 0 is not a platform account.
Existing workspaces, ledgers, assets, platform account definitions, and full ranges continue to work and remain editable after a downgrade. The new plan blocks only another creation while its relevant limit is reached; it does not rewrite balances, history, or transfer behavior.
Every ledger counts toward the workspace limit, including a disabled ledger. A platform account range contains 1–20 IDs and counts as one definition regardless of its length or status. A user can create at most two Free workspaces they own; workspaces joined as a member do not count, and existing downgraded workspaces are preserved.
The vocabulary
An application-owned balance owner identified inside a ledger. The application chooses the account ID format within XferAPI’s URL-safe ASCII rules.
The unit being moved, such as points, credits, coins, or gems. A ledger configures the asset codes it accepts.
The business meaning attached to an account entry, such as top_up, spend, refund, or grant.
The business context of the whole transfer. Together with transfer_id, it forms the idempotency boundary.
One caller-identified N-to-M movement. For every asset, source totals must equal destination totals.
The durable account-level movement produced by one transfer item. Transfer history is the source of truth for accounting state.
The accounting rule
A transfer may debit several accounts and credit several accounts. For each asset, the total on the source side must equal the total on the destination side.
{
"transfer_id": "order_123",
"scene": "spend",
"from_accounts": [
{ "account_id": "member_42", "asset": "points", "action": "spend", "amount": "100" }
],
"to_accounts": [
{ "account_id": "creator_7", "asset": "points", "action": "spend", "amount": "90" },
{ "account_id": "-2", "asset": "points", "action": "spend", "amount": "10" }
]
}Idempotency decisions
The response category determines whether the original transfer_id and scene remain usable. Do not treat every non-ok code the same.
For a timeout, disconnect, invalid or missing envelope, internal_error, service_unavailable, or transfer_state_conflict, resend the original ID, scene, and exact payload. Do not create a new ID or require a read first.
rate_limit_exceeded, quota_exceeded, and billing_suspended do not start a new transfer. After backoff or remediation, resend the same original request.
For transfer creation, this category contains exactly insufficient_balance and execution-time amount_out_of_range. The pair can never later succeed. Fix the condition, then submit a new transfer_id.
transfer_already_reversed means the pair is closed. idempotency_conflict means it belongs to another payload. Use a new ID for the request you are trying to submit.
Ordinary destination entries can start in the future or expire at an exclusive Unix-second boundary. Balance reads and deductions evaluate availability at one server time captured for the Transfer. For each ordinary source account and asset, active batches with an expiration are consumed earliest-expiry-first, followed by permanent balance. Future and expired batches are not spendable; a source entry cannot select a specific batch, and equal-expiry ordering is not contractual. Expiration recycling is managed by XferAPI and is not a user-created transfer.
A reversal applies the inverse balance changes to the complete transfer and moves its records to the reversal state. It is safe to repeat and does not create a second business transfer.
Ready to implement? Start with a working request, then use the API reference for every field and status.