ROOKDocs
POST

Create an internal transfer

ENDPOINT/v1/internal-transfers

Creates a transaction of type INTERNAL_TRANSFER. The response is the Transaction; its id is the transaction_id used on every transaction endpoint. Moves funds between two financial accounts on the program. The source is debited and the destination is credited the same amount. category and type must be a valid pair. Send Idempotency-Key so retries return the original transfer instead of posting twice.

Authentication & Headers

HeaderTypeRequirementDescription
AuthorizationstringREQUIREDAPI key passed as an HTTP Bearer token: Bearer rk_live_...
X-Program-IDUUIDPROGRAM-SCOPEDProgram boundary UUID that scopes the issuing card, wallet, or transfer.
Content-TypestringREQUIREDMust be application/json.
Idempotency-KeystringOPTIONALUnique UUID to prevent duplicate execution of financial creations or mutations.

Request Body Schema

application/json
from_financial_account_idstringuuid
REQUIRED

Source financial account to debit.

to_financial_account_idstringuuid
REQUIRED

Destination financial account to credit.

amountobject
REQUIRED

Size to move. `amount` is a positive integer of minor units; `50000` with `USD` is $500.00.

Properties of amount
amountanyrequired
currencystringrequired
ISO 4217 alphabetic currency code.
categorystring
REQUIRED

Reason for this internal transfer. Pair with `subtype`: `TRANSFER` uses `COLLECTION` or `PAYMENT`; `ADJUSTMENT` uses billing and goodwill types; `BALANCE_OR_FUNDING` moves between available, reserve, and suspense; `FEE` and `REWARD` post to those financial accounts; `PROGRAM_FUNDING` moves program capital.

Enum values:ADJUSTMENTBALANCE_OR_FUNDINGFEEREWARDPROGRAM_FUNDINGTRANSFER
subtypestring
REQUIRED

Subtype of `category` on an internal transfer transaction. `TRANSFER`: `COLLECTION`, `PAYMENT`. `ADJUSTMENT`: `BILLING_ERROR`, `BILLING_ERROR_REVERSAL`, `CORRECTION`, `GOODWILL`. `BALANCE_OR_FUNDING`: `AVAILABLE_TO_RESERVE`, `RESERVE_TO_AVAILABLE`, `AVAILABLE_TO_SUSPENSE`, `SUSPENSE_TO_AVAILABLE`. `FEE`: `LATE`, `NSF`, `ANNUAL`, `ATM`, `FOREIGN_TRANSACTION`, `FEE_REVERSAL`. `REWARD`: `CASH_BACK`, `CASH_BACK_REVERSAL`, `PROMO`, `PROMO_REVERSAL`. `PROGRAM_FUNDING`: `PROGRAM_FUNDING`, `PROGRAM_REPAYMENT`. A mismatched pair returns `422`.

Enum values:COLLECTIONPAYMENTBILLING_ERRORBILLING_ERROR_REVERSALCORRECTIONGOODWILLAVAILABLE_TO_RESERVERESERVE_TO_AVAILABLEAVAILABLE_TO_SUSPENSESUSPENSE_TO_AVAILABLELATENSFANNUALATMFOREIGN_TRANSACTIONFEE_REVERSALCASH_BACKCASH_BACK_REVERSALPROMOPROMO_REVERSALPROGRAM_FUNDINGPROGRAM_REPAYMENT
memostring
optional

Descriptor shown on activity. Omit to leave null.

Response Codes & Schemas

