API de capture
Tudo no Kilden entra por um único endpoint:
POST https://ingest.kilden.io/captureContent-Type: application/jsonOs SDKs o usam por baixo dos panos; você pode chamá-lo diretamente de qualquer backend, script ou integração. Não existe outro caminho de escrita.
Requisição
Seção intitulada “Requisição”O corpo é sempre um batch — um evento único é um batch de um:
{ "write_key": "YOUR_WRITE_KEY", "sent_at": "2026-07-11T12:00:00.000Z", "batch": [ { "uuid": "0197f9d2-5e5a-7cc3-b1a4-1f0e9a2b3c4d", "event": "order_completed", "distinct_id": "user_4821", "properties": { "total": 49.9, "currency": "EUR" }, "timestamp": "2026-07-11T11:59:58.000Z" } ]}| Campo | Obrigatório | Notas |
|---|---|---|
write_key |
sim | Key pública ou secreta, no corpo (não em header). Keys secretas marcam os eventos como fatos server-side — veja Níveis de confiança |
sent_at |
não | Quando o cliente enviou a requisição. Usado apenas para corrigir o desvio de relógio do cliente: real_time ≈ timestamp + (server_now − sent_at) |
batch |
sim | 1 a 1000 eventos |
identity_token |
não | Slot de fallback para o JWT de verificação de identidade quando um header é impossível (sendBeacon). O header Authorization vence se ambos estiverem presentes |
Por evento:
| Campo | Obrigatório | Notas |
|---|---|---|
uuid |
sim | Um UUID válido, gerado pelo cliente. Use UUID v7. Esta é a chave de idempotência: retries com o mesmo uuid são deduplicados, então repetir a requisição diante de qualquer falha é sempre seguro |
event |
sim | Nome do evento, ≤ 200 caracteres. Nomes com prefixo $ são reservados para o sistema |
distinct_id |
sim | ≤ 512 caracteres. UUID v7 com prefixo anon_ = anônimo; qualquer outra coisa é tratada como id de usuário identificado |
properties |
não | Qualquer objeto JSON. Nunca validado por schema — o envelope é tipado, o payload é seu |
timestamp |
não | ISO 8601. Padrão: hora de recebimento no servidor; corrigido com sent_at quando ambos estão presentes |
Headers:
Authorization: Bearer <jwt>— token de verificação de identidade para o batch inteiro (um batch pertence a uma sessão de navegador). Máx. 4096 bytes.Content-Encoding: gzip— suportado e recomendado para batches grandes.
Limites: corpo da requisição ≤ 5 MiB, batch ≤ 1000 eventos.
Resposta
Seção intitulada “Resposta”200 assim que o batch é validado e enfileirado (o capture nunca bloqueia esperando o processamento downstream):
{ "status": "ok" }Os erros são texto puro, não JSON:
| Status | Significado |
|---|---|
400 |
Requisição malformada: invalid JSON body: …, invalid gzip body, write_key is required, batch must not be empty, batch exceeds 1000 events, batch[i]: uuid is not a valid UUID, batch[i]: event is required, batch[i]: event exceeds 200 chars, batch[i]: distinct_id is required, batch[i]: distinct_id exceeds 512 chars, batch[i]: properties is not valid JSON, identity token too large |
401 |
unknown write_key |
403 |
origin not allowed for this project — veja origens permitidas |
405 |
Método diferente de POST/OPTIONS |
Falhas de validação rejeitam o batch inteiro — corrija e reenvie (os UUIDs tornam isso seguro).
Exemplo server-side
Seção intitulada “Exemplo server-side”curl -X POST https://ingest.kilden.io/capture \ -H 'Content-Type: application/json' \ -d '{ "write_key": "sk_your_secret_key", "sent_at": "2026-07-11T12:00:00Z", "batch": [{ "uuid": "0197f9d2-5e5a-7cc3-b1a4-1f0e9a2b3c4d", "event": "subscription_renewed", "distinct_id": "user_4821", "properties": {"plan": "pro", "mrr": 49}, "timestamp": "2026-07-11T12:00:00Z" }] }'Eventos enviados com uma key secreta são marcados como source=server e verified=true — a key secreta é a autenticação. Nunca embuta uma key secreta em um navegador ou app mobile; é para isso que existem as keys públicas.
/capture é um endpoint público de escrita, aberto a CORS por design:
- Toda resposta carrega
Access-Control-Allow-Origin: *(sem credenciais). - O preflight
OPTIONSresponde204comAccess-Control-Allow-Methods: POST,Access-Control-Allow-Headers: Content-Type, Authorization, Content-Encoding,Access-Control-Max-Age: 86400.
Origens permitidas
Seção intitulada “Origens permitidas”Uma write key pública fica visível no código-fonte da sua página, então qualquer um poderia copiá-la. Para impedir que outros sites poluam seus dados, configure origens permitidas nas configurações do projeto: quando a lista não está vazia, requisições de navegador cujo Origin não casa recebem 403.
- Padrões:
scheme://host[:port], com wildcards de subdomínio (https://*.example.com— não casa com o apex; liste os dois se precisar). - Lista vazia (padrão) = permitir tudo.
- Requisições sem header
Origin(curl, backends, apps mobile) sempre passam — esse vetor é coberto pelas keys secretas e pela verificação de identidade, não pela checagem de Origin. Isto é redução de ruído contra o reuso real de keys em navegadores, não uma fronteira de segurança.