Skip to content

Visão geral da API ​

A API do Zynko é a mesma que os apps usam: HTTP com JSON para ler e mudar as coisas, e um gateway WebSocket para receber o que acontece em tempo real. Um bot usa as duas com o token dele.

Base da APIhttps://zynko.org/api
Gatewaywss://zynko.org/api/gateway
FormatoJSON (UTF-8), exceto envio de arquivos (multipart/form-data)

Todas as rotas desta referência são relativas à base. GET /users/@me quer dizer GET https://zynko.org/api/users/@me.

Autenticação ​

Mande o token no cabeçalho Authorization:

http
GET /api/users/@me HTTP/1.1
Host: zynko.org
Authorization: Bot bot_3f9a...e1

O servidor aceita os prefixos Bot e Bearer do mesmo jeito. Tokens de bot começam com bot_ seguido de 64 dígitos hexadecimais e não expiram: valem até o dono gerar um novo (POST /users/@me/bots/{bot_id}/token) ou apagar o bot. Quando isso acontece, as conexões abertas no gateway com o token antigo caem com o código 4000.

Sem token, ou com um token inválido, as rotas respondem 401 unauthorized. Algumas coisas são só para pessoas (criar servidor, entrar por convite, criar bots, fazer amizade); nessas um bot recebe 403 ou 400. A lista de rotas marca cada uma.

IDs ​

Todo id (usuário, servidor, canal, mensagem, cargo, emoji, anexo) é um snowflake de 64 bits e viaja como string no JSON, porque não cabe num number do JavaScript sem perder precisão:

json
{ "id": "1234567890123456789", "channel_id": "1234567890123456000" }

No corpo das requisições o servidor aceita ids como string ou como número, mas mande string. Nos caminhos (/channels/{channel_id}) eles vão como número decimal.

Um snowflake guarda o momento em que foi criado: os 42 bits de cima são milissegundos desde 2026-01-01T00:00:00Z (1767225600000 em Unix ms), e os 22 de baixo são uma sequência. Ordenar por id é ordenar por criação.

js
const EPOCH = 1767225600000n;
const criadoEm = (id) => new Date(Number((BigInt(id) >> 22n) + EPOCH));

criadoEm(msg.id); // Date de quando a mensagem foi enviada

O contrário também funciona: (BigInt(ms) - EPOCH) << 22n é o menor id possível naquele instante, útil para paginar mensagens a partir de uma data (?after=).

Datas e outros valores ​

  • Datas são números: milissegundos desde a época Unix (timestamp, edited_timestamp, joined_at, expires_at, since, created_at).
  • Permissões são números (bits; cabem em 18 bits). Veja Permissões.
  • Cores de cargo são inteiros 0xRRGGBB ou null; a cor de destaque do perfil é uma string "#rrggbb".
  • Rotas que só confirmam algo respondem { "ok": true }.

Erros ​

Os erros da API têm sempre o mesmo formato:

json
{ "code": "forbidden", "message": "Você não tem permissão para isso" }

message é uma frase em português pronta para mostrar a uma pessoa; programe contra code e o status HTTP.

StatuscodeQuando
400bad_requestDado inválido ou ação impossível (nome longo demais, mensagem vazia, canal errado...).
401unauthorizedSem token, ou token inválido.
403forbiddenFalta permissão, ou a rota é só para pessoas.
403email_unverifiedLogin de uma conta com e-mail não confirmado. Não acontece com bots.
404not_foundNão existe ou você não tem acesso.
409conflictNome já em uso (por exemplo o username de um bot novo).
413too_largeArquivo grande demais.
429rate_limitedLimite de requisições estourado.
429slow_modeO modo lento do canal ainda não deixou mandar de novo.
500internalErro do servidor.
503unavailableRecurso não configurado neste servidor (arquivos, voz).

404 em vez de 403

Para que não dê para sondar ids, um servidor de que você não é membro, ou um canal que você não pode ver, responde 404, como se não existisse. 403 aparece quando você vê a coisa mas não pode fazer aquilo com ela.

Erros que o servidor nem chega a processar não seguem esse formato: um JSON malformado, um corpo sem Content-Type: application/json ou um id inválido no caminho voltam com 400, 415 ou 422 e uma mensagem em texto puro.

