The SystemBuddy API
Another system can read and write a narrow, deliberate slice of SystemBuddy over HTTPS: tickets, assets and published knowledge articles. It authenticates with an API key, which is a service identity and never a person. Keys are created by an administrator in Administration, API keys.
1 · Authenticating
Every call carries the key in a header. Both of these are accepted:
X-Api-Key: sbk_3f9a1c40_...Authorization: ApiKey sbk_3f9a1c40_...
A key looks like sbk_3f9a1c40_<random>. The first two segments are the prefix. The prefix is public: it is what the key list, the logs and the audit trail use to name a key, so it is safe to quote in a support conversation. The rest is the secret.
The key is shown exactly once, on the screen that creates it. SystemBuddy stores only a SHA-256 hash of it, so nobody, including us, can display it again. If it is lost or leaked, revoke it and create another.
2 · Scopes
A key carries the named scopes an administrator ticked, and nothing else. A call to an endpoint whose scope the key does not hold is refused with 403 and the refusal is written to the audit trail.
tickets:read, read tickets of the key's organization.tickets:write, raise tickets and add public comments on behalf of an existing account of that organization.assets:read, read the asset inventory.assets:write, update the location, building, room, status and notes of an asset.knowledge:read, read published knowledge base articles.
Give a key the least it needs. A reporting job usually wants tickets:read and nothing more.
3 · What a key can never do
This is the part that matters, so it is worth stating plainly. A key is authenticated by its own scheme, separate from the one people sign in with, and the principal it produces carries no user identity at all: no user id, no role, no group, no inherited permission. There is no scope that grants any of the following, and no endpoint that offers them accepts a key:
- Running scripts, pushing installs or uninstalls, or any other agent action on an endpoint.
- Isolating, locking, wiping or retiring a device.
- Creating, changing, disabling or elevating a user, a role or an API key.
- Reading or writing HR records, and in particular any sensitive employee field.
- Settings, licensing, the audit trail, security exposure, break-glass access, or anything else an administrator does interactively.
Those endpoints answer 401 to a key, exactly as they do to no credential at all. A negative test suite replays every privileged endpoint in the product with a live, fully scoped key on each build and fails if a single one returns success.
4 · Rate limits
Each key has its own requests-per-minute limit, set when it is created and changeable afterwards. It is enforced per key, not per address, so one busy integration cannot spend another one's budget.
- Successful responses carry
X-RateLimit-LimitandX-RateLimit-Remaining. - Over the limit, the API answers
429with aRetry-Afterheader giving the seconds to wait. Honour it: retrying sooner only spends the next window. - The first refusal in a window is audited, so an administrator sees a key that is consistently over its budget without the audit trail filling up.
The server also applies its own per-address limit in front of everything, and a customer's reverse proxy may add a third. If you are being throttled and no Retry-After is present, you are being limited by the edge rather than by the key.
5 · Expiry and revocation
A key has an expiry date, proposed as 90 days and settable up to two years. An expired key stops working on its own, which is the point: an integration nobody owns any more dies quietly instead of living forever.
Revocation is immediate. The moment an administrator revokes a key, the next call presenting it is refused, and the refusal, with its reason, is in the audit trail. Creating a key, changing it and revoking it are all audited too, by prefix, never by material.
The key list shows, for every key, when it was last used and from which address, and how many calls it has served. That is the fastest way to answer "is anything still using this?" before turning it off.
6 · The API description
Each SystemBuddy server publishes an OpenAPI 3.0 document for exactly the surface a key can reach, at /api/v1/openapi.json on that server. It is generated from the running code, so it describes what that version actually serves, including the required scope on every operation. Point your client generator at it.
The endpoints under /api/v1 today:
GET /api/v1/me, what this key is: prefix, organization and scopes. Useful as a connectivity check.GET /api/v1/ticketsandGET /api/v1/tickets/{id}, paged, newest first.POST /api/v1/tickets, raise a ticket for a named requester who already has an account.POST /api/v1/tickets/{id}/comments, add a public comment on behalf of an existing account.GET /api/v1/assetsandGET /api/v1/assets/{id}.PATCH /api/v1/assets/{id}, inventory fields only.GET /api/v1/knowledge/articles, published articles only.
Lists take page and pageSize. pageSize is clamped to 200, so ask for pages rather than everything.
7 · Answers you should handle
200, the body is{"success":true,"data":...}.400, the body was rejected and the message names the field. Unknown fields are refused rather than ignored.401, the key is missing, malformed, unknown, revoked or expired.403, the key does not carry the scope this endpoint needs.404, no such record in this key's organization. A record belonging to another organization is a404, not a403: a key cannot learn that it exists.429, over the key's rate limit. Wait forRetry-After.
Questions?
Email orders@systembuddy.net with the prefix of the key you are working with, never the key itself, and what you are trying to build.
