{
    "openapi": "3.1.0",
    "info": {
        "title": "Assine Bom API",
        "version": "1.0.0",
        "summary": "Envie documentos para assinatura eletrônica e acompanhe o andamento a partir do seu sistema.",
        "description": "API REST da plataforma de assinatura eletrônica **Assine Bom** (MP 2.200-2/2001 e Lei 14.063/2020).\n\nGuia passo a passo: [https://assinebom.com.br/docs](https://assinebom.com.br/docs)\n\n**Autenticação:** crie uma chave em *Integrações* (somente administradores da conta) e envie em `Authorization: Bearer ab_...`.\n\n**Formato:** requisições em JSON ou `multipart/form-data` (para anexar o arquivo); respostas sempre em JSON, exceto os downloads (PDF). Datas em ISO 8601 com fuso.\n\n**Limites:** 120 requisições por minuto por chave; envio de documentos limitado a 30 por minuto. Acima disso a resposta é `429`.\n\n**Atenção ao testar aqui:** as chamadas são reais. Cada documento criado conta no plano da conta e dispara convites por e-mail.",
        "contact": {
            "name": "Fyrel Tecnologia e Negócios Ltda",
            "email": "contato@fyrel.com.br",
            "url": "https://fyrel.com.br"
        },
        "termsOfService": "https://assinebom.com.br/termos",
        "license": {
            "name": "Uso conforme os Termos do Assine Bom",
            "url": "https://assinebom.com.br/termos"
        }
    },
    "servers": [
        {
            "url": "https://assinebom.com.br/api/v1",
            "description": "Produção"
        }
    ],
    "security": [
        {
            "bearerAuth": []
        }
    ],
    "tags": [
        {
            "name": "Documentos",
            "description": "Enviar, consultar, cancelar e baixar documentos."
        },
        {
            "name": "Assinantes",
            "description": "Ações sobre cada pessoa que assina."
        },
        {
            "name": "Modelos",
            "description": "Modelos salvos no painel (documento + papéis + posições)."
        }
    ],
    "paths": {
        "/documents": {
            "get": {
                "tags": [
                    "Documentos"
                ],
                "operationId": "listDocuments",
                "summary": "Listar documentos",
                "description": "Do mais recente para o mais antigo, paginado.",
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "schema": {
                            "$ref": "#/components/schemas/DocumentStatus"
                        }
                    },
                    {
                        "name": "external_ref",
                        "in": "query",
                        "description": "Filtra pela referência que você informou no envio.",
                        "schema": {
                            "type": "string",
                            "maxLength": 120
                        },
                        "example": "pedido-123"
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100,
                            "default": 20
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "default": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Página de documentos.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "data",
                                        "meta"
                                    ],
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Document"
                                            }
                                        },
                                        "meta": {
                                            "$ref": "#/components/schemas/PageMeta"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                }
            },
            "post": {
                "tags": [
                    "Documentos"
                ],
                "operationId": "createDocument",
                "summary": "Enviar documento para assinatura",
                "description": "Cria o documento e convida os assinantes por e-mail (todos de uma vez ou, com `sequential`, um por vez).\n\nEscolha **uma** origem para o arquivo:\n\n- `file` em `multipart/form-data` (PDF ou Word `.docx`, até 20 MB);\n- `file_base64` + `file_name` em JSON;\n- `template_id` de um modelo salvo (os assinantes seguem a ordem dos papéis do modelo; o método de autenticação e as posições vêm do modelo).\n\nArquivos `.docx` são convertidos em PDF. O link de cada assinante (`sign_url`) volta na resposta e vale por 30 dias: você pode mandá-lo por WhatsApp ou pelo seu próprio sistema.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "$ref": "#/components/schemas/CreateDocumentMultipart"
                            },
                            "encoding": {
                                "file": {
                                    "contentType": "application/pdf, application/vnd.openxmlformats-officedocument.wordprocessingml.document"
                                }
                            }
                        },
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/CreateDocumentJson"
                            },
                            "examples": {
                                "arquivo": {
                                    "summary": "Arquivo em base64",
                                    "value": {
                                        "title": "Contrato de prestação de serviços",
                                        "message": "Olá! Segue o contrato para assinatura.",
                                        "external_ref": "pedido-123",
                                        "file_name": "contrato.pdf",
                                        "file_base64": "JVBERi0xLjQKJ...",
                                        "sequential": false,
                                        "signers": [
                                            {
                                                "name": "Maria Souza",
                                                "email": "maria@exemplo.com.br",
                                                "phone": "11912345678",
                                                "cpf": "123.456.789-09",
                                                "auth_method": "email_token"
                                            },
                                            {
                                                "name": "João Lima",
                                                "email": "joao@exemplo.com.br",
                                                "role": "testemunha",
                                                "auth_method": "simple",
                                                "placements": [
                                                    {
                                                        "page": 2,
                                                        "x": 0.5500000000000000444089209850062616169452667236328125,
                                                        "y": 0.7800000000000000266453525910037569701671600341796875,
                                                        "w": 0.299999999999999988897769753748434595763683319091796875,
                                                        "h": 0.07499999999999999722444243843710864894092082977294921875
                                                    }
                                                ]
                                            }
                                        ],
                                        "cc": [
                                            {
                                                "name": "Jurídico",
                                                "email": "juridico@exemplo.com.br"
                                            }
                                        ]
                                    }
                                },
                                "modelo": {
                                    "summary": "A partir de um modelo",
                                    "value": {
                                        "template_id": 7,
                                        "external_ref": "locacao-apto-12",
                                        "signers": [
                                            {
                                                "name": "Ana Locadora",
                                                "email": "ana@exemplo.com.br"
                                            },
                                            {
                                                "name": "Beto Locatário",
                                                "email": "beto@exemplo.com.br",
                                                "phone": "21987654321"
                                            }
                                        ]
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Documento criado e convites disparados.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "data"
                                    ],
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/DocumentDetail"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationError"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                }
            }
        },
        "/documents/{id}": {
            "parameters": [
                {
                    "$ref": "#/components/parameters/DocumentId"
                }
            ],
            "get": {
                "tags": [
                    "Documentos"
                ],
                "operationId": "getDocument",
                "summary": "Consultar documento",
                "description": "Situação atual, assinantes (com `sign_url` de quem pode assinar agora) e links de download.",
                "responses": {
                    "200": {
                        "description": "Documento.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "data"
                                    ],
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/DocumentDetail"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/documents/{id}/cancel": {
            "parameters": [
                {
                    "$ref": "#/components/parameters/DocumentId"
                }
            ],
            "post": {
                "tags": [
                    "Documentos"
                ],
                "operationId": "cancelDocument",
                "summary": "Cancelar envio",
                "description": "Os links deixam de funcionar e o webhook `envelope.canceled` é disparado. Só vale para documentos `in_progress`.",
                "responses": {
                    "200": {
                        "description": "Cancelado.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "data"
                                    ],
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/DocumentDetail"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "409": {
                        "$ref": "#/components/responses/Conflict"
                    }
                }
            }
        },
        "/documents/{id}/signers/{signer_id}/resend": {
            "parameters": [
                {
                    "$ref": "#/components/parameters/DocumentId"
                },
                {
                    "name": "signer_id",
                    "in": "path",
                    "required": true,
                    "description": "Campo `id` do assinante.",
                    "schema": {
                        "type": "integer"
                    },
                    "example": 42
                }
            ],
            "post": {
                "tags": [
                    "Assinantes"
                ],
                "operationId": "resendInvite",
                "summary": "Reenviar convite por e-mail",
                "description": "Mantém o mesmo `sign_url`. Só para assinantes pendentes cuja vez já chegou.",
                "responses": {
                    "200": {
                        "description": "Reenviado.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Message"
                                },
                                "example": {
                                    "message": "Convite reenviado."
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "409": {
                        "$ref": "#/components/responses/Conflict"
                    },
                    "502": {
                        "description": "O servidor de e-mail recusou o endereço. Confira o e-mail ou mande o `sign_url` por outro canal.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Message"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/documents/{id}/download/{kind}": {
            "parameters": [
                {
                    "$ref": "#/components/parameters/DocumentId"
                },
                {
                    "name": "kind",
                    "in": "path",
                    "required": true,
                    "description": "`final`: via assinada e lacrada (com manifesto). `original`: arquivo enviado.",
                    "schema": {
                        "type": "string",
                        "enum": [
                            "final",
                            "original"
                        ]
                    }
                }
            ],
            "get": {
                "tags": [
                    "Documentos"
                ],
                "operationId": "downloadDocument",
                "summary": "Baixar PDF",
                "description": "A via `final` existe depois que todos assinam (`finalized: true`, webhook `envelope.completed`).",
                "responses": {
                    "200": {
                        "description": "Arquivo PDF.",
                        "content": {
                            "application/pdf": {
                                "schema": {
                                    "type": "string",
                                    "contentMediaType": "application/pdf"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "409": {
                        "$ref": "#/components/responses/Conflict"
                    }
                }
            }
        },
        "/templates": {
            "get": {
                "tags": [
                    "Modelos"
                ],
                "operationId": "listTemplates",
                "summary": "Listar modelos",
                "description": "Use o `id` em `template_id` ao enviar. Os assinantes devem vir na mesma ordem de `signers`.",
                "responses": {
                    "200": {
                        "description": "Modelos da conta.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "data"
                                    ],
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Template"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                }
            }
        }
    },
    "webhooks": {
        "signer.signed": {
            "post": {
                "operationId": "webhookSignerSigned",
                "summary": "signer.signed",
                "description": "Uma pessoa assinou. `data.signer` traz quem foi.\n\nConfigure o endereço (https público) em *Integrações*. Enviamos `POST` com JSON e os cabeçalhos:\n\n- `X-AssineBom-Event`: nome do evento;\n- `X-AssineBom-Delivery`: id único da entrega;\n- `X-AssineBom-Signature`: `t=<unix>,v1=<hex>`, onde `v1 = HMAC-SHA256(\"<t>.<corpo bruto>\", segredo)`.\n\nResponda `2xx` em até 10 segundos. Sem sucesso, tentamos de novo em 1, 5, 15, 60, 180, 360 e 720 minutos (8 tentativas, cerca de 22 horas). Eventos podem chegar repetidos ou fora de ordem: use `id` para deduplicar e consulte `GET /documents/{id}` se precisar do estado atual.",
                "security": [],
                "parameters": [
                    {
                        "name": "X-AssineBom-Event",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "const": "signer.signed"
                        }
                    },
                    {
                        "name": "X-AssineBom-Delivery",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "X-AssineBom-Signature",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "example": "t=1760360000,v1=5d41402abc4b2a76b9719d911017c592..."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/WebhookEvent"
                            }
                        }
                    }
                },
                "responses": {
                    "2XX": {
                        "description": "Recebido. Qualquer outro status (ou demora acima de 10 s) gera nova tentativa."
                    }
                }
            }
        },
        "envelope.completed": {
            "post": {
                "operationId": "webhookEnvelopeCompleted",
                "summary": "envelope.completed",
                "description": "Todos assinaram e a via final lacrada foi gerada: já pode baixar em `/documents/{id}/download/final`.\n\nConfigure o endereço (https público) em *Integrações*. Enviamos `POST` com JSON e os cabeçalhos:\n\n- `X-AssineBom-Event`: nome do evento;\n- `X-AssineBom-Delivery`: id único da entrega;\n- `X-AssineBom-Signature`: `t=<unix>,v1=<hex>`, onde `v1 = HMAC-SHA256(\"<t>.<corpo bruto>\", segredo)`.\n\nResponda `2xx` em até 10 segundos. Sem sucesso, tentamos de novo em 1, 5, 15, 60, 180, 360 e 720 minutos (8 tentativas, cerca de 22 horas). Eventos podem chegar repetidos ou fora de ordem: use `id` para deduplicar e consulte `GET /documents/{id}` se precisar do estado atual.",
                "security": [],
                "parameters": [
                    {
                        "name": "X-AssineBom-Event",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "const": "envelope.completed"
                        }
                    },
                    {
                        "name": "X-AssineBom-Delivery",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "X-AssineBom-Signature",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "example": "t=1760360000,v1=5d41402abc4b2a76b9719d911017c592..."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/WebhookEvent"
                            }
                        }
                    }
                },
                "responses": {
                    "2XX": {
                        "description": "Recebido. Qualquer outro status (ou demora acima de 10 s) gera nova tentativa."
                    }
                }
            }
        },
        "envelope.declined": {
            "post": {
                "operationId": "webhookEnvelopeDeclined",
                "summary": "envelope.declined",
                "description": "Alguém recusou; o documento deixa de aceitar assinaturas. `data.signer.decline_reason` traz o motivo.\n\nConfigure o endereço (https público) em *Integrações*. Enviamos `POST` com JSON e os cabeçalhos:\n\n- `X-AssineBom-Event`: nome do evento;\n- `X-AssineBom-Delivery`: id único da entrega;\n- `X-AssineBom-Signature`: `t=<unix>,v1=<hex>`, onde `v1 = HMAC-SHA256(\"<t>.<corpo bruto>\", segredo)`.\n\nResponda `2xx` em até 10 segundos. Sem sucesso, tentamos de novo em 1, 5, 15, 60, 180, 360 e 720 minutos (8 tentativas, cerca de 22 horas). Eventos podem chegar repetidos ou fora de ordem: use `id` para deduplicar e consulte `GET /documents/{id}` se precisar do estado atual.",
                "security": [],
                "parameters": [
                    {
                        "name": "X-AssineBom-Event",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "const": "envelope.declined"
                        }
                    },
                    {
                        "name": "X-AssineBom-Delivery",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "X-AssineBom-Signature",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "example": "t=1760360000,v1=5d41402abc4b2a76b9719d911017c592..."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/WebhookEvent"
                            }
                        }
                    }
                },
                "responses": {
                    "2XX": {
                        "description": "Recebido. Qualquer outro status (ou demora acima de 10 s) gera nova tentativa."
                    }
                }
            }
        },
        "envelope.canceled": {
            "post": {
                "operationId": "webhookEnvelopeCanceled",
                "summary": "envelope.canceled",
                "description": "O remetente cancelou o envio (pelo painel ou pela API).\n\nConfigure o endereço (https público) em *Integrações*. Enviamos `POST` com JSON e os cabeçalhos:\n\n- `X-AssineBom-Event`: nome do evento;\n- `X-AssineBom-Delivery`: id único da entrega;\n- `X-AssineBom-Signature`: `t=<unix>,v1=<hex>`, onde `v1 = HMAC-SHA256(\"<t>.<corpo bruto>\", segredo)`.\n\nResponda `2xx` em até 10 segundos. Sem sucesso, tentamos de novo em 1, 5, 15, 60, 180, 360 e 720 minutos (8 tentativas, cerca de 22 horas). Eventos podem chegar repetidos ou fora de ordem: use `id` para deduplicar e consulte `GET /documents/{id}` se precisar do estado atual.",
                "security": [],
                "parameters": [
                    {
                        "name": "X-AssineBom-Event",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "const": "envelope.canceled"
                        }
                    },
                    {
                        "name": "X-AssineBom-Delivery",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "X-AssineBom-Signature",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "example": "t=1760360000,v1=5d41402abc4b2a76b9719d911017c592..."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/WebhookEvent"
                            }
                        }
                    }
                },
                "responses": {
                    "2XX": {
                        "description": "Recebido. Qualquer outro status (ou demora acima de 10 s) gera nova tentativa."
                    }
                }
            }
        }
    },
    "components": {
        "securitySchemes": {
            "bearerAuth": {
                "type": "http",
                "scheme": "bearer",
                "bearerFormat": "ab_...",
                "description": "Chave criada em Integrações. Exemplo: `Authorization: Bearer ab_3f9c...`"
            }
        },
        "parameters": {
            "DocumentId": {
                "name": "id",
                "in": "path",
                "required": true,
                "description": "Campo `id` (UUID) do documento.",
                "schema": {
                    "type": "string",
                    "format": "uuid"
                },
                "example": "8bcda92e-7ce9-4517-b4d6-ee7ce2c880ed"
            }
        },
        "responses": {
            "Unauthorized": {
                "description": "Chave ausente, inválida ou revogada.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Message"
                        },
                        "example": {
                            "message": "Chave de API inválida ou revogada."
                        }
                    }
                }
            },
            "NotFound": {
                "description": "Não existe ou pertence a outra conta.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Message"
                        }
                    }
                }
            },
            "Conflict": {
                "description": "A ação não vale para a situação atual do documento.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Message"
                        },
                        "example": {
                            "message": "Só é possível cancelar documentos em andamento."
                        }
                    }
                }
            },
            "ValidationError": {
                "description": "Campos inválidos. `errors` traz as mensagens por campo.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/ValidationError"
                        },
                        "example": {
                            "message": "CPF inválido. (and 1 more error)",
                            "errors": {
                                "signers.0.cpf": [
                                    "CPF inválido."
                                ],
                                "signers.1.email": [
                                    "Este e-mail já está na lista de assinantes."
                                ]
                            }
                        }
                    }
                }
            },
            "TooManyRequests": {
                "description": "Limite de requisições atingido. Aguarde o tempo do cabeçalho `Retry-After`.",
                "headers": {
                    "Retry-After": {
                        "schema": {
                            "type": "integer"
                        },
                        "description": "Segundos até liberar."
                    }
                }
            }
        },
        "schemas": {
            "DocumentStatus": {
                "type": "string",
                "enum": [
                    "in_progress",
                    "completed",
                    "declined",
                    "canceled",
                    "expired"
                ],
                "description": "`in_progress` aguardando assinaturas; `completed` todos assinaram; `declined` alguém recusou; `canceled` cancelado pelo remetente; `expired` prazo vencido."
            },
            "AuthMethod": {
                "type": "string",
                "enum": [
                    "simple",
                    "email_token",
                    "icp"
                ],
                "default": "email_token",
                "description": "`email_token`: código de 6 dígitos por e-mail (recomendado). `simple`: e-mail + CPF. `icp`: certificado digital ICP-Brasil A1 do próprio assinante."
            },
            "Placement": {
                "type": "object",
                "required": [
                    "page",
                    "x",
                    "y",
                    "w",
                    "h"
                ],
                "description": "Retângulo em frações da página, com origem no canto superior esquerdo. Ex.: `x: 0.5` é o meio da largura. `kind: rubric` é a rubrica (iniciais); o padrão é a assinatura completa.",
                "properties": {
                    "page": {
                        "type": "integer",
                        "minimum": 1,
                        "example": 2
                    },
                    "x": {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1,
                        "example": 0.5500000000000000444089209850062616169452667236328125
                    },
                    "y": {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1,
                        "example": 0.7800000000000000266453525910037569701671600341796875
                    },
                    "w": {
                        "type": "number",
                        "minimum": 0.05000000000000000277555756156289135105907917022705078125,
                        "maximum": 1,
                        "example": 0.299999999999999988897769753748434595763683319091796875
                    },
                    "h": {
                        "type": "number",
                        "minimum": 0.0200000000000000004163336342344337026588618755340576171875,
                        "maximum": 1,
                        "example": 0.07499999999999999722444243843710864894092082977294921875
                    },
                    "kind": {
                        "type": "string",
                        "enum": [
                            "signature",
                            "rubric"
                        ],
                        "default": "signature"
                    }
                }
            },
            "SignerRole": {
                "type": "string",
                "enum": [
                    "signer",
                    "contratante",
                    "contratada",
                    "testemunha",
                    "fiador",
                    "avalista",
                    "representante",
                    "aprovador"
                ],
                "default": "signer",
                "description": "Papel de quem assina; sai no carimbo, no convite e no manifesto. `signer`: Parte; `contratante`: Contratante; `contratada`: Contratada; `testemunha`: Testemunha; `fiador`: Fiador; `avalista`: Avalista; `representante`: Representante legal; `aprovador`: Aprovador."
            },
            "CopyRecipient": {
                "type": "object",
                "required": [
                    "email"
                ],
                "properties": {
                    "name": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "maxLength": 160,
                        "example": "Departamento Jurídico"
                    },
                    "email": {
                        "type": "string",
                        "format": "email",
                        "maxLength": 190,
                        "example": "juridico@exemplo.com.br"
                    }
                }
            },
            "SignerInput": {
                "type": "object",
                "required": [
                    "name",
                    "email"
                ],
                "properties": {
                    "name": {
                        "type": "string",
                        "maxLength": 160,
                        "example": "Maria Souza"
                    },
                    "email": {
                        "type": "string",
                        "format": "email",
                        "maxLength": 190,
                        "description": "Recebe o convite, o código (em `email_token`) e a via final. Não pode repetir no mesmo documento.",
                        "example": "maria@exemplo.com.br"
                    },
                    "phone": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "maxLength": 25,
                        "description": "WhatsApp com DDD (10 a 13 dígitos; sem DDI assume +55). Só para você mandar o `sign_url`: não enviamos mensagens.",
                        "example": "11912345678"
                    },
                    "cpf": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Opcional. Se informado, o assinante precisa digitar o mesmo CPF.",
                        "example": "123.456.789-09"
                    },
                    "role": {
                        "$ref": "#/components/schemas/SignerRole"
                    },
                    "auth_method": {
                        "$ref": "#/components/schemas/AuthMethod"
                    },
                    "require_photo": {
                        "type": "boolean",
                        "default": false,
                        "description": "Exige selfie e foto do RG/CNH antes de assinar."
                    },
                    "placements": {
                        "type": "array",
                        "maxItems": 40,
                        "items": {
                            "$ref": "#/components/schemas/Placement"
                        },
                        "description": "Onde a assinatura ou a rubrica é desenhada no PDF. `kind` é `signature` (padrão) ou `rubric`. Sem posições, a assinatura aparece só no manifesto ao final."
                    }
                }
            },
            "CreateDocumentJson": {
                "type": "object",
                "required": [
                    "signers"
                ],
                "properties": {
                    "title": {
                        "type": "string",
                        "maxLength": 200,
                        "description": "Obrigatório, exceto com `template_id` (usa o título do modelo).",
                        "example": "Contrato de prestação de serviços"
                    },
                    "message": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "maxLength": 2000,
                        "description": "Aparece no e-mail e na tela de assinatura."
                    },
                    "external_ref": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "maxLength": 120,
                        "description": "Seu identificador (pedido, contrato). Volta nas consultas e nos webhooks.",
                        "example": "pedido-123"
                    },
                    "sequential": {
                        "type": "boolean",
                        "default": false,
                        "description": "Assinatura em ordem: cada pessoa só é convidada depois que a anterior assinar."
                    },
                    "template_id": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "Usa o arquivo, os papéis e as posições de um modelo (veja `GET /templates`)."
                    },
                    "signers": {
                        "type": "array",
                        "minItems": 1,
                        "maxItems": 20,
                        "items": {
                            "$ref": "#/components/schemas/SignerInput"
                        }
                    },
                    "cc": {
                        "type": "array",
                        "maxItems": 10,
                        "description": "Pessoas que não assinam, mas recebem por e-mail a via final (PDF anexo + link). E-mails de assinantes são ignorados aqui.",
                        "items": {
                            "$ref": "#/components/schemas/CopyRecipient"
                        }
                    },
                    "file_base64": {
                        "type": "string",
                        "contentEncoding": "base64",
                        "description": "PDF ou .docx em base64 (aceita prefixo `data:...;base64,`). Até 20 MB."
                    },
                    "file_name": {
                        "type": "string",
                        "maxLength": 200,
                        "example": "contrato.pdf"
                    }
                }
            },
            "CreateDocumentMultipart": {
                "type": "object",
                "required": [
                    "signers"
                ],
                "description": "Campos de lista no formato `signers[0][name]`, `signers[0][placements][0][page]`, etc.",
                "properties": {
                    "title": {
                        "type": "string",
                        "maxLength": 200,
                        "description": "Obrigatório, exceto com `template_id` (usa o título do modelo).",
                        "example": "Contrato de prestação de serviços"
                    },
                    "message": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "maxLength": 2000,
                        "description": "Aparece no e-mail e na tela de assinatura."
                    },
                    "external_ref": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "maxLength": 120,
                        "description": "Seu identificador (pedido, contrato). Volta nas consultas e nos webhooks.",
                        "example": "pedido-123"
                    },
                    "sequential": {
                        "type": "boolean",
                        "default": false,
                        "description": "Assinatura em ordem: cada pessoa só é convidada depois que a anterior assinar."
                    },
                    "template_id": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "Usa o arquivo, os papéis e as posições de um modelo (veja `GET /templates`)."
                    },
                    "signers": {
                        "type": "array",
                        "minItems": 1,
                        "maxItems": 20,
                        "items": {
                            "$ref": "#/components/schemas/SignerInput"
                        }
                    },
                    "cc": {
                        "type": "array",
                        "maxItems": 10,
                        "description": "Pessoas que não assinam, mas recebem por e-mail a via final (PDF anexo + link). E-mails de assinantes são ignorados aqui.",
                        "items": {
                            "$ref": "#/components/schemas/CopyRecipient"
                        }
                    },
                    "file": {
                        "type": "string",
                        "contentMediaType": "application/octet-stream",
                        "description": "PDF ou Word .docx, até 20 MB."
                    }
                }
            },
            "Signer": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer",
                        "example": 42
                    },
                    "position": {
                        "type": "integer",
                        "description": "Ordem do assinante (1, 2, ...).",
                        "example": 1
                    },
                    "name": {
                        "type": "string",
                        "example": "Maria Souza"
                    },
                    "email": {
                        "type": "string",
                        "format": "email",
                        "example": "maria@exemplo.com.br"
                    },
                    "role": {
                        "$ref": "#/components/schemas/SignerRole"
                    },
                    "auth_method": {
                        "$ref": "#/components/schemas/AuthMethod"
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "pending",
                            "signed",
                            "declined"
                        ]
                    },
                    "signed_name": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Nome confirmado pela pessoa ao assinar."
                    },
                    "signed_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "location": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "description": "Geolocalização do momento da assinatura, obrigatória para assinar. Nula enquanto a pessoa não assinou.",
                        "properties": {
                            "latitude": {
                                "type": "number",
                                "example": -23.55051999999999878809830988757312297821044921875
                            },
                            "longitude": {
                                "type": "number",
                                "example": -46.63331000000000159388946485705673694610595703125
                            },
                            "accuracy_m": {
                                "type": [
                                    "integer",
                                    "null"
                                ],
                                "description": "Raio de precisão informado pelo aparelho, em metros.",
                                "example": 18
                            },
                            "map_url": {
                                "type": "string",
                                "format": "uri",
                                "example": "https://www.google.com/maps?q=-23.550520,-46.633310"
                            }
                        }
                    },
                    "declined_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "decline_reason": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                }
            },
            "SignerDetail": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/Signer"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "invited": {
                                "type": "boolean",
                                "description": "O convite por e-mail foi aceito pelo servidor de e-mail."
                            },
                            "invited_at": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "format": "date-time"
                            },
                            "phone": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "description": "WhatsApp em formato internacional, só dígitos.",
                                "example": "5511912345678"
                            },
                            "sign_url": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "format": "uri",
                                "description": "Link pessoal de assinatura. Só aparece enquanto a pessoa pode assinar (pendente e na vez dela). Não exponha publicamente."
                            }
                        }
                    }
                ]
            },
            "Document": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid",
                        "example": "8bcda92e-7ce9-4517-b4d6-ee7ce2c880ed"
                    },
                    "code": {
                        "type": "string",
                        "description": "Código de validação impresso no PDF.",
                        "example": "AB-L9HN-A7BY-RF9H"
                    },
                    "title": {
                        "type": "string",
                        "example": "Contrato de prestação de serviços"
                    },
                    "status": {
                        "$ref": "#/components/schemas/DocumentStatus"
                    },
                    "external_ref": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "example": "pedido-123"
                    },
                    "source": {
                        "type": "string",
                        "enum": [
                            "web",
                            "api",
                            "batch"
                        ],
                        "description": "Por onde o documento foi enviado."
                    },
                    "sequential": {
                        "type": "boolean"
                    },
                    "pages": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "example": 3
                    },
                    "original_sha256": {
                        "type": "string",
                        "description": "Hash do arquivo enviado."
                    },
                    "final_sha256": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Hash da via final lacrada."
                    },
                    "finalized": {
                        "type": "boolean",
                        "description": "A via final assinada já pode ser baixada."
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "expires_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "Prazo para assinar."
                    },
                    "completed_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "canceled_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "validate_url": {
                        "type": "string",
                        "format": "uri",
                        "description": "Página pública de validação."
                    },
                    "signers": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Signer"
                        }
                    }
                }
            },
            "DocumentDetail": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/Document"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "signers": {
                                "type": "array",
                                "items": {
                                    "$ref": "#/components/schemas/SignerDetail"
                                }
                            },
                            "download": {
                                "type": "object",
                                "properties": {
                                    "original": {
                                        "type": "string",
                                        "format": "uri"
                                    },
                                    "final": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "format": "uri",
                                        "description": "`null` até a via final ser gerada."
                                    }
                                }
                            }
                        }
                    }
                ]
            },
            "Template": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer",
                        "example": 7
                    },
                    "name": {
                        "type": "string",
                        "example": "Locação residencial"
                    },
                    "title": {
                        "type": "string",
                        "example": "Contrato de locação"
                    },
                    "pages": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "signers": {
                        "type": "array",
                        "description": "Papéis, na ordem em que os assinantes devem ser enviados.",
                        "items": {
                            "type": "object",
                            "properties": {
                                "label": {
                                    "type": "string",
                                    "example": "Locador"
                                },
                                "auth_method": {
                                    "$ref": "#/components/schemas/AuthMethod"
                                },
                                "require_photo": {
                                    "type": "boolean"
                                }
                            }
                        }
                    }
                }
            },
            "PageMeta": {
                "type": "object",
                "properties": {
                    "current_page": {
                        "type": "integer"
                    },
                    "last_page": {
                        "type": "integer"
                    },
                    "per_page": {
                        "type": "integer"
                    },
                    "total": {
                        "type": "integer"
                    }
                }
            },
            "Message": {
                "type": "object",
                "required": [
                    "message"
                ],
                "properties": {
                    "message": {
                        "type": "string"
                    }
                }
            },
            "ValidationError": {
                "type": "object",
                "required": [
                    "message",
                    "errors"
                ],
                "properties": {
                    "message": {
                        "type": "string"
                    },
                    "errors": {
                        "type": "object",
                        "additionalProperties": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            }
                        }
                    }
                }
            },
            "WebhookEvent": {
                "type": "object",
                "required": [
                    "id",
                    "event",
                    "created_at",
                    "data"
                ],
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "Identificador da entrega (igual ao cabeçalho `X-AssineBom-Delivery`). Use para ignorar repetições."
                    },
                    "event": {
                        "type": "string",
                        "enum": [
                            "signer.signed",
                            "envelope.completed",
                            "envelope.declined",
                            "envelope.canceled",
                            "ping"
                        ]
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "data": {
                        "type": "object",
                        "properties": {
                            "document": {
                                "$ref": "#/components/schemas/Document"
                            },
                            "signer": {
                                "oneOf": [
                                    {
                                        "$ref": "#/components/schemas/Signer"
                                    },
                                    {
                                        "type": "null"
                                    }
                                ],
                                "description": "Quem assinou ou recusou (`signer.signed`, `envelope.declined`)."
                            }
                        }
                    }
                }
            }
        }
    }
}