API pública v1

Documentação para integrações

Use esta página para implementar a criação, atualização e consulta de links curtos em galerias, CRMs, sistemas de orçamento, automações internas ou qualquer ferramenta de atendimento. Ela cobre apenas a API pública v1; rotas internas do painel, checkout e webhooks de cobrança não fazem parte deste contrato.

Base URL

https://api.sua.fot.br/v1

Contrato técnico

/api/v1/openapi.json

Atualização

15/05/2026

Módulo funcional

O painel cria chaves, mostra o token uma vez, permite revogar acessos e registra o último uso.

Isolamento por workspace

Cada chave acessa apenas o tenant dono dela, incluindo links e subdomínios cadastrados.

Escopos claros

Separe chaves de leitura, escrita e estatísticas conforme a necessidade de cada sistema terceiro.

Contrato atual

Pontos importantes desta versão antes de integrar em produção.

Healthcheck sem autenticação

GET /health confirma disponibilidade da API, mas não valida chave, escopos nem acesso ao workspace.

Listagem pontual

GET /links retorna a coleção atual sem paginação ou filtros. Não use esta rota para sincronização em massa.

Descrição persistida

O campo description pode ser enviado em criação e atualização, fica salvo e volta nas respostas de Link.

Referência sequencial

O campo reference_number é gerado automaticamente por tenant e não pode ser editado pela API.

Subdomínios do tenant

GET /subdomains retorna o subdomínio principal e os adicionais cadastrados para o sistema externo escolher sem preenchimento manual.

Limites documentados

Criação pode retornar 402 plan_limit_exceeded quando o workspace atinge a quantidade de links do plano. Clientes também devem tratar 503.

No Windows, se curl.exe só acessarapi.sua.fot.brcom --ssl-no-revoke, trate como sinal para revisar cadeia, OCSP e CRL do certificado. Essa flag deve ser usada apenas para diagnóstico.

Início rápido

Este é o fluxo recomendado para qualquer integração.

  1. 1Abra o dashboard em API & Integrações.
  2. 2Crie uma chave com os escopos necessários.
  3. 3Copie o token exibido uma única vez.
  4. 4Salve o token como segredo no sistema terceiro.
  5. 5Use GET /health apenas para checar disponibilidade da API.
  6. 6Use GET /subdomains para carregar os subdomínios disponíveis do tenant.
  7. 7Envie Authorization: Bearer em todas as chamadas protegidas.
  8. 8Use apenas subdomínios retornados pelo tenant ao criar links.
  9. 9Use Idempotency-Key ao criar links vindos de eventos externos.

Autenticação

As chamadas protegidas usam Bearer token. Nunca exponha a chave no navegador do cliente final.

Authorization: Bearer sk_suafot_xxxxx
links:read

Ler links por id e listar a coleção atual

links:write

Criar, editar e arquivar links

stats:read

Consultar estatísticas de links

Use GET /subdomainspara validar uma chave e carregar os subdomínios do tenant. UseGET /healthapenas como healthcheck público, sem validar chave ou escopos.

Subdomínios do tenant

Use GET /subdomains para buscar os subdomínios válidos antes de criar links em nome do cliente.

curl https://api.sua.fot.br/v1/subdomains \
  -H "Authorization: Bearer sk_suafot_xxxxx"
{
  "data": {
    "tenant": {
      "id": "2b6d7f80-0000-4000-9000-bd5e2f4f9f10",
      "name": "Estúdio Exemplo",
      "slug": "estudio-exemplo",
      "primary_subdomain_slug": "estudio-exemplo"
    },
    "subdomains": [
      {
        "slug": "estudio-exemplo",
        "url": "https://estudio-exemplo.sua.fot.br",
        "is_primary": true
      },
      {
        "slug": "casamentos",
        "url": "https://casamentos.sua.fot.br",
        "is_primary": false
      }
    ],
    "domains": [
      {
        "slug": "estudio-exemplo",
        "url": "https://estudio-exemplo.sua.fot.br",
        "is_primary": true
      },
      {
        "slug": "casamentos",
        "url": "https://casamentos.sua.fot.br",
        "is_primary": false
      }
    ]
  },
  "subdomains": [
    {
      "slug": "estudio-exemplo",
      "url": "https://estudio-exemplo.sua.fot.br",
      "is_primary": true
    },
    {
      "slug": "casamentos",
      "url": "https://casamentos.sua.fot.br",
      "is_primary": false
    }
  ],
  "domains": [
    {
      "slug": "estudio-exemplo",
      "url": "https://estudio-exemplo.sua.fot.br",
      "is_primary": true
    },
    {
      "slug": "casamentos",
      "url": "https://casamentos.sua.fot.br",
      "is_primary": false
    }
  ]
}

