Partner API

Money

Book a deposit, withdrawal or credit on a user's account from your backend. Scope balance:write is off by default, an idempotency key is required and every posting is audited.

POST/api/external/v1/users/{external_id}/transactions

#Book a deposit, withdrawal or credit on the user's account

Auth X-Api-Key balance:write Partner API

Scope balance:write (off by default; only the Octolit CRM owner or an admin with the "Edit transactions" right can put it on a key). The brand's "Money posting" switch must be on (403 brand_disabled otherwise).

The money is booked by the Octolit CRM's own transaction service - the same path a back-office "Add transaction" takes (balance update, first-deposit date, client e-mails, postbacks; for an MT account the balance call to the MT server). status: approved (default) counts at once; status: pending waits for approval in the Octolit CRM and then raises deposit.status / withdrawal.status like any other transaction.

Idempotency key (required: idempotency_key in the body or the Idempotency-Key header, 1-128 characters, unique per company). Repeat a call with the same key and body as often as you like: you get the stored answer again (200, replayed: true) and nothing is booked twice. The same key with a different body answers 409 idempotency_conflict; a posting still being booked 409 in_progress.

A withdrawal over the account's free margin or a credit_out over its credit answers 409 insufficient_funds and books nothing. Every posting leaves an audit row and a line in the client's CRM history naming the key.

Path parameters

external_id string required

Your client id (1-191 letters, digits, . _ @ : + -). Stored on the client as external_user_id.

Headers

Idempotency-Key string optional

The idempotency key when it is not in the body.

Request body · application/json

kind enum required

credit = credit in (a credit line)

depositwithdrawalcreditcredit_out
amount string | number required

> 0, at most 10 decimals (send a string to keep the exact decimals).

currency string | integer optional

3-letter code or id; default the account's currency.

account_id integer optional

One of the user's accounts; default the first one.

status enum optional

Default "approved".

approvedpending
method string optional

Payment method text shown in the Octolit CRM (default partner_api). 0-64 characters.

reference string optional

Your reference (invoice / PSP id); shown in the Octolit CRM and sent back. 0-128 characters.

note string optional

0-255 characters.

idempotency_key string optional

Required unless sent as the Idempotency-Key header. 1-128 characters.

Responses

200

The same key and body again - the stored answer (replayed = true), nothing booked.

201

Booked.

403

insufficient_scope, ip_not_allowed, api_disabled, company_inactive, brand_disabled, sso_disabled, trending_disabled (trading on behalf also: brand_inactive, client_inactive, trading_inactive, trading_denied).

404

not_found / user_not_found / account_not_found / symbol_not_found.

409

idempotency_conflict, in_progress or insufficient_funds (details.available).

422

invalid_request (details.errors per field) or money_rejected (the Octolit CRM's transaction service refused).

curl -X POST "https://api.your-brand.com/api/external/v1/users/cust_10042/transactions" \
  -H "X-Api-Key: $OCTOLIT_PARTNER_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "kind": "deposit",
  "amount": "100.00",
  "currency": "USD",
  "account_id": 55,
  "status": "approved",
  "method": "card",
  "reference": "INV-1001",
  "note": "Card deposit",
  "idempotency_key": "dep-INV-1001"
}'
Response 200
{
  "transaction": {
    "id": 1042,
    "kind": "deposit",
    "status": "approved",
    "amount": "100.00",
    "currency": "USD",
    "account_id": 55,
    "method": "card",
    "reference": "INV-1001",
    "note": "Card deposit",
    "created_at": "2026-11-11T09:30:00.000000Z"
  },
  "balance": {
    "currency": "USD",
    "balance": "10250.00",
    "equity": "10312.40",
    "margin": "108.45",
    "free_margin": "10203.95",
    "margin_level": "9509.3",
    "open_pl": "string",
    "credit": "string",
    "as_of": "2026-11-11T09:30:00Z",
    "accounts": [
      {
        "id": 1042,
        "name": "Main",
        "currency": "USD",
        "demo": false,
        "type": {
          "id": 1042,
          "name": "Main",
          "provider": "string"
        },
        "balance": "10250.00",
        "equity": "10312.40",
        "margin": "108.45",
        "free_margin": "10203.95",
        "margin_level": "9509.3",
        "open_pl": "string",
        "closed_pl": "string",
        "credit": "string",
        "mt_login": "string",
        "created_at": "2026-11-11T09:30:00.000000Z"
      }
    ]
  },
  "idempotency_key": "dep-INV-1001",
  "replayed": false
}
Response 201
{
  "transaction": {
    "id": 1042,
    "kind": "deposit",
    "status": "approved",
    "amount": "100.00",
    "currency": "USD",
    "account_id": 55,
    "method": "card",
    "reference": "INV-1001",
    "note": "Card deposit",
    "created_at": "2026-11-11T09:30:00.000000Z"
  },
  "balance": {
    "currency": "USD",
    "balance": "10250.00",
    "equity": "10312.40",
    "margin": "108.45",
    "free_margin": "10203.95",
    "margin_level": "9509.3",
    "open_pl": "string",
    "credit": "string",
    "as_of": "2026-11-11T09:30:00Z",
    "accounts": [
      {
        "id": 1042,
        "name": "Main",
        "currency": "USD",
        "demo": false,
        "type": {
          "id": 1042,
          "name": "Main",
          "provider": "string"
        },
        "balance": "10250.00",
        "equity": "10312.40",
        "margin": "108.45",
        "free_margin": "10203.95",
        "margin_level": "9509.3",
        "open_pl": "string",
        "closed_pl": "string",
        "credit": "string",
        "mt_login": "string",
        "created_at": "2026-11-11T09:30:00.000000Z"
      }
    ]
  },
  "idempotency_key": "dep-INV-1001",
  "replayed": false
}