Place order
Submits a new order using the familiar reseller-panel shape. Legacy clients may omit idempotency fields; identical requests from the same account are then mapped to the same order for 60 seconds. For exact caller-controlled retries, reuse the same optional request_id, or idempotency_key alias, to return the committed order and charge without another debit. If both are supplied, request_id wins. An ordinary API order is held for 15 seconds before dispatch so it can be cancelled during that grace window.
POST
https://notpanel.com/api/v3action=addAPI key requiredRate limited (shared account + IP + action)Body:
application/x-www-form-urlencodedrequest_id and idempotency_key are optional. Without either, the same account and exact payload receive 60-second duplicate protection; this also means an intentional identical order inside that window returns the first order. Wait 60 seconds or send a unique request_id to place an intentional duplicate immediately. On a retryable response, honor Retry-After when present and then reuse the same idempotency key. Explicit keys remain the strongest retry contract and request_id wins when both aliases are sent.
Parameters
| Name | Type | Description |
|---|---|---|
| keyRequired | string | Your API key. |
| actionRequired | string | Must be the literal string "add". |
| serviceRequired | integer | Service ID from the services list. Service must be active at submission time. |
| request_id | string | Optional preferred caller-supplied opaque idempotency key, unique per logical order and at most 128 characters. Reuse it for exact retries. If request_id and idempotency_key are both supplied, request_id wins. |
| idempotency_key | string | Optional compatibility alias for request_id. If both fields are absent, the server provides 60-second identical-payload duplicate protection. If both aliases are present, request_id wins. |
| linkConditional | string (URL) | Target URL — profile, post, video, or channel. Required when the selected service asks for a link. Up to 1000 characters; must be http(s). |
| quantityConditional | integer | Number of units to deliver, within the service minimum and maximum. |
| runsConditional | integer | Required together with interval only when dripfeed=true. Use a positive integer within the effective configured cap returned by validation; the absolute ceiling is 1000. quantity × runs cannot exceed the service maximum. |
| intervalConditional | integer | Required together with runs only when dripfeed=true. Use a positive whole number of minutes within the effective configured cap returned by validation; the absolute ceiling is 2880 minutes. Non-drip services reject both fields. Drip-feed schedule: maximum 48 hours (runs × interval). |
| coupon | string | Coupon code to apply, subject to the coupon per-user, global, and service constraints. |
| delay | integer | Optional start delay. Use an integer from 1 to 86400 seconds when the selected service supports this field. |
| lpost_count | integer | Optional last-post count for compatible ordinary services. Use an integer from 1 to 500, unless the service defines this as its own canonical field. |
| reactions | string (map) | Optional emoji map for compatible ordinary services. Send JSON or the supported PHP-style single-quote form, with at most 50 emoji keys. Values must be all R for random allocation or all positive integers up to 1000000; never mix modes. For exact counts, their sum becomes the effective quantity and determines the committed charge. |
Example request
Replace YOUR_API_KEY with the key generated under your dashboard’s API page.
curl -X POST https://notpanel.com/api/v3 \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "key=YOUR_API_KEY&action=add&service=1&request_id=550e8400-e29b-41d4-a716-446655440000&link=https://instagram.com/example&quantity=1000"const res = await fetch("https://notpanel.com/api/v3", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
key: "YOUR_API_KEY",
action: "add",
service: "1",
request_id: "550e8400-e29b-41d4-a716-446655440000",
link: "https://instagram.com/example",
quantity: "1000",
}),
});
const data = await res.json();
console.log(data);import requests
res = requests.post(
"https://notpanel.com/api/v3",
data={
"key": "YOUR_API_KEY",
"action": "add",
"service": "1",
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"link": "https://instagram.com/example",
"quantity": "1000",
},
)
print(res.json())<?php
$body = http_build_query([
'key' => 'YOUR_API_KEY',
'action' => 'add',
'service' => '1',
'request_id' => '550e8400-e29b-41d4-a716-446655440000',
'link' => 'https://instagram.com/example',
'quantity' => '1000',
]);
$response = file_get_contents('https://notpanel.com/api/v3', false, stream_context_create([
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
'content' => $body,
'ignore_errors' => true,
],
]));
print_r(json_decode($response, true));
Example response
{
"order": 7001,
"status": "Pending",
"status_key": "pending",
"charge": "0.50",
"currency": "USD",
"cancel_available": true,
"cancel_window_seconds": 15,
"cancel_before": "2026-08-25T10:30:15.000Z"
}Common errors
| Status | Body | Cause |
|---|---|---|
| 400 | {"error":"Service not found"} | The service ID does not exist. Re-fetch the services list and use a current ID. |
| 400 | {"error":"Service has been discontinued and is no longer available"} | The service exists but is disabled, archived, or no longer orderable. Refresh the catalog and choose an available service. |
| 400 | {"error":"Insufficient balance"} | Account balance is below the order's total charge. Top up via the dashboard. |
| 400 | {"error":"Quantity must be a positive integer"} | Quantity was zero, negative, or non-integer. Validate before submission. |
| 409 | {"error":"request_id was already used with different parameters"} | The request conflicts with existing state, such as reusing an add request_id for a different logical order. Use the original request or a new unique identifier as appropriate. |