Reseller API

v1

A 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.

Become a reseller / create an API key

Flow

  1. Apply on the Reseller API page in the client area. Once approved, create your API key on the same page.
  2. Add credit to your account from the client area.
  3. Get products and your prices with GET /products.
  4. 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).
  5. Poll GET /services/{id} until provisioning: "ready", then get the login details from /credentials.
  6. Manage the server with endpoints such as /power, /reinstall and /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 } }
HTTPCodesMeaning
400invalid_jsonThe body is not a valid JSON object
401unauthorizedKey missing, invalid or revoked
402insufficient_creditNot enough credit; see the required and credit fields
403ip_not_allowed, account_inactive, reinstall_disabledAccess not allowed
404not_found, product_not_found, service_not_foundRecord does not exist or does not belong to you
409out_of_stock, not_provisioned, service_not_active, service_busy, no_invoice_due, already_requested, idempotency_in_progressThe action is not possible in the current state
422invalid_*, confirm_required, idempotency_key_required, idempotency_key_reusedParameter error
429rate_limitedLimit exceeded; retry after Retry-After seconds
5xxupstream_error, internal_errorTemporary 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: true header.
  • 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

LimitValue
All requests per key120 per minute
Write requests per key20 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_credit and 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 serversDiscount
1 to 410%
5 to 915%
10 to 1920%
20 or more25%

Your current tier and the next one are included in the GET /account response.

Account

GET/account

Credit, 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

GET/products

VDS 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
    }
  ]
}
GET/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

POST/ordersIdempotency-Key required
FieldTypeDescription
product_idint, requiredid from GET /products
billing_cyclestringmonthly (default), quarterly, semiannually, annually. Only cycles present in the product's prices field are valid.
os_idintFrom os_options. If empty, Ubuntu 24 is installed.
hostnamestringServer 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

GET/services

All your VDS services, newest first.

GET/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"
  }
}
FieldValues
statuspending, active, suspended, terminated, cancelled
provisioningqueued, provisioning (being set up), ready
GET/services/{id}/credentials

Server 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.

GET/services/{id}/status

Live 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.

GET/services/{id}/metrics?range=24h

range: 24h (5-minute points), 7d or 30d (hourly averages).

{ "data": { "range": "24h", "timestamps": [1794200000, ...], "cpu_percent": [...], "ram_percent": [...], "net_mbps": [...] } }
POST/services/{id}/power
{ "action": "restart" }   // start | stop | restart

202 Accepted: { "data": { "accepted": true, "action": "restart" } }

GET/services/{id}/os-templates

Operating systems available for reinstall: [ { "id": 36, "name": "Alma 10" }, ... ]

POST/services/{id}/reinstall
All data on the server is permanently deleted. You must send "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.

POST/services/{id}/password

Replaces the administrator (root / Administrator) password with a new strong one. Send { "confirm": true }. Response: { "data": { "password": "..." } }

Renewal and cancellation

POST/services/{id}/renew

Pays 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": { ... } } }
POST/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

We couldn't find that page

Please try navigating using the options below.

Homepage