Support tickets
Open support tickets and reply to them.
Ticket categories
GET/api/v1/tickets/queuesScope tickets:read
The categories (queues) a ticket can be opened in.
Example
curl -s "https://app.pbn.ltd/api/v1/tickets/queues" \
-H "Authorization: Bearer $PBN_API_KEY"
import os
import requests
headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.get("https://app.pbn.ltd/api/v1/tickets/queues", headers=headers, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/tickets/queues", {
method: "GET",
headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());
Response
200
{
"data": [
{
"slug": "technical-problems",
"title": "Technical Problems"
}
]
}
Errors: rate_limited, scope_missing, unauthorized
List tickets
GET/api/v1/ticketsScope tickets:read
Your tickets, newest first.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
status | query | string (one of: open, closed) | no | Only open or only closed tickets. |
limit | query | integer | no | Items per page (1-200). Default: 50. |
cursor | query | string | no | The next_cursor value of the previous page. Omit for the first page. |
Example
curl -s "https://app.pbn.ltd/api/v1/tickets?status=open" \
-H "Authorization: Bearer $PBN_API_KEY"
import os
import requests
headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.get("https://app.pbn.ltd/api/v1/tickets?status=open", headers=headers, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/tickets?status=open", {
method: "GET",
headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());
Response
200
{
"data": [
{
"id": 4412,
"reference": "general-support-request-4412",
"title": "Site shows error 500",
"queue": "General Support Request",
"status": "open",
"priority": "normal",
"created_at": "2026-09-20T08:00:00Z",
"updated_at": "2026-09-20T08:00:00Z",
"panel_url": "https://app.pbn.ltd/account/tickets"
}
],
"next_cursor": null,
"has_more": false
}
Errors: rate_limited, scope_missing, unauthorized
Read a ticket
GET/api/v1/tickets/{ticket_id}Scope tickets:read
A ticket with every public message (yours and support's). can_reply says if you may add a message now (ticket limits: one message before support answers).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
ticket_id | path | integer | yes | The ticket id. |
Example
curl -s "https://app.pbn.ltd/api/v1/tickets/4412" \
-H "Authorization: Bearer $PBN_API_KEY"
import os
import requests
headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.get("https://app.pbn.ltd/api/v1/tickets/4412", headers=headers, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/tickets/4412", {
method: "GET",
headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`}
});
console.log(res.status, await res.json());
Response
200
{
"data": {
"id": 4412,
"reference": "general-support-request-4412",
"title": "Site shows error 500",
"queue": "General Support Request",
"status": "open",
"priority": "normal",
"created_at": "2026-09-20T08:00:00Z",
"updated_at": "2026-09-20T08:00:00Z",
"panel_url": "https://app.pbn.ltd/account/tickets",
"resolution": null,
"can_reply": true,
"can_reply_reason": null,
"messages": [
{
"at": "2026-09-20T08:00:00Z",
"from": "you",
"text": "My site shows error 500 since this morning."
},
{
"at": "2026-09-20T08:40:00Z",
"from": "support",
"text": "We are looking at it now.",
"attachments": []
}
]
}
}
Errors: not_found, rate_limited, scope_missing, unauthorized
Open a ticket
POST/api/v1/ticketsScope tickets:write
Opens a ticket (support is e-mailed as for a panel ticket). The ticket limits apply: at most 2 open tickets at a time (409 ticket_limit).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
title | body | string | yes | Short summary. |
message | body | string | yes | What happened, what you expected. |
queue | body | string | no | Category slug (GET /tickets/queues). Default: general-support-request. |
priority | body | string (one of: low, normal, high) | no | Priority. Default: normal. |
site_id | body | integer | no | The site it is about (its domain is added to the ticket). |
Example
curl -s -X POST "https://app.pbn.ltd/api/v1/tickets" \
-H "Authorization: Bearer $PBN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title": "Question about my site", "message": "How do I add a subdomain?", "queue": "general-support-request", "site_id": 123}'
import os
import requests
headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.post("https://app.pbn.ltd/api/v1/tickets", headers=headers, json={"title": "Question about my site", "message": "How do I add a subdomain?", "queue": "general-support-request", "site_id": 123}, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/tickets", {
method: "POST",
headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`, "Content-Type": "application/json"},
body: JSON.stringify({"title": "Question about my site", "message": "How do I add a subdomain?", "queue": "general-support-request", "site_id": 123})
});
console.log(res.status, await res.json());
Response
201
{
"data": {
"id": 4412,
"reference": "general-support-request-4412",
"title": "Site shows error 500",
"queue": "General Support Request",
"status": "open",
"priority": "normal",
"created_at": "2026-09-20T08:00:00Z",
"updated_at": "2026-09-20T08:00:00Z",
"panel_url": "https://app.pbn.ltd/account/tickets"
}
}
Errors: conflict, rate_limited, scope_missing, unauthorized, validation_failed
Reply to a ticket
POST/api/v1/tickets/{ticket_id}/messagesScope tickets:write
Adds your message to the ticket (support is notified). One message until support answers.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
ticket_id | path | integer | yes | The ticket id. |
message | body | string | yes | Your message. |
Example
curl -s -X POST "https://app.pbn.ltd/api/v1/tickets/4412/messages" \
-H "Authorization: Bearer $PBN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"message": "Thanks, that worked."}'
import os
import requests
headers = {"Authorization": "Bearer " + os.environ["PBN_API_KEY"]}
r = requests.post("https://app.pbn.ltd/api/v1/tickets/4412/messages", headers=headers, json={"message": "Thanks, that worked."}, timeout=120)
print(r.status_code, r.json())
const res = await fetch("https://app.pbn.ltd/api/v1/tickets/4412/messages", {
method: "POST",
headers: {Authorization: `Bearer ${process.env.PBN_API_KEY}`, "Content-Type": "application/json"},
body: JSON.stringify({"message": "Thanks, that worked."})
});
console.log(res.status, await res.json());
Response
201
{
"data": {
"id": 4412,
"reference": "general-support-request-4412",
"title": "Site shows error 500",
"queue": "General Support Request",
"status": "open",
"priority": "normal",
"created_at": "2026-09-20T08:00:00Z",
"updated_at": "2026-09-20T08:00:00Z",
"panel_url": "https://app.pbn.ltd/account/tickets",
"messages": []
}
}
Errors: conflict, not_found, rate_limited, scope_missing, unauthorized