Transfers
A transfer moves money from one wallet to another. It pairs an expense on the source wallet with income on the destination wallet, and can carry an exchange rate when the wallets use different currencies. All routes require a bearer token and live under /api/v1.
Endpoints
Section titled “Endpoints”| Method | Path | Action |
|---|---|---|
GET | /api/v1/transfers | List transfers |
POST | /api/v1/transfers | Create a transfer |
GET | /api/v1/transfers/{id} | Show one transfer |
PUT | /api/v1/transfers/{id} | Update a transfer |
DELETE | /api/v1/transfers/{id} | Delete a transfer |
Fields
Section titled “Fields”| Field | Type | Required | Notes |
|---|---|---|---|
amount | number | yes | Minimum 0.01. |
from_wallet_id | integer | yes | Source wallet. |
to_wallet_id | integer | yes | Destination wallet. |
exchange_rate | number | no | Greater than 0. Use when currencies differ. |
datetime | string | no | ISO 8601. |
client_id | string | no | Client-generated ID, {device_uuid}:{entity_uuid}. |
expense_transaction_client_id | string | no | Client ID of the paired expense transaction. |
income_transaction_client_id | string | no | Client ID of the paired income transaction. |
created_at | string | no | ISO 8601. |
Create
Section titled “Create”curl -X POST https://api.your-domain.example/api/v1/transfers \ -H "Authorization: Bearer your-token-here" \ -H "Content-Type: application/json" \ -d '{ "amount": 100, "from_wallet_id": 1, "to_wallet_id": 2 }'Response shape
Section titled “Response shape”{ "success": true, "message": "Transfer created", "data": { "id": 5, "amount": 100, "from_wallet_id": 1, "to_wallet_id": 2, "exchange_rate": 1, "user_id": 1, "datetime": "2026-06-14T09:12:00.000000Z", "source_wallet": { "id": 1, "name": "Cash" }, "destination_wallet": { "id": 2, "name": "Bank" }, "transactions": [], "client_generated_id": "device-uuid:entity-uuid", "last_synced_at": "2026-06-14T09:12:00.000000Z" }}The transactions array holds the paired expense and income transactions the transfer generated.