API for bots
The API lets other bots use Catita in a server: read and add XP, give or take money, create custom role keys or make FakeSS screenshots. Discord doesn’t let one bot use another bot’s commands, so this goes over HTTP at https://api.catita.gg/v1.
Create a key
Section titled “Create a key”In /settings > API > Create key (you need Manage Server).
- A key looks like
ctk_1a2b3c4d_…. You see it only once: copy it when you create it. Catita only stores an encrypted fingerprint, so it can’t show it to you again. - Each key works only in its own server: no endpoint takes a server ID, it comes from the key.
- Up to 5 keys per server, each with its own name, permissions, limits and expiry.
- Rotate gives a new secret and the old one stops working right away. Revoke deletes it.
- Every key created, rotated or revoked is posted in the moderation log channel.
Keep it secret: in an environment variable, never in your code or in a message.
Permissions
Section titled “Permissions”New keys can only read. Tick what your bot needs in /settings:
| Permission | Allows |
|---|---|
keys:read |
Seeing custom role keys |
keys:write |
Creating custom role keys (up to 100 a day per key) |
levels:read |
Reading levels and the leaderboard |
levels:write |
Adding or removing XP |
economy:read |
Reading balances |
economy:write |
Giving or taking wallet money |
fakess |
Making screenshots |
Authentication
Section titled “Authentication”Send the key in the Authorization header:
curl https://api.catita.gg/v1/me \ -H "Authorization: Bearer $CATITA_KEY"const res = await fetch('https://api.catita.gg/v1/me', { headers: { Authorization: `Bearer ${process.env.CATITA_KEY}` }});console.log(await res.json());Limits
Section titled “Limits”- 60 requests a minute per key (screenshots: 10). Every response has
X-RateLimit-Remaining; past the limit you get429withRetry-After. - Daily limits per key: by default 50,000 XP and 1,000,000 money, added or removed. Change them in
/settings> API > the key > Limits. They reset at 00:00 UTC, so a leaked key can’t wreck the economy. - Many wrong keys from the same IP block it for 10 minutes.
- JSON bodies up to 16 KB, with
Content-Type: application/json. Unknown fields are rejected.
Retries without duplicates
Section titled “Retries without duplicates”Writes accept an Idempotency-Key header (1 to 64 letters, digits, - or _). If your bot repeats the same request with the same key within 24 hours, it gets the same response (with Idempotent-Replayed: true) and nothing is applied twice.
curl -X POST "https://api.catita.gg/v1/levels/123456789012345678/xp" \ -H "Authorization: Bearer $CATITA_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: event-prize-42" \ -d '{"amount": 500}'Endpoints
Section titled “Endpoints”Every user ID must belong to a member of the key’s server (not a bot). ?instance= picks the leveling or economy instance; without it, the main one.
| Method and path | Permission | What it does |
|---|---|---|
GET /v1/me |
— | The server, the key, its permissions and what’s left of each daily limit |
GET /v1/levels/leaderboard?limit=&offset= |
levels:read |
Leaderboard (up to 100 per page) |
GET /v1/levels/{userId} |
levels:read |
Level, XP, rebirths and rank |
POST /v1/levels/{userId}/xp |
levels:write |
{ "amount": 500 } adds; a negative number removes |
GET /v1/economy/{userId} |
economy:read |
Wallet, bank and net worth |
POST /v1/economy/{userId}/wallet |
economy:write |
{ "amount": 1000 } gives; negative takes (never below zero) |
GET /v1/customroles/keys |
keys:read |
The latest 100 custom role keys |
POST /v1/customroles/keys |
keys:write |
{ "days": 30, "count": 5 } creates keys (1 to 365 days, 1 to 20 keys) |
POST /v1/fakess |
fakess |
PNG screenshot of a message |
Adding XP works like giving it from /settings: it levels people up, gives rewards and posts the announcement. Every money change goes to the server’s ledger as api:<key name>.
Example: reward someone with money
Section titled “Example: reward someone with money”const res = await fetch(`https://api.catita.gg/v1/economy/${userId}/wallet`, { method: 'POST', headers: { Authorization: `Bearer ${process.env.CATITA_KEY}`, 'Content-Type': 'application/json', 'Idempotency-Key': `prize-${interaction.id}` }, body: JSON.stringify({ amount: 1000 })});const data = await res.json();if (!res.ok) throw new Error(data.error.message);console.log(`They now have ${data.wallet}`);FakeSS screenshots
Section titled “FakeSS screenshots”{ "authorId": "123456789012345678", "content": "hi **everyone**", "reply": { "authorId": "234567890123456789", "content": "how are you?" }, "image": "https://cdn.discordapp.com/attachments/…/photo.png", "theme": "dark"}- The author must be a member of the server: name, avatar and color come from Discord and can’t be made up.
contentup to 2000 characters and 10 mentions;themeisdark,darkerorlight.imageonly from Discord’s CDN (cdn.discordapp.comormedia.discordapp.net).- Returns a PNG. When too many are running,
503withRetry-After.
Errors
Section titled “Errors”Always in the same shape:
{ "error": { "code": "missing_scope", "message": "This key needs the \"levels:write\" scope." } }| Status | When |
|---|---|
400 |
Invalid body or parameter |
401 |
Key missing, wrong, expired or revoked |
403 |
The key lacks that permission, or Catita is no longer in the server |
404 |
The person isn’t a member, or the instance doesn’t exist |
409 |
Can’t be done now (leveling off, not enough money…) |
422 |
Idempotency-Key reused for another request, or an image that couldn’t be read |
429 |
Per-minute or daily limit |
503 |
Busy: retry after Retry-After |
The full spec is in openapi.json. To get notified when something happens, see Events.
Catita is a project by Random Dev, a development studio owned by ZENU GROUP LLC. catita.gg
