Um contrato para construir.
Explore operações, scopes, entradas e respostas da API proposta.
Operações
GET/questionsListar questões autorizadas em um snapshot estável
Scope: questions:read · operationId: listQuestions
| Parâmetro | Local | Obrigatório | Contrato |
|---|---|---|---|
| Idempotency-Key | header | Não | Opcional em leitura faturável; retry da mesma operação e parâmetros reaproveita recibo e snapshot por 48h. Chave com parâmetros diferentes retorna 409. Sem chave, cada leitura é independente. Revogação de direitos prevalece sobre replay. |
| cursor | query | Não | {"type":"string"} |
| limit | query | Não | {"type":"integer","minimum":1,"maximum":100,"default":20} |
| board_id | query | Não | {"type":"string"} |
| position_id | query | Não | Obrigatório quando quality=certified; servidor retorna 422 se faltar escopo |
| quality | query | Sim | {"type":"string","enum":["available","certified"]} |
Respostas
200 Objetos entregues são medidos; certified nunca inclui candidatos
{
"description": "Objetos entregues são medidos; certified nunca inclui candidatos",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/QuestionPage"
}
}
}
}default Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade
{
"description": "Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade",
"headers": {
"Retry-After": {
"schema": {
"type": "integer",
"minimum": 0
}
}
},
"content": {
"application/problem+json": {
"schema": {
"type": "object",
"required": [
"type",
"title",
"status",
"code",
"request_id"
],
"properties": {
"type": {
"type": "string",
"format": "uri"
},
"title": {
"type": "string"
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"code": {
"type": "string"
},
"request_id": {
"type": "string"
},
"detail": {
"type": "string"
}
}
}
}
}
}GET/questions/{id}getQuestion
Scope: questions:read · operationId: getQuestion
| Parâmetro | Local | Obrigatório | Contrato |
|---|---|---|---|
| Idempotency-Key | header | Não | Opcional em leitura faturável; retry da mesma operação e parâmetros reaproveita recibo e snapshot por 48h. Chave com parâmetros diferentes retorna 409. Sem chave, cada leitura é independente. Revogação de direitos prevalece sobre replay. |
| id | path | Sim | {"type":"string","minLength":1} |
| revision | query | Não | {"type":"integer","minimum":1} |
| If-None-Match | header | Não | {"type":"string"} |
Respostas
200 Item com origem, licença e estados de qualidade
{
"description": "Item com origem, licença e estados de qualidade",
"headers": {
"ETag": {
"schema": {
"type": "string"
}
},
"X-Usage-Receipt-Id": {
"schema": {
"type": "string"
}
}
},
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Question"
}
}
}
}304 Sem alteração e sem nova cobrança de objeto
{
"description": "Sem alteração e sem nova cobrança de objeto"
}410 Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade
{
"description": "Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade",
"headers": {
"Retry-After": {
"schema": {
"type": "integer",
"minimum": 0
}
}
},
"content": {
"application/problem+json": {
"schema": {
"type": "object",
"required": [
"type",
"title",
"status",
"code",
"request_id"
],
"properties": {
"type": {
"type": "string",
"format": "uri"
},
"title": {
"type": "string"
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"code": {
"type": "string"
},
"request_id": {
"type": "string"
},
"detail": {
"type": "string"
}
}
}
}
}
}default Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade
{
"description": "Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade",
"headers": {
"Retry-After": {
"schema": {
"type": "integer",
"minimum": 0
}
}
},
"content": {
"application/problem+json": {
"schema": {
"type": "object",
"required": [
"type",
"title",
"status",
"code",
"request_id"
],
"properties": {
"type": {
"type": "string",
"format": "uri"
},
"title": {
"type": "string"
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"code": {
"type": "string"
},
"request_id": {
"type": "string"
},
"detail": {
"type": "string"
}
}
}
}
}
}POST/searchsearch
Scope: search:read · operationId: search
| Parâmetro | Local | Obrigatório | Contrato |
|---|---|---|---|
| Idempotency-Key | header | Sim | Mesmo tenant, operação, chave e payload reaproveitam resultado por pelo menos 48 horas |
Corpo da requisição
{
"type": "object",
"additionalProperties": false,
"required": [
"query",
"mode",
"quality",
"price_version",
"max_credits"
],
"allOf": [
{
"if": {
"properties": {
"quality": {
"const": "certified"
}
}
},
"then": {
"required": [
"position_id"
]
}
}
],
"properties": {
"query": {
"type": "string",
"minLength": 1,
"maxLength": 4000
},
"mode": {
"type": "string",
"enum": [
"lexical",
"semantic"
],
"description": "Seleciona S01 ou S02 antes da cobrança"
},
"position_id": {
"type": "string"
},
"quality": {
"type": "string",
"enum": [
"available",
"certified"
]
},
"limit": {
"type": "integer",
"minimum": 1,
"maximum": 20,
"default": 10
},
"price_version": {
"type": "string"
},
"max_amount_brl": {
"type": "number",
"minimum": 0,
"deprecated": true
},
"max_credits": {
"type": "number",
"minimum": 0,
"description": "Créditos de serviço; 1 crédito = R$0,01 nesta versão."
}
}
}Respostas
200 IDs e scores de relevância; score não representa certificação
{
"description": "IDs e scores de relevância; score não representa certificação",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"snapshot_id",
"matches",
"abstained",
"usage_receipt_id"
],
"properties": {
"snapshot_id": {
"type": "string"
},
"matches": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"revision",
"score"
],
"properties": {
"id": {
"type": "string"
},
"revision": {
"type": "integer",
"minimum": 1
},
"score": {
"type": "number",
"description": "Score específico do retrieval; não probabilidade"
}
}
}
},
"abstained": {
"type": "boolean"
},
"abstention_reason": {
"type": [
"string",
"null"
]
},
"usage_receipt_id": {
"type": "string"
}
}
}
}
}
}default Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade
{
"description": "Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade",
"headers": {
"Retry-After": {
"schema": {
"type": "integer",
"minimum": 0
}
}
},
"content": {
"application/problem+json": {
"schema": {
"type": "object",
"required": [
"type",
"title",
"status",
"code",
"request_id"
],
"properties": {
"type": {
"type": "string",
"format": "uri"
},
"title": {
"type": "string"
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"code": {
"type": "string"
},
"request_id": {
"type": "string"
},
"detail": {
"type": "string"
}
}
}
}
}
}GET/exams/{id}getExam
Scope: exams:read · operationId: getExam
| Parâmetro | Local | Obrigatório | Contrato |
|---|---|---|---|
| id | path | Sim | {"type":"string","minLength":1} |
Respostas
200 Concurso e estado documental; campos não documentados permanecem nulos
{
"description": "Concurso e estado documental; campos não documentados permanecem nulos",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"id",
"revision",
"title",
"evidence_stage",
"position_ids",
"document_version_ids"
],
"properties": {
"id": {
"type": "string"
},
"revision": {
"type": "integer",
"minimum": 1
},
"title": {
"type": "string"
},
"program_id": {
"type": [
"string",
"null"
]
},
"evidence_stage": {
"type": "string",
"enum": [
"regulated",
"allocation_documented",
"authorization_documented",
"organizer_contracted",
"notice_published",
"registration_open",
"suspended",
"cancelled",
"completed"
]
},
"position_ids": {
"type": "array",
"items": {
"type": "string"
}
},
"document_version_ids": {
"type": "array",
"items": {
"type": "string"
}
},
"exam_date": {
"type": [
"string",
"null"
],
"format": "date"
}
}
}
}
}
}default Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade
{
"description": "Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade",
"headers": {
"Retry-After": {
"schema": {
"type": "integer",
"minimum": 0
}
}
},
"content": {
"application/problem+json": {
"schema": {
"type": "object",
"required": [
"type",
"title",
"status",
"code",
"request_id"
],
"properties": {
"type": {
"type": "string",
"format": "uri"
},
"title": {
"type": "string"
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"code": {
"type": "string"
},
"request_id": {
"type": "string"
},
"detail": {
"type": "string"
}
}
}
}
}
}GET/positions/{id}/syllabusgetSyllabus
Scope: syllabi:read · operationId: getSyllabus
| Parâmetro | Local | Obrigatório | Contrato |
|---|---|---|---|
| id | path | Sim | {"type":"string","minLength":1} |
| layer | query | Sim | {"type":"string","enum":["documentary","pedagogical"]} |
| as_of | query | Não | {"type":"string","format":"date-time"} |
Respostas
200 Pacote versionado; vazio não é preenchido por inferência de atribuições
{
"description": "Pacote versionado; vazio não é preenchido por inferência de atribuições",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"position_id",
"revision",
"layer",
"nodes"
],
"properties": {
"position_id": {
"type": "string"
},
"revision": {
"type": "integer",
"minimum": 1
},
"layer": {
"type": "string",
"enum": [
"documentary",
"pedagogical"
]
},
"nodes": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Node"
}
}
}
}
}
}
}default Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade
{
"description": "Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade",
"headers": {
"Retry-After": {
"schema": {
"type": "integer",
"minimum": 0
}
}
},
"content": {
"application/problem+json": {
"schema": {
"type": "object",
"required": [
"type",
"title",
"status",
"code",
"request_id"
],
"properties": {
"type": {
"type": "string",
"format": "uri"
},
"title": {
"type": "string"
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"code": {
"type": "string"
},
"request_id": {
"type": "string"
},
"detail": {
"type": "string"
}
}
}
}
}
}POST/quotesOrçar tarefa antes de reservar saldo; sem cobrança
Scope: jobs:write · operationId: createQuote
Corpo da requisição
{
"type": "object",
"additionalProperties": false,
"required": [
"sku",
"input"
],
"properties": {
"sku": {
"type": "string",
"enum": [
"D02",
"D03",
"D04",
"A01",
"Q06"
]
},
"input": {
"description": "Input completo; servidor verifica dimensões, autorização, política e compatibilidade com SKU antes de calcular digest",
"oneOf": [
{
"$ref": "#/components/schemas/DocumentJobInput"
},
{
"$ref": "#/components/schemas/RecurrenceInput"
},
{
"$ref": "#/components/schemas/ClassificationInput"
}
]
}
}
}Respostas
201 Cotação vinculada a tenant, input, SKU e política; validade curta
{
"description": "Cotação vinculada a tenant, input, SKU e política; validade curta",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"id",
"expires_at",
"max_amount_brl",
"price_version",
"input_digest",
"max_credits",
"components"
],
"properties": {
"id": {
"type": "string"
},
"expires_at": {
"type": "string",
"format": "date-time"
},
"max_amount_brl": {
"type": "number",
"minimum": 0
},
"price_version": {
"type": "string"
},
"input_digest": {
"type": "string",
"pattern": "^[a-f0-9]{64}$"
},
"max_credits": {
"type": "number",
"minimum": 0,
"description": "Créditos de serviço; 1 crédito = R$0,01 nesta versão."
},
"components": {
"type": "array",
"items": {
"type": "object",
"required": [
"sku",
"quantity",
"credits"
],
"properties": {
"sku": {
"type": "string"
},
"quantity": {
"type": "number",
"minimum": 0
},
"credits": {
"type": "number",
"minimum": 0
}
}
},
"description": "Decomposição do orçamento, incluindo extração/programa quando necessários; sem dupla cobrança."
}
}
}
}
}
}default Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade
{
"description": "Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade",
"headers": {
"Retry-After": {
"schema": {
"type": "integer",
"minimum": 0
}
}
},
"content": {
"application/problem+json": {
"schema": {
"type": "object",
"required": [
"type",
"title",
"status",
"code",
"request_id"
],
"properties": {
"type": {
"type": "string",
"format": "uri"
},
"title": {
"type": "string"
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"code": {
"type": "string"
},
"request_id": {
"type": "string"
},
"detail": {
"type": "string"
}
}
}
}
}
}POST/document-jobscreateDocumentJob
Scope: documents:write · operationId: createDocumentJob
| Parâmetro | Local | Obrigatório | Contrato |
|---|---|---|---|
| Idempotency-Key | header | Sim | Mesmo tenant, operação, chave e payload reaproveitam resultado por pelo menos 48 horas |
Corpo da requisição
{
"type": "object",
"additionalProperties": false,
"required": [
"input",
"quote_id",
"max_credits"
],
"properties": {
"input": {
"$ref": "#/components/schemas/DocumentJobInput"
},
"quote_id": {
"type": "string"
},
"max_amount_brl": {
"type": "number",
"minimum": 0,
"deprecated": true
},
"max_credits": {
"type": "number",
"minimum": 0,
"description": "Créditos de serviço; 1 crédito = R$0,01 nesta versão."
}
}
}Respostas
202 Job aceito com reserva de saldo; não equivale a certificado
{
"description": "Job aceito com reserva de saldo; não equivale a certificado",
"headers": {
"Location": {
"schema": {
"type": "string"
}
}
},
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Job"
}
}
}
}409 Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade
{
"description": "Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade",
"headers": {
"Retry-After": {
"schema": {
"type": "integer",
"minimum": 0
}
}
},
"content": {
"application/problem+json": {
"schema": {
"type": "object",
"required": [
"type",
"title",
"status",
"code",
"request_id"
],
"properties": {
"type": {
"type": "string",
"format": "uri"
},
"title": {
"type": "string"
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"code": {
"type": "string"
},
"request_id": {
"type": "string"
},
"detail": {
"type": "string"
}
}
}
}
}
}default Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade
{
"description": "Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade",
"headers": {
"Retry-After": {
"schema": {
"type": "integer",
"minimum": 0
}
}
},
"content": {
"application/problem+json": {
"schema": {
"type": "object",
"required": [
"type",
"title",
"status",
"code",
"request_id"
],
"properties": {
"type": {
"type": "string",
"format": "uri"
},
"title": {
"type": "string"
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"code": {
"type": "string"
},
"request_id": {
"type": "string"
},
"detail": {
"type": "string"
}
}
}
}
}
}GET/jobs/{id}getJob
Scope: jobs:read · operationId: getJob
| Parâmetro | Local | Obrigatório | Contrato |
|---|---|---|---|
| id | path | Sim | {"type":"string","minLength":1} |
Respostas
200 Estado sem custo; resultado parcial explicitado
{
"description": "Estado sem custo; resultado parcial explicitado",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Job"
}
}
}
}default Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade
{
"description": "Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade",
"headers": {
"Retry-After": {
"schema": {
"type": "integer",
"minimum": 0
}
}
},
"content": {
"application/problem+json": {
"schema": {
"type": "object",
"required": [
"type",
"title",
"status",
"code",
"request_id"
],
"properties": {
"type": {
"type": "string",
"format": "uri"
},
"title": {
"type": "string"
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"code": {
"type": "string"
},
"request_id": {
"type": "string"
},
"detail": {
"type": "string"
}
}
}
}
}
}POST/analyses/recurrencecreateRecurrenceAnalysis
Scope: analytics:read · operationId: createRecurrenceAnalysis
| Parâmetro | Local | Obrigatório | Contrato |
|---|---|---|---|
| Idempotency-Key | header | Sim | Mesmo tenant, operação, chave e payload reaproveitam resultado por pelo menos 48 horas |
Corpo da requisição
{
"type": "object",
"additionalProperties": false,
"required": [
"input",
"quote_id",
"max_credits"
],
"properties": {
"input": {
"$ref": "#/components/schemas/RecurrenceInput"
},
"quote_id": {
"type": "string"
},
"max_amount_brl": {
"type": "number",
"minimum": 0,
"deprecated": true
},
"max_credits": {
"type": "number",
"minimum": 0,
"description": "Créditos de serviço; 1 crédito = R$0,01 nesta versão."
}
}
}Respostas
202 Análise assíncrona; resultado com contagens, denominadores, cobertura e abstenção
{
"description": "Análise assíncrona; resultado com contagens, denominadores, cobertura e abstenção",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Job"
}
}
}
}default Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade
{
"description": "Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade",
"headers": {
"Retry-After": {
"schema": {
"type": "integer",
"minimum": 0
}
}
},
"content": {
"application/problem+json": {
"schema": {
"type": "object",
"required": [
"type",
"title",
"status",
"code",
"request_id"
],
"properties": {
"type": {
"type": "string",
"format": "uri"
},
"title": {
"type": "string"
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"code": {
"type": "string"
},
"request_id": {
"type": "string"
},
"detail": {
"type": "string"
}
}
}
}
}
}GET/certifications/{id}getCertification
Scope: evidence:read · operationId: getCertification
| Parâmetro | Local | Obrigatório | Contrato |
|---|---|---|---|
| id | path | Sim | {"type":"string","minLength":1} |
Respostas
200 Estado atual, inclusive revogação; sem custo para objeto autorizado
{
"description": "Estado atual, inclusive revogação; sem custo para objeto autorizado",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"id",
"object_id",
"object_revision",
"status",
"policy_version",
"scope",
"issued_at",
"evidence",
"reviewer_ref",
"dependency_digest"
],
"properties": {
"id": {
"type": "string"
},
"object_id": {
"type": "string"
},
"object_revision": {
"type": "integer",
"minimum": 1
},
"status": {
"type": "string",
"enum": [
"active",
"revoked",
"superseded"
]
},
"policy_version": {
"type": "string"
},
"scope": {
"type": "array",
"minItems": 1,
"items": {
"type": "string"
}
},
"issued_at": {
"type": "string",
"format": "date-time"
},
"reviewer_ref": {
"type": "string",
"description": "Identificador auditável do responsável; sem dados pessoais"
},
"dependency_digest": {
"type": "string",
"pattern": "^[a-f0-9]{64}$"
},
"reason": {
"type": [
"string",
"null"
]
},
"evidence": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/components/schemas/SourceRef"
}
}
}
}
}
}
}default Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade
{
"description": "Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade",
"headers": {
"Retry-After": {
"schema": {
"type": "integer",
"minimum": 0
}
}
},
"content": {
"application/problem+json": {
"schema": {
"type": "object",
"required": [
"type",
"title",
"status",
"code",
"request_id"
],
"properties": {
"type": {
"type": "string",
"format": "uri"
},
"title": {
"type": "string"
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"code": {
"type": "string"
},
"request_id": {
"type": "string"
},
"detail": {
"type": "string"
}
}
}
}
}
}GET/changeslistChanges
Scope: changes:read · operationId: listChanges
| Parâmetro | Local | Obrigatório | Contrato |
|---|---|---|---|
| cursor | query | Não | {"type":"string"} |
| limit | query | Não | {"type":"integer","minimum":1,"maximum":100,"default":20} |
Respostas
200 Feed autorizado; cursor inicial cria baseline, expirado retorna 410 e requer snapshot
{
"description": "Feed autorizado; cursor inicial cria baseline, expirado retorna 410 e requer snapshot",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"events",
"next_cursor"
],
"properties": {
"events": {
"type": "array",
"items": {
"$ref": "./event.schema.json"
}
},
"next_cursor": {
"type": "string"
}
}
}
}
}
}410 Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade
{
"description": "Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade",
"headers": {
"Retry-After": {
"schema": {
"type": "integer",
"minimum": 0
}
}
},
"content": {
"application/problem+json": {
"schema": {
"type": "object",
"required": [
"type",
"title",
"status",
"code",
"request_id"
],
"properties": {
"type": {
"type": "string",
"format": "uri"
},
"title": {
"type": "string"
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"code": {
"type": "string"
},
"request_id": {
"type": "string"
},
"detail": {
"type": "string"
}
}
}
}
}
}default Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade
{
"description": "Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade",
"headers": {
"Retry-After": {
"schema": {
"type": "integer",
"minimum": 0
}
}
},
"content": {
"application/problem+json": {
"schema": {
"type": "object",
"required": [
"type",
"title",
"status",
"code",
"request_id"
],
"properties": {
"type": {
"type": "string",
"format": "uri"
},
"title": {
"type": "string"
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"code": {
"type": "string"
},
"request_id": {
"type": "string"
},
"detail": {
"type": "string"
}
}
}
}
}
}GET/usagegetUsage
Scope: billing:read · operationId: getUsage
| Parâmetro | Local | Obrigatório | Contrato |
|---|---|---|---|
| month | query | Sim | {"type":"string","pattern":"^\\d{4}-\\d{2}$"} |
Respostas
200 Agregados reconciliáveis; montantes inteiros em microcentavos BRL
{
"description": "Agregados reconciliáveis; montantes inteiros em microcentavos BRL",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"currency",
"entries"
],
"properties": {
"currency": {
"type": "string",
"const": "BRL"
},
"entries": {
"type": "array",
"items": {
"type": "object",
"required": [
"sku",
"quantity",
"amount_microcents",
"price_version",
"credits"
],
"properties": {
"sku": {
"type": "string"
},
"quantity": {
"type": "number",
"minimum": 0
},
"amount_microcents": {
"type": "integer"
},
"price_version": {
"type": "string"
},
"credits": {
"type": "number",
"description": "Ajustes podem ser negativos; BRL equivalente não é débito adicional."
}
}
}
}
}
}
}
}
}default Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade
{
"description": "Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade",
"headers": {
"Retry-After": {
"schema": {
"type": "integer",
"minimum": 0
}
}
},
"content": {
"application/problem+json": {
"schema": {
"type": "object",
"required": [
"type",
"title",
"status",
"code",
"request_id"
],
"properties": {
"type": {
"type": "string",
"format": "uri"
},
"title": {
"type": "string"
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"code": {
"type": "string"
},
"request_id": {
"type": "string"
},
"detail": {
"type": "string"
}
}
}
}
}
}POST/classification-jobsClassificar prova contra edital/cargo com abstenção
Scope: classification:write · operationId: createClassificationJob
| Parâmetro | Local | Obrigatório | Contrato |
|---|---|---|---|
| Idempotency-Key | header | Sim | Mesmo tenant, operação, chave e payload reaproveitam resultado por pelo menos 48 horas |
Corpo da requisição
{
"type": "object",
"additionalProperties": false,
"required": [
"input",
"quote_id",
"max_credits"
],
"properties": {
"input": {
"$ref": "#/components/schemas/ClassificationInput"
},
"quote_id": {
"type": "string"
},
"max_credits": {
"type": "number",
"minimum": 0,
"description": "Créditos de serviço; 1 crédito = R$0,01 nesta versão."
}
}
}Respostas
202 Aceito; não é declaração de aderência ou anulação
{
"description": "Aceito; não é declaração de aderência ou anulação",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Job"
}
}
}
}default Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade
{
"description": "Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade",
"headers": {
"Retry-After": {
"schema": {
"type": "integer",
"minimum": 0
}
}
},
"content": {
"application/problem+json": {
"schema": {
"type": "object",
"required": [
"type",
"title",
"status",
"code",
"request_id"
],
"properties": {
"type": {
"type": "string",
"format": "uri"
},
"title": {
"type": "string"
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"code": {
"type": "string"
},
"request_id": {
"type": "string"
},
"detail": {
"type": "string"
}
}
}
}
}
}GET/walletgetWallet
Scope: billing:read · operationId: getWallet
Respostas
200 Saldo e reserva auditáveis; sem cartão
{
"description": "Saldo e reserva auditáveis; sem cartão",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"available_credits",
"reserved_credits",
"brl_per_credit",
"price_version"
],
"properties": {
"available_credits": {
"type": "number",
"minimum": 0,
"description": "Créditos de serviço; 1 crédito = R$0,01 nesta versão."
},
"reserved_credits": {
"type": "number",
"minimum": 0,
"description": "Créditos de serviço; 1 crédito = R$0,01 nesta versão."
},
"brl_per_credit": {
"type": "number",
"const": 0.01
},
"price_version": {
"type": "string"
}
}
}
}
}
}default Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade
{
"description": "Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade",
"headers": {
"Retry-After": {
"schema": {
"type": "integer",
"minimum": 0
}
}
},
"content": {
"application/problem+json": {
"schema": {
"type": "object",
"required": [
"type",
"title",
"status",
"code",
"request_id"
],
"properties": {
"type": {
"type": "string",
"format": "uri"
},
"title": {
"type": "string"
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"code": {
"type": "string"
},
"request_id": {
"type": "string"
},
"detail": {
"type": "string"
}
}
}
}
}
}POST/uploadsPreparar upload privado de PDF para URL temporária
Scope: uploads:write · operationId: createUpload
| Parâmetro | Local | Obrigatório | Contrato |
|---|---|---|---|
| Idempotency-Key | header | Sim | Mesmo tenant, operação, chave e payload reaproveitam resultado por pelo menos 48 horas |
Corpo da requisição
{
"type": "object",
"additionalProperties": false,
"required": [
"purpose",
"content_type",
"byte_size",
"sha256"
],
"properties": {
"purpose": {
"type": "string",
"enum": [
"edict",
"exam",
"answer_key",
"private_corpus"
]
},
"content_type": {
"const": "application/pdf"
},
"byte_size": {
"type": "integer",
"minimum": 1,
"maximum": 26214400
},
"sha256": {
"type": "string",
"pattern": "^[a-f0-9]{64}$"
}
}
}Respostas
201 Upload pendente; PUT na URL sem chave de API, com headers retornados
{
"description": "Upload pendente; PUT na URL sem chave de API, com headers retornados",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Upload"
}
}
}
}default Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade
{
"description": "Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade",
"headers": {
"Retry-After": {
"schema": {
"type": "integer",
"minimum": 0
}
}
},
"content": {
"application/problem+json": {
"schema": {
"type": "object",
"required": [
"type",
"title",
"status",
"code",
"request_id"
],
"properties": {
"type": {
"type": "string",
"format": "uri"
},
"title": {
"type": "string"
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"code": {
"type": "string"
},
"request_id": {
"type": "string"
},
"detail": {
"type": "string"
}
}
}
}
}
}POST/uploads/{id}/completeFinalizar upload e iniciar validações de arquivo/hash
Scope: uploads:write · operationId: completeUpload
| Parâmetro | Local | Obrigatório | Contrato |
|---|---|---|---|
| id | path | Sim | {"type":"string","minLength":1} |
| Idempotency-Key | header | Sim | Mesmo tenant, operação, chave e payload reaproveitam resultado por pelo menos 48 horas |
Respostas
202 Verificação iniciada; consultar GET /uploads/{id}
{
"description": "Verificação iniciada; consultar GET /uploads/{id}",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Upload"
}
}
}
}default Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade
{
"description": "Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade",
"headers": {
"Retry-After": {
"schema": {
"type": "integer",
"minimum": 0
}
}
},
"content": {
"application/problem+json": {
"schema": {
"type": "object",
"required": [
"type",
"title",
"status",
"code",
"request_id"
],
"properties": {
"type": {
"type": "string",
"format": "uri"
},
"title": {
"type": "string"
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"code": {
"type": "string"
},
"request_id": {
"type": "string"
},
"detail": {
"type": "string"
}
}
}
}
}
}GET/uploads/{id}Consultar estado da validação do PDF
Scope: uploads:read · operationId: getUpload
| Parâmetro | Local | Obrigatório | Contrato |
|---|---|---|---|
| id | path | Sim | {"type":"string","minLength":1} |
Respostas
200 Somente ready pode ser usado em jobs
{
"description": "Somente ready pode ser usado em jobs",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Upload"
}
}
}
}default Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade
{
"description": "Erro tipado sem segredo; código HTTP distingue autorização, saldo, conflito, limite e indisponibilidade",
"headers": {
"Retry-After": {
"schema": {
"type": "integer",
"minimum": 0
}
}
},
"content": {
"application/problem+json": {
"schema": {
"type": "object",
"required": [
"type",
"title",
"status",
"code",
"request_id"
],
"properties": {
"type": {
"type": "string",
"format": "uri"
},
"title": {
"type": "string"
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"code": {
"type": "string"
},
"request_id": {
"type": "string"
},
"detail": {
"type": "string"
}
}
}
}
}
}Modelos de dados
Os schemas abaixo preservam referências, condições e obrigatoriedade. A OpenAPI baixável é a fonte do contrato.
DocumentJobInput
{
"type": "object",
"additionalProperties": false,
"required": [
"upload_ids",
"task",
"quality_policy"
],
"properties": {
"upload_ids": {
"type": "array",
"minItems": 1,
"maxItems": 10,
"uniqueItems": true,
"items": {
"type": "string",
"minLength": 1
},
"description": "Uploads validados e imutáveis do tenant; tamanho e hash verificados no servidor"
},
"task": {
"type": "string",
"enum": [
"extract_syllabus",
"reconcile_documents"
]
},
"position_id": {
"type": "string"
},
"quality_policy": {
"type": "string",
"enum": [
"extracted",
"documentary_certified"
]
}
},
"allOf": [
{
"if": {
"properties": {
"task": {
"const": "extract_syllabus"
}
}
},
"then": {
"required": [
"position_id"
]
}
}
]
}RecurrenceInput
{
"type": "object",
"additionalProperties": false,
"required": [
"position_id",
"syllabus_revision",
"date_from",
"date_to"
],
"properties": {
"position_id": {
"type": "string"
},
"syllabus_revision": {
"type": "integer",
"minimum": 1
},
"date_from": {
"type": "string",
"format": "date"
},
"date_to": {
"type": "string",
"format": "date"
},
"board_id": {
"type": "string"
}
},
"description": "Servidor valida intervalo e congela população/taxonomia na cotação; mudança de dependência exige nova cotação"
}SourceRef
{
"type": "object",
"required": [
"document_version_id",
"sha256",
"locator"
],
"properties": {
"document_version_id": {
"type": "string"
},
"sha256": {
"type": "string",
"pattern": "^[a-f0-9]{64}$"
},
"page": {
"type": "integer",
"minimum": 1
},
"locator": {
"type": "string",
"minLength": 1
},
"source_url": {
"type": "string",
"format": "uri"
}
}
}Quality
{
"type": "object",
"required": [
"documentary_status",
"semantic_status",
"currentness",
"certificate_ids"
],
"allOf": [
{
"if": {
"anyOf": [
{
"properties": {
"documentary_status": {
"const": "certified"
}
}
},
{
"properties": {
"semantic_status": {
"const": "certified"
}
}
}
]
},
"then": {
"properties": {
"certificate_ids": {
"minItems": 1
}
}
}
}
],
"properties": {
"documentary_status": {
"type": "string",
"enum": [
"candidate",
"reviewed",
"certified",
"rejected"
]
},
"semantic_status": {
"type": "string",
"enum": [
"not_assessed",
"candidate",
"certified",
"abstained",
"rejected"
]
},
"currentness": {
"type": "string",
"enum": [
"current",
"superseded",
"conflicted",
"unknown"
]
},
"certificate_ids": {
"type": "array",
"items": {
"type": "string"
}
}
}
}Question
{
"type": "object",
"required": [
"id",
"revision",
"statement",
"style",
"choices",
"answer",
"provenance",
"quality",
"license_id",
"origin",
"exam_id",
"board_id",
"year",
"semantic_mappings",
"assets"
],
"properties": {
"id": {
"type": "string"
},
"revision": {
"type": "integer",
"minimum": 1
},
"statement": {
"type": "string"
},
"style": {
"type": "string",
"enum": [
"multiple_choice",
"true_false",
"other"
]
},
"choices": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"text"
],
"properties": {
"id": {
"type": "string"
},
"text": {
"type": "string"
}
}
}
},
"answer": {
"type": "object",
"required": [
"revision",
"status",
"correct_choice_ids"
],
"properties": {
"revision": {
"type": "integer",
"minimum": 1
},
"status": {
"type": "string",
"enum": [
"unknown",
"preliminary",
"final",
"annulled"
]
},
"correct_choice_ids": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"provenance": {
"type": "array",
"items": {
"$ref": "#/components/schemas/SourceRef"
}
},
"quality": {
"$ref": "#/components/schemas/Quality"
},
"license_id": {
"type": "string"
},
"origin": {
"type": "string",
"enum": [
"official_exam",
"client_owned",
"synthetic"
]
},
"exam_id": {
"type": [
"string",
"null"
]
},
"board_id": {
"type": [
"string",
"null"
]
},
"year": {
"type": [
"integer",
"null"
],
"minimum": 1900
},
"semantic_mappings": {
"type": "array",
"items": {
"$ref": "#/components/schemas/SemanticMapping"
}
},
"assets": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"url",
"expires_at",
"sha256",
"media_type",
"alt_text"
],
"properties": {
"id": {
"type": "string"
},
"url": {
"type": "string",
"format": "uri"
},
"expires_at": {
"type": "string",
"format": "date-time"
},
"sha256": {
"type": "string",
"pattern": "^[a-f0-9]{64}$"
},
"media_type": {
"type": "string"
},
"alt_text": {
"type": [
"string",
"null"
]
}
}
}
}
}
}SemanticMapping
{
"type": "object",
"required": [
"id",
"concept_id",
"taxonomy_revision",
"position_id",
"syllabus_revision",
"relation",
"status",
"certificate_id",
"evidence"
],
"properties": {
"id": {
"type": "string"
},
"concept_id": {
"type": "string"
},
"taxonomy_revision": {
"type": "integer",
"minimum": 1
},
"position_id": {
"type": [
"string",
"null"
]
},
"syllabus_revision": {
"type": [
"integer",
"null"
],
"minimum": 1
},
"relation": {
"type": "string",
"enum": [
"assesses",
"maps_to",
"broader_than",
"narrower_than",
"equivalent_to"
]
},
"status": {
"type": "string",
"enum": [
"candidate",
"certified",
"rejected",
"abstained"
]
},
"certificate_id": {
"type": [
"string",
"null"
]
},
"evidence": {
"type": "array",
"items": {
"$ref": "#/components/schemas/SourceRef"
}
}
},
"allOf": [
{
"if": {
"properties": {
"status": {
"const": "certified"
}
}
},
"then": {
"properties": {
"certificate_id": {
"type": "string",
"minLength": 1
},
"evidence": {
"minItems": 1
}
}
}
}
]
}QuestionPage
{
"type": "object",
"required": [
"items",
"snapshot_id",
"next_cursor",
"changes_cursor",
"usage_receipt_id"
],
"properties": {
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Question"
}
},
"snapshot_id": {
"type": "string"
},
"next_cursor": {
"type": [
"string",
"null"
]
},
"changes_cursor": {
"type": "string",
"description": "Watermark capturado atomicamente com snapshot; iniciar feed após completar paginação para não perder mudanças"
},
"usage_receipt_id": {
"type": [
"string",
"null"
]
}
}
}Node
{
"type": "object",
"required": [
"id",
"revision",
"parent_id",
"label",
"literal_text",
"provenance",
"quality",
"applicable_position_ids",
"semantic_mappings"
],
"properties": {
"id": {
"type": "string"
},
"revision": {
"type": "integer",
"minimum": 1
},
"parent_id": {
"type": [
"string",
"null"
]
},
"label": {
"type": "string"
},
"literal_text": {
"type": [
"string",
"null"
]
},
"applicable_position_ids": {
"type": "array",
"minItems": 1,
"items": {
"type": "string"
}
},
"semantic_mappings": {
"type": "array",
"items": {
"$ref": "#/components/schemas/SemanticMapping"
}
},
"provenance": {
"type": "array",
"items": {
"$ref": "#/components/schemas/SourceRef"
}
},
"quality": {
"$ref": "#/components/schemas/Quality"
}
}
}Job
{
"type": "object",
"required": [
"id",
"status",
"result",
"error",
"usage_receipt_id"
],
"properties": {
"id": {
"type": "string"
},
"status": {
"type": "string",
"enum": [
"queued",
"processing",
"review_required",
"completed",
"partial",
"failed",
"cancelled"
]
},
"result": {
"type": [
"object",
"null"
],
"required": [
"artifact_id",
"revision",
"download_url",
"expires_at",
"artifact_type"
],
"description": "Ponteiro para artefato versionado autorizado; resultado analítico usa schema RecurrenceResult",
"properties": {
"artifact_id": {
"type": "string"
},
"revision": {
"type": "integer",
"minimum": 1
},
"download_url": {
"type": "string",
"format": "uri"
},
"expires_at": {
"type": "string",
"format": "date-time"
},
"artifact_type": {
"type": "string",
"enum": [
"documentary",
"recurrence",
"classification"
]
}
}
},
"error": {
"type": [
"string",
"null"
]
},
"usage_receipt_id": {
"type": [
"string",
"null"
]
}
}
}RecurrenceResult
{
"type": "object",
"required": [
"snapshot_id",
"taxonomy_revision",
"population_count",
"eligible_count",
"coverage_ratio",
"abstained",
"topics"
],
"properties": {
"snapshot_id": {
"type": "string"
},
"taxonomy_revision": {
"type": "integer",
"minimum": 1
},
"population_count": {
"type": "integer",
"minimum": 0
},
"eligible_count": {
"type": "integer",
"minimum": 0
},
"coverage_ratio": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"abstained": {
"type": "boolean"
},
"topics": {
"type": "array",
"items": {
"type": "object",
"required": [
"concept_id",
"count",
"denominator"
],
"properties": {
"concept_id": {
"type": "string"
},
"count": {
"type": "integer",
"minimum": 0
},
"denominator": {
"type": "integer",
"minimum": 0
},
"frequency": {
"type": [
"number",
"null"
],
"minimum": 0,
"maximum": 1
}
}
}
}
}
}ClassificationInput
{
"type": "object",
"additionalProperties": false,
"required": [
"edict_upload_id",
"exam_upload_id",
"answer_key_upload_id",
"position_label",
"sharing_mode"
],
"properties": {
"edict_upload_id": {
"type": "string"
},
"exam_upload_id": {
"type": "string"
},
"answer_key_upload_id": {
"type": "string"
},
"position_label": {
"type": "string",
"minLength": 1
},
"sharing_mode": {
"type": "string",
"enum": [
"private",
"public_contribution"
]
},
"rights_attestation_id": {
"type": "string"
},
"language": {
"type": "string",
"default": "pt-BR"
}
},
"allOf": [
{
"if": {
"properties": {
"sharing_mode": {
"const": "public_contribution"
}
}
},
"then": {
"required": [
"rights_attestation_id"
]
}
}
],
"description": "Uploads autorizados e cargo obrigatório; contribuição exige direitos compatíveis. Extração/programa novos são componentes do orçamento, sem duplicidade."
}ClassificationResult
{
"type": "object",
"required": [
"job_id",
"model_version",
"syllabus_revision",
"expected_items",
"extracted_items",
"items"
],
"properties": {
"job_id": {
"type": "string"
},
"model_version": {
"type": "string"
},
"syllabus_revision": {
"type": "integer",
"minimum": 1
},
"expected_items": {
"type": [
"integer",
"null"
],
"minimum": 0
},
"extracted_items": {
"type": "integer",
"minimum": 0
},
"items": {
"type": "array",
"items": {
"type": "object",
"required": [
"question_id",
"status",
"mappings",
"evidence"
],
"properties": {
"question_id": {
"type": "string"
},
"status": {
"type": "string",
"enum": [
"supported_match",
"ambiguous",
"no_supported_match",
"insufficient_extraction",
"review_required"
]
},
"mappings": {
"type": "array",
"items": {
"$ref": "#/components/schemas/SemanticMapping"
}
},
"evidence": {
"type": "array",
"items": {
"$ref": "#/components/schemas/SourceRef"
}
}
}
}
}
},
"description": "no_supported_match é indício para revisão, não conclusão jurídica."
}UploadRequest
{
"type": "object",
"additionalProperties": false,
"required": [
"purpose",
"content_type",
"byte_size",
"sha256"
],
"properties": {
"purpose": {
"type": "string",
"enum": [
"edict",
"exam",
"answer_key",
"private_corpus"
]
},
"content_type": {
"const": "application/pdf"
},
"byte_size": {
"type": "integer",
"minimum": 1,
"maximum": 26214400
},
"sha256": {
"type": "string",
"pattern": "^[a-f0-9]{64}$"
}
}
}Upload
{
"type": "object",
"additionalProperties": false,
"required": [
"id",
"status",
"expires_at"
],
"properties": {
"id": {
"type": "string"
},
"status": {
"type": "string",
"enum": [
"pending",
"verifying",
"ready",
"rejected"
]
},
"expires_at": {
"type": "string",
"format": "date-time"
},
"put_url": {
"type": "string",
"format": "uri"
},
"required_headers": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"reason": {
"type": [
"string",
"null"
]
}
},
"allOf": [
{
"if": {
"properties": {
"status": {
"const": "pending"
}
}
},
"then": {
"required": [
"put_url",
"required_headers"
]
}
}
]
}Autenticação
{
"ApiKey": {
"type": "apiKey",
"in": "header",
"name": "X-API-Key",
"description": "Chave opaca server-to-server; nunca chave service_role"
}
}