Authentication and transport
Send the token in Authorization: Bearer YOUR_CONNECTOR_TOKEN. Never place it in the URL, response, or application logs.
Production URLs must use HTTPS with a valid certificate and resolve only to public IP addresses. Redirects, URL credentials, and fragments are rejected.
| Name | Type | Required | Description |
|---|---|---|---|
| Authorization | header | Yes | Bearer token entered in the Custom SMM site settings. |
| Accept | header | Yes | application/json |
| Content-Type | header | No | application/json on POST requests. |
| X-Request-Id | header | No | PANEL ASSIST sends a unique value for tracing. The connector may ignore it and does not need to return it. |
Response contract
Every response must use JSON. Success requires an HTTP 2xx status, success: true, and a data object. Errors require a non-2xx status and the error envelope below.
{
"success": false,
"error": {
"message": "ticket_id must be a positive integer"
}
}| HTTP status | Meaning | Use when |
|---|---|---|
| 400 | Bad Request | Malformed query or JSON. |
| 401 | Unauthorized | Missing or invalid bearer token. |
| 403 | Forbidden | Authenticated but not allowed. |
| 404 | Not Found | Requested ticket or order does not exist. |
| 405 | Method Not Allowed | Wrong HTTP method for the action. |
| 422 | Validation Error | Required fields are missing or invalid. |
| 429 | Too Many Requests | Temporary rate limit. |
| 500/503 | Server Error | Temporary connector failure. |
GET requests may be attempted up to three times after connection failures, HTTP 429, or HTTP 5xx. POST requests are sent once and are not retried automatically.
Pagination
tickets.list, orders.list, and users.list use offset pagination. tickets.get uses the same structure for messages. The pagination object may be omitted for a single page.
"pagination": {
"offset": 0,
"limit": 100,
"total": 245,
"has_more": true,
"next_offset": 100
}- • has_more and next_offset control page traversal. offset, limit, and total are informational.
- • If has_more is true, next_offset must be greater than the requested offset and the page must contain at least one item.
- • If has_more is false, next_offset may be null.
- • Never repeat the same page. PANEL ASSIST stops after 20 pages as a safety limit.
Operations
Required actions
health
Verify the connector version and supported operations.
Request
curl -sS "https://panel.example.com/connector.php?action=health" \
-H "Accept: application/json" \
-H "Authorization: Bearer YOUR_CONNECTOR_TOKEN"Success response
{
"success": true,
"data": {
"version": "1.1",
"capabilities": [
"tickets.list", "tickets.get", "tickets.reply", "tickets.create",
"orders.list", "orders.get", "users.list", "users.find",
"orders.cancel_refund"
]
}
}- • data.version must be a non-empty string.
- • The original eight capabilities remain required.
- • orders.cancel_refund is optional. Advertise it only after implementing the documented atomic cancel-and-refund operation.
tickets.list
Return ticket IDs that should be checked for new customer messages.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| offset | integer | No | Zero-based item offset. Default: 0. |
| limit | integer | No | Items requested per page. Supported range: 1 to 100. |
Request
curl -sS "https://panel.example.com/connector.php?action=tickets.list&offset=0&limit=100" \
-H "Accept: application/json" \
-H "Authorization: Bearer YOUR_CONNECTOR_TOKEN"Success response
{
"success": true,
"data": {
"list": [
{ "id": 4831 },
{ "id": 4829 }
],
"pagination": {
"offset": 0,
"limit": 100,
"total": 2,
"has_more": false,
"next_offset": null
}
}
}- • Each id must be a stable positive integer.
- • Return recently updated open tickets first so new messages are discovered promptly.
tickets.get
Return one ticket and a page of its messages.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| ticket_id | integer | Yes | Stable positive ticket ID. |
| offset | integer | No | Zero-based item offset. Default: 0. |
| limit | integer | No | Items requested per page. Supported range: 1 to 100. |
Request
curl -sS "https://panel.example.com/connector.php?action=tickets.get&ticket_id=4831&offset=0&limit=100" \
-H "Accept: application/json" \
-H "Authorization: Bearer YOUR_CONNECTOR_TOKEN"Success response
{
"success": true,
"data": {
"id": 4831,
"subject": "Order Support",
"status": "pending",
"user": {
"id": 72,
"username": "customer1"
},
"messages": [
{
"id": "msg-901",
"message": "speedup 15020",
"sender_name": "customer1",
"is_staff": false,
"created_timestamp": 1786452600
}
],
"pagination": {
"offset": 0,
"limit": 100,
"total": 1,
"has_more": false,
"next_offset": null
}
}
}- • subject is required because PANEL ASSIST applies its configured ticket-category rules to it.
- • Use status "closed" for a closed ticket. Closed tickets stop being polled after the closing state is observed.
- • Message IDs must remain stable. They only need to be unique inside their ticket.
- • is_staff must be true for staff replies and false for customer messages. Staff messages are never automated.
- • created_timestamp is a Unix timestamp in seconds. Messages are processed oldest first.
tickets.reply
Add a staff reply to an existing ticket.
JSON body
| Name | Type | Required | Description |
|---|---|---|---|
| ticket_id | integer | Yes | Stable positive ticket ID. |
| message | string | Yes | Non-empty reply body. HTML line breaks may be preserved. |
| staff_name | string | No | Staff display name when available. |
Request
curl -sS -X POST "https://panel.example.com/connector.php?action=tickets.reply" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_CONNECTOR_TOKEN" \
--data '{"ticket_id":4831,"message":"Your request was received.","staff_name":"PANEL ASSIST Bot"}'Success response
{
"success": true,
"data": {}
}- • Create exactly one staff message for the supplied ticket.
- • PANEL ASSIST does not retry this POST automatically.
tickets.create
Create a ticket for an exact panel username.
JSON body
| Name | Type | Required | Description |
|---|---|---|---|
| username | string | Yes | Exact panel username. |
| subject | string | Yes | Non-empty ticket subject. |
| message | string | Yes | Non-empty initial message. |
| staff_name | string | No | Staff display name when available. |
Request
curl -sS -X POST "https://panel.example.com/connector.php?action=tickets.create" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_CONNECTOR_TOKEN" \
--data '{"username":"customer1","subject":"Verification code","message":"Your code is 193204"}'Success response
{
"success": true,
"data": {}
}- • Create exactly one ticket for the exact username.
- • PANEL ASSIST does not retry this POST automatically.
orders.list
Return a paginated order list for connection and schema checks.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| offset | integer | No | Zero-based item offset. Default: 0. |
| limit | integer | No | Items requested per page. Supported range: 1 to 100. |
Request
curl -sS "https://panel.example.com/connector.php?action=orders.list&offset=0&limit=100" \
-H "Accept: application/json" \
-H "Authorization: Bearer YOUR_CONNECTOR_TOKEN"Success response
{
"success": true,
"data": {
"list": [{ "id": 15020, "status": "processing", "user": { "id": 72, "username": "customer1" } }],
"pagination": { "offset": 0, "limit": 100, "total": 1, "has_more": false, "next_offset": null }
}
}orders.get
Return the order fields used by ownership, status, mode, provider, refill, and cancellation checks.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| order_id | integer | Yes | Stable positive local order ID. |
Request
curl -sS "https://panel.example.com/connector.php?action=orders.get&order_id=15020" \
-H "Accept: application/json" \
-H "Authorization: Bearer YOUR_CONNECTOR_TOKEN"Success response
{
"success": true,
"data": {
"id": 15020,
"user": { "id": 72, "username": "customer1" },
"status": "processing",
"mode": "auto",
"external_id": "PX-88219",
"provider": { "url": "https://provider.example" },
"service_name": "Instagram Followers | Refill 30 Days",
"created_timestamp": 1783861200,
"actions": {
"refill": false,
"cancel_and_refund": false
},
"refill_expired": false
}
}- • Supported status values used by automation are pending, processing, in_progress, completed, partial, canceled, cancelled, and refunded.
- • mode must be manual or auto when orders.cancel_refund is supported.
- • For a manual order, external_id may be null and provider may be "manual" or null.
- • For a provider order, external_id and provider.url are required so the configured provider destination can be resolved.
- • service_name and created_timestamp let the platform determine refill support and its validity period from the service name. Use a Unix timestamp in seconds.
- • When service_name is explicit, it takes precedence over actions.refill. Existing connectors that omit these fields continue using actions.refill and refill_expired as fallback.
- • Set actions.refill to true only when the service supports refill. Set refill_expired to true after the guarantee expires.
- • Set actions.cancel_and_refund to true only when this exact order can be canceled and its charge returned atomically.
orders.cancel_refund
Atomically cancel one eligible order and return its charge to the customer balance.
JSON body
| Name | Type | Required | Description |
|---|---|---|---|
| order_id | integer | Yes | Stable positive local order ID. |
| reason | string | No | Audit reason supplied by the automation service. |
Request
curl -sS -X POST "https://panel.example.com/connector.php?action=orders.cancel_refund" -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Bearer YOUR_CONNECTOR_TOKEN" --data '{"order_id":15020,"reason":"Canceled automatically at customer request"}'Success response
{
"success": true,
"data": {
"order_id": 15020,
"status": "canceled",
"refunded": true
}
}- • This capability is optional and does not affect connectors that implement only the original eight capabilities.
- • Reject the request unless a fresh lookup of the same order would return actions.cancel_and_refund: true.
- • The status update and balance refund must complete in one database transaction.
- • Use row locking or an equivalent atomic guard so repeated requests cannot refund the order twice.
- • Return success only after both cancellation and refund are committed. The platform sends this POST once and then re-reads orders.get to verify status=canceled.
users.list
Return a paginated user list for connection and schema checks.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| offset | integer | No | Zero-based item offset. Default: 0. |
| limit | integer | No | Items requested per page. Supported range: 1 to 100. |
Request
curl -sS "https://panel.example.com/connector.php?action=users.list&offset=0&limit=100" \
-H "Accept: application/json" \
-H "Authorization: Bearer YOUR_CONNECTOR_TOKEN"Success response
{
"success": true,
"data": {
"list": [{ "id": 72, "username": "customer1" }],
"pagination": { "offset": 0, "limit": 100, "total": 1, "has_more": false, "next_offset": null }
}
}users.find
Find one user by exact username for Telegram and WhatsApp account linking.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| username | string | Yes | Exact username after trimming; matching is case-insensitive. |
Request
curl -sS "https://panel.example.com/connector.php?action=users.find&username=customer1" \
-H "Accept: application/json" \
-H "Authorization: Bearer YOUR_CONNECTOR_TOKEN"Success response
{
"success": true,
"data": {
"user": { "id": 72, "username": "customer1" }
}
}- • When no user matches, return HTTP 200 with {"success":true,"data":{"user":null}}.
Polling and baseline behavior
- 1. PANEL ASSIST polls active sites using its existing scheduled ticket scanner. Your connector does not send webhooks or callbacks.
- 2. On the first successful scan, existing customer messages are recorded as seen and are not automated. Only later messages are processed.
- 3. Changing the Connector URL resets that baseline for the site. Changing only the token does not.
- 4. Return stable ticket, order, user, and message identifiers. Changing IDs causes records to be treated as new data.