Overview
The Reseller API gives approved reseller accounts our live catalog at their reseller price and lets them buy from their prepaid balance. Every order is fulfilled automatically and its delivery details are returned through the API.
The API follows the Buyer API v2 contract, so AI Pro Control child panels and other Buyer API v2 software connect without custom code. All responses are JSON and every request must use HTTPS.
Authentication
Create a key in your panel under Reseller API. Keys start with rsk_ and are shown only once, so store yours on your server when you create it. You can revoke a key at any time and restrict it to your server IP addresses.
Send the key in one of these ways (the first one found is used):
Authorization: Bearer rsk_…— recommendedX-API-Key: rsk_…?key=rsk_…query parameter, or "key" in the JSON body (avoid: URLs end up in logs)
curl -s "https://solomaxhub.com/wp-json/reseller/v2/me" \
-H "Authorization: Bearer rsk_YOUR_KEY"
{
"success": true,
"account": { "id": 123, "name": "My Shop", "reseller": true,
"discountPercent": 20, "balance": 48.5, "currency": "USD" },
"key": { "prefix": "rsk_AbCdEf", "label": "My panel" },
"limits": { "requestsPerMinute": 120 },
"apiVersion": "2.0"
}
Rate limits
Each key may make 120 requests per minute. Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. Above the limit the API answers 429 RATE_LIMITED with a Retry-After header; wait that many seconds before trying again.
Poll the catalog every 30 to 60 seconds at most: stock and prices are refreshed about once a minute.
Safe retries
Send an Idempotency-Key header (1 to 100 characters: letters, digits and . _ : -) with every purchase, for example your own order number. Repeating the same request with the same key never buys twice; it returns the original order and its delivery once ready.
- Same key, same body: the same order (HTTP 200, "idempotentReplay": true).
- Same key, different product, quantity or customer_email: 422 IDEMPOTENCY_CONFLICT.
- Same key while the first request is still running: 409 REQUEST_IN_PROGRESS. Retry in a minute.
- A refused attempt (for example low balance) can be repeated with the same key after you fix the cause.
Keys are scoped to your reseller account, so one key per customer order is enough even if you run several shops.
Endpoints
| Method | Path | What it does |
|---|---|---|
| GET | /me | Account, discount, balance and key details |
| GET | /products | Full catalog at your reseller price, with live stock |
| GET | /products/{productId} | One product, including its full description |
| GET | /balance | Your prepaid balance |
| POST | /purchase | Buy a product from your balance |
| GET | /orders/{orderCode} | Status and delivery of one order |
| GET | /orders?limit=20&page=1 | Your order history (limit 1–100) |
/productsPrices are already your reseller price. Plans of one service are listed as separate products. availability.available is 0 when sold out; 999 means no fixed limit. When purchaseRequirements.customerEmail is true you must send customer_email (the end customer’s address, where invites are sent). quantityFixed: 1 means one unit per request.
{
"success": true,
"currency": "USD",
"count": 1,
"products": [
{
"productId": "svc_123",
"name": "ChatGPT Plus — 1 Month",
"description": "Private account with full access…",
"image": "https://solomaxhub.com/wp-content/uploads/chatgpt.png",
"category": "AI Tools",
"productType": "account",
"price": { "amount": 4.5, "currency": "USD", "text": "$4.50", "suggestedRetail": 5.5 },
"availability": { "available": 12, "inStock": true },
"purchaseRequirements": { "customerEmail": false, "minQuantity": 1, "maxQuantity": 20 }
}
]
}
/balance{ "success": true, "balance": 48.5, "currency": "USD", "balanceText": "$48.50" }
Top up in your panel: Add funds.
Buying
/purchase| Field | Required | Notes |
|---|---|---|
product_id | yes | productId from the catalog |
quantity | no | 1–20, default 1 |
customer_email | when required | Your customer’s email, for invite and slot products |
reference | no | Your own order reference (up to 100 characters), echoed back |
max_unit_price | no | Price protection: refuse with 409 PRICE_CHANGED if the price rose above this |
curl -s -X POST "https://solomaxhub.com/wp-json/reseller/v2/purchase" \
-H "Authorization: Bearer rsk_YOUR_KEY" \
-H "Idempotency-Key: order-1001" \
-H "Content-Type: application/json" \
-d '{"product_id":"svc_123","quantity":1,"reference":"order-1001"}'
{
"success": true,
"idempotentReplay": false,
"order": {
"orderCode": "R7K2M9QX4PZA",
"status": "completed",
"productId": "svc_123",
"quantity": 1,
"reference": "order-1001",
"createdAt": "2026-09-13T10:00:00+00:00",
"deliveredAt": "2026-09-13T10:00:04+00:00"
},
"payment": { "amount": 4.5, "currency": "USD", "unitPrice": 4.5, "refundedAmount": 0, "balanceAfter": 44.0 },
"delivery": { "items": [ { "Email": "[email protected]", "Password": "••••••••" } ] },
"deliveryText": "Email: [email protected]\nPassword: ••••••••"
}
Your balance is charged your reseller price multiplied by the quantity. Fulfilment starts immediately; most products are delivered in the same response.
Order status
processing | Paid and being prepared. No delivery yet. |
|---|---|
completed | Delivered. delivery and deliveryText are included. |
refunded | Could not be delivered; the amount went back to your balance. |
cancelled | Cancelled before delivery. |
While an order is processing, either poll GET /orders/{orderCode} or repeat the same purchase with the same Idempotency-Key. Back off between checks: 1 minute, 2, 5, 15, then hourly.
curl -s "https://solomaxhub.com/wp-json/reseller/v2/orders/R7K2M9QX4PZA" \
-H "Authorization: Bearer rsk_YOUR_KEY"
Delivery format
delivery.items holds one object per delivered unit. Labelled lines such as "Email: …" become fields; any other text is kept under Access or Note. deliveryText carries the same details as plain text, ready to show to your customer.
Delivery details are credentials. Show them only to the customer who bought them and never write them to public logs.
Errors
Every error has the same shape. Branch on error.code, show message to people.
{
"success": false,
"message": "Insufficient balance. You need $1.20 more. Top up, then retry with the same Idempotency-Key.",
"error": { "code": "INSUFFICIENT_BALANCE", "message": "…" },
"requestId": "req_…"
}
| HTTP | Code | Meaning |
|---|---|---|
| 401 | UNAUTHORIZED | Missing, invalid or revoked key. |
| 403 | FORBIDDEN | Account not approved or suspended, or IP not allowed for this key. |
| 403 | HTTPS_REQUIRED | The request was not made over HTTPS. |
| 402 | INSUFFICIENT_BALANCE | Balance too low. Top up and retry with the same Idempotency-Key. |
| 404 | NOT_FOUND | Unknown product or order. |
| 409 | OUT_OF_STOCK | Not enough stock right now. |
| 409 | PRICE_CHANGED | The price is above your max_unit_price. |
| 409 | PRICE_UPDATING | The product is paused while its price is updated. Nothing was charged. |
| 409 | REQUEST_IN_PROGRESS | The same Idempotency-Key is still running. Retry shortly. |
| 410 | ORDER_NOT_DELIVERED | That order could not be delivered and was refunded. |
| 422 | VALIDATION_ERROR | A field is invalid; the message names it. |
| 422 | EMAIL_REQUIRED | This product needs customer_email. |
| 422 | IDEMPOTENCY_CONFLICT | Idempotency-Key reused with a different body. |
| 429 | RATE_LIMITED | Too many requests. Wait for Retry-After. |
| 503 | TEMPORARILY_UNAVAILABLE | Stock or price could not be verified. Nothing was charged; retry later. |
| 503 | API_DISABLED | The API is switched off for maintenance. |
| 500 | SERVER_ERROR | Unexpected error. Repeat purchases with the same Idempotency-Key to learn their real state. |
Child panel setup
Running AI Pro Control on your own domain? Connect it in one minute:
- Open Control → API → + Add provider.
- Adapter: AI Pro reseller API (parent panel).
-
Base URL:
https://solomaxhub.com - Paste your rsk_ key, tick Enable, save, then press Test connection.
- Open API products and import the services you want to sell with your own prices.
Other Buyer API v2 software: use the base URL above with the paths /products, /balance and /purchase, and send the key as a Bearer token or X-API-Key header.
Best practices
- Keep keys on your server. Never put a key in a browser, mobile app or public repository.
- Use one key per shop or bot, restrict each key to your server IPs, and revoke keys you no longer use.
- Always send an Idempotency-Key with purchases and reuse it for retries of the same order.
- Check GET /balance before busy periods and top up early; low balance pauses orders.
- Cache the catalog for 30–60 seconds instead of requesting it for every visitor.