Referência da API

Extração estruturada

Entra um PDF ou uma imagem, sai um JSON validado pelo seu schema. O OCR roda automaticamente quando é preciso.

Duas rotas, a mesma ideia: você descreve o formato que quer como um JSON Schema, e a resposta tem a garantia de ser válida contra ele. Você não extrai o texto por conta própria — o OCR roda automaticamente onde for necessário.

POST/v1/documents/extract
POST/v1/images/extract

Use /documents/extract para um PDF (o OCR só entra nas páginas escaneadas) e /images/extract para uma imagem avulsa — uma foto do celular, um print, um documento escaneado solto —, em que toda imagem passa pelo OCR.

Requisição

As duas recebem multipart/form-data com os mesmos campos:

filefileObrigatório

O PDF (/documents/extract) ou a imagem — JPEG, PNG ou WEBP (/images/extract). É obrigatório enviar ao menos um arquivo, em file ou em files.

filesfile[]Opcional

Vários arquivos numa só requisição — repita o campo uma vez por arquivo. Disponível a partir do Pro; no Go, um segundo arquivo devolve 413 (ele nunca é descartado em silêncio). file e files se combinam, na ordem em que foram enviados. Veja Vários arquivos numa requisição.

schemastringObrigatório

Um JSON Schema (como string) descrevendo os campos a extrair.

systemstringOpcional

Substitui o system prompt configurado na sua stack para esta requisição. Omita para manter o comportamento configurado da stack.

userstringOpcional

Contexto extra sobre este arquivo específico — somado à instrução de extração, não no lugar dela. Use para dizer que tipo de documento ou imagem é este quando a mesma stack trata vários.

max_tokensintegerOpcionalPadrão: 4000

Teto da resposta. Precisa ser maior que 0, até 16000.

Exemplo

curl -X POST "https://api.trystac.com/v1/documents/extract" \
  -H "Authorization: Bearer $STAC_API_KEY" \
  -F file=@nota-fiscal.pdf \
  -F 'schema={
        "type": "object",
        "properties": {
          "numero_nota":       {"type": "string"},
          "cnpj_fornecedor":   {"type": ["string", "null"]},
          "total":             {"type": "number"}
        },
        "required": ["numero_nota", "cnpj_fornecedor", "total"]
      }'
curl -X POST "https://api.trystac.com/v1/images/extract" \
  -H "Authorization: Bearer $STAC_API_KEY" \
  -F file=@nota-fiscal.jpg \
  -F 'schema={"type": "object", "properties": {"total": {"type": "number"}}, "required": ["total"]}'

Resposta

200 OKjson
{
  "data": { "numero_nota": "12345", "cnpj_fornecedor": "11.222.333/0001-81", "total": 1500.0 },
  "pages": 3,
  "files": 1,
  "ocr_used": false,
  "usage": { "prompt_tokens": 2104, "completion_tokens": 48 }
}
dataobjectOpcional

O seu JSON, já validado contra o schema.

pagesintegerOpcional

Número de páginas de um PDF, somado entre os arquivos quando há mais de um. Em /images/extract é o número de imagens (1 no caso comum) — não existe o conceito de "página" para uma imagem avulsa.

filesintegerOpcional

Quantos arquivos entraram nesta extração. Sempre presente (1 no caso comum).

ocr_usedbooleanOpcional

true se o OCR rodou. Em /images/extract é sempre true — toda imagem passa pelo OCR. Em /documents/extract só é true para páginas escaneadas; nesse caso vale revisar o resultado com mais cuidado.

A regra mais importante: campos que podem faltar precisam aceitar null

A saída é restrita por gramática para seguir o seu schema token a token — é isso que garante um JSON válido, mas tem uma consequência que decide a qualidade dos seus resultados:

Declare como anulável todo campo que possa legitimamente não existir:

json
"cnpj_fornecedor": { "type": ["string", "null"] }

Há uma segunda armadilha, na direção oposta: um campo fora de required é opcional no JSON Schema, então o modelo pode simplesmente omitir a chave em vez de procurar o valor — você recebe um 200 com JSON válido e um campo faltando, sem nenhum aviso. A combinação que evita as duas armadilhas é required em todos os campos, com tipos anuláveis nos que podem legitimamente faltar:

json
{
  "type": "object",
  "properties": {
    "numero_nota":     { "type": "string" },
    "cnpj_fornecedor": { "type": ["string", "null"] },
    "total":           { "type": "number" }
  },
  "required": ["numero_nota", "cnpj_fornecedor", "total"]
}

Isso vale também dentro de arrays e objetos aninhados — cada objeto de uma lista precisa do próprio required, ou os itens voltam com campos faltando em silêncio.

Vários arquivos numa requisição

Quando os campos que você quer estão espalhados entre documentos — a nota fiscal e o comprovante, o contrato e o aditivo —, envie todos numa só requisição por files e receba um JSON de volta. Disponível a partir do Pro.

curl -X POST "https://api.trystac.com/v1/documents/extract" \
  -H "Authorization: Bearer $STAC_API_KEY" \
  -F files=@nota-fiscal.pdf \
  -F files=@comprovante.pdf \
  -F 'schema={
        "type": "object",
        "properties": {
          "numero_nota":  {"type": "string"},
          "valor_pago":   {"type": ["number", "null"]}
        },
        "required": ["numero_nota", "valor_pago"]
      }' \
  -F 'user=O número da nota está na nota fiscal; o valor pago está no comprovante.'

Cada arquivo chega ao modelo num bloco numerado próprio, identificado pelo nome do arquivo (--- DOCUMENTO 1 DE 2 (nota-fiscal.pdf) ---), então o user pode dizer onde procurar cada campo.

  • O Go aceita 1 arquivo por requisição. Um segundo arquivo — em files, ou repetindo file — devolve 413 com uma mensagem explicando isso. Para vários documentos no Go, envie uma requisição por arquivo.
  • Os limites do plano valem para a soma. Tamanho e número de páginas são somados entre todos os arquivos da requisição, e ela é recusada antes de qualquer OCR rodar.
  • Um documento vazio aborta a requisição inteira (400, com o nome do arquivo). Seguir sem ele deixaria o modelo preencher o schema a partir dos outros arquivos sem que você tivesse como saber.
  • Quer um JSON por arquivo? Continue enviando uma requisição por arquivo — o envio de vários arquivos é para campos que moram em documentos diferentes.

Erros

StatusSignificado
400Arquivo ilegível ou corrompido, sem texto extraível, schema inválido, ou conteúdo grande demais para a janela de contexto do plano
413Tamanho do arquivo, número de arquivos, número de páginas/resolução, ou schema acima do limite do plano
422max_tokens fora do intervalo aceito, ou nenhum arquivo enviado
502A saída do modelo não passou na validação contra o schema (a resposta inclui raw_output para depuração)

Um raw_output truncado num 502 costuma significar que a resposta não coube no contexto restante — o arquivo é grande e sobrou pouco espaço para o JSON. Divida o PDF ou enxugue o schema.

Limites

LimiteRotaGoProEnterprise
Arquivos por requisiçãoas duas15Personalizado
Tamanho (soma dos arquivos)/documents/extract8 MB15 MBPersonalizado
Páginas por requisição (soma dos arquivos)/documents/extract1530Personalizado
Tamanho (soma dos arquivos)/images/extract5 MB10 MBPersonalizado
Resolução (por imagem)/images/extract20 megapixels20 megapixels20 megapixels

Schema de até 64 KB nas duas rotas. Timeout do servidor: 240s — configure o timeout do seu cliente acima disso; um documento escaneado de várias páginas pode levar minutos.