Limites de requisição (429) ​

Quando um limite estoura, a resposta é 429 com o tempo de espera em milissegundos no corpo e em segundos no cabeçalho Retry-After:

http
HTTP/1.1 429 Too Many Requests
Retry-After: 4

{ "code": "rate_limited", "message": "Calma! Você está indo rápido demais", "retry_after_ms": 3712 }

O modo lento de um canal responde do mesmo jeito, com code: "slow_mode".

Os limites são contados por conta (o bot inteiro, não por canal), em janelas fixas. Os que importam para um bot:

AçãoRotaLimite
Enviar mensagemPOST /channels/{id}/messages10 a cada 10 s
Editar mensagemPATCH /channels/{id}/messages/{id}10 a cada 10 s
ReagirPUT .../reactions/{emoji}20 a cada 10 s
DigitandoPOST /channels/{id}/typing10 a cada 10 s
Enviar anexoPOST /channels/{id}/attachments30 por minuto
Enviar imagem (avatar, ícone, emoji)POST /media10 por minuto
Criar postagem em fórumPOST /channels/{id}/posts10 por minuto
Editar perfilPATCH /users/@me20 por minuto
Criar convitePOST /guilds/{id}/invites20 por hora
Entrar numa sala de vozPOST /channels/{id}/voice20 por minuto
Trocar o servidor de voz da salaPUT /channels/{id}/voice/server10 por minuto

Apagar mensagens, tirar reações e as rotas de gerenciamento não têm limite próprio.

Além disso, cada canal pode ter modo lento (rate_limit_per_user, em segundos): depois de mandar uma mensagem (ou abrir uma postagem), a mesma conta espera esse tempo antes da próxima. Quem tem Gerenciar mensagens ou Gerenciar canais no canal não espera.

Imagens e arquivos ​

Os campos de imagem (avatar, banner, icon, url de emoji) guardam um destes:

  • um caminho relativo do próprio Zynko, /api/media/{id}/{segredo}: público, sem autenticação, com cache longo. Para usar, junte com a origem: https://zynko.org/api/media/...;
  • uma URL absoluta de GIF do KLIPY (https://static.klipy.com/...), usada como está.
js
const urlDaImagem = (v) => (v?.startsWith('/') ? 'https://zynko.org' + v : v);

Para trocar uma imagem, envie o arquivo em POST /media (PNG, JPEG, GIF, WebP ou AVIF, até 16 MB), pegue o id que volta e mande-o como avatar_id, banner_id, icon_id ou image_id na rota que usa a imagem. Uploads que não forem usados somem em um dia.

Anexos de mensagens são outra coisa. Cada canal tem sua chave e os arquivos ficam cifrados; o url de um anexo é /api/attachments/{id} e só quem pode ver o canal consegue baixar, mandando o token. Qualquer outra pessoa recebe 404. Os downloads aceitam Range. Tipos que o navegador pode exibir (imagens, vídeo e áudio comuns) vêm com o Content-Type original; o resto vem como application/octet-stream.

  • Vídeos podem ter uma miniatura em /api/attachments/{id}/thumb (campo thumbnail).
  • Emojis do servidor também estão em /api/emojis/{id}, que redireciona para a imagem, sem autenticação.
  • Imagens de prévias de links (embeds[].image.url) passam por /api/embeds/image?....

Veja Arquivos para os detalhes do envio.

Texto das mensagens ​

O conteúdo é texto com marcação no estilo do Discord. Menções e emojis do servidor ficam dentro do texto:

EscrevaPara
<@ID_DO_USUARIO>mencionar alguém (a pessoa recebe notificação)
<:nome:ID_DO_EMOJI>um emoji do servidor
<a:nome:ID_DO_EMOJI>um emoji animado do servidor

Não há lista separada de menções na mensagem: procure <@id> no content.

Próximos passos ​

  • Gateway: conectar e receber eventos.
  • Eventos: tudo o que chega pelo gateway.
  • Rotas: todas as rotas que um bot pode usar.
  • Objetos: os formatos JSON.
  • Permissões: os bits, os cargos e os canais.

Zynko · zynko.org