API v1

Documentação da API

Integre a Promisse direto no seu sistema. Crie pedidos de puxada, acompanhe o progresso e consulte seus membros autenticados — tudo com uma única API key.

Introdução

A API da Promisse é REST sobre HTTPS e responde sempre em JSON. Todas as rotas públicas vivem sob o prefixo /v1.

URL base

https://auth.promisse.app

Uma chave por bot

Cada bot tem a própria API key, e ela dá acesso apenas aos dados daquele bot.

Limites por chave

O rate limit é contado por API key, não por IP — seu servidor compartilhado não atrapalha.

JSON sempre

Toda resposta traz message e code. Use o campo code para decidir sucesso ou erro.

Autenticação

Toda requisição precisa do header Authorization com a API key do seu bot.

Envie a chave crua, sem prefixo

A API não usa Bearer. Mande o valor da chave diretamente em Authorization. Enviar Authorization: Bearer sua_chave resulta em 401.
# Correto
Authorization: 1376041252205887509-22a4e9c47da0aedd...

# Errado (401)
Authorization: Bearer 1376041252205887509-22a4e9c47da0aedd...

Onde conseguir a sua chave

  1. 1Acesse o painel e abra o bot que você quer integrar.
  2. 2Vá em Configurações, na seção API Key.
  3. 3Clique em Gerar API Key e copie o valor na hora — depois ela aparece mascarada.

Regerar revoga a chave anterior

Cada bot tem uma única API key ativa. Ao gerar uma nova, a antiga deixa de funcionar imediatamente e todas as integrações que a usam quebram. Atualize suas integrações antes de regerar.

Trate a chave como uma senha

A chave dá acesso total aos dados do seu bot. Guarde em variável de ambiente, nunca no front-end, em repositório público ou em mensagens. Se ela vazar, gere uma nova imediatamente.

Tratamento de erros

Este é o ponto mais importante para integrar corretamente: o status HTTP não é confiável em todas as rotas.

Sempre verifique o campo code, não o status HTTP

Várias rotas devolvem erro com HTTP 200 e code: 0 no corpo. Se o seu código só olha res.ok ou status === 200, ele vai tratar erro como sucesso.

Sucesso

{ "message": "OK", "code": 200, "...": "..." }

Erro

{ "message": "401: Unauthorized", "code": 0 }

Padrão recomendado

async function promisse(path, options = {}) {
  const res = await fetch(`https://auth.promisse.app${path}`, {
    ...options,
    headers: {
      Authorization: process.env.PROMISSE_API_KEY,
      "Content-Type": "application/json",
      ...options.headers,
    },
  });

  if (res.status === 429) {
    const retryAfter = Number(res.headers.get("Retry-After") ?? 60);
    throw new Error(`Rate limit atingido, tente em ${retryAfter}s`);
  }

  const data = await res.json();

  // O que decide sucesso e o campo code, nao o status HTTP.
  if (data.code !== 200) {
    throw new Error(data.error ?? data.message);
  }

  return data;
}

Mensagens de erro são strings, não códigos

Os erros identificam-se pelo texto em message (por exemplo "Order Request not found"). Compare pelo texto exato, e prefira tratar qualquer code: 0 como falha genérica em vez de depender de uma lista fechada.

Rate limits

Os limites são contados por API key, em janelas de 60 segundos. Passar do limite devolve HTTP 429.

EndpointLimite
POST/v1/auth/puxar
10 req / min
GET/v1/auth/order
60 req / min
DELETE/v1/auth/order
20 req / min
POST/v1/auth/updatePending
60 req / min
GET/v1/auth/orderserver
60 req / min
GET/v1/auth/@me
60 req / min
POST/v1/auth/@user
60 req / min

Headers em toda resposta

CampoTipoEnvioDescrição
X-RateLimit-Limitopc.numberheaderTotal de requisições permitidas na janela.
X-RateLimit-Remainingopc.numberheaderQuantas requisições ainda restam na janela atual.
Retry-Afteropc.numberheaderSó no 429: segundos a aguardar antes de tentar de novo.

Resposta ao exceder (HTTP 429)

