API Docs
Place and track service orders from your own site or tools. The API is for approved resellers; create a key in Reseller & API. Orders are paid from your wallet at your reseller prices.
Basics
Base URL: https://polido1.com/api/v1
Authenticate every request with your key: Authorization: Bearer nxk_…
Requests and responses are JSON. Prices are in USD. Limits: 120 requests a minute and 30 orders a minute per key.
Every response carries an X-Request-Id header; quote it if you contact support. You can lock a key to your server’s IP addresses and make a key read-only in your dashboard. A machine-readable description is at /api/v1/openapi.json (import it into Postman or Swagger).
curl https://polido1.com/api/v1/account \ -H "Authorization: Bearer YOUR_KEY"
Endpoints
/accountYour wallet balance — what orders are paid from.
{ "email": "you@shop.com", "group": "Silver", "balance": 84.5,
"credit_limit": 0, "available": 84.5, "currency": "USD" }/services?limit=100&cursor=&category=imei&q=samsungActive services with your price, the normal price, and the fields an order needs. Paginated: pass the returned next_cursor to get the next page.
{ "services": [{
"slug": "samsung-imei-unlock", "name": "Samsung IMEI Unlock", "category": "imei",
"price": 8.0, "retail_price": 10.0, "currency": "USD", "delivery": "1-6 Hours",
"description": "…",
"fields": [{ "key": "imei", "label": "IMEI", "type": "imei", "required": true }]
}], "next_cursor": null }Field types: text, number, email, select (with options), imei. Some fields carry a pattern the value must match. GET /services/{slug} returns one service.
/ordersPlace an order. Send the fields the service asks for. Add an Idempotency-Key so a retry can never charge twice.
curl -X POST https://polido1.com/api/v1/orders \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-1001" \
-d '{ "service_slug": "samsung-imei-unlock",
"fields": { "imei": "490154203237518" },
"reference": "my-order-1001" }'201 Created
{ "order": { "number": "NX-AB12CD34", "status": "pending", "total": 8.0, "currency": "USD",
"reference": "my-order-1001", "created_at": "2026-09-24T10:00:00.000Z", "updated_at": "…",
"items": [{ "service": "samsung-imei-unlock", "name": "Samsung IMEI Unlock",
"quantity": 1, "price": 8.0, "fields": { "imei": "490154203237518" }, "result": null }] } }Repeating a request with the same Idempotency-Key returns the original order (status 200, idempotent_replay: true) and does not charge again. Keys are up to 64 characters. reference is your own id for the order (up to 64 characters); it is returned everywhere and you can filter by it. Some services are one device per order; send one order per IMEI, or use the bulk endpoint.
/orders/bulkUp to 50 devices for one service in a single call. Each item becomes its own order.
curl -X POST https://polido1.com/api/v1/orders/bulk -H "Authorization: Bearer YOUR_KEY" -H "Content-Type: application/json" -H "Idempotency-Key: batch-77" -d '{ "service_slug": "samsung-imei-unlock",
"items": [ { "fields": { "imei": "490154203237518" }, "reference": "a1" },
{ "fields": { "imei": "356938035643809" }, "reference": "a2" } ] }'207 Multi-Status (201 if every item was created)
{ "summary": { "total": 2, "created": 1, "failed": 1 },
"results": [ { "index": 0, "status": "created", "order": { "number": "NX-…", … } },
{ "index": 1, "status": "failed", "error": { "code": "validation_failed", "message": "…" } } ] }Items are processed in order. If your wallet can’t cover one, that item and the rest are reported as insufficient_funds without being attempted. The Idempotency-Key replays the whole response.
/orders/{number}Status and result of one of your orders.
Poll this until status is completed; the unlock code or note is in items[].result.
/orders?limit=20&status=completed&reference=my-order-1001&cursor=Your orders, newest first (limit up to 100). Filter by status or your own reference; use next_cursor to page.
Order statuses
pending (waiting to be processed) · processing · completed · rejected and cancelled (your wallet is refunded automatically).
Webhooks
Instead of polling, set an https URL in Reseller & API and we’ll POST an event whenever an order you placed through the API changes status: order.processing, order.completed, order.rejected, order.cancelled. The URL must be publicly reachable (private and internal addresses are refused) and redirects are not followed.
POST https://your-server.com/webhooks/orders
Content-Type: application/json
X-Event-Id: cm9x… (unique per event; use it to ignore duplicates)
X-Event-Type: order.completed
X-Timestamp: 1767225600 (unix seconds)
X-Signature: sha256=3f6c… (HMAC-SHA256 of "<timestamp>.<raw body>" with your secret)
{ "id": "cm9x…", "type": "order.completed", "created_at": "…",
"data": { "order": { "number": "NX-…", "status": "completed", "reference": "my-order-1001", … } } }Verify every request before trusting it, using the raw request body (not re-serialised JSON), and reject old timestamps:
// Node.js
import { createHmac, timingSafeEqual } from "node:crypto";
function verify(secret, headers, rawBody) {
const ts = headers["x-timestamp"];
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false; // older than 5 minutes
const expected = "sha256=" + createHmac("sha256", secret).update(ts + "." + rawBody).digest("hex");
const given = headers["x-signature"] || "";
return given.length === expected.length && timingSafeEqual(Buffer.from(given), Buffer.from(expected));
}Reply with any 2xx within 8 seconds. Otherwise we retry after 1 minute, 5 minutes, 30 minutes, 2 hours and 12 hours, then give up (you can always read the order with GET /orders/{number}). Events can arrive more than once or out of order — treat them as a nudge to read the current status. Use “Send test event” in your dashboard to check your setup.
Errors
Errors are always { "error": { "code": "…", "message": "…" } }.
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_json / invalid_request | The request body is malformed or a value is out of range. |
| 401 | unauthorized / invalid_key | Missing, wrong or revoked API key. |
| 402 | insufficient_funds | Your wallet can't cover the order. Top up and retry. |
| 403 | not_a_reseller | The account is suspended or no longer a reseller. |
| 403 | program_paused | The reseller program is paused. Try again later. |
| 403 | ip_not_allowed | The key is locked to other IP addresses. |
| 403 | read_only_key | A read-only key can't place orders. |
| 404 | not_found | No such service or order (or it isn't yours). |
| 207 | (bulk) | Some items were created and some failed; read results[]. |
| 422 | validation_failed | A field is missing or invalid, the IMEI is blacklisted, or the service can't be ordered. |
| 500 | server_error | Our side. Check GET /orders before retrying, and quote the X-Request-Id. |
| 503 | maintenance | New orders are paused for maintenance. Reads still work; retry shortly. |
| 429 | rate_limited | Too many requests. Wait for the Retry-After seconds. |