/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
The unique ID of the customer in your system. Either adapty-customer-user-id or adapty-profile-id is required.
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.
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.
Balance adjustments to apply atomically. Each currency code may appear only once.
The virtual currency code to adjust.
The amount to apply. A positive value credits (grants) the currency; a negative value debits (spends) it. Cannot be zero.
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.
Unique ID of the created transaction.
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/.
Virtual currency code.
Display name of the virtual currency.
Total balance, including amounts currently held.
Sum of all active holds (reserved amounts). Currently always 0.
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
Source of the error
Array of error messages
Short error name
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
Source of the error
Array of error messages
Short error name
HTTP status code
Forbidden. The Server API for virtual currencies is not enabled for this app. Contact Adapty support to request access.
Schema
Source of the error
Array of error messages
Short error name
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
Source of the error
Array of error messages
Short error name
HTTP status code
Conflict. The error_code field identifies the cause:
idempotency_in_flight— a request with the sameIdempotency-Keyis still being processed. Retry after the interval in theRetry-Afterresponse header.duplicate_source_transaction— the underlying store transaction was already credited, so it is not applied again.
Schema
Source of the error
Array of error messages
Short error name
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
Source of the error
Array of error messages
Short error name
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
Source of the error
Array of error messages
Short error name
HTTP status code
Internal server error