{
  "message": "429: Too Many Requests. Try again in 42 seconds.",
  "code": 0,
  "error": "RATE_LIMIT"
}

Como evitar o 429

Respeite o Retry-After em vez de tentar de novo em loop. Para acompanhar um pedido, consulte GET /v1/auth/order a cada poucos segundos — não em loop apertado. Se precisar de limites maiores, fale com o suporte.

Endpoints

Todas as rotas abaixo exigem o header Authorization com a API key do bot e operam somente sobre os dados desse bot.

POST/v1/auth/puxar

Cria um pedido para puxar seus membros autenticados para um servidor.

10 req / min

Enfileira um pedido de puxada. O pedido entra com status pending e e processado em background pela fila. So pode existir um pedido ativo (pending ou in_progress) por servidor de destino ao mesmo tempo.

Parâmetros

CampoTipoEnvioDescrição
user_idobrig.stringbodyID do usuario do Discord que esta solicitando a puxada.
to_guildobrig.stringbodyID do servidor de destino. Seu bot precisa ja estar nesse servidor.
amountopc.numberbodyQuantidade de membros a puxar. Padrao: todos os membros autenticados disponiveis.
from_serveropc.stringbodyPuxar apenas membros que autenticaram por este servidor de origem. Padrao: todos os servidores.

Exemplo de requisição

curl -X POST https://auth.promisse.app/v1/auth/puxar \
  -H "Authorization: SUA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "user_id": "123456789012345678",
    "to_guild": "987654321098765432",
    "amount": 50
  }'

Resposta de sucesso

{
  "message": "Request successfully sent",
  "code": 200,
  "licenseOrder": 48273910,
  "info": {
    "status": "pending",
    "bot_id": "1376041252205887509",
    "amount": 50,
    "user_id": "123456789012345678",
    "to_guild": "987654321098765432",
    "from_server": "All Servers",
    "server_name": "Meu Servidor",
    "positionOrder": 1
  }
}

Guarde o licenseOrder: e o identificador do pedido, usado para consultar o progresso e para cancelar.

Respostas de erro

Quando aconteceHTTPCorpo
Falta user_id ou to_guild200{ "message": "400: Bad Request", "code": 0, "error": "Missing parameters: to_guild , user_id" }
amount nao e numerico200{ "message": "Amount must be a number", "code": 0 }
to_guild ou user_id invalido200{ "message": "to_guild or user_id is invalid", "code": 0 }
Seu bot nao esta no servidor de destino200{ "message": "Guild not found", "code": 0, "convite": "https://discord.com/oauth2/authorize?..." }
Nenhum membro autenticado disponivel200{ "message": "No registered users found.", "code": 0 }
amount maior que o total disponivel200{ "message": "Amount greater than the number of registered users", "code": 0 }
Ja existe pedido ativo para esse servidor200{ "message": "There is already an active request for this server", "code": 0 }
GET/v1/auth/order

Consulta o status e o progresso de um pedido de puxada.

60 req / min

Retorna o pedido completo e a posicao dele na fila. Use para acompanhar o progresso depois de criar um pedido.

Parâmetros

CampoTipoEnvioDescrição
license_orderobrig.numberqueryO licenseOrder devolvido ao criar o pedido.

Exemplo de requisição

curl "https://auth.promisse.app/v1/auth/order?license_order=48273910" \
  -H "Authorization: SUA_API_KEY"

Resposta de sucesso

{
  "message": "OK",
  "code": 200,
  "order": {
    "license": 48273910,
    "status": "in_progress",
    "bot_id": "1376041252205887509",
    "user_id": "123456789012345678",
    "to_guild": "987654321098765432",
    "amount": 50,
    "from_server": "0",
    "server_name": "Meu Servidor",
    "date": "1757462400000",
    "pulled": { "success": 32, "failed": 3, "in_server": 5 }
  },
  "queue_position": 1
}

status assume os valores pending, in_progress, completed ou canceled. O objeto pulled traz o progresso parcial: success (puxados), failed (falharam) e in_server (ja estavam no servidor). queue_position e 1 para o pedido mais antigo da fila.

Respostas de erro

