POST /api/v2/server-side-api/vc/transactions/

Create virtual currency transaction

Credits or debits one or more virtual currencies for a profile in a single atomic transaction. Use a positive amount to credit (grant) and a negative amount to debit (spend). All items are applied together — if any item fails, none are applied.

Each currency code may appear only once per request. A credit through this endpoint always creates a non-expiring balance.

Header parameters

adapty-customer-user-idstring

The unique ID of the customer in your system. Either adapty-customer-user-id or adapty-profile-id is required.

adapty-profile-idstring

The unique ID of the profile in your system. Your best option if you are working with anonymous profiles. Either adapty-customer-user-id or adapty-profile-id is required.

Idempotency-Keystring · uuid

A UUID v4 that makes the request idempotent. If you retry a request with the same key, Adapty returns the result of the original transaction without changing balances again. Must be a valid UUID v4.

Request body

Request body for creating a virtual currency transaction.

itemsarray of objectrequired

Balance adjustments to apply atomically. Each currency code may appear only once.

currency_codestringrequired

The virtual currency code to adjust.

amountintegerrequired

The amount to apply. A positive value credits (grants) the currency; a negative value debits (spends) it. Cannot be zero.

metadataobject

Optional key-value pairs stored with the transaction. At most 5 keys. Each key matches ^[a-z0-9_]{1,30}$, and each value is at most 200 characters.

Responses

Transaction applied successfully

Schema

Result of a virtual currency transaction.

transaction_idstringrequired

Unique ID of the created transaction.

balancesarray of objectrequired

Post-transaction balance for each currency affected by this request (one entry per item in items). To read the full balance list for the profile, use GET /api/v2/server-side-api/vc/balances/.

codestringrequired

Virtual currency code.

namestringrequired

Display name of the virtual currency.

balanceintegerrequired

Total balance, including amounts currently held.

heldintegerrequired

Sum of all active holds (reserved amounts). Currently always 0.

availableintegerrequired

Balance available to spend, computed as balance - held.

Example
{
  "transaction_id": "0190e8a4-1c2b-7def-8abc-2c1a4b6d8e90",
  "balances": [
    {
      "code": "COINS",
      "name": "Gold Coins",
      "balance": 12950,
      "held": 0,
      "available": 12950
    }
  ]
}

Bad request. The error_code field identifies the cause: insufficient_balance, unknown_currency, duplicate_currency, amount_zero, balance_overflow, empty_items, or idempotency_key_invalid.

Schema
errorsarray of objectrequired
sourcestring

Source of the error

errorsarray of string

Array of error messages

error_codestringrequired

Short error name

status_codeintegerrequired

HTTP status code

Example
{
  "errors": [
    {
      "source": "currency_code",
      "errors": [
        "Insufficient balance for currency COINS"
      ]
    }
  ],
  "error_code": "insufficient_balance",
  "status_code": 400
}

Unauthorized. The API key is missing or invalid.

Schema
errorsarray of objectrequired
sourcestring

Source of the error

errorsarray of string

Array of error messages

error_codestringrequired

Short error name

status_codeintegerrequired

HTTP status code

Forbidden. The Server API for virtual currencies is not enabled for this app. Contact Adapty support to request access.

Schema
errorsarray of objectrequired
sourcestring

Source of the error

errorsarray of string

Array of error messages

error_codestringrequired

Short error name

status_codeintegerrequired

HTTP status code

Example
{
  "errors": [
    {
      "source": null,
      "errors": [
        "Server API for virtual currencies is not enabled for this app. Contact Adapty support to request access."
      ]
    }
  ],
  "error_code": "feature_not_enabled",
  "status_code": 403
}

Profile not found.

Schema
errorsarray of objectrequired
sourcestring

Source of the error

errorsarray of string

Array of error messages

error_codestringrequired

Short error name

status_codeintegerrequired

HTTP status code

Conflict. The error_code field identifies the cause:

  • idempotency_in_flight — a request with the same Idempotency-Key is still being processed. Retry after the interval in the Retry-After response header.
  • duplicate_source_transaction — the underlying store transaction was already credited, so it is not applied again.
Schema
errorsarray of objectrequired
sourcestring

Source of the error

errorsarray of string

Array of error messages

error_codestringrequired

Short error name

status_codeintegerrequired

HTTP status code

Example
{
  "errors": [
    {
      "source": null,
      "errors": [
        "A similar request is being processed."
      ]
    }
  ],
  "error_code": "idempotency_in_flight",
  "status_code": 409
}

Unprocessable entity. The request body failed schema validation — for example, items contains more than 20 entries, or a metadata key or value breaks its constraints.

Schema
errorsarray of objectrequired
sourcestring

Source of the error

errorsarray of string

Array of error messages

error_codestringrequired

Short error name

status_codeintegerrequired

HTTP status code

Too many requests. The per-app or global rate limit was exceeded (error_code is rate_limited). The default limits are 600 requests per minute per app and 6000 requests per minute globally.

Schema
errorsarray of objectrequired
sourcestring

Source of the error

errorsarray of string

Array of error messages

error_codestringrequired

Short error name

status_codeintegerrequired

HTTP status code

Internal server error