Requests, errors and limits
A few rules apply to every request. Follow them and your program will behave well, even when something goes wrong.
Signing every request
Send your key in the Authorization header as a bearer token. Send JSON with Content-Type: application/json.
Authorization: Bearer tfy_your_key_here
Content-Type: application/jsonIds
:guildId can be your Discord server id or Technified’s own id (it starts with gld_). Discord and Roblox accounts are always plain numbers, sent as strings. Everything Technified makes has an id with a short prefix that says what it is: pun_ for a punishment, tkt_ for a ticket, sub_ for a submission.
The easiest is the Discord server id: in Discord, switch on Developer Mode (User Settings → Advanced), then right-click your server and choose Copy Server ID.
Careful
gld_ in front of the Discord server id: gld_123456789012345678 names no server, and every request answers 404.Errors
A refusal comes back with an HTTP status and a JSON body with a stable code. Check the code, never the wording, which may change.
{
"type": "https://docs.technified.dev/errors/missing_permission",
"title": "Missing permission",
"status": 403,
"code": "missing_permission",
"detail": "This needs the moderation.write permission."
}| Status | What it means |
|---|---|
| 400 | Something about the request is wrong, for example a missing header. The detail says what. |
| 401 | No key, or a key that is wrong, expired or revoked. |
| 403 | The key may not do this (missing_permission), the endpoint is for people only, or the server is blocked. |
| 404 | It does not exist, or this key cannot see it. |
| 409 | It cannot happen right now, for example already decided or already lifted. The code says why. |
| 412 | Somebody changed it since you read it (stale_write). Read it again. |
| 422 | A field is wrong. errors lists every field and what was wrong with it. |
| 429 | Too many requests. Wait retryAfter seconds. |
Retrying safely
Networks fail. To retry a write without doing it twice, send an Idempotency-Key header with a random value, and the same value on every retry of that one action. Technified answers the retry with the first answer instead of, say, banning somebody twice.
Idempotency-Key: 3f1c9a52-8b0e-4d1f-9a77-2c5e6d8b1f40Lists and pages
Lists come a page at a time. Ask with limit (and often order=desc); the answer has items and a nextCursor. To get the next page, send that value as cursor. When nextCursor is null, you have everything.
{
"items": [ ... ],
"nextCursor": "pun_01J9Z4T7C2Q8M3N5V6W7X8Y9Z0"
}Rate limits
Each key has its own budget per minute. Every answer tells you where you stand:
x-ratelimit-limit: 300
x-ratelimit-remaining: 287
x-ratelimit-reset: 1791651660| Kind of request | Per minute |
|---|---|
| Reading | 300 |
| Changing something | 60 |
| Ban check (moderation/status) | 1200 |
| Sending to every game server at once | 5 |
Over the limit you get 429 with retryAfter in seconds. Wait that long, then try again.
Changing settings
Settings carry a version so two people cannot overwrite each other. Read the server with GET /guilds/:guildId, and send the settingsVersion you got back as an If-Match header on PATCH /guilds/:guildId/settings. If somebody changed them in between, you get 412; read them again and try once more.
Still stuck? Get help from the Technified team.