Custom SMM Connector v1.1

API Documentation

Implement one HTTP endpoint on your panel. PANEL ASSIST calls that endpoint with an action query parameter to read tickets, users, and orders, create or reply to tickets, and optionally cancel and refund eligible orders.

https://panel.example.com/connector.php?action=ACTION_NAME

Authentication and transport

Bearer token

Send the token in Authorization: Bearer YOUR_CONNECTOR_TOKEN. Never place it in the URL, response, or application logs.

HTTPS and destination safety

Production URLs must use HTTPS with a valid certificate and resolve only to public IP addresses. Redirects, URL credentials, and fragments are rejected.

NameTypeRequiredDescription
AuthorizationheaderYesBearer token entered in the Custom SMM site settings.
AcceptheaderYesapplication/json
Content-TypeheaderNoapplication/json on POST requests.
X-Request-IdheaderNoPANEL 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 statusMeaningUse when
400Bad RequestMalformed query or JSON.
401UnauthorizedMissing or invalid bearer token.
403ForbiddenAuthenticated but not allowed.
404Not FoundRequested ticket or order does not exist.
405Method Not AllowedWrong HTTP method for the action.
422Validation ErrorRequired fields are missing or invalid.
429Too Many RequestsTemporary rate limit.
500/503Server ErrorTemporary 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

GET

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.
GET

tickets.list

Return ticket IDs that should be checked for new customer messages.

Query parameters

NameTypeRequiredDescription
offsetintegerNoZero-based item offset. Default: 0.
limitintegerNoItems 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.
GET

tickets.get

Return one ticket and a page of its messages.

Query parameters

NameTypeRequiredDescription
ticket_idintegerYesStable positive ticket ID.
offsetintegerNoZero-based item offset. Default: 0.
limitintegerNoItems 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.
POST

tickets.reply

Add a staff reply to an existing ticket.

JSON body

NameTypeRequiredDescription
ticket_idintegerYesStable positive ticket ID.
messagestringYesNon-empty reply body. HTML line breaks may be preserved.
staff_namestringNoStaff 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.
POST

tickets.create

Create a ticket for an exact panel username.

JSON body

NameTypeRequiredDescription
usernamestringYesExact panel username.
subjectstringYesNon-empty ticket subject.
messagestringYesNon-empty initial message.
staff_namestringNoStaff 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.
GET

orders.list

Return a paginated order list for connection and schema checks.

Query parameters

NameTypeRequiredDescription
offsetintegerNoZero-based item offset. Default: 0.
limitintegerNoItems 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 }
  }
}
GET

orders.get

Return the order fields used by ownership, status, mode, provider, refill, and cancellation checks.

Query parameters

NameTypeRequiredDescription
order_idintegerYesStable 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.
POST

orders.cancel_refund

Atomically cancel one eligible order and return its charge to the customer balance.

JSON body

NameTypeRequiredDescription
order_idintegerYesStable positive local order ID.
reasonstringNoAudit 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.
GET

users.list

Return a paginated user list for connection and schema checks.

Query parameters

NameTypeRequiredDescription
offsetintegerNoZero-based item offset. Default: 0.
limitintegerNoItems 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 }
  }
}
GET

users.find

Find one user by exact username for Telegram and WhatsApp account linking.

Query parameters

NameTypeRequiredDescription
usernamestringYesExact 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. 1. PANEL ASSIST polls active sites using its existing scheduled ticket scanner. Your connector does not send webhooks or callbacks.
  2. 2. On the first successful scan, existing customer messages are recorded as seen and are not automated. Only later messages are processed.
  3. 3. Changing the Connector URL resets that baseline for the site. Changing only the token does not.
  4. 4. Return stable ticket, order, user, and message identifiers. Changing IDs causes records to be treated as new data.

Implementation checklist

One public HTTPS endpoint
Bearer token checked securely
Only documented GET and POST methods
JSON success and error envelopes
All eight capabilities implemented
Positive stable ticket and order IDs
Stable message IDs and Unix timestamps
Staff messages marked is_staff: true
Offset pagination always advances
No secrets or database errors in responses
Optional refunds are atomic and idempotent