Ao criar ou atualizar links, envie em subdomain_slugapenas um slug retornado nessa lista. Para usar o subdomínio principal, você pode omitir o campo.

Para compatibilidade com integrações já existentes, os mesmos dados também respondem em/tenant/subdomains,/workspace/subdomainse /domains.

Resposta de criação

O campo short_url já vem pronto para compartilhar, e o bloco tenant confirma os subdomínios disponíveis para a chave.

{
  "tenant": {
    "id": "2b6d7f80-0000-4000-9000-bd5e2f4f9f10",
    "name": "Estúdio Exemplo",
    "slug": "estudio-exemplo",
    "primary_subdomain_slug": "estudio-exemplo",
    "subdomains": [
      {
        "slug": "estudio-exemplo",
        "url": "https://estudio-exemplo.sua.fot.br",
        "is_primary": true
      },
      {
        "slug": "casamentos",
        "url": "https://casamentos.sua.fot.br",
        "is_primary": false
      }
    ]
  },
  "data": {
    "id": "b4c0d4f2-0000-4000-9000-2a0d5d8e7f31",
    "reference_number": 1,
    "short_url": "https://casamentos.sua.fot.br/ana-joao",
    "slug": "ana-joao",
    "subdomain_slug": "casamentos",
    "destination_url": "https://galeria.exemplo.com/casamento-ana-joao",
    "link_type": "gallery",
    "title": "Galeria Ana e João",
    "description": "Link enviado pelo Memora",
    "external_id": "galeria-ana-joao-2026",
    "status": "active",
    "expires_at": "2026-12-31T23:59:59.999Z",
    "click_count": 0,
    "created_at": "2026-05-13T19:52:09.000Z",
    "updated_at": "2026-05-13T19:52:09.000Z"
  },
  "idempotent": false
}

Endpoints disponíveis

Todos os endpoints abaixo retornam JSON, exceto DELETE /links/{id}, que retorna 204 sem corpo quando arquiva com sucesso.

MétodoCaminhoEscopoUso
GET/healthpúblicoConfirma disponibilidade. Não valida chave nem escopos.
GET/tenantqualquer chave válidaRetorna o tenant da chave, o subdomínio principal e os adicionais cadastrados.
GET/subdomainsqualquer chave válidaLista os subdomínios do tenant. Também há aliases em /tenant/subdomains, /workspace/subdomains e /domains.
GET/linkslinks:readLista os links do workspace. Sem paginação ou filtros nesta versão.
POST/linkslinks:writeCria um link curto e retorna short_url, id e dados do link.
GET/links/{id}links:readBusca um link específico pelo id interno retornado pela API.
PATCH/links/{id}links:writeAtualiza destino, slug, tipo, validade, status ou campos descritivos.
DELETE/links/{id}links:writeArquiva o link. Ele deixa de redirecionar, mas o histórico continua preservado.
GET/links/{id}/statsstats:readRetorna total de cliques, cliques por dia e principais origens.

Exemplo em JavaScript

Use no backend do sistema terceiro, nunca direto no frontend público.

const response = await fetch("https://api.sua.fot.br/v1/links", {
  method: "POST",
  headers: {
    "Authorization": "Bearer " + process.env.SUAFOT_API_KEY,
    "Content-Type": "application/json",
    "Idempotency-Key": "pedido-123"
  },
  body: JSON.stringify({
    destination_url: "https://galeria.exemplo.com/pedido-123",
    link_type: "gallery",
    title: "Galeria do pedido 123",
    external_id: "pedido-123"
  })
});

const payload = await response.json();
if (!response.ok) throw new Error(payload.error?.message);
return payload.data.short_url;

Exemplo em PHP

Útil para CRMs, sistemas de orçamento e plataformas com backend PHP.

$payload = [
  "destination_url" => "https://galeria.exemplo.com/pedido-123",
  "link_type" => "gallery",
  "title" => "Galeria do pedido 123",
  "external_id" => "pedido-123"
];