Quando aconteceHTTPCorpo
Falta license_order200{ "message": "400: Bad Request", "code": 0, "error": "Missing parameters: license_order" }
Pedido nao existe, nao e do seu bot, ou API key invalida200{ "message": "Order Request not found", "code": 0 }
DELETE/v1/auth/order

Cancela um pedido que ainda esta pending ou in_progress.

20 req / min

Cancela um pedido em andamento. Pedidos com status completed ou canceled nao podem ser cancelados.

Parâmetros

CampoTipoEnvioDescrição
license_orderobrig.numberqueryO licenseOrder do pedido a cancelar.

Exemplo de requisição

curl -X DELETE "https://auth.promisse.app/v1/auth/order?license_order=48273910" \
  -H "Authorization: SUA_API_KEY"

Resposta de sucesso

{
  "message": "Order Request successfully canceled",
  "code": 200
}

O pedido passa para o status canceled e sai da fila. Cancelar e idempotente no sentido pratico: uma segunda chamada para o mesmo pedido devolve Order Request not found, porque ele ja nao esta mais pending nem in_progress.

Respostas de erro

Quando aconteceHTTPCorpo
Falta license_order200{ "message": "400: Bad Request", "code": 0, "error": "Missing parameters: license_order" }
Pedido nao existe, nao esta pending/in_progress, ou API key invalida200{ "message": "Order Request not found", "code": 0 }
POST/v1/auth/updatePending

Recoloca um pedido na fila, voltando o status para pending.

60 req / min

Reenfileira um pedido existente do seu bot, util para retomar um pedido interrompido. Atencao: aqui o license_order vai no corpo da requisicao, diferente das rotas GET e DELETE de /v1/auth/order.

Parâmetros

CampoTipoEnvioDescrição
license_orderobrig.numberbodyO licenseOrder do pedido a reenfileirar.

Exemplo de requisição

curl -X POST https://auth.promisse.app/v1/auth/updatePending \
  -H "Authorization: SUA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "license_order": 48273910 }'

Resposta de sucesso

{
  "message": "Order Request successfully updated",
  "code": 200
}

Respostas de erro

Quando aconteceHTTPCorpo
Falta license_order200{ "message": "400: Bad Request", "code": 0, "error": "Missing parameters: license_order" }
API key invalida200{ "message": "401: Unauthorized", "code": 0 }
Pedido nao existe ou nao e do seu bot200{ "message": "Order Request not found", "code": 0 }
Seu bot nao esta mais no servidor de destino200{ "message": "Guild not found", "code": 0, "convite": "https://discord.com/oauth2/authorize?..." }
GET/v1/auth/orderserver

Conta quantos pedidos seu bot tem em cada status.

60 req / min

Retorna um resumo numerico dos seus pedidos, agrupados por status.

Parâmetros

CampoTipoEnvioDescrição
statusesopc.stringqueryLista de status separados por virgula, sem espacos. Padrao: completed,pending,in_progress

Exemplo de requisição

curl "https://auth.promisse.app/v1/auth/orderserver" \
  -H "Authorization: SUA_API_KEY"

# Filtrando status especificos (sem espaco depois da virgula)
curl "https://auth.promisse.app/v1/auth/orderserver?statuses=pending,canceled" \
  -H "Authorization: SUA_API_KEY"

Resposta de sucesso

{
  "message": "OK",
  "code": 200,
  "counts": {
    "completed": 12,
    "pending": 2,
    "in_progress": 1
  }
}

As chaves de counts sao exatamente os status pedidos em statuses. Status sem nenhum pedido vem com 0.

Respostas de erro

Quando aconteceHTTPCorpo
API key invalida401{ "message": "401: Unauthorized", "code": 0 }
Erro interno500{ "message": "Internal Server Error", "code": 0 }
GET/v1/auth/@me

Lista os membros autenticados no seu bot, ou apenas a contagem.

60 req / min

Retorna os dados da sua aplicacao no Discord junto com os membros autenticados. Atencao ao parametro type: ele muda o tipo do campo users.

Parâmetros

CampoTipoEnvioDescrição
typeopc."all" | "amount"queryall (padrao) retorna o array de IDs; amount retorna apenas a contagem. Qualquer outro valor devolve 400.

