{"openapi":"3.1.0","info":{"title":"TechPS Signature — API de assinatura eletrônica","version":"1.0.0","description":"API para o ERP conduzir todo o ciclo de assinatura sem ninguém abrir o painel:\nenvio do documento, acompanhamento, download do arquivo assinado e relatório de\nevidências.\n\n## Autenticação\n\nToda chamada leva o token no cabeçalho:\n\n```\nAuthorization: Bearer tsk_live_xxxxxxxxxxxxxxxx\n```\n\nO token é criado no painel, em **Segurança → Integração**, e aparece uma única\nvez. Tokens de homologação começam com `tsk_test_` e trabalham sobre a base de\nsandbox, separada da produção.\n\n## Como identificar um documento\n\nOs endpoints aceitam três formas no lugar do `{id}`:\n\n| Forma | Exemplo |\n|---|---|\n| id interno | `128` |\n| id público | `DOC-20261010093015-A7F3C1` |\n| sua referência | `ORDEM-99812` (o que você mandou em `referencia`) |\n\nAssim o ERP não precisa guardar o id da plataforma: basta usar a própria chave.\n\n## Métodos de autenticação do signatário\n\nDefinidos por documento (campo `autenticacao`) ou por signatário\n(`signatarios[].autenticacao`). O que o signatário pede tem prioridade; sem\nnenhum dos dois, vale o padrão da empresa.\n\n| Valor | O que o signatário faz |\n|---|---|\n| `cpf_rg` | digita CPF e RG, conferidos com o cadastro |\n| `rubrica` | desenha a rubrica na tela |\n| `ambos` | CPF e RG mais a rubrica |\n| `facial` | tira uma foto do rosto |\n| `facial_cpf_rg` | foto do rosto mais CPF e RG |\n\n## Ordem das assinaturas\n\nA ordem é a da lista `signatarios`. O próximo só recebe o link quando o\nanterior assina. Com `governanca.funcionario`, a plataforma monta a cadeia\nsozinha: o funcionário primeiro e, depois, os responsáveis do setor e do cargo\ncadastrados para governança.\n\n## Verbos\n\nA API cobre tudo o que o painel faz, com o mesmo significado em todo recurso:\n\n| Verbo | O que faz |\n|---|---|\n| `GET` | lê (lista ou um registro) |\n| `POST` | cria, ou executa uma ação (`\/cancelar`, `\/renovar`, `\/testar`) |\n| `PUT` | substitui o registro inteiro: o que não vier volta ao padrão |\n| `PATCH` | altera só os campos enviados |\n| `DELETE` | **inativa**, não apaga |\n\n`DELETE` nunca remove dados. Assinatura é prova: um funcionário, um certificado ou\num documento que já assinou precisa continuar existindo para a prova fazer sentido.\nO registro passa a `inativo` (ou `cancelado`, no caso de documento), sai das listas e\nnão entra em novos envios. O histórico fica.\n\nEm **funcionários** e **signatários**, `POST` com um CPF já cadastrado atualiza o\nregistro — e o reativa, se estava inativo — em vez de recusar. Assim o ERP pode mandar\nsempre o mesmo payload sem saber se é a primeira vez. A resposta traz `criado: true`\n(HTTP 201) ou `criado: false` (HTTP 200).\n\n## Erros\n\nTodo erro vem em JSON, com um código curto para o seu `switch` e uma frase em\nportuguês para o seu log:\n\n```json\n{ \"erro\": \"tipo_documento_invalido\",\n  \"mensagem\": \"Informe 'tipo_documento_id' ou 'tipo_documento'.\" }\n```\n\n| HTTP | Quando |\n|---|---|\n| 401 | token ausente, inválido ou inativo |\n| 403 | a ação não é permitida para esse token (ex.: sandbox criando token de produção) |\n| 404 | o registro ou o endereço não existe |\n| 405 | endereço certo, verbo errado — a resposta traz o cabeçalho `Allow` |\n| 409 | conflito: nome repetido, ou o token que você está usando |\n| 422 | os dados foram recusados; `mensagem` diz o que corrigir |\n| 429 | passou do limite por minuto |\n| 500 | falha no servidor; o problema fica registrado do nosso lado |\n\n## Lote com separação (e a impressora virtual)\n\nQuando o documento sai em um PDF só, com uma página por pessoa — folha de\npagamento é o caso clássico —, não é preciso recortar nada à mão:\n\n```\nPOST \/api\/v1\/lotes          manda o PDF inteiro\nGET  \/api\/v1\/lotes\/{id}     mostra de quem é cada página\nPATCH ...\/paginas\/{pagina}  corrige o que o sistema não reconheceu\nPOST \/api\/v1\/lotes\/{id}\/enviar   recorta e envia para cada um\n```\n\nO sistema lê cada página (texto do PDF, ou OCR quando é digitalizado), procura\no que a empresa cadastrou em `\/api\/v1\/identificadores` — CPF, matrícula, nome —\ne confere **exatamente** com o cadastro. Páginas seguidas da mesma pessoa viram\num só documento.\n\nPara a **impressora virtual**, mande `origem: \"impressora\"` e\n`enviar_automatico: true` no primeiro passo: a empresa imprime a folha para a\nfila, a fila chama a API e o resto acontece sozinho. Combine com\n`exigir_todas_identificadas: true` para o sistema **não enviar nada** se sobrar\npágina sem dono — documento de salário no e-mail errado é vazamento de dado\npessoal, não um errinho de sistema.\n\n## Sandbox\n\nUm token criado com `ambiente: sandbox` sai com o prefixo `tsk_test_`. Toda resposta\ntraz o campo `ambiente`, para você nunca confundir uma chamada de teste com uma real.\nUm token de sandbox não pode criar token de produção.\n\n## Limites\n\nCada token tem um teto de requisições por minuto (300 por padrão, ajustável).\nPassando do teto, a resposta é `429` e basta repetir em seguida.\n\n## Webhooks\n\nEm vez de ficar consultando, cadastre um webhook e receba os acontecimentos.\nCada entrega vai assinada em `X-TechPS-Assinatura: sha256=<hmac>`, calculada\nsobre o corpo com o segredo do webhook. Confira sempre essa assinatura antes de\nprocessar. Falha de entrega é reenviada seis vezes, com intervalo crescente\n(1, 5, 15, 60, 180 e 720 minutos).","contact":{"name":"Suporte TechPS","email":"suporte@techps.com.br"}},"servers":[{"url":"https:\/\/signature.techps.com.br","description":"Este ambiente"}],"tags":[{"name":"Documentos","description":"Enviar, acompanhar, baixar e encerrar documentos."},{"name":"Signatários","description":"Cadastro de pessoas de fora da empresa."},{"name":"Webhooks","description":"Avisos automáticos para o seu sistema."},{"name":"Consumo","description":"Medição mensal, base da cobrança."},{"name":"Funcionários","description":"Quadro de pessoal e a cadeia de governança de cada um."},{"name":"Setores e cargos","description":"Estrutura da empresa e quem assina por ela."},{"name":"Tipos de documento","description":"Classificação dos documentos enviados."},{"name":"Certificados","description":"Certificados A1 para a finalização ICP-Brasil."},{"name":"Lote com separação","description":"Um PDF com muitos documentos vira um documento por pessoa."},{"name":"Identificadores","description":"O que o sistema procura em cada página do lote."},{"name":"Administração","description":"Tokens, usuários, perfis, empresa e auditoria."}],"components":{"securitySchemes":{"token":{"type":"http","scheme":"bearer","description":"Token criado no painel, em Segurança → Integração."}},"schemas":{"Documento":{"type":"object","example":{"id":128,"id_documento":"DOC-20261010093015-A7F3C1","referencia":"ORDEM-99812","nome_arquivo":"termo_responsabilidade.pdf","tipo_documento":"Termo de Responsabilidade","situacao":"em_progresso","icp_brasil":false,"autenticacao":"cpf_rg","enviado_em":"2026-10-10 09:30:15","expira_em":"2026-10-17 12:30:15","concluido_em":null,"assinaturas":{"concluidas":1,"total":2},"links":{"arquivo":"https:\/\/signature.techps.com.br\/api\/v1\/documentos\/128\/arquivo","evidencias":"https:\/\/signature.techps.com.br\/api\/v1\/documentos\/128\/evidencias"},"signatarios":[{"ordem":1,"nome":"MARIA SOUZA LIMA","email":"maria@empresa.com.br","funcao":"Funcionário","situacao":"assinado","autenticacao":null,"assinado_em":"2026-10-10 10:02:41","protocolo":"B53801829A8C0B682AB8EFCA3A92350D","link_assinatura":null},{"ordem":2,"nome":"CARLOS GESTOR RH","email":"carlos@empresa.com.br","funcao":"Responsável do Setor","situacao":"pendente","autenticacao":"facial_cpf_rg","assinado_em":null,"protocolo":null,"link_assinatura":"https:\/\/signature.techps.com.br\/assinar\/77f33df457..."}]}},"Erro":{"type":"object","properties":{"erro":{"type":"string","description":"Código curto do problema."},"mensagem":{"type":"string","description":"Explicação em português."}},"example":{"erro":"tipo_documento_invalido","mensagem":"Informe 'tipo_documento_id' ou 'tipo_documento'."}}}},"security":[{"token":[]}],"paths":{"\/api\/v1\/lotes":{"post":{"tags":["Lote com separação"],"summary":"Mandar um PDF com muitos documentos","description":"Recebe **um** PDF com vários documentos — a folha de pagamento inteira, por\nexemplo — lê cada página, descobre de quem é e prepara um documento por pessoa.\n\nÉ este o endereço que uma **impressora virtual** usa: a empresa manda imprimir\na folha para uma fila que repassa o PDF para cá, e o resto acontece sozinho.\nMande `origem: \"impressora\"` para o painel mostrar de onde veio.\n\n## O que o sistema faz com o arquivo\n\n1. Lê o texto de cada página. Em PDF gerado por sistema isso é instantâneo e\n   exato. Em PDF digitalizado, entra o OCR, que é mais lento e erra mais.\n2. Procura, em cada página, o que a empresa cadastrou em\n   `GET \/api\/v1\/identificadores` — CPF, matrícula, nome.\n3. Confere o valor lido com o cadastro **de forma exata**. Nada de \"parecido\":\n   o CPF lido tem de existir no cadastro desta empresa.\n4. Agrupa páginas **seguidas** da mesma pessoa num só documento, que é o caso\n   do contracheque de duas folhas.\n\n## Nada é enviado sem conferência (por padrão)\n\nA resposta volta com a separação e o lote em `situacao: \"conferir\"`. Enviar é\num segundo passo: `POST \/api\/v1\/lotes\/{id}\/enviar`.\n\nPara automatizar de verdade, mande `enviar_automatico: true`. E se você quiser\nque o sistema **não envie nada** quando sobrar página sem dono, mande também\n`exigir_todas_identificadas: true` — é o ajuste prudente para folha de\npagamento, porque documento de salário no e-mail errado é vazamento de dado\npessoal, não um errinho de sistema.","requestBody":{"required":true,"content":{"application\/json":{"examples":{"conferir_depois":{"summary":"Separar e esperar a conferência (padrão)","value":{"arquivo_base64":"JVBERi0xLjQKJSVFT0Y=","nome_arquivo":"folha_outubro_2026.pdf","tipo_documento":"Contracheque","grupo":"FOLHA-10-2026","prazo_dias":7}},"impressora_virtual":{"summary":"Impressora virtual, enviando sozinho","value":{"arquivo_base64":"JVBERi0xLjQKJSVFT0Y=","nome_arquivo":"folha_outubro_2026.pdf","tipo_documento_id":7,"grupo":"FOLHA-10-2026","origem":"impressora","enviar_automatico":true,"exigir_todas_identificadas":true}}}},"multipart\/form-data":{"schema":{"type":"object","properties":{"arquivo":{"type":"string","format":"binary"},"tipo_documento_id":{"type":"integer"},"grupo":{"type":"string"},"origem":{"type":"string","enum":["api","impressora"]},"enviar_automatico":{"type":"boolean"}}}}}},"responses":{"201":{"description":"Lido e separado.","content":{"application\/json":{"example":{"lote":{"id":12,"nome_arquivo":"folha_outubro_2026.pdf","paginas":312,"identificadas":309,"sem_dono":3,"documentos_criados":0,"tipo_documento":"Contracheque","grupo":"FOLHA-10-2026","motor_de_leitura":"pdftotext","origem":"impressora","situacao":"conferir","prazo_dias":7,"icp_brasil":false,"criado_em":"2026-10-10 09:14:02","enviado_em":null,"links":{"detalhe":"https:\/\/signature.techps.com.br\/api\/v1\/lotes\/12","enviar":"https:\/\/signature.techps.com.br\/api\/v1\/lotes\/12\/enviar"}},"resumo":{"paginas":312,"identificadas":309,"conferir":1,"sem_dono":2,"motor":"pdftotext"},"envio_automatico":null,"proximo_passo":"Confira as páginas e chame POST \/api\/v1\/lotes\/12\/enviar."}}}},"422":{"description":"Arquivo recusado, tipo de documento ausente, ou o servidor não consegue ler PDF (sem pdftotext, sem OCR e sem serviço remoto).","content":{"application\/json":{"example":{"erro":"lote_recusado","mensagem":"Este servidor não tem pdftotext nem OCR, e não há serviço de leitura configurado."}}}}}},"get":{"tags":["Lote com separação"],"summary":"Listar lotes","responses":{"200":{"description":"Histórico.","content":{"application\/json":{"example":{"lotes":[{"id":12,"nome_arquivo":"folha_outubro_2026.pdf","paginas":312,"identificadas":309,"sem_dono":3,"documentos_criados":0,"tipo_documento":"Contracheque","grupo":"FOLHA-10-2026","motor_de_leitura":"pdftotext","origem":"impressora","situacao":"conferir","prazo_dias":7,"icp_brasil":false,"criado_em":"2026-10-10 09:14:02","enviado_em":null,"links":{"detalhe":"https:\/\/signature.techps.com.br\/api\/v1\/lotes\/12","enviar":"https:\/\/signature.techps.com.br\/api\/v1\/lotes\/12\/enviar"}}],"total":1}}}}}}},"\/api\/v1\/lotes\/{id}":{"get":{"tags":["Lote com separação"],"summary":"Ver a separação página por página","description":"Mostra o que foi lido em cada página e de quem o sistema achou que é. O CPF volta mascarado, porque esta resposta é sobre a separação, não sobre os dados pessoais de cada um.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Páginas.","content":{"application\/json":{"example":{"lote":{"id":12,"nome_arquivo":"folha_outubro_2026.pdf","paginas":312,"identificadas":309,"sem_dono":3,"documentos_criados":0,"tipo_documento":"Contracheque","grupo":"FOLHA-10-2026","motor_de_leitura":"pdftotext","origem":"impressora","situacao":"conferir","prazo_dias":7,"icp_brasil":false,"criado_em":"2026-10-10 09:14:02","enviado_em":null,"links":{"detalhe":"https:\/\/signature.techps.com.br\/api\/v1\/lotes\/12","enviar":"https:\/\/signature.techps.com.br\/api\/v1\/lotes\/12\/enviar"}},"paginas":[{"pagina_id":801,"pagina":1,"situacao":"identificada","motivo":"Achado pelo CPF: MARIA SOUZA LIMA.","lido":{"cpf":"***.***.247-25","matricula":"10428","nome":"MARIA SOUZA LIMA"},"pessoa":{"tipo":"funcionario","id":42,"nome":"MARIA SOUZA LIMA","email":"maria@empresa.com.br","achado_por":"cpf"},"documento_id":null},{"pagina_id":802,"pagina":312,"situacao":"sem_dono","motivo":"Nenhum identificador foi encontrado nesta página.","lido":{"cpf":null,"matricula":null,"nome":null},"pessoa":null,"documento_id":null}]}}}}}},"delete":{"tags":["Lote com separação"],"summary":"Descartar o lote","description":"Apaga o lote e o PDF original. Os documentos já enviados dele continuam valendo — assinatura é prova e não se apaga.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Descartado."}}}},"\/api\/v1\/lotes\/{id}\/paginas\/{pagina}":{"patch":{"tags":["Lote com separação"],"summary":"Corrigir de quem é uma página","description":"Para o que o sistema não reconheceu. Aceita `funcionario_id`, `signatario_id` ou simplesmente `cpf` — que é o que o ERP tem na mão.\n\nMandar os dois ids em **zero** marca a página para **não ser enviada**: é o caso da capa, do resumo e das páginas de totais, que não pertencem a ninguém.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"},"description":"Id do lote."},{"name":"pagina","in":"path","required":true,"schema":{"type":"integer"},"description":"O 'pagina_id' que vem no detalhe do lote."}],"requestBody":{"content":{"application\/json":{"examples":{"pelo_cpf":{"summary":"Atribuir pelo CPF","value":{"cpf":"529.982.247-25"}},"pelo_id":{"summary":"Atribuir pelo id do funcionário","value":{"funcionario_id":42}},"nao_enviar":{"summary":"Marcar para não enviar","value":{"funcionario_id":0,"signatario_id":0}}}}}},"responses":{"200":{"description":"Página atualizada.","content":{"application\/json":{"example":{"pagina_id":802,"situacao":"identificada","pessoa":"MARIA SOUZA LIMA"}}}},"422":{"description":"A pessoa não é desta empresa, não tem e-mail, ou a página já foi enviada.","content":{"application\/json":{"example":{"erro":"pagina_recusada","mensagem":"MARIA SOUZA LIMA não tem e-mail no cadastro. Preencha o e-mail antes de enviar o documento para ela."}}}}}},"put":{"tags":["Lote com separação"],"summary":"Corrigir de quem é uma página (igual ao PATCH)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"pagina","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"content":{"application\/json":{"example":{"cpf":"529.982.247-25"}}}},"responses":{"200":{"description":"Página atualizada."}}}},"\/api\/v1\/lotes\/{id}\/enviar":{"post":{"tags":["Lote com separação"],"summary":"Separar e enviar","description":"Recorta as páginas de cada pessoa num documento próprio e manda para assinar. Só vai o que está **identificado**: página sem dono nunca sai.\n\nPode ser chamado de novo depois de corrigir as páginas que faltavam — o que já foi enviado não é enviado de novo.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Enviado.","content":{"application\/json":{"example":{"enviados":309,"falhas":[],"documentos":[{"documento_id":1841,"id_documento":"DOC-20261010091502-7C1B9A","nome_arquivo":"Contracheque - MARIA SOUZA LIMA.pdf","signatario":{"nome":"MARIA SOUZA LIMA","email":"maria@empresa.com.br"},"links":{"documento":"https:\/\/signature.techps.com.br\/api\/v1\/documentos\/1841","arquivo":"https:\/\/signature.techps.com.br\/api\/v1\/documentos\/1841\/arquivo"}}]}}}},"422":{"description":"Nada identificado, tipo de documento ausente, ou lote já enviado.","content":{"application\/json":{"example":{"erro":"envio_recusado","mensagem":"Nenhuma página está pronta para enviar. Confira as páginas sem dono."}}}}}}},"\/api\/v1\/identificadores":{"get":{"tags":["Identificadores"],"summary":"O que o sistema procura em cada página","description":"Também diz o que este servidor consegue fazer: ler texto, fazer OCR, ou nenhum dos dois. Vale consultar antes de mandar um lote de 300 páginas.","responses":{"200":{"description":"Regras e recursos.","content":{"application\/json":{"example":{"identificadores":[{"id":1,"rotulo":"CPF","campo":"cpf","ancora":null,"padrao":null,"obrigatorio":false,"exato":true,"ordem":1,"situacao":"ativo"},{"id":2,"rotulo":"Matrícula","campo":"matricula","ancora":"Matrícula","padrao":null,"obrigatorio":false,"exato":true,"ordem":2,"situacao":"ativo"}],"recursos_de_leitura":{"texto":true,"ocr":true,"remoto":false,"exec_liberado":true}}}}}}},"post":{"tags":["Identificadores"],"summary":"Cadastrar um identificador","description":"Cada empresa tem um contracheque diferente, então em vez de o sistema adivinhar,\na empresa diz onde o dado está.\n\n| Campo | Para que serve |\n|---|---|\n| `cpf` | o mais seguro: não repete e confere exato com o cadastro |\n| `matricula` | número da matrícula; use a âncora, senão qualquer número serve |\n| `nome` | nome em maiúsculas; só vale quando não há homônimo no cadastro |\n| `email` | endereço encontrado na página |\n| `personalizado` | você escreve a expressão regular |\n\n**A âncora é o detalhe que faz funcionar.** Num contracheque aparecem dezenas de\nnúmeros; `ancora: \"Matrícula\"` faz o sistema procurar só nos 120 caracteres\nseguintes a essa palavra, de modo que \"Matrícula 2001\" não se confunde com\n\"Verba 2001\".\n\nA ordem importa: o sistema tenta pelo CPF primeiro, depois matrícula, depois\nnome. `obrigatorio: true` manda a página direto para conferência quando aquele\ndado não aparece, em vez de o sistema tentar outro caminho.\n\nA expressão própria é **testada no cadastro**: se estiver inválida, o cadastro é\nrecusado na hora, em vez de quebrar o lote de 300 páginas depois.","requestBody":{"required":true,"content":{"application\/json":{"examples":{"cpf_com_ancora":{"summary":"CPF depois da palavra CPF","value":{"rotulo":"CPF do funcionário","campo":"cpf","ancora":"CPF","obrigatorio":true,"ordem":1}},"expressao_propria":{"summary":"Layout fora do comum","value":{"rotulo":"Código interno","campo":"personalizado","padrao":"\/COD[:\\s]*([A-Z]{2}\\d{6})\/","ordem":3}}}}}},"responses":{"201":{"description":"Cadastrado."},"422":{"description":"Expressão inválida, ou campo personalizado sem expressão.","content":{"application\/json":{"example":{"erro":"padrao_invalido","mensagem":"A expressão informada não é válida."}}}}}}},"\/api\/v1\/identificadores\/{id}":{"patch":{"tags":["Identificadores"],"summary":"Alterar identificador","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"content":{"application\/json":{"example":{"ancora":"C.P.F."}}}},"responses":{"200":{"description":"Atualizado."}}},"put":{"tags":["Identificadores"],"summary":"Substituir identificador","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"content":{"application\/json":{"example":{"rotulo":"CPF","campo":"cpf","ancora":"CPF","obrigatorio":true,"ordem":1,"status":"ativo"}}}},"responses":{"200":{"description":"Substituído."}}},"delete":{"tags":["Identificadores"],"summary":"Desativar identificador","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Desativado."}}}},"\/api\/v1\/identificadores\/testar":{"post":{"tags":["Identificadores"],"summary":"Experimentar as regras num PDF","description":"Mostra o que seria lido em cada página, com o trecho do texto, **sem enviar nada e sem guardar o arquivo**. É assim que se acerta o layout antes de valer para a folha inteira.","requestBody":{"required":true,"content":{"application\/json":{"example":{"arquivo_base64":"JVBERi0xLjQKJSVFT0Y="}},"multipart\/form-data":{"schema":{"type":"object","properties":{"arquivo":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"O que foi lido.","content":{"application\/json":{"example":{"motor":"pdftotext","erro":null,"identificadores":2,"paginas":[{"pagina":1,"situacao":"identificada","motivo":"Achado pelo CPF: MARIA SOUZA LIMA.","lido":{"cpf":"***.***.247-25","matricula":"10428","nome":null},"pessoa":"MARIA SOUZA LIMA","trecho":"DEMONSTRATIVO DE PAGAMENTO Competencia 10\/2026 Nome: MARIA SOUZA LIMA CPF: 529.982.247-25 Matricula: 10428"}]}}}}}}},"\/api\/v1\/funcionarios":{"get":{"tags":["Funcionários"],"summary":"Listar funcionarios","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["ativo","inativo","todos"],"default":"ativo"},"description":"Por padrão só os ativos. Use 'todos' para ver também os inativados."},{"name":"busca","in":"query","schema":{"type":"string"},"description":"Filtra por nome, e-mail ou CPF."},{"name":"setor_id","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Lista.","content":{"application\/json":{"example":{"funcionarios":[{"id":42,"nome":"MARIA SOUZA LIMA","matricula":"10428","cpf":"***.***.247-25","email":"maria@empresa.com.br","telefone":"(85) 98888-1234","setor":{"id":3,"nome":"Operação"},"cargo":{"id":7,"nome":"Motorista"},"situacao":"ativo"}],"total":1}}}},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Funcionario não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}},"post":{"tags":["Funcionários"],"summary":"Criar funcionario","requestBody":{"required":true,"content":{"application\/json":{"example":{"nome":"MARIA SOUZA LIMA","cpf":"529.982.247-25","rg":"CE1234567","email":"maria@empresa.com.br","telefone":"(85) 98888-1234","matricula":"10428","setor_id":3,"cargo_id":7}}}},"responses":{"201":{"description":"Criado.","content":{"application\/json":{"example":{"funcionario":{"id":42,"nome":"MARIA SOUZA LIMA","matricula":"10428","cpf":"***.***.247-25","email":"maria@empresa.com.br","telefone":"(85) 98888-1234","setor":{"id":3,"nome":"Operação"},"cargo":{"id":7,"nome":"Motorista"},"situacao":"ativo"}}}}},"409":{"description":"Já existe outro registro com esse nome ou CPF."},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Funcionario não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}},"description":"Se o CPF já estiver cadastrado, o registro é atualizado (e reativado, se estava inativo) em vez de recusar: o ERP pode mandar sempre o mesmo payload. A resposta traz `criado: true` quando foi um cadastro novo (HTTP 201) e `criado: false` quando foi atualização (HTTP 200)."}},"\/api\/v1\/funcionarios\/{id}":{"get":{"tags":["Funcionários"],"summary":"Consultar funcionario","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id do registro."}],"responses":{"200":{"description":"Registro.","content":{"application\/json":{"example":{"funcionario":{"id":42,"nome":"MARIA SOUZA LIMA","matricula":"10428","cpf":"***.***.247-25","email":"maria@empresa.com.br","telefone":"(85) 98888-1234","setor":{"id":3,"nome":"Operação"},"cargo":{"id":7,"nome":"Motorista"},"situacao":"ativo"}}}}},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Funcionario não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}},"description":"No lugar do id você pode passar o CPF (só dígitos) ou a matrícula."},"put":{"tags":["Funcionários"],"summary":"Substituir funcionario","description":"Troca o registro inteiro: o que não for enviado volta ao valor padrão. Para mexer em um campo só, use PATCH.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id do registro."}],"requestBody":{"required":true,"content":{"application\/json":{"example":{"nome":"MARIA SOUZA LIMA","cpf":"529.982.247-25","rg":"CE1234567","email":"maria@empresa.com.br","telefone":"(85) 98888-1234","matricula":"10428","setor_id":3,"cargo_id":7}}}},"responses":{"200":{"description":"Atualizado."},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Funcionario não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}},"patch":{"tags":["Funcionários"],"summary":"Alterar funcionario","description":"Altera apenas os campos enviados; o resto fica como está.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id do registro."}],"requestBody":{"required":true,"content":{"application\/json":{"example":{"status":"inativo"}}}},"responses":{"200":{"description":"Atualizado."},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Funcionario não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}},"delete":{"tags":["Funcionários"],"summary":"Inativar funcionario","description":"O cadastro passa a 'inativo' e sai das listas; nada é apagado, porque quem já assinou precisa continuar identificável na prova. Links já enviados continuam valendo.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id do registro."}],"responses":{"200":{"description":"Inativado.","content":{"application\/json":{"example":{"inativado":true}}}},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Funcionario não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}}},"\/api\/v1\/funcionarios\/{id}\/responsaveis":{"get":{"tags":["Funcionários"],"summary":"Cadeia de governança desta pessoa","description":"Quem assinaria, e em que ordem, num envio por governança: a própria pessoa e depois os responsáveis do setor e do cargo. Serve para o ERP mostrar o caminho antes de enviar.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Cadeia.","content":{"application\/json":{"example":{"funcionario":{"id":42,"nome":"MARIA SOUZA LIMA"},"responsaveis":[{"ordem":1,"funcionario_id":42,"nome":"MARIA SOUZA LIMA","funcao":"Funcionário","origem":"cadastro"},{"ordem":2,"funcionario_id":18,"nome":"CARLOS GESTOR RH","funcao":"Responsável do Setor","origem":"setor"}]}}}}}}},"\/api\/v1\/funcionarios\/{id}\/foto":{"post":{"tags":["Funcionários"],"summary":"Enviar foto de referência (validação facial)","description":"Foto do rosto usada como referência quando a autenticação do documento pede validação facial. Envie como multipart no campo `foto` (JPG ou PNG, até 6 MB). A imagem fica fora da pasta pública: não existe URL que a alcance.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"multipart\/form-data":{"schema":{"type":"object","properties":{"foto":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"Foto guardada."},"422":{"description":"Imagem recusada."}}}},"\/api\/v1\/setores":{"get":{"tags":["Setores e cargos"],"summary":"Listar setores","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["ativo","inativo","todos"],"default":"ativo"},"description":"Por padrão só os ativos. Use 'todos' para ver também os inativados."},{"name":"busca","in":"query","schema":{"type":"string"},"description":"Filtra por nome, e-mail ou CPF."}],"responses":{"200":{"description":"Lista.","content":{"application\/json":{"example":{"setores":[{"id":3,"nome":"Operação","situacao":"ativo","funcionarios":48,"responsaveis_governanca":2}],"total":1}}}},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Setor não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}},"post":{"tags":["Setores e cargos"],"summary":"Criar setor","requestBody":{"required":true,"content":{"application\/json":{"example":{"nome":"Operação","responsaveis":[18,24]}}}},"responses":{"201":{"description":"Criado.","content":{"application\/json":{"example":{"setor":{"id":3,"nome":"Operação","situacao":"ativo","funcionarios":48,"responsaveis_governanca":2}}}}},"409":{"description":"Já existe outro registro com esse nome ou CPF."},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Setor não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}}},"\/api\/v1\/setores\/{id}":{"get":{"tags":["Setores e cargos"],"summary":"Consultar setor","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id do registro."}],"responses":{"200":{"description":"Registro.","content":{"application\/json":{"example":{"setor":{"id":3,"nome":"Operação","situacao":"ativo","funcionarios":48,"responsaveis_governanca":2}}}}},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Setor não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}},"put":{"tags":["Setores e cargos"],"summary":"Substituir setor","description":"Troca o registro inteiro: o que não for enviado volta ao valor padrão. Para mexer em um campo só, use PATCH.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id do registro."}],"requestBody":{"required":true,"content":{"application\/json":{"example":{"nome":"Operação","responsaveis":[18,24]}}}},"responses":{"200":{"description":"Atualizado."},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Setor não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}},"patch":{"tags":["Setores e cargos"],"summary":"Alterar setor","description":"Altera apenas os campos enviados; o resto fica como está.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id do registro."}],"requestBody":{"required":true,"content":{"application\/json":{"example":{"status":"inativo"}}}},"responses":{"200":{"description":"Atualizado."},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Setor não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}},"delete":{"tags":["Setores e cargos"],"summary":"Inativar setor","description":"Só inativa se não houver funcionário ativo no setor; do contrário a resposta diz quantos estão vinculados (HTTP 422), para você movê-los antes.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id do registro."}],"responses":{"200":{"description":"Inativado.","content":{"application\/json":{"example":{"inativado":true}}}},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Setor não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}}},"\/api\/v1\/cargos":{"get":{"tags":["Setores e cargos"],"summary":"Listar cargos","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["ativo","inativo","todos"],"default":"ativo"},"description":"Por padrão só os ativos. Use 'todos' para ver também os inativados."},{"name":"busca","in":"query","schema":{"type":"string"},"description":"Filtra por nome, e-mail ou CPF."}],"responses":{"200":{"description":"Lista.","content":{"application\/json":{"example":{"cargos":[{"id":7,"nome":"Motorista","situacao":"ativo","funcionarios":31,"responsaveis_governanca":1}],"total":1}}}},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Cargo não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}},"post":{"tags":["Setores e cargos"],"summary":"Criar cargo","requestBody":{"required":true,"content":{"application\/json":{"example":{"nome":"Motorista","responsaveis":[18]}}}},"responses":{"201":{"description":"Criado.","content":{"application\/json":{"example":{"cargo":{"id":7,"nome":"Motorista","situacao":"ativo","funcionarios":31,"responsaveis_governanca":1}}}}},"409":{"description":"Já existe outro registro com esse nome ou CPF."},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Cargo não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}}},"\/api\/v1\/cargos\/{id}":{"get":{"tags":["Setores e cargos"],"summary":"Consultar cargo","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id do registro."}],"responses":{"200":{"description":"Registro.","content":{"application\/json":{"example":{"cargo":{"id":7,"nome":"Motorista","situacao":"ativo","funcionarios":31,"responsaveis_governanca":1}}}}},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Cargo não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}},"put":{"tags":["Setores e cargos"],"summary":"Substituir cargo","description":"Troca o registro inteiro: o que não for enviado volta ao valor padrão. Para mexer em um campo só, use PATCH.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id do registro."}],"requestBody":{"required":true,"content":{"application\/json":{"example":{"nome":"Motorista","responsaveis":[18]}}}},"responses":{"200":{"description":"Atualizado."},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Cargo não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}},"patch":{"tags":["Setores e cargos"],"summary":"Alterar cargo","description":"Altera apenas os campos enviados; o resto fica como está.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id do registro."}],"requestBody":{"required":true,"content":{"application\/json":{"example":{"status":"inativo"}}}},"responses":{"200":{"description":"Atualizado."},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Cargo não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}},"delete":{"tags":["Setores e cargos"],"summary":"Inativar cargo","description":"Só inativa se não houver funcionário ativo no cargo.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id do registro."}],"responses":{"200":{"description":"Inativado.","content":{"application\/json":{"example":{"inativado":true}}}},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Cargo não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}}},"\/api\/v1\/setores\/{id}\/responsaveis":{"get":{"tags":["Setores e cargos"],"summary":"Responsáveis de governança do setor","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Lista na ordem de assinatura.","content":{"application\/json":{"example":{"setor_id":3,"responsaveis":[{"funcionario_id":18,"nome":"CARLOS GESTOR RH","email":"carlos@empresa.com.br","ordem":1,"assina_governanca":true}]}}}}}},"post":{"tags":["Setores e cargos"],"summary":"Definir responsáveis do setor (igual ao PUT)","description":"Mesmo efeito do PUT. Existe porque alguns clientes HTTP antigos não mandam PUT; se o seu manda, prefira o PUT.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"example":{"responsaveis":[18,24]}}}},"responses":{"200":{"description":"Lista regravada."}}},"put":{"tags":["Setores e cargos"],"summary":"Definir responsáveis do setor","description":"Regrava a lista inteira, na ordem enviada — é essa ordem que o envio por governança segue. Enviar lista vazia remove todos. Ids inexistentes são recusados (422), sem gravar nada.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"example":{"responsaveis":[18,24]}}}},"responses":{"200":{"description":"Lista regravada."},"422":{"description":"Algum id não existe."}}}},"\/api\/v1\/cargos\/{id}\/responsaveis":{"get":{"tags":["Setores e cargos"],"summary":"Responsáveis de governança do cargo","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Lista na ordem de assinatura.","content":{"application\/json":{"example":{"cargo_id":3,"responsaveis":[{"funcionario_id":18,"nome":"CARLOS GESTOR RH","email":"carlos@empresa.com.br","ordem":1,"assina_governanca":true}]}}}}}},"post":{"tags":["Setores e cargos"],"summary":"Definir responsáveis do cargo (igual ao PUT)","description":"Mesmo efeito do PUT. Existe porque alguns clientes HTTP antigos não mandam PUT; se o seu manda, prefira o PUT.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"example":{"responsaveis":[18,24]}}}},"responses":{"200":{"description":"Lista regravada."}}},"put":{"tags":["Setores e cargos"],"summary":"Definir responsáveis do cargo","description":"Regrava a lista inteira, na ordem enviada — é essa ordem que o envio por governança segue. Enviar lista vazia remove todos. Ids inexistentes são recusados (422), sem gravar nada.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"example":{"responsaveis":[18,24]}}}},"responses":{"200":{"description":"Lista regravada."},"422":{"description":"Algum id não existe."}}}},"\/api\/v1\/tipos-documento":{"get":{"tags":["Tipos de documento"],"summary":"Listar tipos_documento","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["ativo","inativo","todos"],"default":"ativo"},"description":"Por padrão só os ativos. Use 'todos' para ver também os inativados."},{"name":"busca","in":"query","schema":{"type":"string"},"description":"Filtra por nome, e-mail ou CPF."}],"responses":{"200":{"description":"Lista.","content":{"application\/json":{"example":{"tipos_documento":[{"id":1,"nome":"Termo de Responsabilidade","setor":{"id":3,"nome":"Operação"},"exige_assinatura":true,"exige_vencimento":false,"situacao":"ativo"}],"total":1}}}},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Tipo_documento não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}},"post":{"tags":["Tipos de documento"],"summary":"Criar tipo_documento","requestBody":{"required":true,"content":{"application\/json":{"example":{"nome":"Termo de Responsabilidade","setor_id":3,"exige_assinatura":"sim"}}}},"responses":{"201":{"description":"Criado.","content":{"application\/json":{"example":{"tipo_documento":{"id":1,"nome":"Termo de Responsabilidade","setor":{"id":3,"nome":"Operação"},"exige_assinatura":true,"exige_vencimento":false,"situacao":"ativo"}}}}},"409":{"description":"Já existe outro registro com esse nome ou CPF."},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Tipo_documento não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}}},"\/api\/v1\/tipos-documento\/{id}":{"get":{"tags":["Tipos de documento"],"summary":"Consultar tipo_documento","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id do registro."}],"responses":{"200":{"description":"Registro.","content":{"application\/json":{"example":{"tipo_documento":{"id":1,"nome":"Termo de Responsabilidade","setor":{"id":3,"nome":"Operação"},"exige_assinatura":true,"exige_vencimento":false,"situacao":"ativo"}}}}},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Tipo_documento não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}},"put":{"tags":["Tipos de documento"],"summary":"Substituir tipo_documento","description":"Troca o registro inteiro: o que não for enviado volta ao valor padrão. Para mexer em um campo só, use PATCH.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id do registro."}],"requestBody":{"required":true,"content":{"application\/json":{"example":{"nome":"Termo de Responsabilidade","setor_id":3,"exige_assinatura":"sim"}}}},"responses":{"200":{"description":"Atualizado."},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Tipo_documento não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}},"patch":{"tags":["Tipos de documento"],"summary":"Alterar tipo_documento","description":"Altera apenas os campos enviados; o resto fica como está.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id do registro."}],"requestBody":{"required":true,"content":{"application\/json":{"example":{"status":"inativo"}}}},"responses":{"200":{"description":"Atualizado."},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Tipo_documento não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}},"delete":{"tags":["Tipos de documento"],"summary":"Inativar tipo_documento","description":"O tipo sai da lista de novos envios. Os documentos que já usam esse tipo continuam intactos.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id do registro."}],"responses":{"200":{"description":"Inativado.","content":{"application\/json":{"example":{"inativado":true}}}},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Tipo_documento não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}}},"\/api\/v1\/signatarios":{"get":{"tags":["Signatários"],"summary":"Listar signatarios","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["ativo","inativo","todos"],"default":"ativo"},"description":"Por padrão só os ativos. Use 'todos' para ver também os inativados."},{"name":"busca","in":"query","schema":{"type":"string"},"description":"Filtra por nome, e-mail ou CPF."}],"responses":{"200":{"description":"Lista.","content":{"application\/json":{"example":{"signatarios":[{"id":9,"nome":"JOANA PEREIRA","cpf":"***.***.447-05","rg_cadastrado":true,"email":"joana@cliente.com.br","telefone":"(31) 99999-0000","foto_referencia_facial":false,"situacao":"ativo"}],"total":1}}}},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Signatario não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}},"post":{"tags":["Signatários"],"summary":"Criar signatario","requestBody":{"required":true,"content":{"application\/json":{"example":{"nome":"JOANA PEREIRA","cpf":"390.533.447-05","rg":"MG1234567","email":"joana@cliente.com.br","telefone":"(31) 99999-0000"}}}},"responses":{"201":{"description":"Criado.","content":{"application\/json":{"example":{"signatario":{"id":9,"nome":"JOANA PEREIRA","cpf":"***.***.447-05","rg_cadastrado":true,"email":"joana@cliente.com.br","telefone":"(31) 99999-0000","foto_referencia_facial":false,"situacao":"ativo"}}}}},"409":{"description":"Já existe outro registro com esse nome ou CPF."},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Signatario não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}},"description":"Para quem não é funcionário. Se o CPF já existir, o cadastro é atualizado e reativado em vez de recusar. O CPF e o RG daqui são exatamente os conferidos na hora de assinar."}},"\/api\/v1\/signatarios\/{id}":{"get":{"tags":["Signatários"],"summary":"Consultar signatario","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id do registro."}],"responses":{"200":{"description":"Registro.","content":{"application\/json":{"example":{"signatario":{"id":9,"nome":"JOANA PEREIRA","cpf":"***.***.447-05","rg_cadastrado":true,"email":"joana@cliente.com.br","telefone":"(31) 99999-0000","foto_referencia_facial":false,"situacao":"ativo"}}}}},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Signatario não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}},"put":{"tags":["Signatários"],"summary":"Substituir signatario","description":"Troca o registro inteiro: o que não for enviado volta ao valor padrão. Para mexer em um campo só, use PATCH.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id do registro."}],"requestBody":{"required":true,"content":{"application\/json":{"example":{"nome":"JOANA PEREIRA","cpf":"390.533.447-05","rg":"MG1234567","email":"joana@cliente.com.br","telefone":"(31) 99999-0000"}}}},"responses":{"200":{"description":"Atualizado."},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Signatario não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}},"patch":{"tags":["Signatários"],"summary":"Alterar signatario","description":"Altera apenas os campos enviados; o resto fica como está.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id do registro."}],"requestBody":{"required":true,"content":{"application\/json":{"example":{"status":"inativo"}}}},"responses":{"200":{"description":"Atualizado."},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Signatario não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}},"delete":{"tags":["Signatários"],"summary":"Inativar signatario","description":"O cadastro fica inativo; as assinaturas que essa pessoa já fez seguem válidas.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id do registro."}],"responses":{"200":{"description":"Inativado.","content":{"application\/json":{"example":{"inativado":true}}}},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Signatario não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}}},"\/api\/v1\/signatarios\/{id}\/foto":{"post":{"tags":["Signatários"],"summary":"Enviar foto de referência (validação facial)","description":"Foto do rosto usada como referência quando a autenticação do documento pede validação facial. Envie como multipart no campo `foto` (JPG ou PNG, até 6 MB). A imagem fica fora da pasta pública: não existe URL que a alcance.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"multipart\/form-data":{"schema":{"type":"object","properties":{"foto":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"Foto guardada."},"422":{"description":"Imagem recusada."}}}},"\/api\/v1\/certificados":{"get":{"tags":["Certificados"],"summary":"Listar certificados","description":"Traz também `dias_para_vencer`, para o ERP avisar antes de o certificado expirar.","responses":{"200":{"description":"Lista.","content":{"application\/json":{"example":{"certificados":[{"id":1,"nome":"A1 — SAMBAIBA TRANSPORTES","titular":"SAMBAIBA TRANSPORTES LTDA:12345678000199","emissor":"AC Certisign RFB G5","validade":{"inicio":"2026-02-11 09:00:00","fim":"2027-02-11 09:00:00"},"dias_para_vencer":124,"vencido":false,"assinar_automatico":true,"situacao":"ativo"}]}}}}}},"post":{"tags":["Certificados"],"summary":"Cadastrar certificado A1 (.pfx\/.p12)","description":"A senha é conferida na hora: se não abrir o arquivo, o cadastro é recusado. Depois ela é guardada cifrada (AES-256-CBC) e nunca volta em resposta alguma. O arquivo fica fora da pasta pública.","requestBody":{"required":true,"content":{"application\/json":{"example":{"nome":"A1 — SAMBAIBA TRANSPORTES","arquivo_base64":"MIIKr...","senha":"senha-do-certificado","assinar_automatico":true}},"multipart\/form-data":{"schema":{"type":"object","properties":{"arquivo":{"type":"string","format":"binary"},"senha":{"type":"string"},"nome":{"type":"string"}}}}}},"responses":{"201":{"description":"Cadastrado; os dados do titular são lidos do próprio certificado."},"422":{"description":"Arquivo não é PFX, ou a senha está errada."}}}},"\/api\/v1\/certificados\/{id}":{"get":{"tags":["Certificados"],"summary":"Consultar certificado","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Registro."}}},"patch":{"tags":["Certificados"],"summary":"Alterar certificado","description":"Muda nome, uso automático e situação. O arquivo e a senha não se alteram: para trocar o certificado, cadastre outro.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"content":{"application\/json":{"example":{"assinar_automatico":false}}}},"responses":{"200":{"description":"Atualizado."}}},"put":{"tags":["Certificados"],"summary":"Substituir dados do certificado","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"content":{"application\/json":{"example":{"nome":"A1 — matriz","assinar_automatico":true,"status":"ativo"}}}},"responses":{"200":{"description":"Atualizado."}}},"delete":{"tags":["Certificados"],"summary":"Inativar certificado","description":"Deixa de ser usado em novos documentos. Os já finalizados com ele continuam válidos.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Inativado."}}}},"\/api\/v1\/webhooks":{"get":{"tags":["Webhooks"],"summary":"Listar webhooks","responses":{"200":{"description":"Lista e eventos disponíveis.","content":{"application\/json":{"example":{"webhooks":[{"id":3,"nome":"ERP JB — produção","url":"https:\/\/erp.cliente.com.br\/webhooks\/techps","eventos":["documento.concluido","assinatura.registrada"],"situacao":"ativo","ultimo_envio":"2026-10-10 11:18:04","ultimo_resultado":"HTTP 200"}],"eventos_disponiveis":{"documento.enviado":"Documento enviado para assinatura","assinatura.registrada":"Um signatário assinou","documento.concluido":"Todos assinaram","documento.finalizado":"Carimbo ICP-Brasil aplicado","documento.expirado":"Prazo encerrado sem todas as assinaturas","documento.cancelado":"Documento cancelado"}}}}}}},"post":{"tags":["Webhooks"],"summary":"Cadastrar webhook","description":"O segredo volta **uma única vez**: guarde para conferir a assinatura HMAC de cada entrega.","requestBody":{"required":true,"content":{"application\/json":{"example":{"nome":"ERP JB — produção","url":"https:\/\/erp.cliente.com.br\/webhooks\/techps","eventos":["documento.concluido","assinatura.registrada","documento.expirado"]}}}},"responses":{"201":{"description":"Criado.","content":{"application\/json":{"example":{"webhook":{"id":3,"nome":"ERP JB — produção","url":"https:\/\/erp.cliente.com.br\/webhooks\/techps","eventos":["documento.concluido","assinatura.registrada"],"situacao":"ativo","ultimo_envio":"2026-10-10 11:18:04","ultimo_resultado":"HTTP 200"},"segredo":"whsec_8f2b1c9d4e7a6b5c3d2e1f0a9b8c7d6e"}}}},"422":{"description":"URL inválida ou evento desconhecido."}}}},"\/api\/v1\/webhooks\/{id}":{"get":{"tags":["Webhooks"],"summary":"Consultar webhook e últimas entregas","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Registro e histórico."}}},"put":{"tags":["Webhooks"],"summary":"Substituir webhook","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"content":{"application\/json":{"example":{"nome":"ERP JB — produção","url":"https:\/\/erp.cliente.com.br\/webhooks\/techps","eventos":["documento.concluido"],"status":"ativo"}}}},"responses":{"200":{"description":"Atualizado."}}},"patch":{"tags":["Webhooks"],"summary":"Alterar webhook","description":"Útil para mudar só a lista de eventos ou pausar com `status: inativo`. O segredo não muda (e não é devolvido).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"content":{"application\/json":{"example":{"eventos":["documento.concluido","documento.expirado"]}}}},"responses":{"200":{"description":"Atualizado."}}},"delete":{"tags":["Webhooks"],"summary":"Desativar webhook","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Desativado."}}}},"\/api\/v1\/webhooks\/{id}\/testar":{"post":{"tags":["Webhooks"],"summary":"Mandar um evento de teste","description":"Entrega agora um evento `webhook.teste` no seu endereço e devolve o HTTP que o seu servidor respondeu. Serve para validar a conferência da assinatura HMAC antes de ir ao ar.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Seu servidor aceitou.","content":{"application\/json":{"example":{"entregue":true,"http":200}}}},"422":{"description":"Seu servidor não aceitou; a resposta traz o HTTP recebido."}}}},"\/api\/v1\/webhooks\/{id}\/entregas":{"get":{"tags":["Webhooks"],"summary":"Histórico de entregas deste webhook","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Entregas, da mais recente para a mais antiga."}}}},"\/api\/v1\/eventos":{"get":{"tags":["Webhooks"],"summary":"Últimas entregas de todos os webhooks","description":"Diagnóstico: mostra evento, tentativas, HTTP de resposta, erro e quando será a próxima tentativa. Falhas são reenviadas 6 vezes, com intervalo de 1, 5, 15, 60, 180 e 720 minutos.","parameters":[{"name":"limite","in":"query","schema":{"type":"integer","default":50,"maximum":200}}],"responses":{"200":{"description":"Entregas.","content":{"application\/json":{"example":{"eventos":[{"id":418,"webhook":"ERP JB — produção","evento":"documento.concluido","situacao":"entregue","tentativas":1,"http":200,"criado_em":"2026-10-10 11:18:02","ultima_tentativa":"2026-10-10 11:18:04","proxima_tentativa":null,"erro":null}]}}}}}}},"\/api\/v1\/tokens":{"get":{"tags":["Administração"],"summary":"Listar tokens da API","description":"Nunca devolve o token em si — só o prefixo, para você reconhecer qual é qual.","responses":{"200":{"description":"Lista.","content":{"application\/json":{"example":{"tokens":[{"id":1,"nome":"ERP JB — produção","prefixo":"tsk_live_ac5","ambiente":"producao","limite_por_minuto":300,"situacao":"ativo","ultimo_uso":"2026-10-10 14:11:34","chamadas_30_dias":18422}]}}}}}},"post":{"tags":["Administração"],"summary":"Criar token","description":"Use `ambiente: sandbox` para homologação (o token sai com prefixo `tsk_test_`). Um token de sandbox não pode criar token de produção. O valor aparece uma única vez.","requestBody":{"required":true,"content":{"application\/json":{"example":{"nome":"ERP JB — homologação","ambiente":"sandbox","limite_por_minuto":300}}}},"responses":{"201":{"description":"Criado.","content":{"application\/json":{"example":{"token":"tsk_test_2f6a...","id":4,"ambiente":"sandbox"}}}}}}},"\/api\/v1\/tokens\/{id}":{"patch":{"tags":["Administração"],"summary":"Alterar token","description":"Muda nome, limite por minuto (de 10 a 3000) e situação.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"content":{"application\/json":{"example":{"limite_por_minuto":600}}}},"responses":{"200":{"description":"Atualizado."}}},"put":{"tags":["Administração"],"summary":"Substituir dados do token","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"content":{"application\/json":{"example":{"nome":"ERP JB","limite_por_minuto":300,"status":"ativo"}}}},"responses":{"200":{"description":"Atualizado."}}},"delete":{"tags":["Administração"],"summary":"Desativar token","description":"O token em uso na própria chamada não pode se desativar (HTTP 409): use outro token, para você não perder o acesso sem querer.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Desativado."},"409":{"description":"É o token da chamada atual."}}}},"\/api\/v1\/usuarios":{"get":{"tags":["Administração"],"summary":"Listar usuarios","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["ativo","inativo","todos"],"default":"ativo"},"description":"Por padrão só os ativos. Use 'todos' para ver também os inativados."},{"name":"busca","in":"query","schema":{"type":"string"},"description":"Filtra por nome, e-mail ou CPF."}],"responses":{"200":{"description":"Lista.","content":{"application\/json":{"example":{"usuarios":[{"id":5,"nome":"Ana Supervisora","login":"ana.supervisora","email":"ana@empresa.com.br","cpf":"***.***.247-25","perfil":{"id":2,"nome":"Gestor de RH"},"situacao":"ativo","tem_senha_definida":true}],"total":1}}}},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Usuario não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}},"post":{"tags":["Administração"],"summary":"Criar usuario","requestBody":{"required":true,"content":{"application\/json":{"example":{"nome":"Ana Supervisora","login":"ana.supervisora","senha":"SenhaForte2026","email":"ana@empresa.com.br","perfil_id":2}}}},"responses":{"201":{"description":"Criado.","content":{"application\/json":{"example":{"usuario":{"id":5,"nome":"Ana Supervisora","login":"ana.supervisora","email":"ana@empresa.com.br","cpf":"***.***.247-25","perfil":{"id":2,"nome":"Gestor de RH"},"situacao":"ativo","tem_senha_definida":true}}}}},"409":{"description":"Já existe outro registro com esse nome ou CPF."},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Usuario não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}},"description":"A senha é gravada só como hash Argon2id e não volta em resposta alguma; o mínimo é 8 caracteres. Sem o campo `senha`, o usuário fica sem acesso até alguém definir uma. `perfil_id` decide o que ele pode abrir no painel (veja GET \/api\/v1\/perfis)."}},"\/api\/v1\/usuarios\/{id}":{"get":{"tags":["Administração"],"summary":"Consultar usuario","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id do registro."}],"responses":{"200":{"description":"Registro.","content":{"application\/json":{"example":{"usuario":{"id":5,"nome":"Ana Supervisora","login":"ana.supervisora","email":"ana@empresa.com.br","cpf":"***.***.247-25","perfil":{"id":2,"nome":"Gestor de RH"},"situacao":"ativo","tem_senha_definida":true}}}}},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Usuario não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}},"put":{"tags":["Administração"],"summary":"Substituir usuario","description":"Troca o registro inteiro: o que não for enviado volta ao valor padrão. Para mexer em um campo só, use PATCH.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id do registro."}],"requestBody":{"required":true,"content":{"application\/json":{"example":{"nome":"Ana Supervisora","login":"ana.supervisora","senha":"SenhaForte2026","email":"ana@empresa.com.br","perfil_id":2}}}},"responses":{"200":{"description":"Atualizado."},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Usuario não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}},"patch":{"tags":["Administração"],"summary":"Alterar usuario","description":"Altera apenas os campos enviados; o resto fica como está.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id do registro."}],"requestBody":{"required":true,"content":{"application\/json":{"example":{"status":"inativo"}}}},"responses":{"200":{"description":"Atualizado."},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Usuario não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}},"delete":{"tags":["Administração"],"summary":"Inativar usuario","description":"O acesso é bloqueado e o histórico do que a pessoa fez continua na auditoria.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id do registro."}],"responses":{"200":{"description":"Inativado.","content":{"application\/json":{"example":{"inativado":true}}}},"401":{"description":"Token ausente ou inválido."},"404":{"description":"Usuario não encontrado."},"422":{"description":"Dados recusados; a resposta diz o motivo em 'mensagem'."},"429":{"description":"Limite por minuto atingido."}}}},"\/api\/v1\/perfis":{"get":{"tags":["Administração"],"summary":"Listar perfis de acesso","responses":{"200":{"description":"Perfis.","content":{"application\/json":{"example":{"perfis":[{"id":1,"nome":"Administrador","descricao":"Acesso total","usuarios":2},{"id":2,"nome":"Gestor de RH","descricao":"Envio e consulta","usuarios":7}]}}}}}}},"\/api\/v1\/empresa":{"get":{"tags":["Administração"],"summary":"Dados da empresa do token","responses":{"200":{"description":"Empresa.","content":{"application\/json":{"example":{"empresa":{"id":1,"nome":"SAMBAIBA TRANSPORTES LTDA","fantasia":"Sambaíba","cnpj":"12.345.678\/0001-99","autenticacao_padrao":"cpf_rg","situacao":"ativo"}}}}}}},"patch":{"tags":["Administração"],"summary":"Mudar a autenticação padrão","description":"Vale para quem não trouxer autenticação própria no documento ou no signatário — esses dois continuam tendo prioridade.","requestBody":{"required":true,"content":{"application\/json":{"example":{"autenticacao_padrao":"facial_cpf_rg"}}}},"responses":{"200":{"description":"Atualizado."},"422":{"description":"Valor fora da lista permitida."}}},"put":{"tags":["Administração"],"summary":"Mudar a autenticação padrão","description":"Vale para quem não trouxer autenticação própria no documento ou no signatário — esses dois continuam tendo prioridade.","requestBody":{"required":true,"content":{"application\/json":{"example":{"autenticacao_padrao":"facial_cpf_rg"}}}},"responses":{"200":{"description":"Atualizado."},"422":{"description":"Valor fora da lista permitida."}}}},"\/api\/v1\/auditoria":{"get":{"tags":["Administração"],"summary":"Trilha de auditoria","description":"Quem fez o que, quando e de qual IP — inclusive o que foi feito pela API. É o que sustenta uma contestação.","parameters":[{"name":"acao","in":"query","schema":{"type":"string"},"description":"Filtra pela ação, ex.: 'api_' ou 'envio_'."},{"name":"entidade","in":"query","schema":{"type":"string"},"description":"Tabela afetada, ex.: solicitacoes_assinatura."},{"name":"data_inicio","in":"query","schema":{"type":"string","format":"date"}},{"name":"data_fim","in":"query","schema":{"type":"string","format":"date"}},{"name":"pagina","in":"query","schema":{"type":"integer","default":1}},{"name":"por_pagina","in":"query","schema":{"type":"integer","default":50,"maximum":200}}],"responses":{"200":{"description":"Registros.","content":{"application\/json":{"example":{"auditoria":[{"id":9122,"acao":"api_documento_alterado","entidade":"solicitacoes_assinatura","entidade_id":128,"detalhe":{"referencia_externa":"ORDEM-99812"},"usuario":"API","ip":"189.45.12.90","em":"2026-10-10 14:40:44"}],"total":1}}}}}}},"\/api\/v1\/funcionarios\/{id}\/documentos":{"get":{"tags":["Funcionários"],"summary":"Documentos desta pessoa","description":"Tudo em que a pessoa aparece como signatária: assinados, pendentes e expirados, com a evidência da assinatura dela (data, IP, método, protocolo e hash). É o histórico que a ficha dela mostra no painel.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id, CPF ou matrícula."}],"responses":{"200":{"description":"Histórico.","content":{"application\/json":{"example":{"funcionario":{"id":42,"nome":"MARIA SOUZA LIMA","matricula":"10428","cpf":"***.***.247-25"},"resumo":{"total":4,"assinados":3,"pendentes":1,"expirados":0,"com_icp":2,"primeiro":"2026-02-11 09:14:02","ultimo":"2026-10-10 15:53:47"},"documentos":[{"documento_id":128,"id_documento":"DOC-20261010093015-A7F3C1","referencia":"ORDEM-99812","nome_arquivo":"termo_responsabilidade.pdf","tipo_documento":"Termo de Responsabilidade","situacao_documento":"assinado","icp_brasil":true,"enviado_em":"2026-10-10 09:30:15","expira_em":"2026-10-17 12:30:15","minha_parte":{"funcao":"Funcionário","ordem":1,"situacao":"assinado","assinado_em":"2026-10-10 10:02:41","protocolo":"B53801829A8C0B682AB8EFCA3A92350D","ip":"189.45.12.90","autenticacao":"cpf_rg","tem_rubrica":false,"tem_facial":false,"hash_documento_sha256":"9f2c...e81a"},"assinaturas":{"concluidas":2,"total":2}}]}}}}}}},"\/api\/v1\/signatarios\/{id}\/documentos":{"get":{"tags":["Signatários"],"summary":"Documentos desta pessoa","description":"Mesmo histórico, para quem não é funcionário. A ligação é feita pelo CPF, que é o que fica guardado em cada assinatura — um signatário sem CPF cadastrado volta com a lista vazia e um aviso.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Id, CPF ou matrícula."}],"responses":{"200":{"description":"Histórico.","content":{"application\/json":{"example":{"funcionario":{"id":42,"nome":"MARIA SOUZA LIMA","matricula":"10428","cpf":"***.***.247-25"},"resumo":{"total":4,"assinados":3,"pendentes":1,"expirados":0,"com_icp":2,"primeiro":"2026-02-11 09:14:02","ultimo":"2026-10-10 15:53:47"},"documentos":[{"documento_id":128,"id_documento":"DOC-20261010093015-A7F3C1","referencia":"ORDEM-99812","nome_arquivo":"termo_responsabilidade.pdf","tipo_documento":"Termo de Responsabilidade","situacao_documento":"assinado","icp_brasil":true,"enviado_em":"2026-10-10 09:30:15","expira_em":"2026-10-17 12:30:15","minha_parte":{"funcao":"Funcionário","ordem":1,"situacao":"assinado","assinado_em":"2026-10-10 10:02:41","protocolo":"B53801829A8C0B682AB8EFCA3A92350D","ip":"189.45.12.90","autenticacao":"cpf_rg","tem_rubrica":false,"tem_facial":false,"hash_documento_sha256":"9f2c...e81a"},"assinaturas":{"concluidas":2,"total":2}}]}}}}}}},"\/api\/v1\/documentos":{"post":{"tags":["Documentos"],"summary":"Enviar documento para assinatura","description":"Cria o documento, gera o link de cada signatário e envia o convite por e-mail. O PDF vai em `arquivo_base64` (JSON) ou no campo `arquivo` (multipart).","requestBody":{"required":true,"content":{"application\/json":{"examples":{"dois_signatarios":{"summary":"Dois signatários em ordem","value":{"arquivo_base64":"JVBERi0xLjQKJSVFT0Y=","nome_arquivo":"termo_responsabilidade.pdf","tipo_documento":"Termo de Responsabilidade","referencia":"ORDEM-99812","prazo_dias":7,"validar_icp":true,"signatarios":[{"cpf":"529.982.247-25","funcao":"Funcionário"},{"nome":"CARLOS GESTOR RH","email":"carlos@empresa.com.br","cpf":"111.444.777-35","funcao":"Responsável do Setor","autenticacao":"facial_cpf_rg"}]}},"governanca":{"summary":"Governança resolvida pela plataforma","value":{"arquivo_base64":"JVBERi0xLjQKJSVFT0Y=","nome_arquivo":"ficha_epi.pdf","tipo_documento_id":1,"referencia":"EPI-4471","governanca":{"funcionario":"529.982.247-25"}}}}},"multipart\/form-data":{"schema":{"type":"object","properties":{"arquivo":{"type":"string","format":"binary"},"tipo_documento_id":{"type":"integer"},"signatarios":{"type":"string","description":"JSON da lista de signatários."}}}}}},"responses":{"201":{"description":"Documento criado.","content":{"application\/json":{"example":{"documento":{"id":128,"id_documento":"DOC-20261010093015-A7F3C1","referencia":"ORDEM-99812","nome_arquivo":"termo_responsabilidade.pdf","tipo_documento":"Termo de Responsabilidade","situacao":"em_progresso","icp_brasil":false,"autenticacao":"cpf_rg","enviado_em":"2026-10-10 09:30:15","expira_em":"2026-10-17 12:30:15","concluido_em":null,"assinaturas":{"concluidas":1,"total":2},"links":{"arquivo":"https:\/\/signature.techps.com.br\/api\/v1\/documentos\/128\/arquivo","evidencias":"https:\/\/signature.techps.com.br\/api\/v1\/documentos\/128\/evidencias"},"signatarios":[{"ordem":1,"nome":"MARIA SOUZA LIMA","email":"maria@empresa.com.br","funcao":"Funcionário","situacao":"assinado","autenticacao":null,"assinado_em":"2026-10-10 10:02:41","protocolo":"B53801829A8C0B682AB8EFCA3A92350D","link_assinatura":null},{"ordem":2,"nome":"CARLOS GESTOR RH","email":"carlos@empresa.com.br","funcao":"Responsável do Setor","situacao":"pendente","autenticacao":"facial_cpf_rg","assinado_em":null,"protocolo":null,"link_assinatura":"https:\/\/signature.techps.com.br\/assinar\/77f33df457..."}]},"avisos":[]}}}},"401":{"description":"Token ausente ou inválido.","content":{"application\/json":{"example":{"erro":"nao_autorizado","mensagem":"Informe o cabeçalho Authorization: Bearer <token>."}}}},"422":{"description":"Dados recusados.","content":{"application\/json":{"example":{"erro":"signatario_invalido","mensagem":"Signatário 2 (CARLOS): e-mail inválido ou ausente."}}}},"429":{"description":"Limite por minuto atingido.","content":{"application\/json":{"example":{"erro":"limite_excedido","mensagem":"Limite de 300 requisições por minuto atingido."}}}}}},"get":{"tags":["Documentos"],"summary":"Listar documentos","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["andamento","concluido","expirado","cancelado"]}},{"name":"busca","in":"query","schema":{"type":"string"},"description":"Nome do arquivo, id público ou nome do signatário."},{"name":"data_inicio","in":"query","schema":{"type":"string","format":"date"}},{"name":"data_fim","in":"query","schema":{"type":"string","format":"date"}},{"name":"pagina","in":"query","schema":{"type":"integer","default":1}},{"name":"por_pagina","in":"query","schema":{"type":"integer","default":25,"maximum":100}}],"responses":{"200":{"description":"Lista paginada.","content":{"application\/json":{"example":{"documentos":[{"id":128,"id_documento":"DOC-20261010093015-A7F3C1","referencia":"ORDEM-99812","nome_arquivo":"termo_responsabilidade.pdf","tipo_documento":"Termo de Responsabilidade","situacao":"em_progresso","icp_brasil":false,"autenticacao":"cpf_rg","enviado_em":"2026-10-10 09:30:15","expira_em":"2026-10-17 12:30:15","concluido_em":null,"assinaturas":{"concluidas":1,"total":2},"links":{"arquivo":"https:\/\/signature.techps.com.br\/api\/v1\/documentos\/128\/arquivo","evidencias":"https:\/\/signature.techps.com.br\/api\/v1\/documentos\/128\/evidencias"},"signatarios":[{"ordem":1,"nome":"MARIA SOUZA LIMA","email":"maria@empresa.com.br","funcao":"Funcionário","situacao":"assinado","autenticacao":null,"assinado_em":"2026-10-10 10:02:41","protocolo":"B53801829A8C0B682AB8EFCA3A92350D","link_assinatura":null},{"ordem":2,"nome":"CARLOS GESTOR RH","email":"carlos@empresa.com.br","funcao":"Responsável do Setor","situacao":"pendente","autenticacao":"facial_cpf_rg","assinado_em":null,"protocolo":null,"link_assinatura":"https:\/\/signature.techps.com.br\/assinar\/77f33df457..."}]}],"pagina":1,"por_pagina":25,"total":1}}}}}}},"\/api\/v1\/me":{"get":{"tags":["Documentos"],"summary":"Com que token e empresa estou falando","description":"Primeira chamada de qualquer integração: confirma o token, a empresa, o ambiente, o limite por minuto e a lista de eventos de webhook disponíveis.","responses":{"200":{"description":"Token e empresa.","content":{"application\/json":{"example":{"token":{"nome":"ERP JB — produção","prefixo":"tsk_live_ac5","ambiente":"producao","limite_por_minuto":300,"ultimo_uso":"2026-10-10 14:11:34"},"empresa":{"id":1,"nome":"SAMBAIBA TRANSPORTES LTDA","autenticacao_padrao":"cpf_rg"}}}}}}}},"\/api\/v1\/indicadores":{"get":{"tags":["Documentos"],"summary":"Números do painel","description":"Os mesmos totais que aparecem no painel: pendentes, concluídos, a vencer e vencidos. A chamada também encerra os documentos cujo prazo passou.","responses":{"200":{"description":"Indicadores."}}}},"\/api\/v1\/pendencias":{"get":{"tags":["Documentos"],"summary":"O que falta uma pessoa assinar","description":"É o que o ERP usa para mostrar \"você tem 3 documentos para assinar\" na tela do funcionário, com o link de cada um. Só traz o que é a vez dela na ordem.","parameters":[{"name":"cpf","in":"query","schema":{"type":"string"},"example":"529.982.247-25"},{"name":"matricula","in":"query","schema":{"type":"string"}},{"name":"funcionario_id","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Pendências.","content":{"application\/json":{"example":{"funcionario":{"id":42,"nome":"MARIA SOUZA LIMA","matricula":"10428","cpf":"***.***.247-25"},"pendencias":[{"documento_id":128,"id_documento":"DOC-20261010093015-A7F3C1","nome_arquivo":"termo_responsabilidade.pdf","tipo_documento":"Termo de Responsabilidade","funcao":"Funcionário","enviado_em":"2026-10-10 09:30:15","expira_em":"2026-10-17 12:30:15","link_assinatura":"https:\/\/signature.techps.com.br\/assinar\/8dbb4fb14cf7..."}],"total":1}}}},"404":{"description":"Pessoa não encontrada.","content":{"application\/json":{"example":{"erro":"funcionario_nao_encontrado","mensagem":"Nenhum funcionário ativo com esse CPF, matrícula ou id."}}}}}}},"\/api\/v1\/documentos\/lote":{"post":{"tags":["Documentos"],"summary":"O mesmo PDF para várias pessoas","description":"Cada pessoa recebe um documento próprio, com link, protocolo e arquivo independentes — é o que permite acompanhar quem assinou e quem não. Até 200 por chamada. Com `governanca: true`, cada destinatário gera a sua cadeia de responsáveis.\n\nA resposta lista o que foi criado e, em `falhas`, quem foi recusado e por quê: um destinatário sem e-mail não impede os outros.","requestBody":{"required":true,"content":{"application\/json":{"example":{"arquivo_base64":"JVBERi0xLjQKJSVFT0Y=","nome_arquivo":"comunicado_interno.pdf","tipo_documento":"Comunicado","grupo":"COMUNICADO-2026-10","prazo_dias":7,"destinatarios":["529.982.247-25","111.444.777-35","390.533.447-05"]}}}},"responses":{"201":{"description":"Lote criado.","content":{"application\/json":{"example":{"grupo":"COMUNICADO-2026-10","criados":2,"recusados":1,"documentos":[{"id":128,"id_documento":"DOC-20261010093015-A7F3C1","referencia":"ORDEM-99812","nome_arquivo":"termo_responsabilidade.pdf","tipo_documento":"Termo de Responsabilidade","situacao":"em_progresso","icp_brasil":false,"autenticacao":"cpf_rg","enviado_em":"2026-10-10 09:30:15","expira_em":"2026-10-17 12:30:15","concluido_em":null,"assinaturas":{"concluidas":1,"total":2},"links":{"arquivo":"https:\/\/signature.techps.com.br\/api\/v1\/documentos\/128\/arquivo","evidencias":"https:\/\/signature.techps.com.br\/api\/v1\/documentos\/128\/evidencias"},"signatarios":[{"ordem":1,"nome":"MARIA SOUZA LIMA","email":"maria@empresa.com.br","funcao":"Funcionário","situacao":"assinado","autenticacao":null,"assinado_em":"2026-10-10 10:02:41","protocolo":"B53801829A8C0B682AB8EFCA3A92350D","link_assinatura":null},{"ordem":2,"nome":"CARLOS GESTOR RH","email":"carlos@empresa.com.br","funcao":"Responsável do Setor","situacao":"pendente","autenticacao":"facial_cpf_rg","assinado_em":null,"protocolo":null,"link_assinatura":"https:\/\/signature.techps.com.br\/assinar\/77f33df457..."}]}],"falhas":[{"destinatario":"390.533.447-05","motivo":"Signatário sem e-mail cadastrado."}]}}}},"422":{"description":"Nenhum documento pôde ser criado."}}}},"\/api\/v1\/documentos\/{id}":{"get":{"tags":["Documentos"],"summary":"Consultar situação","description":"Aceita id interno, id público (DOC-...) ou a sua referência.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"example":"ORDEM-99812"}],"responses":{"200":{"description":"Documento.","content":{"application\/json":{"example":{"documento":{"id":128,"id_documento":"DOC-20261010093015-A7F3C1","referencia":"ORDEM-99812","nome_arquivo":"termo_responsabilidade.pdf","tipo_documento":"Termo de Responsabilidade","situacao":"em_progresso","icp_brasil":false,"autenticacao":"cpf_rg","enviado_em":"2026-10-10 09:30:15","expira_em":"2026-10-17 12:30:15","concluido_em":null,"assinaturas":{"concluidas":1,"total":2},"links":{"arquivo":"https:\/\/signature.techps.com.br\/api\/v1\/documentos\/128\/arquivo","evidencias":"https:\/\/signature.techps.com.br\/api\/v1\/documentos\/128\/evidencias"},"signatarios":[{"ordem":1,"nome":"MARIA SOUZA LIMA","email":"maria@empresa.com.br","funcao":"Funcionário","situacao":"assinado","autenticacao":null,"assinado_em":"2026-10-10 10:02:41","protocolo":"B53801829A8C0B682AB8EFCA3A92350D","link_assinatura":null},{"ordem":2,"nome":"CARLOS GESTOR RH","email":"carlos@empresa.com.br","funcao":"Responsável do Setor","situacao":"pendente","autenticacao":"facial_cpf_rg","assinado_em":null,"protocolo":null,"link_assinatura":"https:\/\/signature.techps.com.br\/assinar\/77f33df457..."}]}}}}},"404":{"description":"Não encontrado.","content":{"application\/json":{"example":{"erro":"nao_encontrado","mensagem":"Documento não encontrado."}}}}}},"patch":{"tags":["Documentos"],"summary":"Alterar o documento","description":"O arquivo e os signatários **não** mudam depois do envio: mexer neles invalidaria as assinaturas já colhidas. Para trocar o PDF, cancele e envie outro.\n\nO que se altera aqui é o que não afeta a prova: `referencia`, `grupo`, `tipo_documento_id`, `validar_icp` e `prazo_dias`. Mandar `prazo_dias` renova o prazo e **gera links novos** para quem ainda não assinou — os antigos param de funcionar.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application\/json":{"example":{"referencia":"ORDEM-99812-REV2","prazo_dias":15}}}},"responses":{"200":{"description":"Alterado.","content":{"application\/json":{"example":{"documento":{"id":128,"id_documento":"DOC-20261010093015-A7F3C1","referencia":"ORDEM-99812","nome_arquivo":"termo_responsabilidade.pdf","tipo_documento":"Termo de Responsabilidade","situacao":"em_progresso","icp_brasil":false,"autenticacao":"cpf_rg","enviado_em":"2026-10-10 09:30:15","expira_em":"2026-10-17 12:30:15","concluido_em":null,"assinaturas":{"concluidas":1,"total":2},"links":{"arquivo":"https:\/\/signature.techps.com.br\/api\/v1\/documentos\/128\/arquivo","evidencias":"https:\/\/signature.techps.com.br\/api\/v1\/documentos\/128\/evidencias"},"signatarios":[{"ordem":1,"nome":"MARIA SOUZA LIMA","email":"maria@empresa.com.br","funcao":"Funcionário","situacao":"assinado","autenticacao":null,"assinado_em":"2026-10-10 10:02:41","protocolo":"B53801829A8C0B682AB8EFCA3A92350D","link_assinatura":null},{"ordem":2,"nome":"CARLOS GESTOR RH","email":"carlos@empresa.com.br","funcao":"Responsável do Setor","situacao":"pendente","autenticacao":"facial_cpf_rg","assinado_em":null,"protocolo":null,"link_assinatura":"https:\/\/signature.techps.com.br\/assinar\/77f33df457..."}]},"alterados":["referencia_externa"],"avisos":["Prazo renovado: 1 link(s) de assinatura foram substituídos."]}}}},"422":{"description":"Documento cancelado ou expirado não pode ser alterado."}}},"put":{"tags":["Documentos"],"summary":"Substituir os dados alteráveis","description":"Mesmos campos do PATCH, com a diferença de sempre substituir: `referencia` e `grupo` ausentes ficam vazios.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application\/json":{"example":{"referencia":"ORDEM-99812","grupo":"RH-2026"}}}},"responses":{"200":{"description":"Substituído."}}},"delete":{"tags":["Documentos"],"summary":"Cancelar o documento","description":"Mesmo efeito de `POST \/cancelar`. Os links pendentes param de funcionar na hora; o documento fica como `cancelado` e o histórico permanece. Um documento já concluído não pode ser cancelado.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application\/json":{"example":{"motivo":"pedido cancelado no ERP"}}}},"responses":{"200":{"description":"Cancelado."},"422":{"description":"Já concluído, já cancelado ou expirado.","content":{"application\/json":{"example":{"erro":"cancelamento_recusado","mensagem":"Documento já concluído não pode ser cancelado."}}}}}}},"\/api\/v1\/documentos\/{id}\/signatarios":{"get":{"tags":["Documentos"],"summary":"Quem assina e em que ordem","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Signatários.","content":{"application\/json":{"example":{"documento_id":128,"id_documento":"DOC-20261010093015-A7F3C1","signatarios":[{"ordem":1,"nome":"MARIA SOUZA LIMA","email":"maria@empresa.com.br","funcao":"Funcionário","situacao":"assinado","autenticacao":null,"assinado_em":"2026-10-10 10:02:41","protocolo":"B53801829A8C0B682AB8EFCA3A92350D","link_assinatura":null},{"ordem":2,"nome":"CARLOS GESTOR RH","email":"carlos@empresa.com.br","funcao":"Responsável do Setor","situacao":"pendente","autenticacao":"facial_cpf_rg","assinado_em":null,"protocolo":null,"link_assinatura":"https:\/\/signature.techps.com.br\/assinar\/77f33df457..."}]}}}}}}},"\/api\/v1\/documentos\/{id}\/reenviar":{"post":{"tags":["Documentos"],"summary":"Reenviar o convite por e-mail","description":"Para quando o e-mail caiu no spam. O link é o mesmo: reenviar não invalida nada nem muda o prazo (para isso, use PATCH com `prazo_dias`). Só recebe quem é a vez na ordem.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Convite na fila de envio."},"422":{"description":"Não há assinatura pendente neste documento."}}}},"\/api\/v1\/documentos\/{id}\/finalizar":{"post":{"tags":["Documentos"],"summary":"Aplicar o certificado ICP-Brasil","description":"Normalmente acontece sozinho quando a última assinatura entra. Este endereço serve para refazer, se na hora o certificado estava vencido ou ausente. Se já estava finalizado, a resposta diz isso e nada é refeito.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Finalizado.","content":{"application\/json":{"example":{"finalizado":true,"ja_estava_finalizado":false,"codigo_verificacao":"A7F3C19B34"}}}},"422":{"description":"Ainda falta alguém assinar, ou não há certificado ativo."}}}},"\/api\/v1\/documentos\/{id}\/arquivo":{"get":{"tags":["Documentos"],"summary":"Baixar o PDF","description":"Devolve o arquivo mais recente: com as assinaturas registradas e, quando houver, o carimbo ICP-Brasil.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"O PDF.","content":{"application\/pdf":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"Arquivo indisponível.","content":{"application\/json":{"example":{"erro":"arquivo_ausente","mensagem":"O arquivo não está disponível."}}}}}}},"\/api\/v1\/documentos\/{id}\/evidencias":{"get":{"tags":["Documentos"],"summary":"Relatório de evidências","description":"Tudo o que foi registrado em cada assinatura: data e hora, IP, navegador, localização (quando o signatário permite), método de autenticação, protocolo e hash do documento.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Evidências.","content":{"application\/json":{"example":{"documento":{"id":128,"id_documento":"DOC-20261010093015-A7F3C1","nome_arquivo":"termo_responsabilidade.pdf","situacao":"assinado","icp_brasil":true,"enviado_em":"2026-10-10 09:30:15","concluido_em":"2026-10-10 11:18:02"},"assinaturas":[{"ordem":1,"nome":"MARIA SOUZA LIMA","email":"maria@empresa.com.br","funcao":"Funcionário","situacao":"assinado","cpf":"***.***.247-25","rg":"informado","assinado_em":"2026-10-10 10:02:41","ip":"189.45.12.90","navegador":"Mozilla\/5.0 (iPhone; CPU iPhone OS 17_5)","localizacao":{"latitude":-3.731899999999999995026200849679298698902130126953125,"longitude":-38.52669999999999816964191268198192119598388671875},"protocolo":"B53801829A8C0B682AB8EFCA3A92350D","hash_documento_sha256":"9f2c...e81a","autenticacao":"cpf_rg","tem_rubrica":false,"facial":null}],"base_legal":"MP 2.200-2\/2001 e Lei 14.063\/2020"}}}}}}},"\/api\/v1\/documentos\/{id}\/renovar":{"post":{"tags":["Documentos"],"summary":"Renovar o prazo","description":"Estende o prazo e gera links novos para quem ainda não assinou. Os links antigos deixam de funcionar.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application\/json":{"example":{"prazo_dias":7}}}},"responses":{"200":{"description":"Prazo renovado.","content":{"application\/json":{"example":{"documento":{"id":128,"id_documento":"DOC-20261010093015-A7F3C1","referencia":"ORDEM-99812","nome_arquivo":"termo_responsabilidade.pdf","tipo_documento":"Termo de Responsabilidade","situacao":"em_progresso","icp_brasil":false,"autenticacao":"cpf_rg","enviado_em":"2026-10-10 09:30:15","expira_em":"2026-10-17 12:30:15","concluido_em":null,"assinaturas":{"concluidas":1,"total":2},"links":{"arquivo":"https:\/\/signature.techps.com.br\/api\/v1\/documentos\/128\/arquivo","evidencias":"https:\/\/signature.techps.com.br\/api\/v1\/documentos\/128\/evidencias"},"signatarios":[{"ordem":1,"nome":"MARIA SOUZA LIMA","email":"maria@empresa.com.br","funcao":"Funcionário","situacao":"assinado","autenticacao":null,"assinado_em":"2026-10-10 10:02:41","protocolo":"B53801829A8C0B682AB8EFCA3A92350D","link_assinatura":null},{"ordem":2,"nome":"CARLOS GESTOR RH","email":"carlos@empresa.com.br","funcao":"Responsável do Setor","situacao":"pendente","autenticacao":"facial_cpf_rg","assinado_em":null,"protocolo":null,"link_assinatura":"https:\/\/signature.techps.com.br\/assinar\/77f33df457..."}]},"links_renovados":1}}}},"422":{"description":"Nada pendente para renovar.","content":{"application\/json":{"example":{"erro":"renovacao_recusada","mensagem":"Esse documento não tem assinatura pendente."}}}}}}},"\/api\/v1\/documentos\/{id}\/cancelar":{"post":{"tags":["Documentos"],"summary":"Cancelar documento","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application\/json":{"example":{"motivo":"pedido cancelado no ERP"}}}},"responses":{"200":{"description":"Cancelado."},"422":{"description":"Já concluído.","content":{"application\/json":{"example":{"erro":"cancelamento_recusado","mensagem":"Documento já concluído não pode ser cancelado."}}}}}}},"\/api\/v1\/webhooks\/{id}\/remover":{"post":{"tags":["Webhooks"],"summary":"Desativar webhook","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Desativado."},"404":{"description":"Não encontrado."}}}},"\/api\/v1\/consumo":{"get":{"tags":["Consumo"],"summary":"Medição do mês","description":"Base da cobrança combinada: CPFs ativos da corporação e CPFs ativos no mês entre os externos. Cada pessoa conta uma vez, mesmo assinando vários documentos.","parameters":[{"name":"competencia","in":"query","schema":{"type":"string","example":"2026-10"}}],"responses":{"200":{"description":"Medição.","content":{"application\/json":{"example":{"consumo":{"competencia":"2026-10","cobranca":{"cpfs_ativos_internos":142,"cpfs_ativos_externos":17,"cpfs_ativos_total":159,"cpfs_no_cadastro":180,"assinaturas_com_facial":23},"documentos":{"enviados":310,"concluidos":287,"com_icp_brasil":94,"pela_api":298,"expirados":6},"api":{"chamadas":1204,"erros":3}}}}}}}}}},"webhooks":{"documento.concluido":{"post":{"summary":"Todos assinaram","description":"Enviado quando a última assinatura entra. Confira o cabeçalho `X-TechPS-Assinatura` antes de processar.","requestBody":{"content":{"application\/json":{"example":{"evento":"documento.concluido","ocorrido_em":"2026-10-10T11:18:02-03:00","dados":{"documento_id":128,"id_documento":"DOC-20261010093015-A7F3C1","referencia":"ORDEM-99812","nome_arquivo":"termo_responsabilidade.pdf","icp_brasil":true,"concluido_em":"2026-10-10 11:18:02","links":{"arquivo":"https:\/\/signature.techps.com.br\/api\/v1\/documentos\/128\/arquivo","evidencias":"https:\/\/signature.techps.com.br\/api\/v1\/documentos\/128\/evidencias"}}}}}},"responses":{"200":{"description":"Responda 2xx. Qualquer outra resposta provoca nova tentativa."}}}},"assinatura.registrada":{"post":{"summary":"Um signatário assinou","requestBody":{"content":{"application\/json":{"example":{"evento":"assinatura.registrada","ocorrido_em":"2026-10-10T10:02:41-03:00","dados":{"documento_id":128,"id_documento":"DOC-20261010093015-A7F3C1","referencia":"ORDEM-99812","signatario":{"nome":"MARIA SOUZA LIMA","email":"maria@empresa.com.br","funcao":"Funcionário","ordem":1},"protocolo":"B53801829A8C0B682AB8EFCA3A92350D","assinaturas":{"concluidas":1,"total":2}}}}}},"responses":{"200":{"description":"Responda 2xx."}}}}}}