Reseller API — Ordering Services
Four product lines can be ordered for a customer: CDN, Cloud VPS, shared hosting and mailbox seats. Every order debits your credit balance immediately at your wholesale price.
Idempotency is required
All four ordering endpoints require an Idempotency-Key header. Send a unique value — a UUID is ideal — for each order attempt, and reuse the same value when retrying.
Idempotency-Key: 3f8a2c14-9d4e-4b71-a0c2-5e6f8b1d2a33
This is what stops a network timeout from provisioning and charging twice:
- Same key, same body, already completed → the original response is replayed with an
Idempotency-Replayed: trueheader. Nothing is charged again. - Same key, same body, still running →
409. Retry in a moment. - Same key, different body →
422. Use a fresh key for a new order. - No key at all →
400.
If the request fails with a 5xx, the key is released so a genuine retry re-runs the order.
Check your balance first
Ordering beyond your balance returns 402 and provisions nothing:
{
"message": "Insufficient credit. This service costs $15.00 but your balance is $4.20. Top up and try again.",
"required": 15.00,
"credit_balance": 4.20,
"shortfall": 10.80
}
Order a CDN service
curl -X POST "https://cdnshark.com/api/reseller/services" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"customer_id": 4210,
"plan_id": 3,
"domain_name": "cdn.example.com"
}'
Returns 201 with the order, the created service, the amount charged and your new balance.
Order a Cloud VPS
POST /api/reseller/vps
{
"customer_id": 4210,
"plan_id": 11,
"region_id": 2,
"os_key": "ubuntu-24.04",
"hostname": "web01.example.com",
"billing_cycle": "monthly",
"ssh_pubkey": "ssh-ed25519 AAAA..."
}
billing_cycle is one of monthly, quarterly, yearly or 2year; longer cycles carry a discount, quoted per cycle on the plan endpoint. Supply either ssh_pubkey or password.
VPS builds are asynchronous. The order is charged straight away; the instance appears with status pending and becomes running when Proxmox finishes. Subscribe to the reseller.service.active webhook rather than polling.
Order shared hosting
POST /api/reseller/hosting
{
"customer_id": 4210,
"plan_id": 7,
"primary_domain": "example.com",
"username": "examplecom"
}
The primary_domain must already be an active CDN domain owned by the same customer — hosting sits behind the CDN, so order the CDN service first. username is 3–32 characters, lowercase letters and digits, starting with a letter, and unique platform-wide.
Order mailbox seats
POST /api/reseller/mail
{"customer_id": 4210, "plan_id": 9, "quantity": 5}
This buys a quantity of seats. Your customer then creates the individual mailboxes from their own portal.
Suspend and reactivate a service
POST /api/reseller/services/{id}/suspend
POST /api/reseller/services/{id}/unsuspend
POST /api/reseller/vps/{id}/suspend
POST /api/reseller/vps/{id}/unsuspend
POST /api/reseller/hosting/{id}/suspend
POST /api/reseller/hosting/{id}/unsuspend
Unlike suspending a customer, this genuinely stops the service: CDN delivery is cut, a VPS is powered off, a hosting account is disabled. Suspension does not refund credit.
Check what a product is available
Product lines can be switched off platform-wide. Before showing a product in your storefront, check:
GET /api/reseller/products
Ordering a product that is switched off returns 403.