Skip to content

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.

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.

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

Send the key in the Authorization header:

Ventana de terminal
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());
  • 60 requests a minute per key (screenshots: 10). Every response has X-RateLimit-Remaining; past the limit you get 429 with Retry-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.

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.

Ventana de terminal
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}'

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>.

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}`);
{
"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.
  • content up to 2000 characters and 10 mentions; theme is dark, darker or light.
  • image only from Discord’s CDN (cdn.discordapp.com or media.discordapp.net).
  • Returns a PNG. When too many are running, 503 with Retry-After.

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