OneProvider
Reseller API

Reseller API keys and clients

Create, top up, pause and delete client API keys and manage your customers through the OneProvider reseller API, with curl examples for every call.

Issue, top up, pause and delete client keys and manage your customers through the reseller API, with curl examples.

All models, capabilities, and prices Documentation index for AI agents: https://oneprovider.dev/docs/llms.txt

The key object

Key fields
FieldDescription
idOpaque signed identifier, not a number.
name, customer_labelKey name and a customer label (for example a nickname).
customer_idThe customer the key belongs to, or null.
tailLast characters of the key, for recognition.
statusactive, paused, expired, deleting
limit_usdTotal sold: spent plus remaining.
spent_usd, remaining_usdSpent and remaining.
expires_at, created_atExpiry and creation (UTC).
last_used_atAlways null for now.
concurrencyParallel request limit, stored with the key.
dashboard_urlA neutral dashboard link for your client. It is not the key secret.

Issue a key

POST /keys (scope keys; an Idempotency-Key header is required). Required: name and limit_usd; optional: expires_days (1..365, default 30) or expires_hours (1 to 8760, for example 1 for a one-hour key; not both), customer_id, customer_label, concurrency.

bash
curl -s -X POST https://app.oneprovider.dev/partner/v1/keys \
-H "Authorization: Bearer $OP_PARTNER_TOKEN" \
-H "Idempotency-Key: key-anna-001" \
-H "Content-Type: application/json" \
-d '{"name":"anna-main","limit_usd":"25.00","expires_days":30,"customer_label":"Anna"}'
# a one-hour key
curl -s -X POST https://app.oneprovider.dev/partner/v1/keys -H "Authorization: Bearer $OP_PARTNER_TOKEN" -H "Idempotency-Key: key-trial-001" -H "Content-Type: application/json" -d '{"name":"trial","limit_usd":"1.00","expires_hours":1}'

Several identical keys at once: POST /keys/bulk with count (1..50), name_prefix and the same limit_usd, expires_days/expires_hours. The keys are named {name_prefix}-1 … {name_prefix}-N. The whole sum count x limit_usd is checked first; if the call still stops half way, repeat it with the same Idempotency-Key: the keys already made come back again and the rest are issued.

json
{
"id": "<key id>",
"name": "anna-main",
"customer_label": "Anna",
"status": "active",
"limit_usd": "25.00",
"spent_usd": "0.00",
"remaining_usd": "25.00",
"expires_at": "2026-11-07T12:00:00Z",
"dashboard_url": "<dashboard link>",
"key": "sk-..."
}
The secret is shown once The key field exists only in the issue response (201). Hand it to your client and store it immediately: the secret cannot be retrieved later, so issue a new key if it is lost. No other response or webhook carries secrets.

The key limit is reserved on the reseller balance. If it does not fit into Free (available_usd), the answer is 409 insufficient_balance; a repeated name gives 409 name_taken, and reaching the key maximum gives 409 key_limit.

List and read

bash
# active keys of one customer
curl -s "https://app.oneprovider.dev/partner/v1/keys?status=active&customer_id=<customer id>&limit=50" \
-H "Authorization: Bearer $OP_PARTNER_TOKEN"
# one key (no secret) with dashboard_url
curl -s https://app.oneprovider.dev/partner/v1/keys/<key id> \
-H "Authorization: Bearer $OP_PARTNER_TOKEN"

Filters: status, query (search by name and label), customer_id. Daily usage at GET /keys/{id}/usage returns {"items": []} for now: daily usage is coming soon.

Edit, top up, pause

bash
# change the limit / expiry / name / label / concurrency
curl -s -X PATCH https://app.oneprovider.dev/partner/v1/keys/<key id> \
-H "Authorization: Bearer $OP_PARTNER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"limit_usd":"40.00"}'
# add 10.00 USD to the key limit
curl -s -X POST https://app.oneprovider.dev/partner/v1/keys/<key id>/topup \
-H "Authorization: Bearer $OP_PARTNER_TOKEN" \
-H "Idempotency-Key: topup-anna-001" \
-H "Content-Type: application/json" \
-d '{"amount_usd":"10.00"}'
# pause and resume
curl -s -X POST https://app.oneprovider.dev/partner/v1/keys/<key id>/pause -H "Authorization: Bearer $OP_PARTNER_TOKEN"
curl -s -X POST https://app.oneprovider.dev/partner/v1/keys/<key id>/resume -H "Authorization: Bearer $OP_PARTNER_TOKEN"

limit_usd in PATCH is the new total limit; it cannot go below what is already spent (400 limit_below_spent). An increase, like a new key, must fit into Free. Lowering the limit returns the unspent difference to Free at once. Pausing keeps the reserve.

Delete a key

bash
curl -s -X DELETE https://app.oneprovider.dev/partner/v1/keys/<key id> \
-H "Authorization: Bearer $OP_PARTNER_TOKEN"

The answer is 200 {"state":"deleted"} when the key is gone at once, or 202 {"state":"deleting"} while deletion is in progress. The unspent remainder of the limit returns to Free at once.

Rotate a key

POST /keys/{id}/rotate (scope keys; an Idempotency-Key header is required): a new secret for the same client, for example when the old one leaked. The old secret stops working immediately. The unspent remainder and the expiry move to the new key.

bash
curl -s -X POST https://app.oneprovider.dev/partner/v1/keys/<key id>/rotate \
-H "Authorization: Bearer $OP_PARTNER_TOKEN" \
-H "Idempotency-Key: rotate-anna-001"

This is a new key with a new id: the spent history stays with the old (now deleted) key. The 201 answer contains the key object, key (the new secret, shown once) and rotated_from (the id of the old key). Errors: 404 key_not_found, 409 key_limit, 503 provider_unavailable.

Customers

A customer is your buyer. Keys, orders and codes can be linked to one: your own identifier is stored in external_id (unique, up to 64 characters).

bash
curl -s -X POST https://app.oneprovider.dev/partner/v1/customers \
-H "Authorization: Bearer $OP_PARTNER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"external_id":"user-77","name":"Anna","note":"from the Telegram shop"}'
curl -s "https://app.oneprovider.dev/partner/v1/customers?external_id=user-77" \
-H "Authorization: Bearer $OP_PARTNER_TOKEN"

Customer object: id, external_id, name, note, blocked, keys_count, created_at. Edit name and note with PATCH /customers/{id}. A repeated external_id gives 409 customer_exists.

Block a customer

bash
curl -s -X PATCH https://app.oneprovider.dev/partner/v1/customers/<customer id> \
-H "Authorization: Bearer $OP_PARTNER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"blocked":true}'

Blocking (scope keys) pauses all live keys of the customer and marks them blocked: true. Issuing keys, orders and code redemptions for them answer 409 customer_blocked. Unblocking ({"blocked":false}) resumes only the keys the block paused: keys you paused yourself stay paused.

Last updated: 2026-10-21 Found a bug? @Oneproviderhelpbot