DocsAbrir Studio

Ingest HTTP

Um POST com um objeto JSON. Sem SDK, sem dependência — dá para usar de um script de uma linha.

Endpoints

POST /api/v1/submit
A key vai num header. É o caminho normal.
POST /api/v1/f/:apiKey
A key vai na URL. Útil quando você não controla os headers.
GET /api/v1/form
Devolve a definição do Form. Ver forma.form().

Autenticação

A API key identifica o Form. Ela é pública por natureza — vai no browser do seu cliente — então trate como identificador, não como segredo. Qualquer um destes serve:

Authorization: Bearer frm_…
O mais comum.
X-Forma-Key: frm_…
Quando Authorization já é usado por outra coisa.
X-Api-Key: frm_…
Alias do anterior.
/api/v1/f/frm_…
Na URL, sem header nenhum.
curl
curl -X POST https://forma.app/api/v1/submit \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer frm_..." \
  -d '{"email":"ana@acme.com","message":"…","rating":4}'
fetch
await fetch("https://forma.app/api/v1/submit", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-Forma-Key": "frm_...",
  },
  body: JSON.stringify({ email: "ana@acme.com", rating: 4 }),
});

O corpo

Precisa ser um objeto JSON — não um array, não um valor solto. Chaves a mais do que os Fields são guardadas e aparecem em Outros no Studio. Um Form sem Fields aceita qualquer objeto.

Limites

20 req/min por IP
Padrão. Muda com INGEST_RATE_LIMIT_IP.
60 req/min por API key
Padrão. Muda com INGEST_RATE_LIMIT_KEY.
100 KB
Tamanho máximo do corpo.
CORS aberto
Dá para postar direto do browser.

Ler a definição tem contador próprio, então consultar GET /api/v1/form nunca gasta o limite de envio.

Respostas

201
{ "ok": true, "id": "…" }
400
JSON inválido, corpo que não é objeto, ou um Field que não bate. A mensagem traz a key.
401
API key ausente.
404
Key desconhecida, ou o Form está pausado.
413
Corpo acima de 100 KB.
429
Limite estourado. O header Retry-After traz os segundos.