API para desenvolvedores

Documentação da API

Crie links protegidos, consulte análises com foco em privacidade e registre conversões do seu produto.

01

Faça sua primeira solicitação

A API é de servidor para servidor. Nunca exponha um token no JavaScript do navegador ou em um pacote móvel público.

  1. 1Ative Pro ou BusinessO acesso à API está disponível nos planos pagos compatíveis e durante o teste Pro.
  2. 2Crie um token com escopoEscolha apenas as permissões necessárias para sua integração no Console do Desenvolvedor.
  3. 3Envie por HTTPSAuthorization: Bearer 4ul_live_…
  4. 4Armazene como uma senhaO token completo é exibido uma vez. Revogue-o imediatamente se houver risco de exposição.
curl "https://4ul.ink/api/v1/links?per_page=1" \
  -H "Authorization: Bearer YOUR_TOKEN"
02

Referência de endpoints

Todo acesso a objetos é restrito ao workspace atribuído ao token.

MétodoCaminhoEscopoResultado
GET/api/v1/linkslinks:readLinks paginados
POST/api/v1/linkslinks:writeCria um link protegido
PATCH/api/v1/links/{id}links:writeAtualiza os campos enviados
DELETE/api/v1/links/{id}links:writeDesativa sem excluir análises
GET/api/v1/links/{id}/analyticsanalytics:readAnálises agregadas
POST/api/v1/conversionslinks:writeRegistra um evento atribuído
GET/api/v1/domainsdomains:readDomínios personalizados
POST/api/v1/domainsdomains:writeConectar um domínio
POST/api/v1/domains/{id}/verifydomains:writeVerificar DNS
DELETE/api/v1/domains/{id}domains:writeRemover
GET/api/v1/webhookswebhooks:readEndpoints de webhook
POST/api/v1/webhookswebhooks:writeAdicionar endpoint
PATCH/api/v1/webhooks/{id}webhooks:writeAtualiza os campos enviados
POST/api/v1/webhooks/{id}/testwebhooks:writeEnviar teste
POST/api/v1/webhooks/{id}/rotate-secretwebhooks:writeGirar segredo
DELETE/api/v1/webhooks/{id}webhooks:writeExcluir
03

Solicitações e respostas

Os nomes dos campos correspondem exatamente à API v1 ativa.

POST

Criar um link

links:write
{
    "destination_url": "https://example.com",
    "slug": "launch",
    "title": "Launch article"
}
destination_url
URL pública HTTP ou HTTPS obrigatória.
title
Opcional, até 190 caracteres.
slug
Alias personalizado opcional, de 3 a 80 caracteres.
201

Resposta do link

application/json
{
  "data": {
    "id": 123,
    "slug": "launch",
    "short_url": "https://4ul.ink/launch",
    "destination_url": "https://example.com/article",
    "title": "Launch article",
    "click_count": 0,
    "is_active": true,
    "created_at": "2026-07-25 12:00:00"
  }
}
GET

Listar links

?page=1&per_page=25
{
  "data": [{ "id": 123, "slug": "launch", "is_active": true }],
  "meta": {
    "page": 1,
    "per_page": 25,
    "total": 1,
    "total_pages": 1
  }
}

per_page aceita de 1 a 100. Os objetos de link usam a estrutura completa acima.

GET

Ler análises

analytics:read
/api/v1/links/123/analytics?period=custom
  &from=2026-07-01
  &to=2026-07-20

Os períodos são 7, 30, 90 ou custom. A resposta inclui visão geral, comparações, qualidade do tráfego, conversões, séries diárias, públicos e padrões horários, nunca IPs brutos.

PATCH

Atualizar um link

/api/v1/links/123
{
  "destination_url": "https://example.com/new",
  "title": "New title",
  "slug": "new-alias",
  "is_active": true
}

Somente os campos enviados mudam. Alterar o destino agenda automaticamente uma nova análise Nova Shield.

POST

Registrar uma conversão

/api/v1/conversions
{
  "click_token": "4ul_click_…",
  "event": "sale",
  "external_id": "order_1042",
  "amount": 49.00,
  "currency": "USD"
}

Os eventos são lead, sale ou refund. Um evento externo duplicado retorna HTTP 409 e nunca é contado duas vezes.

Escopos do token

links:read
lista links.
links:write
cria, atualiza e desativa links e registra conversões.
analytics:read
lê análises de links.
domains:read / domains:write
Domínios personalizados
webhooks:read / webhooks:write
Webhooks assinados

Limites de solicitações

Os tokens permitem 120 solicitações por minuto mais a cota mensal do workspace. Analytics tem limite adicional de 60 por minuto. HTTP 429 inclui Retry-After e RateLimit. Os redirecionamentos continuam funcionando.

Idempotência

Ao criar links, envie um Idempotency-Key de 8 a 128 caracteres imprimíveis. A chave vale por 24 horas no workspace. Uma repetição idêntica reproduz a resposta; dados diferentes com a mesma chave retornam HTTP 409.

HTTP

Erros

Os erros usam um formato JSON único. Status comuns: 400 JSON inválido, 401 token inválido, 403 sem escopo ou plano, 404 não encontrado, 409 conflito, 413 corpo grande, 415 tipo incorreto, 422 validação e 429 limite.

{
  "error": "destination_url must be a valid public HTTP or HTTPS URL.",
  "code": "invalid_destination",
  "field": "destination_url",
  "request_id": "req_7fd9c0c8d821e84b3d69d171",
  "error_details": {
    "code": "invalid_destination",
    "message": "destination_url must be a valid public HTTP or HTTPS URL.",
    "field": "destination_url",
    "request_id": "req_7fd9c0c8d821e84b3d69d171"
  }
}
HMAC

Verifique cada webhook

Eventos: link.created, link.updated, link.disabled, link.clicked, conversion.created, shield.status_changed e endpoint.test. A entrega automática tenta até cinco vezes.

Os webhooks de disponibilidade usam shield.availability_changed com transições e diagnósticos HTTP limitados, sem URLs de destino.

Cabeçalhos de entrega

X-4ulink-Event: conversion.created
X-4ulink-Delivery: EVENT_UUID
X-4ulink-Timestamp: UNIX_TIMESTAMP
X-4ulink-Signature: sha256=HEX_HMAC

Verificação em PHP

$raw = file_get_contents('php://input');
$signed = $timestamp . '.' . $raw;
$expected = 'sha256=' . hash_hmac('sha256', $signed, $secret);

if (!hash_equals($expected, $signature)) {
    http_response_code(401);
    exit;
}

Use o corpo bruto, compare assinaturas em tempo constante, rejeite timestamps com mais de cinco minutos e armazene X-4ulink-Delivery para tentativas idempotentes. O endpoint deve usar HTTPS público na porta 443.