Exemplo de requisição

# Lista completa de IDs
curl "https://auth.promisse.app/v1/auth/@me" \
  -H "Authorization: SUA_API_KEY"

# Apenas a contagem
curl "https://auth.promisse.app/v1/auth/@me?type=amount" \
  -H "Authorization: SUA_API_KEY"

Resposta de sucesso

// type=all (padrao)
{
  "message": "OK",
  "code": 200,
  "users": ["123456789012345678", "234567890123456789"],
  "name": "Meu Bot",
  "uri": ["https://auth.promisse.app/login"],
  "id": "1376041252205887509"
}

// type=amount
{
  "message": "OK",
  "code": 200,
  "users": 1542,
  "name": "Meu Bot",
  "uri": ["https://auth.promisse.app/login"],
  "id": "1376041252205887509"
}

O campo users muda de tipo conforme o type: array de strings em all, numero inteiro em amount. Trate os dois casos no seu codigo. Em type=all a lista nao e paginada.

Respostas de erro

Quando aconteceHTTPCorpo
type diferente de all ou amount400{ "message": "400: Bad Request", "code": 0, "error": "type must be 'all' or 'amount'" }
API key invalida, ou token do seu bot revogado no Discord401{ "message": "401: Unauthorized", "code": 0 }
Falha ao consultar o Discord500{ "message": "Erro ao consultar o Discord", "code": 0 }
POST/v1/auth/@user

Consulta os dados de um membro autenticado especifico.

60 req / min

Retorna o registro de um membro que autenticou no seu bot. So encontra membros com autenticacao ativa.

Parâmetros

CampoTipoEnvioDescrição
user_idobrig.stringbodyID do usuario do Discord a consultar.

Exemplo de requisição

curl -X POST https://auth.promisse.app/v1/auth/@user \
  -H "Authorization: SUA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "user_id": "123456789012345678" }'

Resposta de sucesso

{
  "message": "OK",
  "code": 200,
  "user": {
    "bot_id": "1376041252205887509",
    "user_id": "123456789012345678",
    "user_name": "usuario",
    "servers": [{ "server_id": "987654321098765432" }],
    "verified_at": "1757462400000"
  }
}

As credenciais OAuth2 do membro (access_token, refresh_token, expiration_token) nunca sao retornadas por esta rota.

Respostas de erro

Quando aconteceHTTPCorpo
Falta user_id400{ "message": "400: Bad Request, user_id", "code": 0 }
API key invalida401{ "message": "401: Unauthorized", "code": 0 }
Usuario nao autenticado no seu bot200{ "message": "User not found", "code": 0, "bot_id": "..." }

Exemplo completo

Criando um pedido e acompanhando até o fim, com respeito ao rate limit.

const API_KEY = process.env.PROMISSE_API_KEY;
const BASE = "https://auth.promisse.app";

// 1. Cria o pedido
const criar = await fetch(`${BASE}/v1/auth/puxar`, {
  method: "POST",
  headers: { Authorization: API_KEY, "Content-Type": "application/json" },
  body: JSON.stringify({
    user_id: "123456789012345678",
    to_guild: "987654321098765432",
  }),
}).then((r) => r.json());

if (criar.code !== 200) throw new Error(criar.message);
const pedido = criar.licenseOrder;
console.log(`Pedido ${pedido} criado na posicao ${criar.info.positionOrder}`);

// 2. Acompanha ate terminar (intervalo de 5s respeita o limite de 60/min)
let status = "pending";
while (status === "pending" || status === "in_progress") {
  await new Promise((r) => setTimeout(r, 5000));

  const res = await fetch(
    `${BASE}/v1/auth/order?license_order=${pedido}`,
    { headers: { Authorization: API_KEY } },
  ).then((r) => r.json());

  if (res.code !== 200) throw new Error(res.message);

  status = res.order.status;
  const { success, failed, in_server } = res.order.pulled;
  console.log(`${status} - ok:${success} falhou:${failed} ja_estava:${in_server}`);
}

console.log("Finalizado com status:", status);

Precisa de ajuda?