Skip to content

API v1 — Referência de integração

Referência dos endpoints da API v1, para quem vai consumir a API (dev ou LLM). Cada funcionalidade tem sua própria página:

  • llm.mdguia auto-contido para LLMs e agentes: contrato completo, entrada/saída de cada endpoint, tipos TypeScript, cliente pronto, receitas de integração e regras a seguir. Comece por aqui se for uma LLM.
  • auth/ — registro, login, logout, refresh, recuperação de senha e verificação de e-mail.
  • organizations/ — CRUD de organizações.
  • users/ — CRUD de usuários dentro de uma organização.
  • clients/ — CRUD de clientes dentro de uma organização.

Base URL

https://api.fastgivr.com.br. Todos os caminhos abaixo são relativos a /v1 (ex.: POST /v1/auth/login).

Autenticação

Token Bearer (JWT) via header Authorization: Bearer <access_token>. O access_token é obtido em POST /v1/auth/register ou POST /v1/auth/login.

Rotas marcadas como 🔒 Autenticado exigem esse header. As demais são públicas.

Formato de resposta (envelope padrão)

Sucesso:

json
{
    "code": 200,
    "success": true,
    "<chave>": { "...": "..." },
    "message": "Mensagem opcional de sucesso"
}

A <chave> varia por endpoint (user, users, organization, organizations, data) — está indicada em cada endpoint documentado abaixo.

Erro:

json
{
    "code": 422,
    "success": false,
    "data": { "campo": ["mensagem de validação"] },
    "message": "Dados de entrada inválidos."
}

data traz os detalhes do erro (ex.: erros de validação por campo) quando existirem, ou null.

Contexto de organização (importante para users/ e clients/)

Um usuário pode pertencer a várias organizações. Os endpoints em organizations/ sempre operam sobre uma organização explícita ({id} na URL). Já os endpoints em users/ e clients/ operam sobre a organização em contexto, resolvida assim:

  1. Se o header organization ou X-Organization-Id for enviado com o uuid de uma organização à qual o usuário pertence, essa é a organização usada.
  2. Caso contrário, cai para a organização de maior id entre as quais o usuário pertence (a mais recente).
  3. Se o usuário não pertencer a nenhuma organização, a API responde com erro (organização não encontrada).

Recomendação para o front-end: sempre que o usuário estiver operando dentro de uma organização específica (ex.: um seletor de organização na UI), envie o header X-Organization-Id: <uuid-da-organizacao> em toda chamada a users/* e clients/*. O uuid de cada organização vem no campo uuid do objeto retornado por organizations/*.

Status de Organização

Valores possíveis do campo status: ACTIVE, INACTIVE, SUSPENDED, DISABLED, DISQUALIFIED, SOFT_DELETED, DELETED. Organizações são criadas com status INACTIVE por padrão.

Tipos genéricos (TypeScript)

Use estes tipos como base para qualquer chamada — todos os endpoints desta API respeitam o mesmo envelope:

ts
type ApiSuccess<T, Key extends string = "data"> = {
    code: number;
    success: true;
    message?: string;
} & { [K in Key]: T };

type ApiError = {
    code?: number;
    success: false;
    data: Record<string, string[]> | string | null;
    message: string;
};

type ApiResult<T, Key extends string = "data"> = ApiSuccess<T, Key> | ApiError;

Cliente mínimo (fetch)

Exemplo de wrapper que já resolve base URL, Authorization e o header de organização — use como referência para gerar o client do front-end:

ts
const BASE_URL = "https://api.fastgivr.com.br/v1";

type ApiOptions = {
    token?: string; // access_token retornado por /auth/login ou /auth/register
    organizationUuid?: string; // uuid da organização em contexto (rotas de /users)
    body?: unknown;
};

async function apiFetch<T = unknown>(
    method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE",
    path: string, // ex.: '/auth/login', '/organizations', '/users/5'
    { token, organizationUuid, body }: ApiOptions = {},
): Promise<T> {
    const headers: Record<string, string> = {
        "Content-Type": "application/json",
    };
    if (token) headers["Authorization"] = `Bearer ${token}`;
    if (organizationUuid) headers["X-Organization-Id"] = organizationUuid;

    const res = await fetch(`${BASE_URL}${path}`, {
        method,
        headers,
        body: body ? JSON.stringify(body) : undefined,
    });

    const json = await res.json();

    if (!res.ok || json.success === false) {
        throw new Error(json.message ?? "Erro desconhecido na API");
    }

    return json;
}

// Exemplos de uso:
// await apiFetch('POST', '/auth/login', { body: { email, password } });
// await apiFetch('GET', '/users', { token, organizationUuid });

Fluxos recomendados

Cadastro + primeira organização:

  1. POST /auth/register → guarda access_token.
  2. POST /organizations (com o token) → cria a primeira organização do usuário; guarde o uuid retornado — é o que vai no header X-Organization-Id daqui em diante.
  3. POST /auth/send-verification-code / POST /auth/verify-email → fluxo de verificação de e-mail (opcional, não bloqueia o uso da API).

Login e uso normal:

  1. POST /auth/login → guarda access_token.
  2. GET /auth/me → lista as organizações do usuário (organizations[].uuid); deixe o usuário escolher uma no seletor de organização da UI, se houver mais de uma.
  3. Toda chamada a /users/* inclui Authorization: Bearer <token> e X-Organization-Id: <uuid escolhido>.

Sessão expirada / token perto de expirar:

  • Use expires_in (segundos) da resposta de login/registro para agendar POST /auth/refresh antes de expirar, substituindo o access_token guardado.
  • Se qualquer chamada 🔒 retornar 401, o token está inválido/expirado — a resposta vem como {"success": false, ...}; redirecione para o login.