---
title: "Create a transfer"
method: POST
path: "/api/transfers"
tags: ["Transfers"]
---

# Create a transfer

`POST /api/transfers`

Initiate a new payment transfer. Idempotent via optional `idempotency-key` header.
The transfer enters the `INITIATED` state and proceeds through the state machine:
`INITIATED → SUBMITTED → ACCEPTED → SETTLED` (or `→ RETURNED` / `→ FAILED`).

## Headers

- `x-tenant-id` string, required
- `x-canonical-version` '1', required
- `idempotency-key` string, uuid

## Request body

- CreateTransferRequest
  - `tenantId` string, required
  - `intent` 'AUTH' | 'CAPTURE' | 'PUSH' | 'PULL', required
  - `amount` Amount, required
    - `value` string, required — Decimal amount as string
    - `currency` string, required — ISO 4217 currency code
  - `sourceCurrency` string, required — ISO 4217 currency code
  - `targetCurrency` string, required — ISO 4217 currency code
  - `fxStrategy` 'NOT_APPLICABLE' | 'QUOTE_AT_SUBMIT' | 'PASS_THROUGH', required
  - `payer` Party, required
    - `type` string, required — Party type (e.g., WALLET, MOBILE_MONEY, BANK_ACCOUNT)
    - `id` string, required — Party identifier
  - `payee` Party, required
    - `type` string, required — Party type (e.g., WALLET, MOBILE_MONEY, BANK_ACCOUNT)
    - `id` string, required — Party identifier
  - `railHints` string[] — Preferred rails for routing
  - `feeModel` string — Fee model identifier
  - `endUserRef` string — End-user reference (e.g., invoice number)
  - `externalRef` string — External system reference
  - `traceparent` string — W3C traceparent header for distributed tracing
  - `metadata` object — Arbitrary key-value metadata

## Response `200`

Idempotent duplicate — returns existing transfer

- CreateTransferResponse
  - `transferId` string, uuid
  - `state` 'INITIATED' | 'SUBMITTED' | 'ACCEPTED' | 'SETTLED' | 'RETURNED' | 'FAILED'
  - `rail` string, nullable

## Other responses

- `201` — Transfer created
- `400` — Validation error
- `401` — Missing or invalid authentication
- `409` — Idempotency conflict — same key, different body
- `422` — Compliance denied
- `500` — Internal server error

---

[API](https://skmtc.dev/stalela/apis/stalela-transfers-api.md) · [All operations](https://skmtc.dev/stalela/apis/stalela-transfers-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/stalela/stalela-transfers-api/revisions/752749e46059/schema)
