Reseller API
Run bulk phone-number scans programmatically. Submit a number list with a service and a country, we validate and price it against your prepaid wallet, run it, and hand back a downloadable result file — all through a single API-key header. No OAuth, no sessions, no cookies.
Base URL
Every path below is relative to the production base URL. Paths have no trailing slash.
https://api.p-syke.com/api/reseller
What you can do
Authentication
Authenticate psyke Reseller API requests with the X-Reseller-API-Key header. How to create, rotate and revoke keys, and the exact 401 behavior.
API reference
Full endpoint reference for the psyke Reseller API: every method, path, request field, response schema, example, and the errors each endpoint can return.
Errors
Complete error reference for the psyke Reseller API — every error code, its HTTP status, meaning and how to fix it, plus the two error-object shapes.
Rate limits & billing
Rate limits, prepaid wallet balance, per-number token pricing, and the 2000-number and 20 MB limits of the psyke Reseller API.
Services catalog
The 11 services available through the psyke Reseller API — service code, platform and per-number USD price.
OpenAPI spec
Machine-readable OpenAPI 3 specification for the psyke Reseller API — download the JSON and generate SDKs, mocks and Postman collections.
Quickstart — submit, poll, download
- Get an API key. Sign in to the psyke app → API access and create a key. The plaintext key (
rsl_live_…) is shown once — copy it immediately. - Submit an order.
POST /orderswith aservice_code, acountry, and afileof ≥ 2,000 numbers (multipart). You are charged at submit time and get back anorder_id. - Poll status.
GET /orders/{order_id}every 30–60 seconds untilstatusiscompleted(orfailed). - Download the result.
GET /orders/{order_id}/resultreturns the finished CSV/TSV file.
A complete, runnable end-to-end example in three languages (set KEY to your real key and numbers.txt to your list):
export BASE="https://api.p-syke.com/api/reseller"
export KEY="rsl_live_xxxxxxxxxxxxxxxx"
# 1. Submit (multipart). numbers.txt = one number per line, ≥ 2000 valid.
ORDER_ID=$(curl -s -X POST "$BASE/orders" \
-H "X-Reseller-API-Key: $KEY" \
-H "Idempotency-Key: order-2026-07-17-001" \
-F "service_code=tg-active" \
-F "country=US" \
-F "[email protected]" \
| python3 -c 'import sys,json;print(json.load(sys.stdin)["order_id"])')
echo "order $ORDER_ID"
# 2. Poll every 45s until completed (or failed).
while :; do
status=$(curl -s "$BASE/orders/$ORDER_ID" -H "X-Reseller-API-Key: $KEY" \
| python3 -c 'import sys,json;print(json.load(sys.stdin)["status"])')
echo "status=$status"
[ "$status" = "completed" ] && break
[ "$status" = "failed" ] && { echo "order failed"; exit 1; }
sleep 45
done
# 3. Download the result file (CSV or TSV; -OJ honors the server filename).
curl -s "$BASE/orders/$ORDER_ID/result" -H "X-Reseller-API-Key: $KEY" -OJimport time
import requests
BASE = "https://api.p-syke.com/api/reseller"
KEY = "rsl_live_xxxxxxxxxxxxxxxx"
headers = {"X-Reseller-API-Key": KEY}
# 1. Submit
with open("numbers.txt", "rb") as fh:
resp = requests.post(
f"{BASE}/orders",
headers={**headers, "Idempotency-Key": "order-2026-07-17-001"},
data={"service_code": "tg-active", "country": "US"},
files={"file": fh},
)
resp.raise_for_status()
order = resp.json()
order_id = order["order_id"]
print("submitted", order_id, "cost", order["cost"])
# 2. Poll
while True:
r = requests.get(f"{BASE}/orders/{order_id}", headers=headers)
r.raise_for_status()
status = r.json()["status"]
print("status", status)
if status == "completed":
break
if status == "failed":
raise SystemExit("order failed: " + r.json()["failure_message"])
time.sleep(45)
# 3. Download
res = requests.get(f"{BASE}/orders/{order_id}/result", headers=headers)
res.raise_for_status()
with open(f"{order_id}_result.csv", "wb") as out:
out.write(res.content)
print("saved", f"{order_id}_result.csv")import { readFile, writeFile } from "node:fs/promises";
import { setTimeout as sleep } from "node:timers/promises";
const BASE = "https://api.p-syke.com/api/reseller";
const KEY = "rsl_live_xxxxxxxxxxxxxxxx";
const headers = { "X-Reseller-API-Key": KEY };
// 1. Submit (Node 18+ has global fetch, FormData and Blob)
const form = new FormData();
form.set("service_code", "tg-active");
form.set("country", "US");
form.set("file", new Blob([await readFile("numbers.txt")]), "numbers.txt");
const submit = await fetch(`${BASE}/orders`, {
method: "POST",
headers: { ...headers, "Idempotency-Key": "order-2026-07-17-001" },
body: form,
});
if (!submit.ok) throw new Error(`submit failed: ${submit.status}`);
const order = await submit.json();
const orderId = order.order_id;
console.log("submitted", orderId, "cost", order.cost);
// 2. Poll
for (;;) {
const r = await fetch(`${BASE}/orders/${orderId}`, { headers });
if (!r.ok) throw new Error(`poll failed: ${r.status}`);
const { status, failure_message } = await r.json();
console.log("status", status);
if (status === "completed") break;
if (status === "failed") throw new Error(`order failed: ${failure_message}`);
await sleep(45_000);
}
// 3. Download
const res = await fetch(`${BASE}/orders/${orderId}/result`, { headers });
if (!res.ok) throw new Error(`download failed: ${res.status}`);
await writeFile(`${orderId}_result.csv`, Buffer.from(await res.arrayBuffer()));
console.log("saved", `${orderId}_result.csv`);Order status lifecycle
- queued
- running
- completed
- failed
The five status values are draft, queued, running, completed, failed. A completed order has a downloadable result; a failed order carries a customer-safe failure_message and is auto-refunded. Poll GET /orders/{order_id} — do not loop on the /result endpoint (it returns 409 NOT_READY until completion).
Endpoints at a glance
| Method | Path | Purpose |
|---|---|---|
| GET | /api/reseller/services | List services |
| GET | /api/reseller/countries | List countries |
| GET | /api/reseller/balance | Get wallet balance |
| POST | /api/reseller/orders | Submit an order |
| GET | /api/reseller/orders/{order_id} | Poll order status |
| GET | /api/reseller/orders/{order_id}/result | Download result |