201The internal transfer was created.
application/json
{
  "id": "5c8e1b39-0d6f-4a12-b9e4-4f7a2c8d3465",
  "object": "transaction",
  "type": "INTERNAL_TRANSFER",
  "status": "SETTLED",
  "transfer_ids": [
    "6f2d8a41-3c7e-4b95-a1d0-8e5c2f7b9a63"
  ],
  "amount": {
    "amount": 50000,
    "currency": "USD"
  },
  "wallet_id": "4d8f2a10-6c3e-4b91-9e5a-2f7c8d1e0b44",
  "financial_account_id": "9b3e1c70-4d2a-4f86-8c1b-5e7a2d9f0c14",
  "direction": "DEBIT",
  "category": "TRANSFER",
  "memo": "Internal transfer to operating",
  "events": [
    {
      "id": "7d3f1a50-2e68-4b91-c4d7-1a9e6f0b3842",
      "type": "CREATED",
      "amount": {
        "amount": 50000,
        "currency": "USD"
      },
      "result": "APPROVED",
      "financial_account_id": "9b3e1c70-4d2a-4f86-8c1b-5e7a2d9f0c14",
      "created_at": "2026-08-26T18:40:00Z"
    },
    {
      "id": "9e4a2b61-3f79-4c02-d5e8-2b0f7a1c4953",
      "type": "SETTLED",
      "amount": {
        "amount": 50000,
        "currency": "USD"
      },
      "result": "APPROVED",
      "financial_account_id": "9b3e1c70-4d2a-4f86-8c1b-5e7a2d9f0c14",
      "created_at": "2026-08-26T18:40:05Z"
    }
  ],
  "created_at": "2026-08-26T18:40:00Z",
  "updated_at": "2026-08-26T18:40:05Z",
  "from_financial_account_id": "9b3e1c70-4d2a-4f86-8c1b-5e7a2d9f0c14",
  "to_financial_account_id": "5f6a8b21-3c47-4e90-bd12-7a4e8c1f3056",
  "subtype": "COLLECTION",
  "result": "APPROVED"
}
400Bad Request: malformed JSON, failed schema validation, or conflicting parameters.
application/json
{
  "error": {
    "type": "invalid_request_error",
    "code": "invalid_request",
    "message": "invalid order by: foo. Valid options are: [created_at updated_at]",
    "param": "order_by",
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "doc_url": "https://docs.rookpayments.com/errors/invalid_request"
  }
}
401Unauthorized: missing, malformed, or unknown API key.
application/json
{
  "error": {
    "type": "authentication_error",
    "code": "authentication_error",
    "message": "A valid API key is required.",
    "param": null,
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "doc_url": "https://docs.rookpayments.com/errors/authentication_error"
  }
}
403Forbidden: the API key is denied by RBAC, or it cannot access this program. A resource that exists on another program or organization returns `404 not_found`, not `403`.
application/json
{
  "error": {
    "type": "permission_error",
    "code": "permission_denied",
    "message": "The API key cannot access this program.",
    "param": "X-Program-ID",
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "doc_url": "https://docs.rookpayments.com/errors/permission_denied"
  }
}
404Not Found: unknown id, or the resource is not visible to this API key.
application/json
{
  "error": {
    "type": "not_found_error",
    "code": "not_found",
    "message": "No card found for the given id.",
    "param": "card_id",
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "doc_url": "https://docs.rookpayments.com/errors/not_found"
  }
}
409Conflict: incompatible state, or Idempotency-Key reused with a different body.
application/json
{
  "error": {
    "type": "conflict_error",
    "code": "conflict",
    "message": "The card cannot be reissued from its current state.",
    "param": null,
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "doc_url": "https://docs.rookpayments.com/errors/conflict"
  }
}
422Unprocessable Entity: the document is valid JSON but violates a business rule.
application/json
{
  "error": {
    "type": "invalid_request_error",
    "code": "insufficient_funds",
    "message": "The source financial account does not have enough available balance.",
    "param": "amount",
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "doc_url": "https://docs.rookpayments.com/errors/insufficient_funds"
  }
}
429Too Many Requests: the API key exceeded its rate limit.
application/json
{
  "error": {
    "type": "rate_limit_error",
    "code": "rate_limited",
    "message": "Rate limit exceeded. Retry after the number of seconds in Retry-After.",
    "param": null,
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "doc_url": "https://docs.rookpayments.com/errors/rate_limited"
  }
}
500Internal Server Error: unexpected failure. Retry with the same Idempotency-Key.
application/json
{
  "error": {
    "type": "api_error",
    "code": "internal_error",
    "message": "An unexpected error occurred. Retry with the same Idempotency-Key.",
    "param": null,
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "doc_url": "https://docs.rookpayments.com/errors/internal_error"
  }
}