API reference
Management API
Part of the panel API at /docs/panel, with a panel API key (`sdevc_`) given the monitoring scopes. Monitoring keys cannot use it.
← Monitoring docs14 endpointsUpdated
Browse the docs
Monitoring
Application monitoring: the errors, metrics, events and slow operations your code sends
with the SillyDev SDKs (from sillydev import monitoring in Python,
sillydev/monitoring in JavaScript). Here you manage projects and their keys and read
what was collected. Only available while monitoring is switched on; otherwise every
endpoint here returns 404. Reading needs the monitoring.read scope and changing
anything monitoring.write. Neither is part of a key's default scopes: give them to a
key in the panel.
Projects belong to the account, not to a server, and nothing is collected until you
make a key and call init() with it.
List monitoring projects
GET/monitoring/projects
Account scope monitoring.read
Lists the account's monitoring projects, each with the limits that apply to it now. meta says what the account may still do. An account's limits follow its plan by themselves; while any server it owns has a paid plan, every project gets the paid limits. Returns 404 while monitoring is switched off.
Example
curl "https://sillydev.co.uk/panel/api/client/monitoring/projects" \ -H "Authorization: Bearer $SILLYDEV_API_KEY" \ -H "Accept: application/json"
Response 200The projects.
{
"object": "list",
"data": [
{
"object": "monitoring_project",
"attributes": {
"uuid": "5f0c8a52-3e1b-4b8e-9d1f-6a2c7e4b9a10",
"name": "orders-bot",
"node": {
"number": 1,
"public_url": "https://ingest1.sillydev.co.uk"
},
"allowed_origins": [
"https://example.com"
],
"tier": "free",
"disabled": false,
"limits": {
"series": 40,
"errors_per_day": 5000,
"events_per_day": 10000,
"slow_per_day": 2000,
"requests_per_minute": 60,
"browser_requests_per_minute": 120,
"retention_minute_days": 2,
"retention_hour_days": 90,
"retention_day_days": 400,
"retention_occurrence_days": 30,
"retention_event_days": 14
},
"keys_limit": 5,
"alerts": {
"new_issue": true,
"regression": true,
"error_spike": null,
"heartbeat_minutes": 10
},
"servers": [
{
"uuid": "8f4b1c2d-7a6e-4f3b-9c1d-2e5a6b7c8d90",
"identifier": "8f4b1c2d",
"name": "My bot"
}
],
"keys_count": 2,
"created_at": "2026-10-13T22:00:00+00:00"
}
}
],
"meta": {
"tier": "free",
"project_limit": 2,
"can_create": true,
"email_verified": true
}
}Every field in the response
| Name | Type | Description |
|---|---|---|
| objectrequired | string | |
| datarequired | array of object | |
| data[].objectrequired | string | |
| data[].attributesrequired | object | |
| data[].attributes.uuidrequired | string (uuid) | |
| data[].attributes.namerequired | string | |
| data[].attributes.noderequired | object | Where the project's data is sent. The SDKs work this out from the key. |
| data[].attributes.node.number | integer | |
| data[].attributes.node.public_url | string (uri) | |
| data[].attributes.allowed_originsrequired | array of string | Websites browser keys work from. |
| data[].attributes.tierrequired | one of 'free', 'paid' | paid while any server the account owns has a paid plan. |
| data[].attributes.disabledrequired | boolean | Switched off by an administrator. Data sent to a disabled project is refused. |
| data[].attributes.limitsrequired | object | What the project may send and how long it is kept. A day is the UTC day. |
| data[].attributes.limits.series | integer | Metric series (a name plus a set of tag values) the project may have. Data for new series beyond this is dropped. |
| data[].attributes.limits.errors_per_day | integer | |
| data[].attributes.limits.events_per_day | integer | |
| data[].attributes.limits.slow_per_day | integer | Slow operations recorded per day. |
| data[].attributes.limits.requests_per_minute | integer | Requests per minute from server keys. |
| data[].attributes.limits.browser_requests_per_minute | integer | Requests per minute from browser keys. |
| data[].attributes.limits.retention_minute_days | integer | Days metrics are kept at one-minute resolution. |
| data[].attributes.limits.retention_hour_days | integer | Days metrics are kept at one-hour resolution. |
| data[].attributes.limits.retention_day_days | integer | Days metrics are kept at one-day resolution. |
| data[].attributes.limits.retention_occurrence_days | integer | Days each error occurrence is kept. Issues themselves are kept. |
| data[].attributes.limits.retention_event_days | integer | |
| data[].attributes.keys_limitrequired | integer | How many keys you may make for the project. |
| data[].attributes.alertsrequired | object | |
| data[].attributes.alerts.new_issue | boolean | Email when an error happens that has not been seen before. |
| data[].attributes.alerts.regression | boolean | Email when a resolved issue happens again. |
| data[].attributes.alerts.error_spike | integer | null | Email when at least this many errors happen in five minutes. |
| data[].attributes.alerts.heartbeat_minutes | integer | null | Email when no heartbeat has arrived for this many minutes, and again when one does. |
| data[].attributes.serversrequired | array of object | Servers linked to the project in the panel. |
| data[].attributes.keys_countrequired | integer | |
| data[].attributes.created_atrequired | string (date-time) | |
| metarequired | object | |
| meta.tier | one of 'free', 'paid' | |
| meta.project_limit | integer | How many projects the account may have now. |
| meta.can_create | boolean | Whether createMonitoringProject would succeed now. |
| meta.email_verified | boolean |
Errors
- 401 No API key was sent, or it is wrong, expired or deleted.
- 403 The key is valid but may not do this: it lacks the permission or account scope, it is limited to other servers or IP addresses, or the account may not do it at all.
- 404 There is no such resource, or the key cannot see it. Features that are switched off answer 404 too.
Create a monitoring project
POST/monitoring/projects
Account scope monitoring.writeLimited to 5 per minute
Creates a project and returns it. Nothing is collected until you create a key
(createMonitoringKey) and call init() in your code with it.
The account's email address must be confirmed (403 otherwise), and an account may have a limited number of projects, more while it has a paid server: over the limit answers 400. Returns 404 while monitoring is switched off.
Body
| Name | Type | Description |
|---|---|---|
| namerequired | string |
Example
curl -X POST "https://sillydev.co.uk/panel/api/client/monitoring/projects" \
-H "Authorization: Bearer $SILLYDEV_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"name":"orders-bot"}'Response 201The new project.
{
"object": "monitoring_project",
"attributes": {
"uuid": "5f0c8a52-3e1b-4b8e-9d1f-6a2c7e4b9a10",
"name": "orders-bot",
"node": {
"number": 1,
"public_url": "https://ingest1.sillydev.co.uk"
},
"allowed_origins": [],
"tier": "free",
"disabled": false,
"limits": {
"series": 40,
"errors_per_day": 5000,
"events_per_day": 10000,
"slow_per_day": 2000,
"requests_per_minute": 60,
"browser_requests_per_minute": 120,
"retention_minute_days": 2,
"retention_hour_days": 90,
"retention_day_days": 400,
"retention_occurrence_days": 30,
"retention_event_days": 14
},
"keys_limit": 5,
"alerts": {
"new_issue": true,
"regression": true,
"error_spike": null,
"heartbeat_minutes": null
},
"servers": [],
"keys_count": 0,
"created_at": "2026-10-13T22:00:00+00:00"
}
}Every field in the response
| Name | Type | Description |
|---|---|---|
| objectrequired | string | |
| attributesrequired | object | |
| attributes.uuidrequired | string (uuid) | |
| attributes.namerequired | string | |
| attributes.noderequired | object | Where the project's data is sent. The SDKs work this out from the key. |
| attributes.node.number | integer | |
| attributes.node.public_url | string (uri) | |
| attributes.allowed_originsrequired | array of string | Websites browser keys work from. |
| attributes.tierrequired | one of 'free', 'paid' | paid while any server the account owns has a paid plan. |
| attributes.disabledrequired | boolean | Switched off by an administrator. Data sent to a disabled project is refused. |
| attributes.limitsrequired | object | What the project may send and how long it is kept. A day is the UTC day. |
| attributes.limits.series | integer | Metric series (a name plus a set of tag values) the project may have. Data for new series beyond this is dropped. |
| attributes.limits.errors_per_day | integer | |
| attributes.limits.events_per_day | integer | |
| attributes.limits.slow_per_day | integer | Slow operations recorded per day. |
| attributes.limits.requests_per_minute | integer | Requests per minute from server keys. |
| attributes.limits.browser_requests_per_minute | integer | Requests per minute from browser keys. |
| attributes.limits.retention_minute_days | integer | Days metrics are kept at one-minute resolution. |
| attributes.limits.retention_hour_days | integer | Days metrics are kept at one-hour resolution. |
| attributes.limits.retention_day_days | integer | Days metrics are kept at one-day resolution. |
| attributes.limits.retention_occurrence_days | integer | Days each error occurrence is kept. Issues themselves are kept. |
| attributes.limits.retention_event_days | integer | |
| attributes.keys_limitrequired | integer | How many keys you may make for the project. |
| attributes.alertsrequired | object | |
| attributes.alerts.new_issue | boolean | Email when an error happens that has not been seen before. |
| attributes.alerts.regression | boolean | Email when a resolved issue happens again. |
| attributes.alerts.error_spike | integer | null | Email when at least this many errors happen in five minutes. |
| attributes.alerts.heartbeat_minutes | integer | null | Email when no heartbeat has arrived for this many minutes, and again when one does. |
| attributes.serversrequired | array of object | Servers linked to the project in the panel. |
| attributes.servers[].uuidrequired | string (uuid) | |
| attributes.servers[].identifierrequired | string | The server's 8-character identifier. |
| attributes.servers[].namerequired | string | |
| attributes.keys_countrequired | integer | |
| attributes.created_atrequired | string (date-time) |
Errors
- 400 The account already has as many projects as it may.
- 401 No API key was sent, or it is wrong, expired or deleted.
- 403 The key lacks the
monitoring.writescope, or the account's email address is not confirmed yet. - 404 There is no such resource, or the key cannot see it. Features that are switched off answer 404 too.
- 409 The resource is busy or in a state that does not allow this right now.
- 422 Some fields were missing or invalid. There is one error per problem, and
meta.source_fieldnames the field. - 429 Too many requests. Wait for the number of seconds in the
Retry-Afterheader, then try again. - 503 The monitoring service cannot be reached right now. Nothing is lost; try again in a few minutes.
Get a monitoring project
GET/monitoring/projects/{project}
Account scope monitoring.read
Returns one of the account's projects. Somebody else's project is a 404, the same as one that does not exist.
Parameters
| Name | Type | Description |
|---|---|---|
| projectrequired | string (uuid) | The project's uuid. |
Example
curl "https://sillydev.co.uk/panel/api/client/monitoring/projects/{project}" \
-H "Authorization: Bearer $SILLYDEV_API_KEY" \
-H "Accept: application/json"Response 200The project.
Every field in the response
| Name | Type | Description |
|---|---|---|
| objectrequired | string | |
| attributesrequired | object | |
| attributes.uuidrequired | string (uuid) | |
| attributes.namerequired | string | |
| attributes.noderequired | object | Where the project's data is sent. The SDKs work this out from the key. |
| attributes.node.number | integer | |
| attributes.node.public_url | string (uri) | |
| attributes.allowed_originsrequired | array of string | Websites browser keys work from. |
| attributes.tierrequired | one of 'free', 'paid' | paid while any server the account owns has a paid plan. |
| attributes.disabledrequired | boolean | Switched off by an administrator. Data sent to a disabled project is refused. |
| attributes.limitsrequired | object | What the project may send and how long it is kept. A day is the UTC day. |
| attributes.limits.series | integer | Metric series (a name plus a set of tag values) the project may have. Data for new series beyond this is dropped. |
| attributes.limits.errors_per_day | integer | |
| attributes.limits.events_per_day | integer | |
| attributes.limits.slow_per_day | integer | Slow operations recorded per day. |
| attributes.limits.requests_per_minute | integer | Requests per minute from server keys. |
| attributes.limits.browser_requests_per_minute | integer | Requests per minute from browser keys. |
| attributes.limits.retention_minute_days | integer | Days metrics are kept at one-minute resolution. |
| attributes.limits.retention_hour_days | integer | Days metrics are kept at one-hour resolution. |
| attributes.limits.retention_day_days | integer | Days metrics are kept at one-day resolution. |
| attributes.limits.retention_occurrence_days | integer | Days each error occurrence is kept. Issues themselves are kept. |
| attributes.limits.retention_event_days | integer | |
| attributes.keys_limitrequired | integer | How many keys you may make for the project. |
| attributes.alertsrequired | object | |
| attributes.alerts.new_issue | boolean | Email when an error happens that has not been seen before. |
| attributes.alerts.regression | boolean | Email when a resolved issue happens again. |
| attributes.alerts.error_spike | integer | null | Email when at least this many errors happen in five minutes. |
| attributes.alerts.heartbeat_minutes | integer | null | Email when no heartbeat has arrived for this many minutes, and again when one does. |
| attributes.serversrequired | array of object | Servers linked to the project in the panel. |
| attributes.servers[].uuidrequired | string (uuid) | |
| attributes.servers[].identifierrequired | string | The server's 8-character identifier. |
| attributes.servers[].namerequired | string | |
| attributes.keys_countrequired | integer | |
| attributes.created_atrequired | string (date-time) |
Errors
- 401 No API key was sent, or it is wrong, expired or deleted.
- 403 The key is valid but may not do this: it lacks the permission or account scope, it is limited to other servers or IP addresses, or the account may not do it at all.
- 404 There is no such resource, or the key cannot see it. Features that are switched off answer 404 too.
Update a monitoring project
PATCH/monitoring/projects/{project}
Account scope monitoring.writeLimited to 30 per minute
Changes the project's name, the websites its browser keys work from, and its alert
emails. Only the fields you send change; within alerts, only the alerts you send.
allowed_origins replaces the whole list. Each entry is an origin as a browser sends
it, a scheme and host with an optional port and no path, e.g. https://example.com.
Browser data from anywhere else is refused.
Alerts are emailed to the account. error_spike is a number of errors in five
minutes and heartbeat_minutes how long without a heartbeat counts as stopped; null
switches either off. Each kind of alert is emailed at most once every half hour per
project, and a stopped heartbeat once, then once more when it comes back.
Parameters
| Name | Type | Description |
|---|---|---|
| projectrequired | string (uuid) | The project's uuid. |
Body
| Name | Type | Description |
|---|---|---|
| name | string | |
| allowed_origins | array of string | |
| alerts | object | |
| alerts.new_issue | boolean | |
| alerts.regression | boolean | |
| alerts.error_spike | integer | null | |
| alerts.heartbeat_minutes | integer | null |
Example
curl -X PATCH "https://sillydev.co.uk/panel/api/client/monitoring/projects/{project}" \
-H "Authorization: Bearer $SILLYDEV_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"allowed_origins":["https://example.com"],"alerts":{"heartbeat_minutes":10}}'Response 200The project as it is now.
Every field in the response
| Name | Type | Description |
|---|---|---|
| objectrequired | string | |
| attributesrequired | object | |
| attributes.uuidrequired | string (uuid) | |
| attributes.namerequired | string | |
| attributes.noderequired | object | Where the project's data is sent. The SDKs work this out from the key. |
| attributes.node.number | integer | |
| attributes.node.public_url | string (uri) | |
| attributes.allowed_originsrequired | array of string | Websites browser keys work from. |
| attributes.tierrequired | one of 'free', 'paid' | paid while any server the account owns has a paid plan. |
| attributes.disabledrequired | boolean | Switched off by an administrator. Data sent to a disabled project is refused. |
| attributes.limitsrequired | object | What the project may send and how long it is kept. A day is the UTC day. |
| attributes.limits.series | integer | Metric series (a name plus a set of tag values) the project may have. Data for new series beyond this is dropped. |
| attributes.limits.errors_per_day | integer | |
| attributes.limits.events_per_day | integer | |
| attributes.limits.slow_per_day | integer | Slow operations recorded per day. |
| attributes.limits.requests_per_minute | integer | Requests per minute from server keys. |
| attributes.limits.browser_requests_per_minute | integer | Requests per minute from browser keys. |
| attributes.limits.retention_minute_days | integer | Days metrics are kept at one-minute resolution. |
| attributes.limits.retention_hour_days | integer | Days metrics are kept at one-hour resolution. |
| attributes.limits.retention_day_days | integer | Days metrics are kept at one-day resolution. |
| attributes.limits.retention_occurrence_days | integer | Days each error occurrence is kept. Issues themselves are kept. |
| attributes.limits.retention_event_days | integer | |
| attributes.keys_limitrequired | integer | How many keys you may make for the project. |
| attributes.alertsrequired | object | |
| attributes.alerts.new_issue | boolean | Email when an error happens that has not been seen before. |
| attributes.alerts.regression | boolean | Email when a resolved issue happens again. |
| attributes.alerts.error_spike | integer | null | Email when at least this many errors happen in five minutes. |
| attributes.alerts.heartbeat_minutes | integer | null | Email when no heartbeat has arrived for this many minutes, and again when one does. |
| attributes.serversrequired | array of object | Servers linked to the project in the panel. |
| attributes.servers[].uuidrequired | string (uuid) | |
| attributes.servers[].identifierrequired | string | The server's 8-character identifier. |
| attributes.servers[].namerequired | string | |
| attributes.keys_countrequired | integer | |
| attributes.created_atrequired | string (date-time) |
Errors
- 401 No API key was sent, or it is wrong, expired or deleted.
- 403 The key is valid but may not do this: it lacks the permission or account scope, it is limited to other servers or IP addresses, or the account may not do it at all.
- 404 There is no such resource, or the key cannot see it. Features that are switched off answer 404 too.
- 422 Some fields were missing or invalid. There is one error per problem, and
meta.source_fieldnames the field. - 429 Too many requests. Wait for the number of seconds in the
Retry-Afterheader, then try again.
Delete a monitoring project
DELETE/monitoring/projects/{project}
Account scope monitoring.write
Deletes the project and its keys at once, and all of its data (metrics, issues, events, slow operations) shortly after. Linked servers are unlinked and lose their key from their next start. This cannot be undone.
Parameters
| Name | Type | Description |
|---|---|---|
| projectrequired | string (uuid) | The project's uuid. |
Example
curl -X DELETE "https://sillydev.co.uk/panel/api/client/monitoring/projects/{project}" \
-H "Authorization: Bearer $SILLYDEV_API_KEY" \
-H "Accept: application/json"Response 204Done. There is no response body.
Errors
- 401 No API key was sent, or it is wrong, expired or deleted.
- 403 The key is valid but may not do this: it lacks the permission or account scope, it is limited to other servers or IP addresses, or the account may not do it at all.
- 404 There is no such resource, or the key cannot see it. Features that are switched off answer 404 too.
List a project's keys
GET/monitoring/projects/{project}/keys
Account scope monitoring.read
Lists the project's keys without their secrets, which are only shown when a key is made. hint is a key's last four characters. Keys the panel made for linked servers are listed too, with server set.
Parameters
| Name | Type | Description |
|---|---|---|
| projectrequired | string (uuid) | The project's uuid. |
Example
curl "https://sillydev.co.uk/panel/api/client/monitoring/projects/{project}/keys" \
-H "Authorization: Bearer $SILLYDEV_API_KEY" \
-H "Accept: application/json"Response 200The keys.
{
"object": "list",
"data": [
{
"object": "monitoring_key",
"attributes": {
"id": 7,
"name": "Production",
"kind": "server",
"hint": "x9Qa",
"server": null,
"created_at": "2026-10-13T22:05:00+00:00"
}
}
]
}Every field in the response
| Name | Type | Description |
|---|---|---|
| objectrequired | string | |
| datarequired | array of object | |
| data[].objectrequired | string | |
| data[].attributesrequired | object | |
| data[].attributes.idrequired | integer | |
| data[].attributes.namerequired | string | |
| data[].attributes.kindrequired | one of 'server', 'browser' | |
| data[].attributes.hintrequired | string | The key's last four characters. |
| data[].attributes.serverrequired | any | The linked server this key was made for, or null for a key you made. |
| data[].attributes.created_atrequired | string (date-time) |
Errors
- 401 No API key was sent, or it is wrong, expired or deleted.
- 403 The key is valid but may not do this: it lacks the permission or account scope, it is limited to other servers or IP addresses, or the account may not do it at all.
- 404 There is no such resource, or the key cannot see it. Features that are switched off answer 404 too.
Create a key
POST/monitoring/projects/{project}/keys
Account scope monitoring.writeLimited to 10 per minute
Makes a key and returns its secret in meta.secret_key, once: it cannot be shown
again. A server key (sdevm_...) is for your application's backend and must be
kept secret. A browser key (sdevb_...) is for a web page; it can only send data,
and only from the project's allowed_origins.
The number after the prefix is the project's ingest node, so the SDKs work out where
to send data from the key alone. A project may have a limited number of keys
(keys_limit on the project); the keys made for linked servers do not count.
Parameters
| Name | Type | Description |
|---|---|---|
| projectrequired | string (uuid) | The project's uuid. |
Body
| Name | Type | Description |
|---|---|---|
| namerequired | string | |
| kindrequired | one of 'server', 'browser' |
Example
curl -X POST "https://sillydev.co.uk/panel/api/client/monitoring/projects/{project}/keys" \
-H "Authorization: Bearer $SILLYDEV_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"name":"Production","kind":"server"}'Response 201The new key, with its secret in `meta`.
{
"object": "monitoring_key",
"attributes": {
"id": 7,
"name": "Production",
"kind": "server",
"hint": "x9Qa",
"server": null,
"created_at": "2026-10-13T22:05:00+00:00"
},
"meta": {
"secret_key": "sdevm_1_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx9Qa"
}
}Every field in the response
| Name | Type | Description |
|---|---|---|
| objectrequired | string | |
| attributesrequired | object | |
| attributes.idrequired | integer | |
| attributes.namerequired | string | |
| attributes.kindrequired | one of 'server', 'browser' | |
| attributes.hintrequired | string | The key's last four characters. |
| attributes.serverrequired | any | The linked server this key was made for, or null for a key you made. |
| attributes.created_atrequired | string (date-time) | |
| metarequired | object | |
| meta.secret_keyrequired | string | The whole key. Shown this once. |
Errors
- 400 The project already has as many keys as it may.
- 401 No API key was sent, or it is wrong, expired or deleted.
- 403 The key is valid but may not do this: it lacks the permission or account scope, it is limited to other servers or IP addresses, or the account may not do it at all.
- 404 There is no such resource, or the key cannot see it. Features that are switched off answer 404 too.
- 422 Some fields were missing or invalid. There is one error per problem, and
meta.source_fieldnames the field. - 429 Too many requests. Wait for the number of seconds in the
Retry-Afterheader, then try again.
Delete a key
DELETE/monitoring/projects/{project}/keys/{key}
Account scope monitoring.write
Deletes the key. Data sent with it is refused within moments. Deleting the key of a linked server unlinks that server.
Parameters
| Name | Type | Description |
|---|---|---|
| projectrequired | string (uuid) | The project's uuid. |
| keyrequired | integer | The key's numeric id. |
Example
curl -X DELETE "https://sillydev.co.uk/panel/api/client/monitoring/projects/{project}/keys/{key}" \
-H "Authorization: Bearer $SILLYDEV_API_KEY" \
-H "Accept: application/json"Response 204Done. There is no response body.
Errors
- 401 No API key was sent, or it is wrong, expired or deleted.
- 403 The key is valid but may not do this: it lacks the permission or account scope, it is limited to other servers or IP addresses, or the account may not do it at all.
- 404 There is no such resource, or the key cannot see it. Features that are switched off answer 404 too.
List issues
GET/monitoring/projects/{project}/issues
Account scope monitoring.read
Lists the project's issues: errors grouped by where they happened, newest first by
default. This and the other data endpoints answer with the monitoring service's JSON
as it is, without the object/attributes envelope, and their times are Unix
seconds.
Returns 503 MonitoringUnavailable while the monitoring service cannot be reached;
your data is not lost, as the SDKs keep it until it can be sent.
Parameters
| Name | Type | Description |
|---|---|---|
| projectrequired | string (uuid) | The project's uuid. |
| status | one of 'unresolved', 'resolved', 'ignored', 'all' | Which issues to list. |
| environment | string | Only issues seen in this environment. |
| release | string | Only issues seen in this release. |
| q | string | Searches the issues' type and title. |
| sort | one of 'last_seen', 'first_seen', 'count' | The order of the list. |
| page | integer | The page of results to return, starting at 1. |
| per_page | integer | How many issues to return on each page. |
Example
curl "https://sillydev.co.uk/panel/api/client/monitoring/projects/{project}/issues" \
-H "Authorization: Bearer $SILLYDEV_API_KEY" \
-H "Accept: application/json"Response 200A page of issues.
{
"data": [
{
"fingerprint": "3f1a9c0e5b7d2a4c",
"type": "KeyError",
"title": "'user_id'",
"culprit": "on_order (bot/cogs/orders.py)",
"status": "unresolved",
"handled": false,
"count": 1312,
"count_24h": 41,
"first_seen": 1760100000,
"last_seen": 1760390405,
"regressed_at": null,
"first_release": "1.4.0",
"last_release": "1.4.2",
"environments": [
"production"
],
"services": [
"orders-bot"
],
"sparkline": [
0,
0,
3,
1,
0,
2,
4,
1,
0,
0,
1,
3,
2,
0,
0,
1,
5,
2,
1,
0,
3,
4,
2,
6
]
}
],
"pagination": {
"total": 57,
"page": 1,
"per_page": 25
}
}Every field in the response
| Name | Type | Description |
|---|---|---|
| data | array of object | |
| data[].fingerprint | string | |
| data[].type | string | The exception's type, e.g. KeyError. |
| data[].title | string | The first occurrence's message, at most 200 characters. |
| data[].culprit | string | null | The innermost frame in your own code. |
| data[].status | one of 'unresolved', 'resolved', 'ignored' | |
| data[].handled | boolean | Whether the latest occurrence was caught by your code. |
| data[].count | integer | |
| data[].count_24h | integer | |
| data[].first_seen | integer | Unix seconds. |
| data[].last_seen | integer | Unix seconds. |
| data[].regressed_at | integer | null | When a resolved issue last came back, in Unix seconds. |
| data[].first_release | string | null | |
| data[].last_release | string | null | |
| data[].environments | array of string | |
| data[].services | array of string | |
| data[].sparkline | array of integer | Hourly counts for the last 24 hours, oldest first. |
| pagination | object | |
| pagination.total | integer | |
| pagination.page | integer | |
| pagination.per_page | integer |
Errors
- 401 No API key was sent, or it is wrong, expired or deleted.
- 403 The key is valid but may not do this: it lacks the permission or account scope, it is limited to other servers or IP addresses, or the account may not do it at all.
- 404 There is no such resource, or the key cannot see it. Features that are switched off answer 404 too.
- 422 Some fields were missing or invalid. There is one error per problem, and
meta.source_fieldnames the field. - 503 The monitoring service cannot be reached right now. Nothing is lost; try again in a few minutes.
Get an issue
GET/monitoring/projects/{project}/issues/{fingerprint}
Account scope monitoring.read
Returns one issue with its hourly counts for the last 14 days (history) and its latest occurrence (latest), including the stack trace.
Parameters
| Name | Type | Description |
|---|---|---|
| projectrequired | string (uuid) | The project's uuid. |
| fingerprintrequired | string | The issue's fingerprint. |
Example
curl "https://sillydev.co.uk/panel/api/client/monitoring/projects/{project}/issues/{fingerprint}" \
-H "Authorization: Bearer $SILLYDEV_API_KEY" \
-H "Accept: application/json"Response 200The issue.
Every field in the response
| Name | Type | Description |
|---|---|---|
| fingerprint | string | |
| type | string | The exception's type, e.g. KeyError. |
| title | string | The first occurrence's message, at most 200 characters. |
| culprit | string | null | The innermost frame in your own code. |
| status | one of 'unresolved', 'resolved', 'ignored' | |
| handled | boolean | Whether the latest occurrence was caught by your code. |
| count | integer | |
| count_24h | integer | |
| first_seen | integer | Unix seconds. |
| last_seen | integer | Unix seconds. |
| regressed_at | integer | null | When a resolved issue last came back, in Unix seconds. |
| first_release | string | null | |
| last_release | string | null | |
| environments | array of string | |
| services | array of string | |
| sparkline | array of integer | Hourly counts for the last 24 hours, oldest first. |
| history | array of array of integer | [hour, count] pairs for the last 14 days, hours in Unix seconds. |
| latest | object | |
| latest.id | integer | |
| latest.ts | integer | Unix seconds. |
| latest.type | string | |
| latest.message | string | |
| latest.handled | boolean | |
| latest.stack | array of object | The stack frames, outermost first. |
| latest.cause | object | null | The exception this one was raised from, in the same shape. |
| latest.tags | object | |
| latest.context | object | |
| latest.service | string | |
| latest.environment | string | |
| latest.release | string | null | |
| latest.instance | string |
Errors
- 401 No API key was sent, or it is wrong, expired or deleted.
- 403 The key is valid but may not do this: it lacks the permission or account scope, it is limited to other servers or IP addresses, or the account may not do it at all.
- 404 There is no such resource, or the key cannot see it. Features that are switched off answer 404 too.
- 503 The monitoring service cannot be reached right now. Nothing is lost; try again in a few minutes.
Resolve, ignore or reopen an issue
PATCH/monitoring/projects/{project}/issues/{fingerprint}
Account scope monitoring.writeLimited to 60 per minute
Sets the issue's status. A resolved issue that happens again goes back to unresolved with regressed_at set (and, if the regression alert is on, you are emailed). An ignored issue stays ignored.
Parameters
| Name | Type | Description |
|---|---|---|
| projectrequired | string (uuid) | The project's uuid. |
| fingerprintrequired | string | The issue's fingerprint. |
Body
| Name | Type | Description |
|---|---|---|
| statusrequired | one of 'resolved', 'ignored', 'unresolved' |
Example
curl -X PATCH "https://sillydev.co.uk/panel/api/client/monitoring/projects/{project}/issues/{fingerprint}" \
-H "Authorization: Bearer $SILLYDEV_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"status":"resolved"}'Response 200The issue as it is now.
Every field in the response
| Name | Type | Description |
|---|---|---|
| fingerprint | string | |
| type | string | The exception's type, e.g. KeyError. |
| title | string | The first occurrence's message, at most 200 characters. |
| culprit | string | null | The innermost frame in your own code. |
| status | one of 'unresolved', 'resolved', 'ignored' | |
| handled | boolean | Whether the latest occurrence was caught by your code. |
| count | integer | |
| count_24h | integer | |
| first_seen | integer | Unix seconds. |
| last_seen | integer | Unix seconds. |
| regressed_at | integer | null | When a resolved issue last came back, in Unix seconds. |
| first_release | string | null | |
| last_release | string | null | |
| environments | array of string | |
| services | array of string | |
| sparkline | array of integer | Hourly counts for the last 24 hours, oldest first. |
Errors
- 401 No API key was sent, or it is wrong, expired or deleted.
- 403 The key is valid but may not do this: it lacks the permission or account scope, it is limited to other servers or IP addresses, or the account may not do it at all.
- 404 There is no such resource, or the key cannot see it. Features that are switched off answer 404 too.
- 422 Some fields were missing or invalid. There is one error per problem, and
meta.source_fieldnames the field. - 429 Too many requests. Wait for the number of seconds in the
Retry-Afterheader, then try again. - 503 The monitoring service cannot be reached right now. Nothing is lost; try again in a few minutes.
List an issue's occurrences
GET/monitoring/projects/{project}/issues/{fingerprint}/occurrences
Account scope monitoring.read
Every time the issue happened, newest first, each with its stack trace, tags and context, and where it ran.
Parameters
| Name | Type | Description |
|---|---|---|
| projectrequired | string (uuid) | The project's uuid. |
| fingerprintrequired | string | The issue's fingerprint. |
| page | integer | The page of results to return, starting at 1. |
| per_page | integer | How many occurrences to return on each page. |
Example
curl "https://sillydev.co.uk/panel/api/client/monitoring/projects/{project}/issues/{fingerprint}/occurrences" \
-H "Authorization: Bearer $SILLYDEV_API_KEY" \
-H "Accept: application/json"Response 200A page of occurrences.
{
"data": [
{
"id": 5521,
"ts": 1760390405,
"type": "KeyError",
"message": "'user_id'",
"handled": false,
"stack": [
{
"function": "on_order",
"module": "bot.cogs.orders",
"filename": "bot/cogs/orders.py",
"lineno": 88,
"in_app": true
}
],
"cause": null,
"tags": {
"command": "order"
},
"context": [],
"service": "orders-bot",
"environment": "production",
"release": "1.4.2",
"instance": "a3f9c2e1"
}
],
"pagination": {
"total": 1312,
"page": 1,
"per_page": 25
}
}Every field in the response
| Name | Type | Description |
|---|---|---|
| data | array of object | |
| data[].id | integer | |
| data[].ts | integer | Unix seconds. |
| data[].type | string | |
| data[].message | string | |
| data[].handled | boolean | |
| data[].stack | array of object | The stack frames, outermost first. |
| data[].cause | object | null | The exception this one was raised from, in the same shape. |
| data[].tags | object | |
| data[].context | object | |
| data[].service | string | |
| data[].environment | string | |
| data[].release | string | null | |
| data[].instance | string | |
| pagination | object | |
| pagination.total | integer | |
| pagination.page | integer | |
| pagination.per_page | integer |
Errors
- 401 No API key was sent, or it is wrong, expired or deleted.
- 403 The key is valid but may not do this: it lacks the permission or account scope, it is limited to other servers or IP addresses, or the account may not do it at all.
- 404 There is no such resource, or the key cannot see it. Features that are switched off answer 404 too.
- 503 The monitoring service cannot be reached right now. Nothing is lost; try again in a few minutes.
List events
GET/monitoring/projects/{project}/events
Account scope monitoring.read
The events your application recorded (deploys, sign-ups, anything you send with event()), and those of linked servers (server.crashed, server.started and so on), newest first. Page back with before, using the next of the previous page.
Parameters
| Name | Type | Description |
|---|---|---|
| projectrequired | string (uuid) | The project's uuid. |
| range | one of '1h', '6h', '24h', '7d', '30d', '90d', '1y' | How far back to look, ending now. Leave it out and send from and to for any other span. |
| from | integer | The start of the span, in Unix seconds. Used only without range; defaults to a day before to. |
| to | integer | The end of the span, in Unix seconds. Used only without range; defaults to now. |
| name | string | Only events with this name. |
| before | integer | Only events older than this event id. |
| limit | integer | How many events to return. |
Example
curl "https://sillydev.co.uk/panel/api/client/monitoring/projects/{project}/events" \
-H "Authorization: Bearer $SILLYDEV_API_KEY" \
-H "Accept: application/json"Response 200The events.
{
"data": [
{
"id": 812,
"ts": 1760390410,
"name": "deploy",
"service": "orders-bot",
"environment": "production",
"attributes": {
"version": "1.4.2"
}
}
],
"next": 799
}Every field in the response
| Name | Type | Description |
|---|---|---|
| data | array of object | |
| data[].id | integer | |
| data[].ts | integer | Unix seconds. |
| data[].name | string | |
| data[].service | string | |
| data[].environment | string | |
| data[].attributes | object | |
| next | integer | null | The before for the next page, or null at the end. |
Errors
- 401 No API key was sent, or it is wrong, expired or deleted.
- 403 The key is valid but may not do this: it lacks the permission or account scope, it is limited to other servers or IP addresses, or the account may not do it at all.
- 404 There is no such resource, or the key cannot see it. Features that are switched off answer 404 too.
- 422 Some fields were missing or invalid. There is one error per problem, and
meta.source_fieldnames the field. - 503 The monitoring service cannot be reached right now. Nothing is lost; try again in a few minutes.
Get a project's usage
GET/monitoring/projects/{project}/usage
Account scope monitoring.read
How much of its limits the project has used today (the UTC day), how many metric series it has, what was dropped for being over a limit, and roughly how much it stores.
Parameters
| Name | Type | Description |
|---|---|---|
| projectrequired | string (uuid) | The project's uuid. |
Example
curl "https://sillydev.co.uk/panel/api/client/monitoring/projects/{project}/usage" \
-H "Authorization: Bearer $SILLYDEV_API_KEY" \
-H "Accept: application/json"Response 200The usage.
{
"series": {
"used": 31,
"limit": 40
},
"today": {
"errors": {
"used": 120,
"limit": 5000
},
"events": {
"used": 40,
"limit": 10000
},
"slow": {
"used": 3,
"limit": 2000
},
"requests": 8123
},
"dropped_today": {
"series_limit": 12
},
"storage_bytes": 2101234
}Every field in the response
| Name | Type | Description |
|---|---|---|
| series | object | |
| series.used | integer | |
| series.limit | integer | |
| today | object | |
| today.errors | object | |
| today.errors.used | integer | |
| today.errors.limit | integer | |
| today.events | object | |
| today.events.used | integer | |
| today.events.limit | integer | |
| today.slow | object | |
| today.slow.used | integer | |
| today.slow.limit | integer | |
| today.requests | integer | |
| dropped_today | object | Items dropped today, by reason (e.g. series_limit, error_quota). |
| storage_bytes | integer | An estimate of what the project stores. |
Errors
- 401 No API key was sent, or it is wrong, expired or deleted.
- 403 The key is valid but may not do this: it lacks the permission or account scope, it is limited to other servers or IP addresses, or the account may not do it at all.
- 404 There is no such resource, or the key cannot see it. Features that are switched off answer 404 too.
- 503 The monitoring service cannot be reached right now. Nothing is lost; try again in a few minutes.
Read next