LITTLEFOX API · V1
From catalog
to delivery.
Bring LittleFox to your website, bot or app. Explore products, purchase from your balance and retrieve delivery through one API.
curl "$BASE_URL/api/v1/me?currency=USD" \
-H "Authorization: Bearer $API_KEY"Examples use sample values. Get current prices and product IDs from the catalog.
Your first request in three steps
- Create your key
In the bot, open Profile → API key → Create my API key.
- Set up your environment
Store the key as API_KEY on your server. Set BASE_URL to this website’s origin, without a trailing slash.
- Check your balance
Run the request below or connect on the API test page. Viewing your balance and catalog is free.
curl "$BASE_URL/api/v1/me?currency=USD" \
-H "Authorization: Bearer $API_KEY"The base path is /api/v1. Use HTTPS; responses are JSON. Successful responses contain ok: true and data. Errors contain ok: false and error.
Your key, one shared balance
Include your key in every request header. It grants access only to its owner’s balance and orders.
Authorization: Bearer YOUR_API_KEYThe X-API-Key header is also supported. Keys in the URL are not accepted.
/api/v1/meReturns your Telegram ID, username, balance and request limit. You share the same balance with the bot; top up from your profile.
| Field / value | Description |
|---|---|
balance_kopeks | Available to spend. Held funds are already excluded; do not subtract them again. |
held_kopeks | Funds held for orders that are still processing. |
limits.requests_per_minute | Your key’s current request limit per minute. |
Keep it out of public code, logs and repositories. Disabling API pauses access. Reissuing immediately revokes the old key while preserving your balance and history.
Catalog, stock and prices
/api/v1/products?page=1&limit=50&lang=en¤cy=USD| Field / value | Description |
|---|---|
page / limit | Page and page size: limit is 1–100, default 50. Response: items, page, limit, total, pages, has_more. |
available=true | In-stock products only. Without this filter, temporarily unavailable products are included. |
lang=ru / en | Language of product names and descriptions. Independent of currency. |
{
"id": 42,
"name": "Example product",
"price_kopeks": 19900,
"price": "199.00",
"currency": "RUB",
"stock": 12,
"stock_unlimited": false,
"available": true,
"category": {
"id": 3,
"name": "Subscriptions"
},
"wholesale_tiers": [
{
"min_quantity": 5,
"unit_price_kopeks": 17900,
"unit_price": "179.00",
"currency": "RUB"
}
]
}When out of stock
For stock=0 and available=false, disable purchasing. The name, price, description and ID remain available. The same product returns after restocking.
When buying in quantity
The highest applicable wholesale_tiers threshold is used. Price and stock are checked again when the order is created.
/api/v1/products/{id}Refresh the catalog within your request limit; changes are not pushed automatically. For stock_unlimited=true, stock is null and does not run out. Services requiring extra parameters are purchased in the bot.
Display currency and exact payment
Add currency=RUB or currency=USD to balance, catalog, order and transaction requests. RUB is the default. Language and currency are independent; no separate USD wallet is created.
| Field / value | Description |
|---|---|
price / total / balance | Display strings in the selected currency, rounded to two decimals. Also applies to held, unit_price, charged, refunded and amount. |
…_kopeks | Exact amounts in kopeks: 100 = 1 RUB. Use them to calculate order totals and spending caps. |
exchange_rate | Shop rate: RUB per 1 USD, with an exact decimal rate and updated_at timestamp. One rate per response; null for RUB. |
{
"currency": "USD",
"settlement_currency": "RUB",
"exchange_rate": {
"base": "USD",
"quote": "RUB",
"rate": "80",
"updated_at": "2026-09-20T12:00:00.000Z"
},
"items": [
{
"id": 42,
"price_kopeks": 19900,
"price": "2.49",
"currency": "USD"
}
]
}Do not convert rounded USD prices back into kopeks or multiply them to calculate payment. Build max_total_kopeks from exact prices, quantity and the applicable discount tier. A small USD amount may round to 0.00; this does not make the product free.
The server determines the price. max_total_kopeks caps spending; it does not set the price. price, currency and exchange_rate are not accepted in the order body. Response currency never changes the charge.
USD history uses the current response’s rate. Save the response and rate for a snapshot at request time. If the rate is unavailable, USD returns 503 exchange_rate_unavailable before creating an order; retry in RUB with the same idempotency key.
Descriptions for websites and bots
Each response includes the language selected with lang, in two formats without shop-specific formatting commands.
| Field / value | Description |
|---|---|
description | Plain text. Links keep their label and URL; animated emoji become standard characters. |
description_html | Website-ready HTML: strong, em, u, s, code, pre, blockquote, a, br. No scripts, event handlers or styles; spoilers are visible. |
{
"description": "Product description\nGuide (https://example.com/guide)",
"description_html": "<strong>Product description</strong><br><a href=\"https://example.com/guide\" rel=\"noopener noreferrer\">Guide</a>"
}delivery_data is passed through unchanged. Preserve it in full, including line breaks.
Purchase from your balance
/api/v1/orders?currency=USDOne request creates an order for 1–100 units of one product. This charges the key owner’s balance. Save the idempotency key and parameters before sending.
curl -X POST "$BASE_URL/api/v1/orders?currency=USD" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: store-order-1042" \
-d '{
"product_id": 42,
"quantity": 1,
"max_total_kopeks": 19900,
"client_order_id": "1042"
}'| Field / value | Description |
|---|---|
Idempotency-Key | Required header: 8–128 ASCII letters, digits or : _ -. New for each order, unchanged on retries. |
product_id | Product ID from the current catalog. 42 above is a sample value. |
quantity | Integer from 1 to 100, subject to stock. |
max_total_kopeks | Required cap for the entire order, from 1 to 100000000. Orders above the cap are rejected. |
client_order_id | Optional order reference, up to 128 characters. Does not replace Idempotency-Key. |
Deliver to your customer only when status=delivered. data.delivery_data contains the complete payload: text, multiple lines or JSON encoded as a string.
Test the complete purchase flow
The test product is available to every API client. Find is_test=true in the catalog and use its id. Stock is unlimited: stock=null, stock_unlimited=true, available=true; api_only=true.
One unit costs 100 kopeks (1 RUB). USD responses show the equivalent at the shop rate. Delivery contains unique fictional email | password pairs on example.com, with no access to real accounts. The order appears in My purchases, API history and statistics.
- Send a standard POST /orders with the test product ID, quantity=1 and max_total_kopeks=100.
- Wait for delivered and save delivery_data. Reuse the same Idempotency-Key if you retry.
The website guides you through confirmation, result checking, and copying or downloading delivery. Your API key stays in tab memory; only the operation identity is saved for recovery.
Open API testOne order, one idempotency key
If the response is lost, repeat the original POST with the same Idempotency-Key and parameters. A new key creates a new purchase; changing the original parameters returns 409 idempotency_conflict. Changing the response currency does not create a new order.
/api/v1/orders/{id}Once you know the ID, check that order with GET no more than once every 5 seconds.
| Field / value | Description |
|---|---|
processing | The order is accepted and processing; funds may be held. |
recovering | The system is verifying the result automatically. Wait for completion before creating another purchase. |
delivered | Purchase complete. Funds are charged and delivery_data is populated. |
failed | Purchase rejected before a charge. See failure_code and failure_message. |
refunded | Purchase not completed; the hold was returned to your balance in full. |
Until the result is confirmed, the system does not repurchase or release held funds. Verification continues after restarts. Accepted orders keep processing even if the key is disabled.
Orders and balance transactions
/api/v1/orders?page=1&limit=20The key owner’s API orders. Filter by client_order_id to find your reference. Lists omit delivery data; request the individual order by ID.
/api/v1/transactions?page=1&limit=50All transactions on your balance. amount_kopeks is signed: positive for credits, negative for charges or holds. purchase_hold becomes purchase after delivery; purchase_refund is a return.
Both lists accept limit from 1 to 100. has_more indicates another page. Use currency=RUB or currency=USD for display amounts.
Errors and request limits
{
"ok": false,
"error": {
"code": "insufficient_balance",
"message": "Your available balance is too low."
}
}Handle error.code rather than message text. A purchase error may still include order data. Keep the same idempotency key after network errors or 5xx responses.
| Field / value | Description |
|---|---|
400 / 415 | Check JSON, fields, Content-Type and Idempotency-Key. |
401 / 403 | Key invalid, disabled or reissued, or access restricted. |
402 | Insufficient balance. Top up in the bot. |
404 | Product or owned order not found. |
409 | Price, stock or parameters conflict, or another order is processing. Check error.code. |
429 | Rate limit reached. Wait Retry-After seconds; find your limit in /me. |
503 | API disabled or rate unavailable. For exchange_rate_unavailable, retry in RUB with the same idempotency key. |
Need help? Contact support through the bot. Include the order ID and error.code; keep your full API key private.