$ch = curl_init("https://api.sua.fot.br/v1/links");
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer " . getenv("SUAFOT_API_KEY"),
    "Content-Type: application/json",
    "Idempotency-Key: pedido-123"
  ],
  CURLOPT_POSTFIELDS => json_encode($payload)
]);

$result = json_decode(curl_exec($ch), true);
$shortUrl = $result["data"]["short_url"];

Erros e idempotência

Planeje o sistema terceiro para tratar erro de validação, falta de escopo, plano sem espaço para novos links e repetição de eventos.

HTTPCódigoQuando acontece
401missing_api_keyA chamada não enviou Authorization: Bearer.
403invalid_api_keyA chave não existe, foi revogada ou expirou.
403missing_scopeA chave não tem a permissão necessária para o endpoint.
402plan_limit_exceededO workspace atingiu o limite de links do plano atual.
413payload_too_largeO JSON enviado é maior que o limite aceito pela rota.
429api_rate_limit_exceededO tenant atingiu o limite mensal de chamadas da API.
404not_foundO recurso não existe dentro do workspace da chave.
422validation_errorO payload enviado não passou na validação.
503service_not_configuredA API ainda não está configurada no ambiente.

Idempotency-Key

Envie um valor estável por evento externo, como id do pedido, id da galeria ou id do cliente. Se a mesma chave chegar de novo, a API retorna o link já criado em vez de duplicar.

Quantidade de links

Se o workspace atingir a quantidade de links do plano, a criação retorna 402 com o código plan_limit_exceeded.

Limite de API

Quando o tenant atinge o limite mensal de chamadas, a API retorna 429 com o código api_rate_limit_exceeded.

Serviço indisponível

Mesmo em produção, trate 503 como falha temporária de configuração ou ambiente e tente novamente mais tarde.

Prompts para Vibe Coding

Copie estes prompts para pedir a implementação em outro sistema com menos ambiguidade.

Implementar criação automática de link

Implemente uma integração backend com a API do sua.fot.br. Use a base URL https://api.sua.fot.br/v1. A chave deve ficar em variável de ambiente SUAFOT_API_KEY. Ao publicar uma galeria, envie POST /links com Authorization Bearer, Content-Type application/json e Idempotency-Key igual ao id da galeria. O body deve enviar destination_url, link_type "gallery", title, description e external_id. Salve id e short_url retornados no registro da galeria. Trate erros 401, 402, 403, 422 e 503 com mensagens claras no painel administrativo.

Sincronizar atualização de link

Adicione uma rotina para atualizar links já criados no sua.fot.br. Quando a URL da galeria ou o título mudar, chame PATCH https://api.sua.fot.br/v1/links/{id}. Use Authorization Bearer com SUAFOT_API_KEY. Envie apenas os campos alterados. Se a API retornar 404, mostre que o link não pertence ao workspace da chave. Se retornar 422, exiba a mensagem da API para o usuário.

Buscar estatísticas

Crie uma tela administrativa que leia estatísticas do sua.fot.br. Para cada link salvo, chame GET https://api.sua.fot.br/v1/links/{id}/stats usando uma chave com escopo stats:read. Mostre total_clicks, clicks_by_day e top_referrers. Faça cache curto no backend para evitar chamadas repetidas em sequência.

Criar cliente reutilizável

Crie um cliente de API chamado SuaFotClient com métodos getSubdomains, getTenant, createLink, updateLink, archiveLink, getLink, listLinks e getStats. O cliente deve receber apiKey e baseUrl no construtor, montar o header Authorization Bearer, enviar JSON, interpretar respostas de erro no formato { error: { code, message } } e nunca expor a chave no frontend. Use getSubdomains em GET /subdomains para carregar os subdomínios disponíveis e use listLinks apenas para conferência pontual, porque GET /links ainda não tem paginação ou filtros.

Checklist de produção

Antes de liberar a integração para clientes reais, confirme estes pontos.

  • A chave está salva como segredo no backend do sistema terceiro.
  • A integração usa Idempotency-Key em toda criação automática.
  • O sistema salva id e short_url retornados pela API.
  • GET /health é usado só como healthcheck, sem validar chave ou escopos.
  • Erros 401, 402, 403, 422 e 503 têm tratamento visível para o operador.
  • A chave tem apenas os escopos necessários.
  • O domínio wildcard dos links por workspace está configurado em produção.