Skip to content
CWPControl Web PanelDocumentation

Staff API

Updated

The staff API lets scripts and tools work with tickets and services, for example an AI assistant that drafts replies, or your own monitoring. A key acts as the staff member who created it: it has exactly that staff member’s permissions and departments, and replies are posted under their name.

Where to find it: My account → API keys. The role needs the permission Use the staff API.

My account with the API keys

Keys

  • Create a key under My account → API keys, with a name and optionally Only from IPs. The key is shown once. Only its hash is stored.
  • Revoke a key at any time. Last used and the last IP are shown.
  • Every write and every reveal of a secret is written to the audit log.
  • Failed attempts are throttled per IP: after 20 failures, the API answers 429 for 15 minutes.

Requests

Base URL: https://billing.example.com/api/v1

curl -H "Authorization: Bearer <key>" https://billing.example.com/api/v1/me

Request bodies can be JSON or form fields. Answers are JSON. Errors come with an HTTP status 4xx and {"error": "…"}.

Method and pathWhat it does
GET /meThe staff member and the permissions of the key
GET /ticketsTickets of the key’s departments. Parameters: status (awaiting, active, all or a status name), dept, client, q (ticket number, e-mail or words in subject, messages or client), page, per (1–200, default 50). The answer has page and pages.
GET /tickets/{id}The ticket with its messages, notes, client, services, servers and credentials. Use ?by=tid to pass the ticket number instead of the internal ID. This works on every /tickets/{id}/… call. Root passwords are included only for keys with reveal credentials, and every read is logged.
POST /tickets/{id}/replymessage, status (default Answered), operator (the user name to sign as; needs reply in the name of another staff member)
POST /tickets/{id}/notemessage: a staff note that only staff see
POST /tickets/{id}/statusstatus: changes the status without e-mailing the client
POST /tickets/{id}/updatestatus, priority, department_id, assigned_admin_id
GET /tickets/{id}/attachments/{aid}Downloads an attachment.
GET /clients/{id}/servicesThe client’s services
POST /services/{id}/passwordpassword, ticket: replaces the stored root password, for example after a client sent the new one. Needs reveal credentials and reply.

Example: reply to a ticket by its number

curl -X POST -H "Authorization: Bearer <key>" -H "Content-Type: application/json" \
     -d '{"message":"Hello, the issue is fixed.","status":"Answered"}' \
     "https://billing.example.com/api/v1/tickets/482913/reply?by=tid"

nginx and the Authorization header

With PHP-FPM behind nginx, pass the header to PHP: fastcgi_param HTTP_AUTHORIZATION $http_authorization;. Without it, every call answers 401 invalid API key. Instead of the header, you can send the key as X-Api-Key: <key>.

CWP sync API

The CWP Billing module on your CWP servers uses its own API under /api/v1/cwp/ (pair, ping, accounts, packages, report, event, link, import), with a server token per server. It is used only by the module. See CWP servers and the CWP Billing module.

Common problems

AnswerCause
401 invalid API keyThe key is wrong or revoked, or the Authorization header does not reach PHP (nginx, see above).
403 IP not allowed for this keyThe caller’s IP is not in Only from IPs.
403 the role of this admin has no API permissionThe role lacks Use the staff API.
404 for a ticketThe ticket is in a department the key’s staff member cannot see, or you passed a ticket number without ?by=tid.
403 permission … missingThe role lacks the permission named in the answer, for example tickets.reply.
429 too many failed attemptsWait 15 minutes, then fix the key.

Related