{
    "openapi": "3.1.0",
    "info": {
        "title": "API EuMonitoro",
        "version": "1.0.0",
        "summary": "Acesso programático às coletas e indicadores de monitoramento ambiental.",
        "description": "Os mesmos dados que você vê na plataforma, disponíveis para o seu BI, ERP ou portal.\n\n**Autenticação** — token Bearer emitido em *Integrações e API* no painel do gestor.\nO token pertence à organização, não a uma pessoa: ele continua valendo quando alguém\nsai da empresa.\n\n**Envelope estável** — a resposta de uma coleta tem sempre as mesmas chaves e os\nmesmos tipos, qualquer que seja a normativa. O que é específico de cada normativa\nfica isolado em `dados_normativa`, fora da garantia de versão.\n\n**Limites** — aplicados por organização, nunca por token: criar credenciais novas\nnão aumenta a cota.",
        "contact": {
            "name": "Suporte EuMonitoro",
            "url": "https://eumonitoro.eco.br/contato"
        }
    },
    "servers": [
        {
            "url": "https://eumonitoro.eco.br/api/v1",
            "description": "Produção"
        }
    ],
    "tags": [
        {
            "name": "Projetos",
            "description": "Projetos de monitoramento e suas cotas de coleta."
        },
        {
            "name": "Coletas",
            "description": "Coletas de campo já processadas e normalizadas."
        },
        {
            "name": "Indicadores",
            "description": "Números consolidados — os mesmos do relatório entregue ao órgão."
        },
        {
            "name": "Escrita",
            "description": "Alterações de dado. Exigem nível Automação e ficam registradas na trilha de auditoria."
        },
        {
            "name": "Ingestão",
            "description": "Envio de coletas do seu próprio sistema. Nível Engine."
        }
    ],
    "security": [
        {
            "tokenBearer": []
        }
    ],
    "paths": {
        "/projetos": {
            "get": {
                "tags": [
                    "Projetos"
                ],
                "summary": "Lista os projetos da organização",
                "operationId": "listarProjetos",
                "security": [
                    {
                        "tokenBearer": [
                            "projetos.read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "Filtra pelo status do projeto.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "pendente",
                                "ativo",
                                "erro",
                                "arquivado"
                            ]
                        }
                    },
                    {
                        "$ref": "#/components/parameters/limite"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Página de projetos.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Colecao"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Projeto"
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/NaoAutenticado"
                    },
                    "403": {
                        "$ref": "#/components/responses/SemPermissao"
                    },
                    "429": {
                        "$ref": "#/components/responses/LimiteExcedido"
                    }
                }
            }
        },
        "/projetos/{projeto}": {
            "get": {
                "tags": [
                    "Projetos"
                ],
                "summary": "Detalha um projeto, com a cota de coletas",
                "operationId": "obterProjeto",
                "security": [
                    {
                        "tokenBearer": [
                            "projetos.read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/projeto"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Projeto com o bloco de cota.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/ProjetoComCota"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NaoEncontrado"
                    }
                }
            }
        },
        "/projetos/{projeto}/coletas": {
            "post": {
                "tags": [
                    "Ingestão"
                ],
                "summary": "Envia uma coleta do seu próprio sistema",
                "description": "A coleta percorre o mesmo motor das que vêm do ODK: é normalizada pelo processador da normativa do projeto, tem as espécies enriquecidas e passa a alimentar os indicadores. A cota do projeto vale igual — acima dela a coleta é aceita porém fica retida.",
                "operationId": "ingerirColeta",
                "x-disponivel": false,
                "security": [
                    {
                        "tokenBearer": [
                            "coletas.ingest"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/projeto"
                    },
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "description": "Chave única por envio. Com ela, reenviar após timeout devolve a resposta original em vez de duplicar a coleta.",
                        "schema": {
                            "type": "string",
                            "maxLength": 128
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/ColetaEntrada"
                            },
                            "example": {
                                "raw_data": {
                                    "DIA": "2026-08-20",
                                    "INICIO_GRUPO": {
                                        "ID_PROP": "Fazenda Nova"
                                    },
                                    "P_GRUPO": {
                                        "PARCELAS": "7"
                                    }
                                },
                                "coletado_em": "2026-08-20T09:00:00-03:00",
                                "coletor": "Equipe de campo A",
                                "identificador_externo": "coleta-4821"
                            }
                        }
                    }
                },
                "responses": {
                    "202": {
                        "description": "Coleta aceita. `status` indica se entrou na cota (`raw`) ou ficou retida (`retido`).",
                        "headers": {
                            "Location": {
                                "description": "URL da coleta criada.",
                                "schema": {
                                    "type": "string"
                                }
                            },
                            "Idempotency-Replayed": {
                                "description": "Presente quando a resposta veio da chave de idempotência.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "coleta_id": {
                                                    "type": "integer"
                                                },
                                                "projeto_id": {
                                                    "type": "integer"
                                                },
                                                "status": {
                                                    "type": "string",
                                                    "enum": [
                                                        "raw",
                                                        "retido"
                                                    ]
                                                },
                                                "ativa": {
                                                    "type": "boolean"
                                                },
                                                "mensagem": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NaoEncontrado"
                    },
                    "409": {
                        "$ref": "#/components/responses/IdempotenciaConflito"
                    },
                    "422": {
                        "$ref": "#/components/responses/PayloadInvalido"
                    }
                }
            },
            "patch": {
                "tags": [
                    "Escrita"
                ],
                "summary": "Inclui ou exclui em massa as coletas do projeto",
                "description": "As coletas retidas por cota ficam de fora: não foram processadas e não podem entrar em cálculo algum.",
                "operationId": "atualizarColetasEmMassa",
                "security": [
                    {
                        "tokenBearer": [
                            "coletas.write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/projeto"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "ativa"
                                ],
                                "properties": {
                                    "ativa": {
                                        "type": "boolean"
                                    }
                                }
                            },
                            "example": {
                                "ativa": true
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Contagem do resultado.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "afetadas": {
                                                    "type": "integer"
                                                },
                                                "ativas": {
                                                    "type": "integer"
                                                },
                                                "inativas": {
                                                    "type": "integer"
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NaoEncontrado"
                    }
                }
            },
            "get": {
                "tags": [
                    "Coletas"
                ],
                "summary": "Lista as coletas de um projeto",
                "operationId": "listarColetas",
                "security": [
                    {
                        "tokenBearer": [
                            "coletas.read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/projeto"
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "Estado da coleta no pipeline de processamento.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "raw",
                                "processado",
                                "erro",
                                "retido"
                            ]
                        }
                    },
                    {
                        "name": "ativa",
                        "in": "query",
                        "required": false,
                        "description": "Apenas coletas incluídas (ou excluídas) dos cálculos.",
                        "schema": {
                            "type": "boolean"
                        }
                    },
                    {
                        "name": "coletado_apos",
                        "in": "query",
                        "required": false,
                        "description": "Data mínima de coleta (ISO 8601).",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "coletado_antes",
                        "in": "query",
                        "required": false,
                        "description": "Data máxima de coleta (ISO 8601).",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/limite"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Página de coletas.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Colecao"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Coleta"
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NaoEncontrado"
                    },
                    "422": {
                        "$ref": "#/components/responses/PayloadInvalido"
                    }
                }
            }
        },
        "/coletas/{coleta}": {
            "get": {
                "tags": [
                    "Coletas"
                ],
                "summary": "Detalha uma coleta",
                "operationId": "obterColeta",
                "security": [
                    {
                        "tokenBearer": [
                            "coletas.read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/coleta"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Coleta no envelope estável.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Coleta"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NaoEncontrado"
                    }
                }
            },
            "patch": {
                "tags": [
                    "Escrita"
                ],
                "summary": "Inclui ou exclui a coleta dos cálculos",
                "description": "A coleta não é apagada: sai dos indicadores mas continua auditável. Coleta retida por cota não pode ser ativada.",
                "operationId": "atualizarColeta",
                "security": [
                    {
                        "tokenBearer": [
                            "coletas.write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/coleta"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "ativa"
                                ],
                                "properties": {
                                    "ativa": {
                                        "type": "boolean",
                                        "description": "`true` inclui nos indicadores, `false` exclui."
                                    }
                                }
                            },
                            "example": {
                                "ativa": false
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Coleta atualizada.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Coleta"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NaoEncontrado"
                    },
                    "422": {
                        "$ref": "#/components/responses/PayloadInvalido"
                    }
                }
            }
        },
        "/coletas/{coleta}/reprocessar": {
            "post": {
                "tags": [
                    "Escrita"
                ],
                "summary": "Reprocessa a coleta com o processador atual",
                "description": "Útil quando um processador é corrigido. Roda em fila: acompanhe pelo webhook `coleta.reprocessada`.",
                "operationId": "reprocessarColeta",
                "security": [
                    {
                        "tokenBearer": [
                            "coletas.write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/coleta"
                    }
                ],
                "responses": {
                    "202": {
                        "description": "Reprocessamento enfileirado.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Enfileirado"
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NaoEncontrado"
                    }
                }
            }
        },
        "/projetos/{projeto}/sincronizar": {
            "post": {
                "tags": [
                    "Escrita"
                ],
                "summary": "Dispara sincronização com o ODK Central",
                "description": "Há um bloqueio de 2 minutos por projeto: o ODK Central é infraestrutura compartilhada e não pode ser martelado.",
                "operationId": "sincronizarProjeto",
                "security": [
                    {
                        "tokenBearer": [
                            "coletas.write"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/projeto"
                    }
                ],
                "responses": {
                    "202": {
                        "description": "Sincronização enfileirada.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Enfileirado"
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NaoEncontrado"
                    }
                }
            }
        },
        "/projetos/{projeto}/indicadores": {
            "get": {
                "tags": [
                    "Indicadores"
                ],
                "summary": "Indicadores consolidados do projeto",
                "description": "Os mesmos números que saem no relatório entregue ao órgão. Considera apenas coletas processadas e marcadas como ativas.",
                "operationId": "obterIndicadores",
                "security": [
                    {
                        "tokenBearer": [
                            "projetos.read",
                            "coletas.read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/projeto"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Indicadores consolidados.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Indicadores"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NaoEncontrado"
                    }
                }
            }
        },
        "/projetos/{projeto}/cobertura": {
            "get": {
                "tags": [
                    "Coletas"
                ],
                "summary": "Segmentos de cobertura, um por linha",
                "description": "Achata os segmentos de todas as coletas do projeto. A paginação é por COLETA, não por linha — o cursor permanece estável.",
                "operationId": "listarCobertura",
                "security": [
                    {
                        "tokenBearer": [
                            "coletas.read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/projeto"
                    },
                    {
                        "$ref": "#/components/parameters/somenteAtivas"
                    },
                    {
                        "$ref": "#/components/parameters/limite"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Segmentos de cobertura.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ColecaoAchatada"
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NaoEncontrado"
                    }
                }
            }
        },
        "/projetos/{projeto}/especies": {
            "get": {
                "tags": [
                    "Coletas"
                ],
                "summary": "Espécies registradas, uma por linha",
                "operationId": "listarEspecies",
                "security": [
                    {
                        "tokenBearer": [
                            "coletas.read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/projeto"
                    },
                    {
                        "$ref": "#/components/parameters/somenteAtivas"
                    },
                    {
                        "$ref": "#/components/parameters/limite"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Espécies por coleta.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ColecaoAchatada"
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NaoEncontrado"
                    }
                }
            }
        },
        "/projetos/{projeto}/observacoes": {
            "get": {
                "tags": [
                    "Coletas"
                ],
                "summary": "Observações de campo, uma por linha",
                "operationId": "listarObservacoes",
                "security": [
                    {
                        "tokenBearer": [
                            "coletas.read"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "$ref": "#/components/parameters/projeto"
                    },
                    {
                        "$ref": "#/components/parameters/somenteAtivas"
                    },
                    {
                        "$ref": "#/components/parameters/limite"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Observações por coleta.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ColecaoAchatada"
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NaoEncontrado"
                    }
                }
            }
        }
    },
    "components": {
        "securitySchemes": {
            "tokenBearer": {
                "type": "http",
                "scheme": "bearer",
                "description": "Token criado em *Integrações e API* no painel do gestor. Envie no cabeçalho `Authorization: Bearer <segredo>`."
            }
        },
        "parameters": {
            "projeto": {
                "name": "projeto",
                "in": "path",
                "required": true,
                "description": "Identificador do projeto.",
                "schema": {
                    "type": "integer"
                }
            },
            "coleta": {
                "name": "coleta",
                "in": "path",
                "required": true,
                "description": "Identificador da coleta.",
                "schema": {
                    "type": "integer"
                }
            },
            "limite": {
                "name": "limite",
                "in": "query",
                "required": false,
                "description": "Itens por página. Valores acima do teto são reduzidos ao teto, sem erro.",
                "schema": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100,
                    "default": 25
                }
            },
            "cursor": {
                "name": "cursor",
                "in": "query",
                "required": false,
                "description": "Cursor da próxima página, devolvido em `proxima_pagina`.",
                "schema": {
                    "type": "string"
                }
            },
            "somenteAtivas": {
                "name": "somente_ativas",
                "in": "query",
                "required": false,
                "description": "Considera apenas coletas incluídas nos cálculos.",
                "schema": {
                    "type": "boolean",
                    "default": true
                }
            }
        },
        "responses": {
            "NaoAutenticado": {
                "description": "Token ausente ou inválido",
                "content": {
                    "application/problem+json": {
                        "schema": {
                            "$ref": "#/components/schemas/Problema"
                        },
                        "example": {
                            "type": "https://eumonitoro.com/errors/nao-autenticado",
                            "title": "Token ausente ou inválido",
                            "status": 0,
                            "detail": "Descrição legível do que aconteceu.",
                            "request_id": "3ddc3a09-f13d-4658-a7c3-1db59e41b497"
                        }
                    }
                }
            },
            "SemPermissao": {
                "description": "Token sem permissão para esta operação",
                "content": {
                    "application/problem+json": {
                        "schema": {
                            "$ref": "#/components/schemas/Problema"
                        },
                        "example": {
                            "type": "https://eumonitoro.com/errors/escopo-insuficiente",
                            "title": "Token sem permissão para esta operação",
                            "status": 0,
                            "detail": "Descrição legível do que aconteceu.",
                            "request_id": "3ddc3a09-f13d-4658-a7c3-1db59e41b497"
                        }
                    }
                }
            },
            "PlanoInativo": {
                "description": "Plano de API inativo",
                "content": {
                    "application/problem+json": {
                        "schema": {
                            "$ref": "#/components/schemas/Problema"
                        },
                        "example": {
                            "type": "https://eumonitoro.com/errors/plano-inativo",
                            "title": "Plano de API inativo",
                            "status": 0,
                            "detail": "Descrição legível do que aconteceu.",
                            "request_id": "3ddc3a09-f13d-4658-a7c3-1db59e41b497"
                        }
                    }
                }
            },
            "NaoEncontrado": {
                "description": "Recurso não encontrado",
                "content": {
                    "application/problem+json": {
                        "schema": {
                            "$ref": "#/components/schemas/Problema"
                        },
                        "example": {
                            "type": "https://eumonitoro.com/errors/nao-encontrado",
                            "title": "Recurso não encontrado",
                            "status": 0,
                            "detail": "Descrição legível do que aconteceu.",
                            "request_id": "3ddc3a09-f13d-4658-a7c3-1db59e41b497"
                        }
                    }
                }
            },
            "PayloadInvalido": {
                "description": "Requisição inválida",
                "content": {
                    "application/problem+json": {
                        "schema": {
                            "$ref": "#/components/schemas/Problema"
                        },
                        "example": {
                            "type": "https://eumonitoro.com/errors/payload-invalido",
                            "title": "Requisição inválida",
                            "status": 0,
                            "detail": "Descrição legível do que aconteceu.",
                            "request_id": "3ddc3a09-f13d-4658-a7c3-1db59e41b497"
                        }
                    }
                }
            },
            "LimiteExcedido": {
                "description": "Limite de requisições excedido",
                "content": {
                    "application/problem+json": {
                        "schema": {
                            "$ref": "#/components/schemas/Problema"
                        },
                        "example": {
                            "type": "https://eumonitoro.com/errors/limite-excedido",
                            "title": "Limite de requisições excedido",
                            "status": 0,
                            "detail": "Descrição legível do que aconteceu.",
                            "request_id": "3ddc3a09-f13d-4658-a7c3-1db59e41b497"
                        }
                    }
                }
            },
            "IdempotenciaConflito": {
                "description": "Idempotency-Key reutilizada com corpo diferente",
                "content": {
                    "application/problem+json": {
                        "schema": {
                            "$ref": "#/components/schemas/Problema"
                        },
                        "example": {
                            "type": "https://eumonitoro.com/errors/idempotencia-conflito",
                            "title": "Idempotency-Key reutilizada com corpo diferente",
                            "status": 0,
                            "detail": "Descrição legível do que aconteceu.",
                            "request_id": "3ddc3a09-f13d-4658-a7c3-1db59e41b497"
                        }
                    }
                }
            }
        },
        "schemas": {
            "Colecao": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "array",
                        "items": {
                            "type": "object"
                        }
                    },
                    "proxima_pagina": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Cursor da próxima página; `null` na última."
                    },
                    "tem_mais": {
                        "type": "boolean"
                    }
                },
                "required": [
                    "data",
                    "proxima_pagina",
                    "tem_mais"
                ]
            },
            "ColecaoAchatada": {
                "type": "object",
                "description": "Cada coleta gera N linhas. A paginação continua sendo por coleta.",
                "properties": {
                    "data": {
                        "type": "array",
                        "items": {
                            "type": "object"
                        }
                    },
                    "proxima_pagina": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "tem_mais": {
                        "type": "boolean"
                    },
                    "coletas_na_pagina": {
                        "type": "integer"
                    }
                }
            },
            "Projeto": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "nome": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "pendente",
                            "ativo",
                            "erro",
                            "arquivado"
                        ]
                    },
                    "normativa": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "examples": [
                            "SMA 32"
                        ]
                    },
                    "template": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "properties": {
                            "id": {
                                "type": "integer"
                            },
                            "nome": {
                                "type": "string"
                            },
                            "bioma": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            }
                        }
                    },
                    "propriedade": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "municipio": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "uf": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "bioma": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "area_monitoramento": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Hectares."
                    },
                    "responsavel_tecnico": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "odk_form_id": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "implantado_em": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "ultima_sincronizacao": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "ultima_coleta": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    }
                }
            },
            "ProjetoComCota": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/Projeto"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "cota": {
                                "type": "object",
                                "description": "Coletas contratadas para este projeto. Acima da cota, a coleta entra como `retido` e não é processada.",
                                "properties": {
                                    "alocada": {
                                        "type": "integer"
                                    },
                                    "consumida": {
                                        "type": "integer"
                                    },
                                    "retida": {
                                        "type": "integer"
                                    },
                                    "vagas": {
                                        "type": "integer"
                                    }
                                }
                            }
                        }
                    }
                ]
            },
            "Coleta": {
                "type": "object",
                "description": "Envelope estável: as chaves e os tipos não mudam entre normativas.",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "projeto_id": {
                        "type": "integer"
                    },
                    "normativa": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "schema_version": {
                        "type": "string",
                        "const": "1.0"
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "raw",
                            "processado",
                            "erro",
                            "retido"
                        ]
                    },
                    "ativa": {
                        "type": "boolean",
                        "description": "Se entra nos cálculos de indicadores."
                    },
                    "origem": {
                        "type": "object",
                        "properties": {
                            "tipo": {
                                "type": "string",
                                "enum": [
                                    "odk",
                                    "importacao"
                                ]
                            },
                            "instance_id": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "form_id": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            }
                        }
                    },
                    "coletado_em": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date",
                        "description": "Data declarada no formulário de campo."
                    },
                    "recebido_em": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "processado_em": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "coletor": {
                        "type": "object",
                        "description": "Quem realizou a coleta em campo.",
                        "properties": {
                            "rotulo": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "description": "Nome do técnico. **Contém dado pessoal** — trate conforme a LGPD no seu sistema. É conteúdo obrigatório do relatório entregue ao órgão, por isso não é omitido."
                            }
                        }
                    },
                    "parcela": {
                        "$ref": "#/components/schemas/Parcela"
                    },
                    "gps": {
                        "$ref": "#/components/schemas/Gps"
                    },
                    "indicadores": {
                        "type": "object",
                        "properties": {
                            "cobertura_nativa": {
                                "type": [
                                    "number",
                                    "null"
                                ]
                            },
                            "cobertura_exotica": {
                                "type": [
                                    "number",
                                    "null"
                                ]
                            },
                            "diversidade_especies": {
                                "type": [
                                    "integer",
                                    "null"
                                ]
                            },
                            "indice_regeneracao": {
                                "type": [
                                    "number",
                                    "null"
                                ]
                            },
                            "ipa": {
                                "type": [
                                    "number",
                                    "null"
                                ]
                            }
                        }
                    },
                    "especies": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Especie"
                        },
                        "description": "Sempre presente; lista vazia quando não há registro."
                    },
                    "cobertura": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "properties": {
                            "pct_nativa": {
                                "type": [
                                    "number",
                                    "null"
                                ]
                            },
                            "segmentos": {
                                "type": "array",
                                "items": {
                                    "$ref": "#/components/schemas/SegmentoCobertura"
                                }
                            }
                        },
                        "description": "`null` quando a normativa não coleta cobertura."
                    },
                    "observacoes": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "texto": {
                                    "type": [
                                        "string",
                                        "null"
                                    ]
                                },
                                "fotos": {
                                    "type": "array",
                                    "items": {
                                        "type": "string"
                                    }
                                }
                            }
                        },
                        "description": "Sempre lista, mesmo quando o formulário registra texto único."
                    },
                    "dados_normativa": {
                        "type": "object",
                        "description": "Campos específicos da normativa. **Fora da garantia de versão** — é aqui que a evolução acontece sem quebrar o contrato."
                    }
                }
            },
            "Parcela": {
                "type": "object",
                "properties": {
                    "propriedade": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "numero": {
                        "type": [
                            "integer",
                            "string",
                            "null"
                        ]
                    },
                    "vegetacao": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "etapa": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "hora_inicio": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "examples": [
                            "08:20"
                        ]
                    },
                    "hora_fim": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "examples": [
                            "09:05"
                        ]
                    },
                    "ano": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "tecnico": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                }
            },
            "Gps": {
                "type": [
                    "object",
                    "null"
                ],
                "description": "Coordenada da parcela; `null` quando o formulário não registrou.",
                "properties": {
                    "lat": {
                        "type": "number"
                    },
                    "lng": {
                        "type": "number"
                    },
                    "accuracy": {
                        "type": [
                            "number",
                            "null"
                        ],
                        "description": "Precisão em metros."
                    },
                    "altitude": {
                        "type": [
                            "number",
                            "null"
                        ],
                        "description": "Altitude em metros."
                    }
                }
            },
            "Especie": {
                "type": "object",
                "properties": {
                    "nome_cientifico": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Nome enriquecido pela taxonomia quando disponível."
                    },
                    "nome_vulgar": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "genero": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "familia": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "grupo_funcional": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Estágio sucessional: pioneira, secundária inicial ou tardia."
                    },
                    "sindrome_dispersao": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Zoo (animal), Ane (vento) ou Aut (autocórica)."
                    },
                    "link_reflora": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "contagem": {
                        "type": [
                            "integer",
                            "number"
                        ],
                        "description": "Indivíduos registrados."
                    },
                    "altura_media": {
                        "type": [
                            "number",
                            "null"
                        ],
                        "description": "Metros."
                    },
                    "enriquecida": {
                        "type": "boolean",
                        "description": "Se os dados taxonômicos foram completados automaticamente."
                    },
                    "pendente_id": {
                        "type": "boolean",
                        "description": "Espécie ainda não identificada em campo."
                    },
                    "notas": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                }
            },
            "SegmentoCobertura": {
                "type": "object",
                "description": "Trecho da linha de amostragem. Medidas em metros lineares.",
                "properties": {
                    "tipo": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "examples": [
                            "nativa",
                            "clareira",
                            "exotica"
                        ]
                    },
                    "parcela_segmento": {
                        "type": [
                            "integer",
                            "string",
                            "null"
                        ],
                        "description": "Parcela declarada no próprio segmento, quando o formulário a repete."
                    },
                    "metros": {
                        "type": [
                            "number",
                            "integer"
                        ]
                    },
                    "metros_nativos": {
                        "type": [
                            "number",
                            "integer"
                        ]
                    },
                    "metros_exoticos": {
                        "type": [
                            "number",
                            "integer"
                        ]
                    },
                    "metros_efetivos": {
                        "type": [
                            "number",
                            "integer"
                        ],
                        "description": "Metragem que conta para o indicador de cobertura."
                    },
                    "especie_exotica": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                }
            },
            "Indicadores": {
                "type": "object",
                "properties": {
                    "projeto_id": {
                        "type": "integer"
                    },
                    "normativa": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "schema_version": {
                        "type": "string"
                    },
                    "coletas_consideradas": {
                        "type": "integer",
                        "description": "Coletas processadas e ativas que entraram no cálculo."
                    },
                    "calculado_em": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "cobertura": {
                        "type": "object",
                        "properties": {
                            "nativa_media": {
                                "type": [
                                    "number",
                                    "null"
                                ],
                                "description": "Percentual."
                            },
                            "exotica_media": {
                                "type": [
                                    "number",
                                    "null"
                                ]
                            },
                            "exotica_segmentos_media": {
                                "type": [
                                    "number",
                                    "null"
                                ]
                            },
                            "clareira_media": {
                                "type": [
                                    "number",
                                    "null"
                                ]
                            },
                            "solo_exposto_media": {
                                "type": [
                                    "number",
                                    "null"
                                ]
                            },
                            "parcelas_acima_do_minimo": {
                                "type": "integer",
                                "description": "Parcelas com cobertura nativa igual ou superior a 30%."
                            }
                        }
                    },
                    "diversidade": {
                        "type": "object",
                        "properties": {
                            "densidade_media": {
                                "type": [
                                    "number",
                                    "null"
                                ],
                                "description": "Indivíduos por hectare."
                            },
                            "especies_media_por_parcela": {
                                "type": [
                                    "number",
                                    "null"
                                ]
                            },
                            "individuos_media_por_parcela": {
                                "type": [
                                    "number",
                                    "null"
                                ]
                            },
                            "total_familias": {
                                "type": "integer"
                            },
                            "total_nao_identificados": {
                                "type": "integer"
                            },
                            "concentracao_top5_pct": {
                                "type": [
                                    "number",
                                    "null"
                                ],
                                "description": "Percentual de indivíduos concentrado nas 5 espécies mais abundantes."
                            }
                        }
                    },
                    "classificacao": {
                        "type": "object",
                        "description": "Enquadramento usado pelo órgão para julgar a adequação da área.",
                        "properties": {
                            "status_cobertura": {
                                "type": "string"
                            },
                            "status_densidade": {
                                "type": "string"
                            },
                            "status_especies": {
                                "type": "string"
                            },
                            "por_faixa": {
                                "type": "object",
                                "description": "Classificação por faixa etária do plantio."
                            }
                        }
                    },
                    "grupos_funcionais": {
                        "type": "object",
                        "description": "Distribuição por estágio sucessional.",
                        "additionalProperties": {
                            "$ref": "#/components/schemas/RiquezaAbundancia"
                        }
                    },
                    "sindromes_dispersao": {
                        "type": "object",
                        "additionalProperties": {
                            "$ref": "#/components/schemas/RiquezaAbundancia"
                        }
                    },
                    "destaques": {
                        "type": "object",
                        "properties": {
                            "familias_mais_ricas": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "especies_destaque": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "especies_ameacadas": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            }
                        }
                    },
                    "especies": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "nome_cientifico": {
                                    "type": [
                                        "string",
                                        "null"
                                    ]
                                },
                                "nome_vulgar": {
                                    "type": [
                                        "string",
                                        "null"
                                    ]
                                },
                                "familia": {
                                    "type": [
                                        "string",
                                        "null"
                                    ]
                                },
                                "grupo_funcional": {
                                    "type": [
                                        "string",
                                        "null"
                                    ]
                                },
                                "sindrome_dispersao": {
                                    "type": [
                                        "string",
                                        "null"
                                    ]
                                },
                                "total_individuos": {
                                    "type": "integer",
                                    "description": "Somado entre todas as parcelas do projeto."
                                },
                                "pendente_id": {
                                    "type": "boolean"
                                },
                                "ameacada": {
                                    "type": "boolean"
                                },
                                "categoria_ameaca": {
                                    "type": [
                                        "string",
                                        "null"
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "RiquezaAbundancia": {
                "type": "object",
                "properties": {
                    "riqueza_pct": {
                        "type": [
                            "number",
                            "null"
                        ],
                        "description": "Percentual sobre o número de espécies."
                    },
                    "abundancia_pct": {
                        "type": [
                            "number",
                            "null"
                        ],
                        "description": "Percentual sobre o número de indivíduos."
                    }
                }
            },
            "ColetaEntrada": {
                "type": "object",
                "required": [
                    "raw_data"
                ],
                "properties": {
                    "raw_data": {
                        "type": "object",
                        "description": "Campos da coleta, no formato do formulário da normativa do projeto. Limites: 1 MB, 20 níveis de aninhamento, 10.000 campos."
                    },
                    "coletado_em": {
                        "type": "string",
                        "format": "date-time",
                        "description": "Quando a coleta ocorreu em campo. Padrão: agora."
                    },
                    "coletor": {
                        "type": "string",
                        "maxLength": 120,
                        "description": "Quem coletou, como texto livre."
                    },
                    "identificador_externo": {
                        "type": "string",
                        "maxLength": 100,
                        "description": "Identificador da coleta no seu sistema. Repetido no mesmo projeto, o envio é recusado — protege contra duplicata mesmo sem Idempotency-Key."
                    }
                }
            },
            "Enfileirado": {
                "type": "object",
                "description": "Trabalho aceito e enfileirado. O resultado chega por webhook ou consultando o recurso depois.",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "status": {
                                "type": "string",
                                "const": "enfileirado"
                            },
                            "mensagem": {
                                "type": "string"
                            }
                        }
                    }
                }
            },
            "Problema": {
                "type": "object",
                "description": "Erro no formato RFC 7807. Trate a falha pelo `type`, nunca pelo `title`.",
                "properties": {
                    "type": {
                        "type": "string",
                        "format": "uri"
                    },
                    "title": {
                        "type": "string"
                    },
                    "status": {
                        "type": "integer"
                    },
                    "detail": {
                        "type": "string"
                    },
                    "errors": {
                        "type": "object",
                        "description": "Presente apenas em erro de validação."
                    },
                    "request_id": {
                        "type": "string",
                        "description": "Informe ao suporte para localizar a requisição no nosso log."
                    }
                },
                "required": [
                    "type",
                    "title",
                    "status",
                    "detail"
                ]
            }
        }
    }
}