{
  "openapi": "3.1.0",
  "info": {
    "title": "API upCampo",
    "version": "2026-08-20",
    "summary": "API REST de integração da plataforma upCampo com ERPs de terceiros.",
    "description": "API pública da upCampo, usada pelos ERPs dos clientes (Siagri, Sankhya e outros) para ler cadastros e movimentos da fazenda e devolver o identificador do lado deles.\n\n**Autenticação.** `POST /autenticar` troca `client_id` + `client_secret` por um bearer token válido por 24 horas. O par de credenciais é individual por parceiro × empresa × fazenda, e o identificador da empresa e o da fazenda ficam fixados no token — não são parâmetro de nenhuma chamada. Use o token até ele expirar: gerar um token por requisição sobrecarrega o serviço e leva a bloqueio temporário.\n\n**ID_REFERENCIA.** Todas as tabelas têm a coluna `ID_REFERENCIA`, onde fica o identificador do registro no sistema do parceiro. É ela que decide se um `POST` é inserção (não encontrado) ou atualização (encontrado), e é ela que aparece em todo `GET` sob a forma `ID_<ENTIDADE>_REFERENCIA`.\n\n**Convenções.** Parâmetros de `GET` vão na URL, em minúsculo e diferenciando maiúsculas de minúsculas. Corpos de `POST` são sempre arrays, com os atributos em MAIÚSCULO. Datas no formato `AAAA-MM-DD`. Exclusão lógica com `DELETADO: true`. Nas rotas de movimento, a janela entre `data_inicial` e `data_final` é de no máximo 7 dias.\n\nA liberação de cada endpoint é feita caso a caso — procure a equipe da upCampo.",
    "termsOfService": "https://www.upcampo.com.br",
    "contact": {
      "name": "Equipe upCampo",
      "url": "https://suporte.upcampo.com.br/api/",
      "email": "contato@upcampo.com.br"
    }
  },
  "externalDocs": {
    "description": "Documentação da API em HTML, com exemplos de requisição e retorno",
    "url": "https://suporte.upcampo.com.br/api/"
  },
  "servers": [
    {
      "url": "https://api.upcampo.com.br",
      "description": "Produção"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    { "name": "Autenticação", "description": "Geração e conferência do token." },
    { "name": "Lavoura", "description": "Cultura, variedade, talhão, safra e plantio da safra." },
    { "name": "Cadastros", "description": "Classe de produto, produto, local de estoque, equipamento, tipo de atividade e identificação resumida." },
    { "name": "Estoque", "description": "Movimentação de nota fiscal, transferência, inventário e saldo." },
    { "name": "Ordem de serviço", "description": "Ordem de serviço agrícola: insumos, devoluções e execuções." },
    { "name": "Frota", "description": "Abastecimento." },
    { "name": "Algodão", "description": "Fardos e o peso da algodoeira." },
    { "name": "Armazenagem", "description": "Romaneio de colheita e classificação." },
    { "name": "Referência", "description": "Rotas que gravam apenas o ID_REFERENCIA em um registro existente." }
  ],
  "paths": {
    "/autenticar": {
      "post": {
        "tags": ["Autenticação"],
        "summary": "Gerar o token de acesso",
        "description": "Troca as credenciais do parceiro por um bearer token, hoje válido por 24 horas. Use o token até expirar: são no máximo **10 tentativas de autenticação a cada 15 minutos por `client_id`**, e passando disso a API responde 429 com o cabeçalho `Retry-After`. O limite é por client_id, então um parceiro que exagera não afeta os outros.",
        "operationId": "autenticar",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/Credenciais" },
              "example": {
                "client_id": "CLIENT ID QUE A UPCAMPO LHE INFORMARÁ",
                "client_secret": "CLIENT SECRET QUE A UPCAMPO LHE INFORMARÁ",
                "audience": "https://api.upcampo.com.br",
                "grant_type": "client_credentials"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token gerado.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Token" },
                "example": {
                  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…",
                  "token_type": "Bearer"
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/NaoAutorizado" },
          "429": {
            "description": "Tentativas de autenticação demais para o mesmo `client_id`: limite de 10 a cada 15 minutos.",
            "headers": {
              "Retry-After": {
                "description": "Segundos até o acesso voltar.",
                "schema": { "type": "integer", "examples": [900] }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": { "type": "string", "const": "Erro" },
                    "error": { "type": "string" }
                  }
                },
                "example": {
                  "status": "Erro",
                  "error": "Muitas tentativas de autenticação. Gere o token uma vez e use-o até expirar (24 horas), em vez de gerar um por chamada. Tente de novo em 900 segundos."
                }
              }
            }
          }
        }
      }
    },
    "/teste": {
      "get": {
        "tags": ["Autenticação"],
        "summary": "Conferir o token",
        "description": "Teste leve do token, sem consultar o banco de dados. O campo `nome` traz a fazenda e o ambiente (PROD ou HOMOLOGACAO).",
        "operationId": "testarToken",
        "responses": {
          "200": {
            "description": "Token válido.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": { "type": "string", "examples": ["Sucesso"] },
                    "mensagem": { "type": "string" },
                    "nome": { "type": "string" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/NaoAutorizado" }
        }
      }
    },

    "/cultura": {
      "get": {
        "tags": ["Lavoura"],
        "summary": "Listar culturas",
        "operationId": "listarCulturas",
        "responses": {
          "200": {
            "description": "Culturas cadastradas.",
            "content": {
              "application/json": {
                "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Cultura" } }
              }
            }
          },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" }
        }
      },
      "post": {
        "tags": ["Lavoura"],
        "summary": "Incluir ou alterar culturas",
        "operationId": "gravarCulturas",
        "requestBody": { "$ref": "#/components/requestBodies/Cultura" },
        "responses": {
          "200": { "$ref": "#/components/responses/EscritaOk" },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" },
          "500": { "$ref": "#/components/responses/EscritaErro" }
        }
      }
    },

    "/variedade": {
      "get": {
        "tags": ["Lavoura"],
        "summary": "Listar variedades",
        "operationId": "listarVariedades",
        "responses": {
          "200": {
            "description": "Variedades cadastradas.",
            "content": {
              "application/json": {
                "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Variedade" } }
              }
            }
          },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" }
        }
      },
      "post": {
        "tags": ["Lavoura"],
        "summary": "Incluir ou alterar variedades",
        "operationId": "gravarVariedades",
        "requestBody": { "$ref": "#/components/requestBodies/Variedade" },
        "responses": {
          "200": { "$ref": "#/components/responses/EscritaOk" },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" },
          "500": { "$ref": "#/components/responses/EscritaErro" }
        }
      }
    },

    "/talhao": {
      "get": {
        "tags": ["Lavoura"],
        "summary": "Listar talhões",
        "description": "Use esta rota para descobrir a descrição exata e os identificadores do talhão antes de filtrar outras rotas por ele.",
        "operationId": "listarTalhoes",
        "parameters": [
          {
            "name": "setor",
            "in": "query",
            "required": false,
            "description": "Setor do talhão — na maioria das fazendas, o nome da unidade dentro do grupo.",
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": {
            "description": "Talhões cadastrados.",
            "content": {
              "application/json": {
                "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Talhao" } }
              }
            }
          },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" }
        }
      }
    },

    "/safra": {
      "get": {
        "tags": ["Lavoura"],
        "summary": "Listar safras",
        "operationId": "listarSafras",
        "responses": {
          "200": {
            "description": "Safras cadastradas.",
            "content": {
              "application/json": {
                "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Safra" } }
              }
            }
          },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" }
        }
      }
    },

    "/plantio_safra": {
      "get": {
        "tags": ["Lavoura"],
        "summary": "Listar o plantio da safra",
        "description": "O plantio da safra amarra safra, talhão, cultura, variedade e área. É a chave que fardo, romaneio e ordem de serviço usam para apontar para a lavoura.",
        "operationId": "listarPlantioSafra",
        "parameters": [
          { "name": "id_safra", "in": "query", "required": false, "schema": { "type": "string" } },
          { "name": "id_cultura", "in": "query", "required": false, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "Registros de plantio da safra.",
            "content": {
              "application/json": {
                "schema": { "type": "array", "items": { "$ref": "#/components/schemas/PlantioSafra" } }
              }
            }
          },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" }
        }
      }
    },

    "/classe_produto": {
      "get": {
        "tags": ["Cadastros"],
        "summary": "Listar classes de produto",
        "operationId": "listarClassesProduto",
        "parameters": [
          { "name": "id_upcampo", "in": "query", "required": false, "schema": { "type": "string" } },
          { "name": "codigo", "in": "query", "required": false, "schema": { "type": "string" } },
          { "name": "id_referencia", "in": "query", "required": false, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "Classes de produto.",
            "content": {
              "application/json": {
                "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ClasseProduto" } }
              }
            }
          },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" }
        }
      },
      "post": {
        "tags": ["Cadastros"],
        "summary": "Incluir ou alterar classes de produto",
        "operationId": "gravarClassesProduto",
        "requestBody": { "$ref": "#/components/requestBodies/ClasseProduto" },
        "responses": {
          "200": { "$ref": "#/components/responses/EscritaOk" },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" },
          "500": { "$ref": "#/components/responses/EscritaErro" }
        }
      }
    },

    "/produto": {
      "get": {
        "tags": ["Cadastros"],
        "summary": "Listar produtos e serviços",
        "operationId": "listarProdutos",
        "parameters": [
          { "name": "id_upcampo", "in": "query", "required": false, "schema": { "type": "string" } },
          { "name": "codigo", "in": "query", "required": false, "schema": { "type": "string" } },
          { "name": "id_referencia", "in": "query", "required": false, "schema": { "type": "string" } },
          { "name": "id_classe", "in": "query", "required": false, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "Produtos cadastrados.",
            "content": {
              "application/json": {
                "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Produto" } }
              }
            }
          },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" }
        }
      },
      "post": {
        "tags": ["Cadastros"],
        "summary": "Incluir ou alterar produtos",
        "operationId": "gravarProdutos",
        "requestBody": { "$ref": "#/components/requestBodies/Produto" },
        "responses": {
          "200": { "$ref": "#/components/responses/EscritaOk" },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" },
          "500": { "$ref": "#/components/responses/EscritaErro" }
        }
      }
    },

    "/local_estoque": {
      "get": {
        "tags": ["Cadastros"],
        "summary": "Listar locais de estoque",
        "description": "Somente leitura. Para gravar o identificador do seu sistema, use `POST /local_estoqueReferencia`.",
        "operationId": "listarLocaisEstoque",
        "parameters": [
          { "name": "setor", "in": "query", "required": false, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "Locais de estoque.",
            "content": {
              "application/json": {
                "schema": { "type": "array", "items": { "$ref": "#/components/schemas/LocalEstoque" } }
              }
            }
          },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" }
        }
      }
    },

    "/equipamento": {
      "get": {
        "tags": ["Cadastros"],
        "summary": "Listar frota, equipamentos e bem feitorias",
        "operationId": "listarEquipamentos",
        "parameters": [
          { "name": "id_classificacao", "in": "query", "required": false, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "Equipamentos cadastrados.",
            "content": {
              "application/json": {
                "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Equipamento" } }
              }
            }
          },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" }
        }
      },
      "post": {
        "tags": ["Cadastros"],
        "summary": "Incluir ou alterar equipamentos",
        "operationId": "gravarEquipamentos",
        "requestBody": { "$ref": "#/components/requestBodies/Equipamento" },
        "responses": {
          "200": { "$ref": "#/components/responses/EscritaOk" },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" },
          "500": { "$ref": "#/components/responses/EscritaErro" }
        }
      }
    },

    "/tipo_atividade": {
      "get": {
        "tags": ["Cadastros"],
        "summary": "Listar tipos de atividade",
        "description": "O tipo de atividade é o que a ordem de serviço faz: aplicação de defensivo, adubação, plantio, colheita.",
        "operationId": "listarTiposAtividade",
        "responses": {
          "200": {
            "description": "Tipos de atividade.",
            "content": {
              "application/json": {
                "schema": { "type": "array", "items": { "$ref": "#/components/schemas/TipoAtividade" } }
              }
            }
          },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" }
        }
      }
    },

    "/identificacao_resumida": {
      "get": {
        "tags": ["Cadastros"],
        "summary": "Listar identificações resumidas",
        "description": "Ide. Res. é a abreviação de Identificação Resumida (IDERES), uma espécie de subgrupo do tipo de atividade.",
        "operationId": "listarIdentificacoesResumidas",
        "responses": {
          "200": {
            "description": "Identificações resumidas.",
            "content": {
              "application/json": {
                "schema": { "type": "array", "items": { "$ref": "#/components/schemas/IdentificacaoResumida" } }
              }
            }
          },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" }
        }
      }
    },

    "/movimentacao": {
      "get": {
        "tags": ["Estoque"],
        "summary": "Listar movimentações (notas fiscais)",
        "description": "Entrada de nota fiscal de produto ou de serviço no estoque. É a movimentação que forma o custo médio de cada produto em cada local.",
        "operationId": "listarMovimentacoes",
        "parameters": [
          { "$ref": "#/components/parameters/datmodInicial" },
          { "$ref": "#/components/parameters/dataInicial" },
          { "$ref": "#/components/parameters/dataFinal" },
          { "$ref": "#/components/parameters/status" },
          { "name": "numero", "in": "query", "required": false, "description": "Número da nota. Alternativa aos filtros de data.", "schema": { "type": "string" } },
          { "$ref": "#/components/parameters/idReferencia" }
        ],
        "responses": {
          "200": {
            "description": "Movimentações do período.",
            "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object" } } } }
          },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" }
        }
      },
      "post": {
        "tags": ["Estoque"],
        "summary": "Incluir ou alterar movimentações",
        "operationId": "gravarMovimentacoes",
        "requestBody": { "$ref": "#/components/requestBodies/Movimentacao" },
        "responses": {
          "200": { "$ref": "#/components/responses/EscritaOk" },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" },
          "500": { "$ref": "#/components/responses/EscritaErro" }
        }
      }
    },

    "/transferencia": {
      "get": {
        "tags": ["Estoque"],
        "summary": "Listar transferências entre locais de estoque",
        "operationId": "listarTransferencias",
        "parameters": [
          { "$ref": "#/components/parameters/dataInicialObrigatoria" },
          { "$ref": "#/components/parameters/dataFinalObrigatoria" },
          { "$ref": "#/components/parameters/status" },
          { "name": "codigo", "in": "query", "required": false, "schema": { "type": "string" } },
          { "$ref": "#/components/parameters/idReferencia" },
          { "name": "id_upcampo", "in": "query", "required": false, "schema": { "type": "string" } },
          { "name": "id_local_origem", "in": "query", "required": false, "schema": { "type": "string" } },
          { "name": "id_local_destino", "in": "query", "required": false, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "Transferências do período, com os itens aninhados em `itens`.",
            "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object" } } } }
          },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" }
        }
      },
      "post": {
        "tags": ["Estoque"],
        "summary": "Incluir ou alterar transferências",
        "description": "Documento finalizado não pode ser alterado, e a upCampo barra a operação que deixaria o saldo da origem negativo.",
        "operationId": "gravarTransferencias",
        "requestBody": { "$ref": "#/components/requestBodies/Transferencia" },
        "responses": {
          "200": { "$ref": "#/components/responses/EscritaOk" },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" },
          "500": { "$ref": "#/components/responses/EscritaErro" }
        }
      }
    },

    "/inventario": {
      "post": {
        "tags": ["Estoque"],
        "summary": "Acertar o saldo de um produto",
        "description": "Em vez de lançar entrada ou saída, informa-se qual é o saldo correto do produto naquele local, naquela data.",
        "operationId": "gravarInventario",
        "requestBody": { "$ref": "#/components/requestBodies/Inventario" },
        "responses": {
          "200": { "$ref": "#/components/responses/EscritaOk" },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" },
          "500": { "$ref": "#/components/responses/EscritaErro" }
        }
      }
    },

    "/estoque": {
      "get": {
        "tags": ["Estoque"],
        "summary": "Consultar o saldo de estoque",
        "description": "O saldo na upCampo é por produto **e** por local de estoque — o mesmo produto pode ter saldos diferentes em barracões diferentes.",
        "operationId": "consultarEstoque",
        "parameters": [
          { "name": "id_locest_referencia", "in": "query", "required": false, "schema": { "type": "string" } },
          { "name": "id_produto_referencia", "in": "query", "required": false, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "Saldos atuais.",
            "content": {
              "application/json": {
                "schema": { "type": "array", "items": { "$ref": "#/components/schemas/SaldoEstoque" } }
              }
            }
          },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" }
        }
      }
    },

    "/ordem_agricola_completa": {
      "get": {
        "tags": ["Ordem de serviço"],
        "summary": "Ordem de serviço agrícola completa",
        "description": "Devolve cabeçalho, produtos, talhões e execuções em um objeto só. A quantidade de cada produto é lançada para a ordem inteira e rateada entre os talhões pela área de cada um.",
        "operationId": "listarOrdensCompletas",
        "parameters": [
          { "$ref": "#/components/parameters/dataInicial" },
          { "$ref": "#/components/parameters/dataFinal" },
          { "$ref": "#/components/parameters/idTipati" },
          { "$ref": "#/components/parameters/idTipatiReferencia" },
          { "$ref": "#/components/parameters/status" },
          { "name": "codigo", "in": "query", "required": false, "schema": { "type": "string" } },
          { "$ref": "#/components/parameters/idReferencia" }
        ],
        "responses": {
          "200": {
            "description": "Ordens do período.",
            "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object" } } } }
          },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" }
        }
      }
    },

    "/ordem_agricola_insumo": {
      "get": {
        "tags": ["Ordem de serviço"],
        "summary": "Insumos da ordem de serviço",
        "description": "Cabeçalho da ordem mais as listas `produtos`, `talhoes` e `execucoes`. `QUANTIDADE_TOTAL_PRODUTO` é o que saiu do estoque na ordem inteira; `QUANTIDADE_PROPORCIONAL` é a fatia de um talhão — não lance as duas.",
        "operationId": "listarOrdensInsumo",
        "parameters": [
          { "$ref": "#/components/parameters/datmodInicial" },
          { "$ref": "#/components/parameters/dataInicial" },
          { "$ref": "#/components/parameters/dataFinal" },
          { "$ref": "#/components/parameters/idTipati" },
          { "$ref": "#/components/parameters/idTipatiReferencia" },
          { "$ref": "#/components/parameters/status" },
          { "name": "codigo", "in": "query", "required": false, "schema": { "type": "string" } },
          { "$ref": "#/components/parameters/idReferencia" }
        ],
        "responses": {
          "200": {
            "description": "Ordens com os insumos baixados.",
            "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object" } } } }
          },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" }
        }
      }
    },

    "/ordem_agricola_devolucao": {
      "get": {
        "tags": ["Ordem de serviço"],
        "summary": "Devoluções da ordem de serviço",
        "description": "A diferença entre o programado e o executado. `QUANTIDADE_DIFERENCA` vem sempre positiva; quem diz a direção é `TIPO_DIFERENCA` (`ENTRADA` volta ao estoque, `SAÍDA` sai dele).",
        "operationId": "listarOrdensDevolucao",
        "parameters": [
          { "$ref": "#/components/parameters/datmodInicial" },
          { "$ref": "#/components/parameters/dataInicial" },
          { "$ref": "#/components/parameters/dataFinal" },
          { "$ref": "#/components/parameters/idTipati" },
          { "$ref": "#/components/parameters/idTipatiReferencia" },
          { "$ref": "#/components/parameters/status" },
          { "name": "codigo", "in": "query", "required": false, "schema": { "type": "string" } },
          { "$ref": "#/components/parameters/idReferencia" }
        ],
        "responses": {
          "200": {
            "description": "Diferenças a devolver ou a retirar.",
            "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object" } } } }
          },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" }
        }
      }
    },

    "/ordem_agricola_execucao": {
      "get": {
        "tags": ["Ordem de serviço"],
        "summary": "Execuções da ordem de serviço",
        "description": "Uma linha por execução: quem operou, com qual máquina, em qual talhão e quantas horas.",
        "operationId": "listarOrdensExecucao",
        "parameters": [
          { "$ref": "#/components/parameters/datmodInicial" },
          { "$ref": "#/components/parameters/dataInicial" },
          { "$ref": "#/components/parameters/dataFinal" },
          { "$ref": "#/components/parameters/status" },
          { "$ref": "#/components/parameters/idReferencia" }
        ],
        "responses": {
          "200": {
            "description": "Execuções do período.",
            "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object" } } } }
          },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" }
        }
      }
    },

    "/abastecimento": {
      "get": {
        "tags": ["Frota"],
        "summary": "Listar abastecimentos",
        "operationId": "listarAbastecimentos",
        "parameters": [
          { "$ref": "#/components/parameters/datmodInicial" },
          { "$ref": "#/components/parameters/dataInicial" },
          { "$ref": "#/components/parameters/dataFinal" },
          { "$ref": "#/components/parameters/status" },
          { "name": "id_locest", "in": "query", "required": false, "description": "Local de estoque, pelo identificador da upCampo.", "schema": { "type": "string" } },
          { "name": "id_locest_referencia", "in": "query", "required": false, "schema": { "type": "string" } },
          { "name": "id_equipamento", "in": "query", "required": false, "description": "Equipamento, pelo identificador da upCampo.", "schema": { "type": "string" } },
          { "name": "id_equipamento_referencia", "in": "query", "required": false, "schema": { "type": "string" } },
          { "name": "numero", "in": "query", "required": false, "schema": { "type": "string" } },
          { "$ref": "#/components/parameters/idReferencia" }
        ],
        "responses": {
          "200": {
            "description": "Abastecimentos do período.",
            "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object" } } } }
          },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" }
        }
      }
    },

    "/fardo": {
      "get": {
        "tags": ["Algodão"],
        "summary": "Listar fardos de algodão",
        "description": "Os filtros de talhão comparam de forma exata, sem busca parcial: o valor precisa ser idêntico ao retornado pela rota. Quem usa esta rota para a entrada na algodoeira precisa devolver o peso por `POST /fardoPeso` — sem isso, o acesso é bloqueado.",
        "operationId": "listarFardos",
        "parameters": [
          { "$ref": "#/components/parameters/dataInicialObrigatoria" },
          { "$ref": "#/components/parameters/dataFinalObrigatoria" },
          { "name": "id_talhao_upcampo", "in": "query", "required": false, "schema": { "type": "string" } },
          { "name": "id_talhao_referencia", "in": "query", "required": false, "schema": { "type": "string" } },
          { "name": "id_plantio_safra_referencia", "in": "query", "required": false, "schema": { "type": "string" } },
          { "name": "talhao_descricao", "in": "query", "required": false, "description": "Comparação exata.", "schema": { "type": "string" } },
          { "name": "setor", "in": "query", "required": false, "description": "Comparação exata.", "schema": { "type": "string" } },
          { "name": "talhao_descricao_setor", "in": "query", "required": false, "description": "Descrição e setor concatenados; comparação exata.", "schema": { "type": "string" } },
          { "name": "talhao_finalizado", "in": "query", "required": false, "description": "Valor inválido é ignorado e a consulta retorna sem esse filtro.", "schema": { "type": "string", "enum": ["true", "false", "1", "0"] } }
        ],
        "responses": {
          "200": {
            "description": "Fardos do período.",
            "content": {
              "application/json": {
                "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Fardo" } }
              }
            }
          },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" }
        }
      },
      "post": {
        "tags": ["Algodão"],
        "summary": "Incluir fardo",
        "description": "Cadastro completo do fardo. Para atualizar só a referência ou só o peso, use `/fardoReferencia` e `/fardoPeso`.",
        "operationId": "gravarFardos",
        "requestBody": { "$ref": "#/components/requestBodies/FardoEntrada" },
        "responses": {
          "200": { "$ref": "#/components/responses/EscritaOk" },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" },
          "500": { "$ref": "#/components/responses/EscritaErro" }
        }
      }
    },

    "/fardoEspecifico": {
      "get": {
        "tags": ["Algodão"],
        "summary": "Buscar um fardo",
        "description": "O filtro é um destes: `qrcode`, `moduleid`, `codigo` ou `id`. Preenchendo mais de um, vale o último dessa lista; não preenchendo nenhum, nada é retornado.",
        "operationId": "buscarFardo",
        "parameters": [
          { "name": "qrcode", "in": "query", "required": false, "schema": { "type": "string" } },
          { "name": "moduleid", "in": "query", "required": false, "schema": { "type": "string" } },
          { "name": "codigo", "in": "query", "required": false, "schema": { "type": "string" } },
          { "name": "id", "in": "query", "required": false, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "O fardo encontrado.",
            "content": {
              "application/json": {
                "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Fardo" } }
              }
            }
          },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" }
        }
      }
    },

    "/fardoPeso": {
      "post": {
        "tags": ["Algodão"],
        "summary": "Atualizar o peso do fardo",
        "description": "A algodoeira pesa o fardo recolhido e devolve o `PESALG` para a upCampo. É condição de acesso para quem consome `/fardo`, `/fardoEspecifico` ou `/romcol` na entrada da algodoeira.",
        "operationId": "gravarPesoFardos",
        "requestBody": { "$ref": "#/components/requestBodies/FardoPeso" },
        "responses": {
          "200": { "$ref": "#/components/responses/EscritaOk" },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" },
          "500": { "$ref": "#/components/responses/EscritaErro" }
        }
      }
    },

    "/romcol": {
      "get": {
        "tags": ["Armazenagem"],
        "summary": "Listar romaneios de colheita",
        "description": "O romaneio registra a pesagem e a classificação de cada carga que chega do talhão. `TOTLIQ` é o saldo que entra no estoque e forma a produtividade.",
        "operationId": "listarRomaneios",
        "parameters": [
          { "$ref": "#/components/parameters/dataInicialObrigatoria" },
          { "$ref": "#/components/parameters/dataFinalObrigatoria" }
        ],
        "responses": {
          "200": {
            "description": "Romaneios do período.",
            "content": {
              "application/json": {
                "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Romaneio" } }
              }
            }
          },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" }
        }
      },
      "post": {
        "tags": ["Armazenagem"],
        "summary": "Incluir romaneio de colheita",
        "operationId": "gravarRomaneios",
        "requestBody": { "$ref": "#/components/requestBodies/RomaneioEntrada" },
        "responses": {
          "200": { "$ref": "#/components/responses/EscritaOk" },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" },
          "500": { "$ref": "#/components/responses/EscritaErro" }
        }
      }
    },

    "/romcolClassificacao": {
      "post": {
        "tags": ["Armazenagem"],
        "summary": "Atualizar a classificação do romaneio",
        "description": "Para o caso em que a carga é pesada primeiro e classificada depois.",
        "operationId": "gravarClassificacaoRomaneio",
        "requestBody": { "$ref": "#/components/requestBodies/RomaneioClassificacao" },
        "responses": {
          "200": { "$ref": "#/components/responses/EscritaOk" },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" },
          "500": { "$ref": "#/components/responses/EscritaErro" }
        }
      }
    },

    "/{entidade}Referencia": {
      "post": {
        "tags": ["Referência"],
        "summary": "Gravar só o ID_REFERENCIA",
        "description": "Grava o identificador do sistema do parceiro num registro existente, sem reenviar o objeto inteiro.\n\nEntidades aceitas: `safra`, `plantio_safra`, `tipo_atividade`, `equipe`, `funcionario`, `local_estoque`, `cultura`, `variedade`, `classe`, `produto`, `equipamento`, `movimentacao`, `transferencia`, `fardo`, `abastecimento`, `ordem_agricola_insumo`, `ordem_agricola_execucao` e `ordem_agricola_completa`.",
        "operationId": "gravarReferencia",
        "parameters": [
          {
            "name": "entidade",
            "in": "path",
            "required": true,
            "description": "Nome da entidade, sem o sufixo `Referencia`.",
            "schema": {
              "type": "string",
              "enum": [
                "safra", "plantio_safra", "tipo_atividade", "equipe", "funcionario",
                "local_estoque", "cultura", "variedade", "classe", "produto",
                "equipamento", "movimentacao", "transferencia", "fardo", "abastecimento",
                "ordem_agricola_insumo", "ordem_agricola_execucao", "ordem_agricola_completa"
              ]
            }
          },
          { "name": "id_upcampo", "in": "query", "required": true, "description": "Identificador do registro na base da upCampo.", "schema": { "type": "string" } },
          { "name": "id_referencia", "in": "query", "required": true, "description": "Identificador do registro no sistema do parceiro.", "schema": { "type": "string" } },
          { "name": "codSai", "in": "query", "required": false, "description": "Só em `ordem_agricola_completaReferencia`: usado quando o código gerado no sistema do parceiro é diferente do código da ordem na upCampo.", "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "$ref": "#/components/responses/EscritaOk" },
          "400": { "$ref": "#/components/responses/ErroBanco" },
          "401": { "$ref": "#/components/responses/NaoAutorizado" },
          "500": { "$ref": "#/components/responses/EscritaErro" }
        }
      }
    }
  },

  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Token obtido em `POST /autenticar`, válido por 24 horas. A empresa e a fazenda ficam fixadas no token."
      }
    },

    "parameters": {
      "datmodInicial": {
        "name": "datmod_inicial",
        "in": "query",
        "required": false,
        "description": "Data de modificação inicial, para sincronização incremental. Formato `AAAA-MM-DD HH:MM:SS`; a hora é opcional e, sem ela, vale a partir da meia-noite. Guarde a data de cada consulta e use-a na consulta seguinte.",
        "schema": {
          "type": "string",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}( \\d{2}:\\d{2}(:\\d{2})?)?$",
          "examples": ["2024-03-15 07:00:00", "2024-03-15"]
        }
      },
      "dataInicial": {
        "name": "data_inicial",
        "in": "query",
        "required": false,
        "description": "Data inicial do documento, no formato `AAAA-MM-DD`. A janela entre data_inicial e data_final é de no máximo 7 dias.",
        "schema": { "type": "string", "format": "date", "examples": ["2024-08-19"] }
      },
      "dataFinal": {
        "name": "data_final",
        "in": "query",
        "required": false,
        "description": "Data final do documento, no formato `AAAA-MM-DD`. A janela entre data_inicial e data_final é de no máximo 7 dias.",
        "schema": { "type": "string", "format": "date", "examples": ["2024-08-25"] }
      },
      "dataInicialObrigatoria": {
        "name": "data_inicial",
        "in": "query",
        "required": true,
        "description": "Data inicial, no formato `AAAA-MM-DD`. A janela entre data_inicial e data_final é de no máximo 7 dias.",
        "schema": { "type": "string", "format": "date", "examples": ["2024-08-19"] }
      },
      "dataFinalObrigatoria": {
        "name": "data_final",
        "in": "query",
        "required": true,
        "description": "Data final, no formato `AAAA-MM-DD`. A janela entre data_inicial e data_final é de no máximo 7 dias.",
        "schema": { "type": "string", "format": "date", "examples": ["2024-08-25"] }
      },
      "status": {
        "name": "status",
        "in": "query",
        "required": false,
        "schema": { "type": "string", "enum": ["Finalizado", "Pendente"] }
      },
      "idReferencia": {
        "name": "id_referencia",
        "in": "query",
        "required": false,
        "description": "Identificador do registro no sistema do parceiro.",
        "schema": { "type": "string" }
      },
      "idTipati": {
        "name": "id_tipati",
        "in": "query",
        "required": false,
        "description": "Tipo de atividade, pelo identificador da upCampo.",
        "schema": { "type": "string" }
      },
      "idTipatiReferencia": {
        "name": "id_tipati_referencia",
        "in": "query",
        "required": false,
        "description": "Tipo de atividade, pelo identificador do ERP terceiro.",
        "schema": { "type": "string" }
      }
    },

    "responses": {
      "EscritaOk": {
        "description": "Registros processados. Percorra o array para saber o status de cada id enviado.",
        "content": {
          "application/json": {
            "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ResultadoEscrita" } },
            "example": [
              { "TABELA": "PRODUTO", "ID_UPCAMPO": "7B6E1387-E3BC-4DE9-B8F2-63703B4F9495", "ID_REFERENCIA": "30", "STATUS": "INCLUIDO", "MENSAGEM": "" }
            ]
          }
        }
      },
      "EscritaErro": {
        "description": "Erro de validação: a requisição chegou ao banco de dados e alguma regra barrou o registro. O corpo continua sendo o array de resultados, com `STATUS: \"ERRO\"` em pelo menos uma linha.",
        "content": {
          "application/json": {
            "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ResultadoEscrita" } },
            "example": [
              { "TABELA": "CABECALHO", "ID_UPCAMPO": "B674DF03-052C-427D-9CCD-FFA553F88D18", "ID_REFERENCIA": "21", "STATUS": "ERRO", "MENSAGEM": "Documento finalizado não pode ser alterado" }
            ]
          }
        }
      },
      "NaoAutorizado": {
        "description": "Token ausente, inválido ou expirado.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "status": { "type": "string" },
                "error": { "type": "string" }
              }
            },
            "examples": {
              "invalido": { "value": { "status": "Erro", "error": "Token não inválido" } },
              "ausente": { "value": { "status": "Erro", "error": "Token não fornecido" } }
            }
          }
        }
      },
      "ErroBanco": {
        "description": "Erro de requisição ou de banco de dados.",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ErroBanco" }
          }
        }
      }
    },

    "requestBodies": {
      "Cultura": {
        "required": true,
        "content": {
          "application/json": {
            "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Cultura" } },
            "example": [
              { "ID_REFERENCIA": "1", "CODIGO": "0001", "DESCRICAO": "Cultura- TESTE INTEGRACAO 2", "ATIVO": true, "DELETADO": false }
            ]
          }
        }
      },
      "Variedade": {
        "required": true,
        "content": {
          "application/json": {
            "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Variedade" } },
            "example": [
              { "ID_REFERENCIA": "1", "CODIGO": "0001", "DESCRICAO": "Variedade integracao", "ATIVO": true, "DELETADO": false, "ID_CULTURA_REFERENCIA": "1" }
            ]
          }
        }
      },
      "ClasseProduto": {
        "required": true,
        "content": {
          "application/json": {
            "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ClasseProduto" } },
            "example": [
              { "ID_REFERENCIA": "1", "CODIGO": "0001", "DESCRICAO": "Classe integracao", "ATIVO": true, "DELETADO": false }
            ]
          }
        }
      },
      "Produto": {
        "required": true,
        "content": {
          "application/json": {
            "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Produto" } },
            "example": [
              { "ID_REFERENCIA": "30", "CODIGO": "0001", "DESCRICAO": "TV 40 POLEGADA - TESTE INTEGRACAO 1", "MARCA": "LG", "CODUNI": "UN", "ATIVO": true, "DELETADO": false, "ID_CLASSE_REFERENCIA": "25" }
            ]
          }
        }
      },
      "Equipamento": {
        "required": true,
        "content": {
          "application/json": {
            "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Equipamento" } },
            "example": [
              { "ID_REFERENCIA": "1", "TIPO": "Frota", "CODIGO": "0001", "DESCRICAO": "Trator 001", "PLACA": "JHD-1234", "CHASSI": "12345687", "MODELO": "T20", "MARCA": "JONH DEERE", "ATIVO": true, "DELETADO": false }
            ]
          }
        }
      },
      "Movimentacao": {
        "required": true,
        "content": {
          "application/json": {
            "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Movimentacao" } },
            "example": [
              {
                "ID_REFERENCIA": "2",
                "NUMERO": "0002",
                "DATA": "2024-4-27",
                "CNPJCPF": "0123",
                "RAZSOC": "NOVO INTEGRACAO",
                "NOMFAN": "NOVO IN",
                "CHANFE": "5555.44444.5555.6666.9999.99999",
                "VALTOT": 200.5,
                "VALDES": 0,
                "VALFRE": 0,
                "VALLIQ": 200.5,
                "DELETADO": false,
                "ITENS": [
                  { "ID_REFERENCIA": "A", "ID_PRODUTO_REFERENCIA": "1", "ID_LOCEST_REFERENCIA": "1010101", "QUANTIDADE": 40, "VALUNI": 2, "VALTOT": 40, "VALLIQ": 40 }
                ]
              }
            ]
          }
        }
      },
      "Transferencia": {
        "required": true,
        "content": {
          "application/json": {
            "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Transferencia" } },
            "example": [
              {
                "ID_REFERENCIA": "21",
                "DATA": "2023-3-27",
                "ID_LOCESTORI_REFERENCIA": "1010101",
                "ID_LOCESTDES_REFERENCIA": "2010101",
                "NUMEXT": "0021",
                "QUEMENTREGOU": "José",
                "QUEMRECEBEU": "João",
                "NUMNF": "00158",
                "ITENS": [
                  { "ID_REFERENCIA": "21_A", "ID_PRODUTO_REFERENCIA": "1", "QUANTIDADE": 5, "VALUNI": 2, "VALLIQ": 10 }
                ]
              }
            ]
          }
        }
      },
      "Inventario": {
        "required": true,
        "content": {
          "application/json": {
            "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Inventario" } },
            "example": [
              { "ID_REFERENCIA": "1", "ID_PRODUTO_REFERENCIA": "1", "ID_LOCEST_REFERENCIA": "1010101", "DATA": "2023-02-01", "SALDO": 20, "VALUNI": 30, "VALTOT": 600 }
            ]
          }
        }
      },
      "FardoEntrada": {
        "required": true,
        "content": {
          "application/json": {
            "schema": { "type": "array", "items": { "$ref": "#/components/schemas/FardoEntrada" } },
            "example": [
              {
                "ID_REFERENCIA": "111",
                "ID_PLANTIO_SAFRA_REFERENCIA": "12",
                "MODULEID": "MODULEID",
                "QRCODE": "QRCODE",
                "LATITUDE": "1",
                "LONGITUDE": "2",
                "PESFAZ": 1100,
                "PESALG": 1500.6,
                "HECTARE": 0.5,
                "STATUS": "No campo",
                "DATA": "2023-7-03",
                "ID_EQUIPAMENTO_REFERENCIA": "1"
              }
            ]
          }
        }
      },
      "FardoPeso": {
        "required": true,
        "content": {
          "application/json": {
            "schema": { "type": "array", "items": { "$ref": "#/components/schemas/FardoPeso" } },
            "example": [
              {
                "ID_FARDO_UPCAMPO": "D83E100A-DFDB-451A-B4BB-56ED09EA851C",
                "ID_REFERENCIA": "1",
                "PESALG": 1500.6,
                "STATUS": "Recolhido",
                "DATA": "2023-6-21",
                "ID_EQUIPAMENTO_REFERENCIA": "1",
                "ID_LOCEST_REFERENCIA": "1010101",
                "NUMCOL": "0059"
              }
            ]
          }
        }
      },
      "RomaneioEntrada": {
        "required": true,
        "content": {
          "application/json": {
            "schema": { "type": "array", "items": { "$ref": "#/components/schemas/RomaneioEntrada" } },
            "example": [
              {
                "ID_REFERENCIA": "1",
                "NUMERO": "4826",
                "DATA": "2023-12-13",
                "HORA": 8,
                "MINUTO": 42,
                "PESBRU": 85700,
                "PESTAR": 27560,
                "PESLIQ": 58140,
                "UMIPER": 13.2,
                "IMPPER": 1.6,
                "IMPDESKG": 349,
                "QUEPER": 10,
                "QUEDESKG": 1163,
                "TOTDES": 1512,
                "TOTLIQ": 56628,
                "ID_PLANTIO_SAFRA_REFERENCIA": "1",
                "ID_EQUIPAMENTO_REFERENCIA": "1",
                "ID_LOCEST_REFERENCIA": "1",
                "ID_PRODUTO_REFERENCIA": "1",
                "MOTORISTA": "JOSE CARLOS PEREIRA"
              }
            ]
          }
        }
      },
      "RomaneioClassificacao": {
        "required": true,
        "content": {
          "application/json": {
            "schema": { "type": "array", "items": { "$ref": "#/components/schemas/RomaneioClassificacao" } },
            "example": [
              {
                "ID_REFERENCIA": "1",
                "ID_ROMCOL_UPCAMPO": "9ryejRKRhClBLcKTXwvx",
                "UMIPER": 13.2,
                "IMPPER": 1.6,
                "IMPDESKG": 349,
                "QUEPER": 10,
                "QUEDESKG": 1163,
                "TOTDES": 1512,
                "TOTLIQ": 56628
              }
            ]
          }
        }
      }
    },

    "schemas": {
      "Credenciais": {
        "type": "object",
        "required": ["client_id", "client_secret", "audience", "grant_type"],
        "properties": {
          "client_id": { "type": "string", "description": "Fornecido pela upCampo." },
          "client_secret": { "type": "string", "description": "Fornecido pela upCampo." },
          "audience": { "type": "string", "const": "https://api.upcampo.com.br" },
          "grant_type": { "type": "string", "const": "client_credentials" }
        }
      },
      "Token": {
        "type": "object",
        "description": "Token de acesso. A validade (hoje 24 horas) fica dentro do próprio JWT, no campo `exp` — o corpo da resposta não traz um `expires_in`.",
        "required": ["access_token", "token_type"],
        "properties": {
          "access_token": { "type": "string", "description": "JWT a ser enviado no cabeçalho Authorization." },
          "token_type": { "type": "string", "const": "Bearer" }
        }
      },
      "ResultadoEscrita": {
        "type": "object",
        "description": "Uma linha por registro processado. Em documentos com cabeçalho e itens, vem uma linha `CABECALHO` e uma `DETALHE` por item; basta uma com `ERRO` para o documento inteiro não ser gravado.",
        "properties": {
          "TABELA": { "type": "string", "description": "Tabela em questão.", "examples": ["PRODUTO", "CABECALHO", "DETALHE"] },
          "ID_UPCAMPO": { "type": ["string", "null"], "description": "Identificador interno da upCampo." },
          "ID_REFERENCIA": { "type": ["string", "null"], "description": "Identificador do sistema parceiro." },
          "STATUS": { "type": "string", "enum": ["INCLUIDO", "ALTERADO", "ERRO"] },
          "MENSAGEM": { "type": "string", "description": "Quando o status é ERRO, descreve o motivo." }
        }
      },
      "ErroBanco": {
        "type": "object",
        "properties": {
          "status": { "type": "string", "examples": ["Erro"] },
          "detalhe": {
            "type": "object",
            "properties": {
              "message": { "type": "string" },
              "code": { "type": "string" },
              "number": { "type": "integer" },
              "state": { "type": "integer" },
              "class": { "type": "integer" },
              "serverName": { "type": "string" },
              "procName": { "type": "string" },
              "lineNumber": { "type": "integer" }
            }
          }
        }
      },

      "Cultura": {
        "type": "object",
        "required": ["ID_REFERENCIA", "DESCRICAO"],
        "properties": {
          "ID_REFERENCIA": { "type": "string", "description": "Identificador no ERP terceiro. Encontrado, é atualização; não encontrado, é registro novo." },
          "DESCRICAO": { "type": "string" },
          "CODIGO": { "type": "string" },
          "ATIVO": { "type": "boolean" },
          "DELETADO": { "type": "boolean", "description": "true envia uma exclusão." }
        }
      },
      "Variedade": {
        "type": "object",
        "required": ["ID_REFERENCIA", "DESCRICAO", "ID_CULTURA_REFERENCIA"],
        "properties": {
          "ID_REFERENCIA": { "type": "string" },
          "DESCRICAO": { "type": "string" },
          "CODIGO": { "type": "string" },
          "DIACIC": { "type": "integer", "description": "Dias do ciclo." },
          "ATIVO": { "type": "boolean" },
          "DELETADO": { "type": "boolean" },
          "ID_CULTURA_REFERENCIA": { "type": "string", "description": "Cultura no ERP terceiro, mapeada no cadastro da upCampo." }
        }
      },
      "Talhao": {
        "type": "object",
        "properties": {
          "ID_REFERENCIA": { "type": ["string", "null"] },
          "DESCRICAO": { "type": "string" },
          "CODIGO": { "type": "string" },
          "AREA": { "type": "number", "description": "Em hectares." },
          "SETOR": { "type": ["string", "null"] },
          "ATIVO": { "type": "boolean" },
          "DELETADO": { "type": "boolean" }
        }
      },
      "Safra": {
        "type": "object",
        "properties": {
          "ID_REFERENCIA": { "type": ["string", "null"] },
          "DESCRICAO": { "type": "string" },
          "CODIGO": { "type": "string" },
          "ATIVO": { "type": "boolean" },
          "DELETADO": { "type": "boolean" }
        }
      },
      "PlantioSafra": {
        "type": "object",
        "properties": {
          "ID": { "type": "string" },
          "ID_SAFRA": { "type": "string" },
          "ID_QUADRA": { "type": "string", "description": "Talhão (quadra, no banco)." },
          "ID_CULTURA": { "type": "string" },
          "ID_VARIEDADE": { "type": ["string", "null"] },
          "AREA": { "type": "number", "description": "Em hectares." },
          "DATPLA": { "type": ["string", "null"], "description": "Data de plantio." },
          "DATCOL": { "type": ["string", "null"], "description": "Data de colheita." },
          "ATIVO": { "type": "boolean" },
          "ID_EMPRESA": { "type": "string" },
          "ID_FILIAL": { "type": "string" }
        }
      },
      "ClasseProduto": {
        "type": "object",
        "required": ["ID_REFERENCIA", "DESCRICAO"],
        "properties": {
          "ID_REFERENCIA": { "type": "string" },
          "DESCRICAO": { "type": "string" },
          "CODIGO": { "type": "string" },
          "ATIVO": { "type": "boolean" },
          "DELETADO": { "type": "boolean" }
        }
      },
      "Produto": {
        "type": "object",
        "required": ["ID_REFERENCIA", "DESCRICAO"],
        "properties": {
          "ID_REFERENCIA": { "type": "string" },
          "DESCRICAO": { "type": "string" },
          "CODIGO": { "type": "string" },
          "MARCA": { "type": "string" },
          "CODUNI": { "type": "string", "description": "Abreviação da unidade. Exemplo: KG." },
          "ATIVO": { "type": "boolean" },
          "NCM": { "type": "string" },
          "COMBUSTIVEL": { "type": "boolean" },
          "SEMENTE": { "type": "boolean" },
          "DELETADO": { "type": "boolean" },
          "CLASSE_DESCRICAO": { "type": "string" },
          "ID_CLASSE_UPCAMPO": { "type": "string" },
          "ID_CLASSE_REFERENCIA": { "type": "string" }
        }
      },
      "LocalEstoque": {
        "type": "object",
        "properties": {
          "ID_UPCAMPO": { "type": "string" },
          "ID_REFERENCIA": { "type": ["string", "null"] },
          "DESCRICAO": { "type": "string" },
          "CODIGO": { "type": "string" },
          "ATIVO": { "type": "boolean" },
          "DELETADO": { "type": "boolean" }
        }
      },
      "Equipamento": {
        "type": "object",
        "required": ["ID_REFERENCIA", "TIPO", "DESCRICAO"],
        "properties": {
          "ID_REFERENCIA": { "type": "string" },
          "TIPO": { "type": "string", "enum": ["Frota", "Equipamento", "Bem Feitoria"] },
          "DESCRICAO": { "type": "string" },
          "CODIGO": { "type": "string" },
          "PLACA": { "type": "string" },
          "CHASSI": { "type": "string" },
          "MODELO": { "type": "string" },
          "MARCA": { "type": "string" },
          "ATIVO": { "type": "boolean" },
          "DELETADO": { "type": "boolean" }
        }
      },
      "TipoAtividade": {
        "type": "object",
        "properties": {
          "ID": { "type": "string" },
          "ID_REFERENCIA": { "type": ["string", "null"] },
          "DESCRICAO": { "type": "string" },
          "CODIGO": { "type": "string" },
          "ATIVO": { "type": "boolean" },
          "CLASSIFICACAO": { "type": "string" }
        }
      },
      "IdentificacaoResumida": {
        "type": "object",
        "properties": {
          "ID": { "type": "string" },
          "ID_REFERENCIA": { "type": ["string", "null"] },
          "DESCRICAO": { "type": "string" },
          "CODIGO": { "type": "string" },
          "ATIVO": { "type": "boolean" }
        }
      },

      "Movimentacao": {
        "type": "object",
        "required": ["ID_REFERENCIA", "NUMERO", "DATA", "CNPJCPF", "RAZSOC", "VALTOT", "VALLIQ", "ITENS"],
        "properties": {
          "ID_REFERENCIA": { "type": "string" },
          "NUMERO": { "type": "string", "description": "Número da NF." },
          "DATA": { "type": "string", "format": "date" },
          "CNPJCPF": { "type": "string", "description": "CNPJ ou CPF do emitente. Não encontrado, é adicionado automaticamente na base da upCampo." },
          "RAZSOC": { "type": "string" },
          "NOMFAN": { "type": "string" },
          "CODFOR": { "type": "string", "description": "Código do emitente no sistema do parceiro." },
          "CHANFE": { "type": "string", "description": "Chave da NF-e." },
          "VALTOT": { "type": "number" },
          "VALDES": { "type": "number" },
          "VALFRE": { "type": "number" },
          "VALLIQ": { "type": "number" },
          "DELETADO": { "type": "boolean" },
          "ITENS": { "type": "array", "items": { "$ref": "#/components/schemas/MovimentacaoItem" } }
        }
      },
      "MovimentacaoItem": {
        "type": "object",
        "required": ["ID_REFERENCIA", "ID_PRODUTO_REFERENCIA", "QUANTIDADE", "VALUNI", "VALTOT", "VALLIQ"],
        "description": "Informe ID_LOCEST_REFERENCIA (o custo entra no estoque) ou ID_EQUIPAMENTO_REFERENCIA (o custo vai direto para uma frota).",
        "properties": {
          "ID_REFERENCIA": { "type": "string" },
          "ID_PRODUTO_REFERENCIA": { "type": "string" },
          "ID_LOTE_REFERENCIA": { "type": "string" },
          "DATVEN": { "type": "string", "format": "date", "description": "Vencimento do lote." },
          "NUMLOT": { "type": "string" },
          "ID_LOCEST_REFERENCIA": { "type": "string" },
          "ID_EQUIPAMENTO_REFERENCIA": { "type": "string" },
          "CODUNI": { "type": "string" },
          "QUANTIDADE": { "type": "number" },
          "VALUNI": { "type": "number" },
          "VALTOT": { "type": "number" },
          "VALDES": { "type": "number" },
          "VALFRE": { "type": "number" },
          "VALLIQ": { "type": "number" },
          "DELETADO": { "type": "boolean" }
        }
      },
      "Transferencia": {
        "type": "object",
        "required": ["ID_REFERENCIA", "DATA", "ID_LOCESTORI_REFERENCIA", "ID_LOCESTDES_REFERENCIA", "ITENS"],
        "properties": {
          "ID_REFERENCIA": { "type": "string" },
          "DATA": { "type": "string", "format": "date" },
          "ID_LOCESTORI_REFERENCIA": { "type": "string", "description": "Local de estoque de origem." },
          "ID_LOCESTDES_REFERENCIA": { "type": "string", "description": "Local de estoque de destino." },
          "NUMEXT": { "type": "string", "description": "Código do documento no ERP terceiro." },
          "QUEMRECEBEU": { "type": "string" },
          "QUEMENTREGOU": { "type": "string" },
          "NUMNF": { "type": "string" },
          "OBSERVACAO": { "type": "string" },
          "DELETADO": { "type": "boolean" },
          "ITENS": { "type": "array", "items": { "$ref": "#/components/schemas/TransferenciaItem" } }
        }
      },
      "TransferenciaItem": {
        "type": "object",
        "required": ["ID_PRODUTO_REFERENCIA", "QUANTIDADE", "VALUNI", "VALLIQ"],
        "properties": {
          "ID_REFERENCIA": { "type": "string" },
          "ID_PRODUTO_REFERENCIA": { "type": "string" },
          "ID_LOTE_REFERENCIA": { "type": "string" },
          "QUANTIDADE": { "type": "number" },
          "VALUNI": { "type": "number" },
          "VALLIQ": { "type": "number" },
          "DELETADO": { "type": "boolean" }
        }
      },
      "Inventario": {
        "type": "object",
        "required": ["ID_REFERENCIA", "SALDO"],
        "description": "Informe o produto e o local pela referência do ERP ou pelo identificador da upCampo — um dos dois em cada caso.",
        "properties": {
          "ID_REFERENCIA": { "type": "string" },
          "ID_PRODUTO_REFERENCIA": { "type": "string" },
          "ID_PRODUTO_UPCAMPO": { "type": "string" },
          "ID_LOTE_REFERENCIA": { "type": "string" },
          "ID_LOTE_UPCAMPO": { "type": "string" },
          "ID_LOCEST_REFERENCIA": { "type": "string" },
          "ID_LOCEST_UPCAMPO": { "type": "string" },
          "DATA": { "type": "string", "format": "date" },
          "SALDO": { "type": "number" },
          "VALUNI": { "type": "number" },
          "VALTOT": { "type": "number" }
        }
      },
      "SaldoEstoque": {
        "type": "object",
        "properties": {
          "ID_ESTOQUE_UPCAMPO": { "type": "string" },
          "LOCEST_DESCRICAO": { "type": "string" },
          "ID_LOCEST_UPCAMPO": { "type": "string" },
          "ID_LOCEST_REFERENCIA": { "type": ["string", "null"] },
          "PRODUTO_DESCRICAO": { "type": "string" },
          "ID_PRODUTO_UPCAMPO": { "type": "string" },
          "ID_PRODUTO_REFERENCIA": { "type": ["string", "null"] },
          "SALDO": { "type": "number" }
        }
      },

      "Fardo": {
        "type": "object",
        "properties": {
          "ID_FARDO_UPCAMPO": { "type": "string" },
          "CODIGO": { "type": "string" },
          "DATASTRING": { "type": "string", "description": "dd/mm/yyyy." },
          "DATA": { "type": "string", "description": "yyyy-mm-dd." },
          "HORA": { "type": "integer" },
          "MINUTO": { "type": "integer" },
          "QRCODE": { "type": ["string", "null"] },
          "MODULEID": { "type": ["string", "null"], "description": "Número único que a colhedora grava no fardo." },
          "STATUS": { "type": "string", "enum": ["No campo", "Recolhido"] },
          "PESFAZ": { "type": ["number", "null"], "description": "Peso na fazenda, em kg." },
          "PESALG": { "type": ["number", "null"], "description": "Peso da algodoeira, depois de recolhido." },
          "HECTARE": { "type": ["number", "null"] },
          "LATITUDE": { "type": ["string", "number", "null"] },
          "LONGITUDE": { "type": ["string", "number", "null"] },
          "OBSERVACAO": { "type": ["string", "null"] },
          "ID_REFERENCIA": { "type": ["string", "null"] },
          "TALHAO_DESCRICAO": { "type": ["string", "null"] },
          "TALHAO_DESCRICAO_SETOR": { "type": ["string", "null"] },
          "ID_TALHAO_UPCAMPO": { "type": ["string", "null"] },
          "ID_TALHAO_REFERENCIA": { "type": ["string", "null"] },
          "SETOR": { "type": ["string", "null"] },
          "ID_SETOR_REFERENCIA": { "type": ["string", "null"] },
          "VARIEDADE_DESCRICAO": { "type": ["string", "null"] },
          "ID_VARIEDADE_UPCAMPO": { "type": ["string", "null"] },
          "ID_VARIEDADE_REFERENCIA": { "type": ["string", "null"] },
          "CULTURA_DESCRICAO": { "type": ["string", "null"] },
          "ID_CULTURA_UPCAMPO": { "type": ["string", "null"] },
          "ID_CULTURA_REFERENCIA": { "type": ["string", "null"] },
          "SAFRA_DESCRICAO": { "type": ["string", "null"] },
          "ID_SAFRA_UPCAMPO": { "type": ["string", "null"] },
          "ID_SAFRA_REFERENCIA": { "type": ["string", "null"] },
          "ID_PLANTIO_SAFRA_UPCAMPO": { "type": ["string", "null"] },
          "ID_PLANTIO_SAFRA_REFERENCIA": { "type": ["string", "null"] },
          "TALHAO_FINALIZADO": { "type": ["boolean", "null"] },
          "EQUIPAMENTO_DESCRICAO": { "type": ["string", "null"] },
          "ID_EQUIPAMENTO_UPCAMPO": { "type": ["string", "null"] },
          "ID_EQUIPAMENTO_REFERENCIA": { "type": ["string", "null"] }
        }
      },
      "FardoEntrada": {
        "type": "object",
        "required": ["ID_REFERENCIA", "DATA", "STATUS", "CONTEC"],
        "description": "Informe ID_PLANTIO_SAFRA_REFERENCIA ou a combinação ID_TALHAO_REFERENCIA + ID_VARIEDADE_REFERENCIA + ID_CULTURA_REFERENCIA + ID_SAFRA_REFERENCIA.",
        "properties": {
          "DATA": { "type": "string", "format": "date" },
          "QRCODE": { "type": "string" },
          "MODULEID": { "type": "string" },
          "STATUS": { "type": "string", "enum": ["No campo", "Recolhido"] },
          "PESFAZ": { "type": "number" },
          "PESALG": { "type": "number" },
          "HECTARE": { "type": "number" },
          "LATITUDE": { "type": "string" },
          "LONGITUDE": { "type": "string" },
          "OBSERVACAO": { "type": "string" },
          "ID_REFERENCIA": { "type": "string" },
          "CONTEC": { "type": "boolean", "description": "Conferido pelo técnico." },
          "ID_PLANTIO_SAFRA_REFERENCIA": { "type": "string" },
          "ID_TALHAO_REFERENCIA": { "type": "string" },
          "ID_VARIEDADE_REFERENCIA": { "type": "string" },
          "ID_CULTURA_REFERENCIA": { "type": "string" },
          "ID_SAFRA_REFERENCIA": { "type": "string" },
          "ID_EQUIPAMENTO_REFERENCIA": { "type": "string" }
        }
      },
      "FardoPeso": {
        "type": "object",
        "required": ["ID_FARDO_UPCAMPO", "PESALG", "STATUS", "DATA"],
        "properties": {
          "ID_FARDO_UPCAMPO": { "type": "string" },
          "ID_REFERENCIA": { "type": "string" },
          "PESALG": { "type": "number", "description": "Peso da algodoeira, depois de recolhido." },
          "STATUS": { "type": "string", "enum": ["No campo", "Recolhido"] },
          "DATA": { "type": "string", "format": "date" },
          "ID_EQUIPAMENTO_REFERENCIA": { "type": "string" },
          "ID_LOCEST_REFERENCIA": { "type": "string" },
          "NUMCOL": { "type": "string", "description": "Número da coleta no ERP terceiro." }
        }
      },

      "Classificacao": {
        "type": "object",
        "description": "Percentuais e descontos da classificação. Cada tipo tem o mesmo trio: PER (percentual medido), DES (percentual de desconto da tabela de classificação) e DESKG (desconto em kg já aplicado sobre o PESLIQ).",
        "properties": {
          "UMIPER": { "type": ["number", "null"], "description": "% de umidade." },
          "UMIDES": { "type": ["number", "null"] },
          "UMIDESKG": { "type": ["number", "null"] },
          "IMPPER": { "type": ["number", "null"], "description": "% de impureza." },
          "IMPDES": { "type": ["number", "null"] },
          "IMPDESKG": { "type": ["number", "null"] },
          "AVAPER": { "type": ["number", "null"], "description": "% de avariado." },
          "AVADES": { "type": ["number", "null"] },
          "AVADESKG": { "type": ["number", "null"] },
          "QUEPER": { "type": ["number", "null"], "description": "% de quebrado." },
          "QUEDES": { "type": ["number", "null"] },
          "QUEDESKG": { "type": ["number", "null"] },
          "ARDPER": { "type": ["number", "null"], "description": "% de ardido." },
          "ARDDES": { "type": ["number", "null"] },
          "ARDDESKG": { "type": ["number", "null"] },
          "ARMPER": { "type": ["number", "null"], "description": "% de armazenagem." },
          "ARMDES": { "type": ["number", "null"] },
          "ARMDESKG": { "type": ["number", "null"] },
          "TOTDES": { "type": ["number", "null"], "description": "Total de desconto, em kg." },
          "TOTLIQ": { "type": ["number", "null"], "description": "Total líquido final — o saldo que entra no estoque e forma a produtividade." }
        }
      },
      "Romaneio": {
        "allOf": [
          { "$ref": "#/components/schemas/Classificacao" },
          {
            "type": "object",
            "properties": {
              "ID_ROMCOL_UPCAMPO": { "type": "string" },
              "NUMERO": { "type": "string" },
              "NUMAUT": { "type": ["string", "null"], "description": "Número da autorização." },
              "DATASTRING": { "type": "string" },
              "DATA": { "type": "string" },
              "HORA": { "type": "integer" },
              "MINUTO": { "type": "integer" },
              "PESBRU": { "type": "number", "description": "Peso bruto — primeiro peso, caminhão cheio, em kg." },
              "PESTAR": { "type": "number", "description": "Peso tara — segundo peso, caminhão vazio, em kg." },
              "PESLIQ": { "type": "number", "description": "Peso líquido inicial, sem classificação." },
              "OBSERVACAO": { "type": ["string", "null"] },
              "ID_REFERENCIA": { "type": ["string", "null"] },
              "TALHAO_DESCRICAO": { "type": ["string", "null"] },
              "SETOR": { "type": ["string", "null"] },
              "ID_SETOR_REFERENCIA": { "type": ["string", "null"] },
              "ID_TALHAO_UPCAMPO": { "type": ["string", "null"] },
              "ID_TALHAO_REFERENCIA": { "type": ["string", "null"] },
              "VARIEDADE_DESCRICAO": { "type": ["string", "null"] },
              "CULTURA_DESCRICAO": { "type": ["string", "null"] },
              "SAFRA_DESCRICAO": { "type": ["string", "null"] },
              "ID_PLANTIO_SAFRA_UPCAMPO": { "type": ["string", "null"] },
              "ID_PLANTIO_SAFRA_REFERENCIA": { "type": ["string", "null"] },
              "EQUIPAMENTO_DESCRICAO": { "type": ["string", "null"] },
              "PLACA": { "type": ["string", "null"] },
              "MOTORISTA": { "type": ["string", "null"] },
              "LOCEST_DESCRICAO": { "type": ["string", "null"] },
              "PRODUTO_DESCRICAO": { "type": ["string", "null"] }
            }
          }
        ]
      },
      "RomaneioEntrada": {
        "allOf": [
          { "$ref": "#/components/schemas/Classificacao" },
          {
            "type": "object",
            "required": ["ID_REFERENCIA", "NUMERO", "PESBRU", "PESTAR", "PESLIQ", "ID_LOCEST_REFERENCIA", "ID_PRODUTO_REFERENCIA"],
            "description": "Informe ID_PLANTIO_SAFRA_REFERENCIA ou a combinação ID_TALHAO_REFERENCIA + ID_VARIEDADE_REFERENCIA + ID_CULTURA_REFERENCIA + ID_SAFRA_REFERENCIA. Informe ID_EQUIPAMENTO_REFERENCIA ou PLACA.",
            "properties": {
              "ID_REFERENCIA": { "type": "string" },
              "NUMERO": { "type": "string" },
              "NUMAUT": { "type": "string" },
              "DATA": { "type": "string", "format": "date" },
              "HORA": { "type": "integer" },
              "MINUTO": { "type": "integer" },
              "PESBRU": { "type": "number" },
              "PESTAR": { "type": "number" },
              "PESLIQ": { "type": "number" },
              "OBSERVACAO": { "type": "string" },
              "ID_PLANTIO_SAFRA_REFERENCIA": { "type": "string" },
              "ID_TALHAO_REFERENCIA": { "type": "string" },
              "ID_VARIEDADE_REFERENCIA": { "type": "string" },
              "ID_CULTURA_REFERENCIA": { "type": "string" },
              "ID_SAFRA_REFERENCIA": { "type": "string" },
              "ID_SETOR_REFERENCIA": { "type": "string" },
              "ID_EQUIPAMENTO_REFERENCIA": { "type": "string" },
              "PLACA": { "type": "string" },
              "MOTORISTA": { "type": "string" },
              "ID_LOCEST_REFERENCIA": { "type": "string", "description": "Local de estoque (armazém) de destino." },
              "ID_PRODUTO_REFERENCIA": { "type": "string", "description": "Produto que entra no estoque — soja, milho." }
            }
          }
        ]
      },
      "RomaneioClassificacao": {
        "allOf": [
          { "$ref": "#/components/schemas/Classificacao" },
          {
            "type": "object",
            "required": ["ID_REFERENCIA"],
            "properties": {
              "ID_REFERENCIA": { "type": "string" },
              "ID_ROMCOL_UPCAMPO": { "type": "string" }
            }
          }
        ]
      }
    }
  }
}
