Reseller API
v1A REST API to sell and manage our Turkey-based VDS servers under your own brand.
Base URL: https://bihosting.com.tr/reseller-api/v1
All requests use HTTPS and all responses are JSON. No infrastructure provider branding appears on the servers or in API responses, so you can offer the service to your customers under your own brand.
Flow
- Apply on the Reseller API page in the client area. Once approved, create your API key on the same page.
- Add credit to your account from the client area.
- Get products and your prices with
GET /products. - Place an order with
POST /orders. The amount is deducted from your credit and the server is set up automatically (usually within a few minutes). - Poll
GET /services/{id}untilprovisioning: "ready", then get the login details from/credentials. - Manage the server with endpoints such as
/power,/reinstalland/password.
Authentication
Once your reseller application is approved, you create your API key yourself on the Reseller API page in your client area. The key starts with bhr_ and is shown only once, when it is created. Send it as a header with every request:
Authorization: Bearer bhr_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Do not put the key in client-side code (browser, mobile app); use it only from your own server. You can restrict the key to specific IPs on the same page (recommended); requests from other IPs are then rejected with 403 ip_not_allowed. If you think your key has leaked, revoke it on the same page right away and create a new one. You can have at most 5 active keys.
Requests and responses
POST request bodies are sent as JSON (Content-Type: application/json). Successful responses are returned in the data field:
{ "data": { ... } }
Amounts are in your account currency and include VAT. Dates use the YYYY-MM-DD format; metric timestamps are Unix seconds.
Errors
Errors return an HTTP status code and a stable code. Write your code against the code value, not the message text.
{ "error": { "code": "insufficient_credit", "message": "Insufficient account credit.", "required": 180.0, "credit": 50.0 } }
| HTTP | Codes | Meaning |
|---|---|---|
| 400 | invalid_json | The body is not a valid JSON object |
| 401 | unauthorized | Key missing, invalid or revoked |
| 402 | insufficient_credit | Not enough credit; see the required and credit fields |
| 403 | ip_not_allowed, account_inactive, reinstall_disabled | Access not allowed |
| 404 | not_found, product_not_found, service_not_found | Record does not exist or does not belong to you |
| 409 | out_of_stock, not_provisioned, service_not_active, service_busy, no_invoice_due, already_requested, idempotency_in_progress | The action is not possible in the current state |
| 422 | invalid_*, confirm_required, idempotency_key_required, idempotency_key_reused | Parameter error |
| 429 | rate_limited | Limit exceeded; retry after Retry-After seconds |
| 5xx | upstream_error, internal_error | Temporary error; try again shortly |
Idempotent requests
To avoid placing the same order twice after a network failure, the Idempotency-Key header is required on POST /orders and optional on other POST requests. Generate a unique value (e.g. a UUID) for each new operation and reuse the same value when retrying.
Idempotency-Key: 6f1c2a9e-4b7d-4e0a-9d3f-1a2b3c4d5e6f
- A repeated request with the same key is not processed again; the original response is returned as is, with the
Idempotent-Replayed: trueheader. - Keys are kept for 24 hours. Using the same key for a different request returns
422 idempotency_key_reused. - Temporary errors such as 429 and 5xx are not stored; you can safely retry with the same key.
Rate limits
| Limit | Value |
|---|---|
| All requests per key | 120 per minute |
| Write requests per key | 20 per minute |
| Power action (same server) | 1 per 20 seconds |
| Reinstall (same server) | 1 per 10 minutes |
| Password reset (same server) | 2 per 5 minutes |
Status and usage responses come from a short-lived cache. Instead of polling a server every second, we recommend polling every 15 to 30 seconds.
Credit and payment
- Reseller accounts are prepaid. Orders and renewals are paid from your account credit. If your credit is not enough, the request is rejected with
402 insufficient_creditand nothing is created. - Renewal invoices are generated 14 days before the due date. Three days before the due date the invoice is paid automatically from your credit; you can also pay it immediately with
POST /services/{id}/renew. - If your credit is low, we send you an email. Unpaid services may be suspended according to BiHosting's general terms.
- Track your credit and unpaid invoices with
GET /account.
Discount tiers
Your discount is set automatically by your number of active servers. When your tier changes, the new discount applies within an hour to new orders and to the renewal amounts of your existing servers.
| Active servers | Discount |
|---|---|
| 1 to 4 | 10% |
| 5 to 9 | 15% |
| 10 to 19 | 20% |
| 20 or more | 25% |
Your current tier and the next one are included in the GET /account response.
Account
/accountCredit, discount tier and unpaid invoices.
curl https://bihosting.com.tr/reseller-api/v1/account \
-H "Authorization: Bearer $BIHOSTING_KEY"
{
"data": {
"client_id": 123, "company": "Example Ltd", "currency": "USD",
"credit": 250.0, "unpaid_invoices": 0, "unpaid_total": 0.0,
"active_services": 6, "discount_percent": 15.0,
"next_tier": { "min_services": 10, "discount": 20.0 },
"tiers": [ { "min_services": 1, "discount_percent": 10.0 }, ... ]
}
}
Products
/productsVDS plans on sale and your prices. list is the list price, price is the price with your discount applied.
{
"data": [
{
"id": 64, "name": "TR 9950X VDS 1", "series": "TR 9950X VDS", "cpu_model": "Ryzen 9 9950X",
"specs": { "cores": 4, "ram_gb": 4, "disk_gb": 75 },
"in_stock": true, "currency": "USD",
"prices": { "monthly": { "list": 20.0, "price": 18.0 }, "annually": { "list": 200.0, "price": 180.0 } },
"os_reinstall": true
}
]
}
/products/{id}A single product; it also returns the operating systems you can choose when ordering, in the os_options field.
"os_options": [ { "id": 58, "name": "Ubuntu 24" }, { "id": 45, "name": "Windows 11 PRO" }, ... ]
Orders
/ordersIdempotency-Key required| Field | Type | Description |
|---|---|---|
product_id | int, required | id from GET /products |
billing_cycle | string | monthly (default), quarterly, semiannually, annually. Only cycles present in the product's prices field are valid. |
os_id | int | From os_options. If empty, Ubuntu 24 is installed. |
hostname | string | Server name, e.g. srv1.example.com |
curl -X POST https://bihosting.com.tr/reseller-api/v1/orders \
-H "Authorization: Bearer $BIHOSTING_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"product_id":64,"billing_cycle":"monthly","os_id":58,"hostname":"srv1.example.com"}'
201 Created
{
"data": {
"order_id": 1201, "invoice_id": 34800, "amount": 18.0, "currency": "USD", "credit_left": 232.0,
"service": { "id": 2801, "product": "TR 9950X VDS 1", "status": "pending", "provisioning": "queued", ... }
}
}
The order is paid immediately and setup is queued. Setup usually takes a few minutes; check GET /services/{id} every 30 to 60 seconds until provisioning is ready. When the server is ready, a notice is also sent to the email address on your account.
Services
/servicesAll your VDS services, newest first.
/services/{id}{
"data": {
"id": 2801, "product_id": 64, "product": "TR 9950X VDS 1",
"status": "active", "provisioning": "ready",
"hostname": "srv1.example.com", "ip": "203.0.113.10", "additional_ips": [],
"billing_cycle": "monthly", "recurring_amount": 18.0,
"registered_at": "2026-11-09", "next_due_date": "2026-12-09"
}
}
| Field | Values |
|---|---|
status | pending, active, suspended, terminated, cancelled |
provisioning | queued, provisioning (being set up), ready |
/services/{id}/credentialsServer IP, username and current administrator password.
{ "data": { "ip": "203.0.113.10", "username": "root", "password": "..." } }
Server management
These endpoints only work on active services whose setup is complete.
/services/{id}/statusLive state, resource usage and monthly traffic.
{
"data": {
"state": "running", "power": true, "os": "linux", "uptime_min": 17520,
"ip": "203.0.113.10", "additional_ips": [],
"usage": { "cpu_percent": 12.4, "ram_percent": 41.0, "ram_usage": 3.3, "ram_max": 8,
"disk_percent": 30.5, "disk_usage": 61, "disk_max": 200, "net_mbps": 2.1 },
"usage_available": true,
"traffic": { "ready": true, "percent": 9, "used_tb": 0.9, "limit_tb": 10, "period_end": "2026-12-01", "is_limited": false },
"operation": null, "stale": false
}
}
If operation is set, an operation such as an install or restore is running on the server. stale: true means live data could not be fetched and the last known state is shown.
/services/{id}/metrics?range=24hrange: 24h (5-minute points), 7d or 30d (hourly averages).
{ "data": { "range": "24h", "timestamps": [1794200000, ...], "cpu_percent": [...], "ram_percent": [...], "net_mbps": [...] } }
/services/{id}/power{ "action": "restart" } // start | stop | restart
202 Accepted: { "data": { "accepted": true, "action": "restart" } }
/services/{id}/os-templatesOperating systems available for reinstall: [ { "id": 36, "name": "Alma 10" }, ... ]
/services/{id}/reinstall"confirm": true in the request.{ "os_id": 36, "confirm": true }
202 Accepted: { "data": { "accepted": true, "os": "Alma 10", "password": "new-password" } }. The install takes a few minutes; follow its progress in the operation field of /status.
/services/{id}/passwordReplaces the administrator (root / Administrator) password with a new strong one. Send { "confirm": true }. Response: { "data": { "password": "..." } }
Renewal and cancellation
/services/{id}/renewPays the service's unpaid renewal invoice from your credit right away. If no invoice has been generated yet, it returns 409 no_invoice_due with the next_due_date.
{ "data": { "invoice_id": 34900, "amount": 18.0, "credit_left": 214.0, "service": { ... } } }
/services/{id}/cancel{ "type": "end_of_period", "reason": "Customer left" } // end_of_period | immediate
end_of_period closes the service at the end of the paid period, immediate as soon as possible. Unused time is not refunded.
Terms of use
- You are responsible for the services you sell and how your customers use them. Spam, attacks, unauthorized scanning and illegal content are prohibited.
- When an abuse complaint is received for an IP, you are notified by email and given time to respond. If it is not resolved within that time, the IP may be blocked.
- In serious cases affecting the infrastructure or other customers (being a DDoS source, heavy spam, etc.) the server may be shut down without prior notice; you are informed at the same time.
- We recommend applying the same rules to your customers.
Questions: open a support ticket