{
  "openapi": "3.1.0",
  "info": {
    "title": "API da CartaFlow",
    "version": "1.0.0",
    "summary": "Envio automático de correspondências físicas para todo o Brasil.",
    "description": "A API da CartaFlow imprime, envelopa e posta correspondências pelos Correios para qualquer endereço do Brasil, como carta simples ou registrada, e verifica endereços físicos com uma correspondência com código. Toda requisição usa JSON e uma chave de API no cabeçalho Authorization.",
    "contact": {
      "name": "CartaFlow",
      "url": "https://www.cartaflow.com.br"
    }
  },
  "servers": [
    {
      "url": "https://api.cartaflow.com.br/v1",
      "description": "API da CartaFlow."
    }
  ],
  "security": [
    {
      "apiKey": []
    }
  ],
  "tags": [
    {
      "name": "letters",
      "x-displayName": "Correspondências",
      "description": "Envie PDFs para impressão e postagem, acompanhe o status e calcule o preço."
    },
    {
      "name": "uploads",
      "x-displayName": "Uploads de PDF",
      "description": "Envie PDFs grandes, de até 10 MB, em duas etapas, antes de criar a correspondência."
    },
    {
      "name": "verifications",
      "x-displayName": "Verificações de endereço",
      "description": "Confirme que uma pessoa recebe correspondência no endereço que informou."
    },
    {
      "name": "postal_codes",
      "x-displayName": "CEP",
      "description": "Consulte o endereço de um CEP."
    },
    {
      "name": "account",
      "x-displayName": "Conta e saldo",
      "description": "Dados da conta, saldo e movimentações."
    },
    {
      "name": "events",
      "x-displayName": "Eventos",
      "description": "Os eventos dos últimos 30 dias."
    },
    {
      "name": "webhooks",
      "x-displayName": "Webhooks",
      "description": "O que a CartaFlow envia para o seu servidor."
    }
  ],
  "paths": {
    "/letters": {
      "post": {
        "operationId": "createLetter",
        "tags": [
          "letters"
        ],
        "summary": "Criar uma correspondência",
        "description": "Envia um documento para impressão e postagem. A CartaFlow confere o endereço e o documento, debita o preço do seu saldo e devolve a correspondência com status `received`. Se algo estiver errado, nada é criado nem cobrado, e a resposta 422 lista todos os problemas de uma vez.\n\nEnvie o PDF de uma destas formas:\n\n| Forma | Como | PDF de até |\n| --- | --- | --- |\n| Arquivo na requisição | multipart/form-data, com o PDF no campo `file` e os outros campos junto | 4 MB |\n| Por URL | JSON, `document.type: url`: baixamos o PDF na hora | 10 MB |\n| Upload em duas etapas | POST /v1/uploads, PUT do arquivo no `upload_url` e JSON com `document.type: upload` | 10 MB |\n| Base64 | JSON, `document.type: base64`: o PDF dentro do JSON | 3 MB |\n\nO corpo da requisição tem até 4,5 MB. Para PDFs maiores que 4 MB, use URL ou o upload em duas etapas.\n\nPara enviar o arquivo junto com os dados, troque o formato do corpo para multipart/form-data:\n\n```bash\ncurl https://api.cartaflow.com.br/v1/letters \\\n  -H \"Authorization: Bearer $CARTAFLOW_API_KEY\" \\\n  -F \"file=@fatura-outubro.pdf\" \\\n  -F \"to[name]=Destinatário Exemplo\" \\\n  -F \"to[postal_code]=01001-000\" \\\n  -F \"to[number]=128\" \\\n  -F \"color=true\"\n```\n\nUm PDF também pode ter marcações como `{{nome}}`: envie os valores em `variables` e nós escrevemos cada um no lugar da sua marcação.\n\nNo endereço, só `name`, `postal_code` e `number` são obrigatórios: o resto é preenchido a partir do CEP quando você não envia.\n\nPara enviar como carta registrada, com código de rastreio dos Correios, envie `postal_services` com `registered`. O aviso de recebimento (`return_receipt`) e a mão própria (`restricted_delivery`) vão junto com o registro. Cada serviço tem acréscimo no preço.\n\nPara agendar, envie `send_date`. A correspondência agendada é validada agora, fica em `scheduled` e só é cobrada na data do envio, quando o saldo precisa cobrir o preço.\n\nEnvie sempre o cabeçalho `Idempotency-Key`, por exemplo com o id da fatura. Se a conexão cair e você repetir a chamada, a API devolve a mesma correspondência em vez de criar outra.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Dois formatos, com os mesmos campos: **application/json**, com o PDF em `document` (URL, upload em duas etapas ou base64), ou **multipart/form-data**, com o arquivo do PDF no campo `file` (até 4 MB). Troque o formato no seletor do quadro abaixo.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateLetterRequest"
              },
              "examples": {
                "pdf_url": {
                  "summary": "PDF por URL",
                  "value": {
                    "to": {
                      "name": "Destinatário Exemplo",
                      "postal_code": "01001-000",
                      "number": "128",
                      "complement": "Ap. 52"
                    },
                    "document": {
                      "type": "url",
                      "url": "https://arquivos.exemplo.com.br/faturas/2026-10-0042.pdf"
                    },
                    "color": true,
                    "reference": "fatura-2026-10-0042",
                    "metadata": {
                      "customer_id": "1842"
                    }
                  }
                },
                "pdf_upload": {
                  "summary": "PDF enviado com POST /v1/uploads",
                  "value": {
                    "to": {
                      "name": "Destinatário Exemplo",
                      "postal_code": "01001-000",
                      "number": "128",
                      "complement": "Ap. 52"
                    },
                    "document": {
                      "type": "upload",
                      "upload_id": "upl_6Np3Vx8Rk2Tq"
                    },
                    "reference": "fatura-2026-10-0042"
                  }
                },
                "registered": {
                  "summary": "Carta registrada com AR",
                  "value": {
                    "to": {
                      "name": "Destinatário Exemplo",
                      "postal_code": "01001-000",
                      "number": "128",
                      "complement": "Ap. 52"
                    },
                    "document": {
                      "type": "upload",
                      "upload_id": "upl_2Hc7Tm4Zq9Lw"
                    },
                    "postal_services": [
                      "registered",
                      "return_receipt"
                    ],
                    "reference": "contrato-5531"
                  }
                },
                "pdf_base64": {
                  "summary": "PDF em base64",
                  "value": {
                    "to": {
                      "name": "Destinatário Exemplo",
                      "postal_code": "01001-000",
                      "number": "128",
                      "complement": "Ap. 52"
                    },
                    "document": {
                      "type": "base64",
                      "data": "JVBERi0xLjcKJcfsj6IKNSAwIG9iago8PC9MZW5ndGggNiAwIFI..."
                    },
                    "double_sided": true,
                    "reference": "contrato-5531"
                  }
                },
                "scheduled": {
                  "summary": "Agendada para uma data",
                  "value": {
                    "to": {
                      "name": "Destinatário Exemplo",
                      "postal_code": "01001-000",
                      "number": "128",
                      "complement": "Ap. 52"
                    },
                    "document": {
                      "type": "url",
                      "url": "https://arquivos.exemplo.com.br/lembretes/revisao-2291.pdf"
                    },
                    "send_date": "2026-10-20",
                    "reference": "lembrete-revisao-2291"
                  }
                },
                "full_address": {
                  "summary": "Endereço completo",
                  "value": {
                    "to": {
                      "name": "Destinatário Exemplo",
                      "street": "Praça da Sé",
                      "number": "128",
                      "complement": "Ap. 52",
                      "neighborhood": "Sé",
                      "city": "São Paulo",
                      "state": "SP",
                      "postal_code": "01001-000"
                    },
                    "document": {
                      "type": "url",
                      "url": "https://arquivos.exemplo.com.br/faturas/2026-10-0042.pdf"
                    },
                    "color": true,
                    "reference": "fatura-2026-10-0042"
                  }
                },
                "pdf_variables": {
                  "summary": "PDF com variáveis",
                  "value": {
                    "to": {
                      "name": "Destinatário Exemplo",
                      "postal_code": "01001-000",
                      "number": "128",
                      "complement": "Ap. 52"
                    },
                    "document": {
                      "type": "url",
                      "url": "https://arquivos.exemplo.com.br/cobrancas/aviso-cobranca.pdf",
                      "variables": {
                        "nome": "Destinatário Exemplo",
                        "valor": "R$ 189,90",
                        "vencimento": "20/10/2026"
                      }
                    },
                    "reference": "cobranca-8841"
                  }
                }
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/CreateLetterUpload"
              },
              "example": {
                "file": "fatura-outubro.pdf",
                "to": {
                  "name": "Destinatário Exemplo",
                  "postal_code": "01001-000",
                  "number": "128",
                  "complement": "Ap. 52"
                },
                "color": true,
                "reference": "fatura-2026-10-0042"
              },
              "encoding": {
                "file": {
                  "contentType": "application/pdf"
                },
                "to": {
                  "style": "deepObject",
                  "explode": true
                },
                "from": {
                  "style": "deepObject",
                  "explode": true
                },
                "variables": {
                  "style": "deepObject",
                  "explode": true
                },
                "metadata": {
                  "style": "deepObject",
                  "explode": true
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "A correspondência foi criada. Status `received` (já cobrada) ou `scheduled` (agendada, cobrada na data do envio).",
            "headers": {
              "Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Letter"
                },
                "examples": {
                  "received": {
                    "summary": "Enviada na hora",
                    "value": {
                      "id": "ltr_8Kq2wX4mN7pR",
                      "object": "letter",
                      "status": "received",
                      "to": {
                        "name": "Destinatário Exemplo",
                        "street": "Praça da Sé",
                        "number": "128",
                        "complement": "Ap. 52",
                        "neighborhood": "Sé",
                        "city": "São Paulo",
                        "state": "SP",
                        "postal_code": "01001-000"
                      },
                      "from": {
                        "name": "Exemplo Serviços Ltda.",
                        "street": "Avenida Exemplo",
                        "number": "1000",
                        "complement": "Sala 301",
                        "neighborhood": "Bela Vista",
                        "city": "São Paulo",
                        "state": "SP",
                        "postal_code": "01310-100"
                      },
                      "document": {
                        "type": "url",
                        "url": "https://arquivos.exemplo.com.br/faturas/2026-10-0042.pdf",
                        "variables": null
                      },
                      "color": true,
                      "double_sided": false,
                      "address_placement": "first_page",
                      "postal_services": [],
                      "pages": 2,
                      "sheets": 2,
                      "price": {
                        "currency": "BRL",
                        "total": 1135,
                        "items": [
                          {
                            "type": "base",
                            "quantity": 1,
                            "unit_amount": 990,
                            "amount": 990
                          },
                          {
                            "type": "additional_sheets",
                            "quantity": 1,
                            "unit_amount": 75,
                            "amount": 75
                          },
                          {
                            "type": "color",
                            "quantity": 2,
                            "unit_amount": 35,
                            "amount": 70
                          }
                        ]
                      },
                      "send_date": null,
                      "cancellation_reason": null,
                      "failure_reason": null,
                      "tracking_code": null,
                      "preview_url": "https://files.cartaflow.com.br/previews/ltr_8Kq2wX4mN7pR.pdf?expires=1760369400&signature=9c1f2a7d",
                      "reference": "fatura-2026-10-0042",
                      "metadata": {
                        "customer_id": "1842"
                      },
                      "status_transitions": {
                        "received_at": "2026-10-13T14:20:00Z",
                        "in_production_at": null,
                        "printed_at": null,
                        "posted_at": null,
                        "canceled_at": null,
                        "failed_at": null
                      },
                      "created_at": "2026-10-13T14:20:00Z"
                    }
                  },
                  "registered": {
                    "summary": "Carta registrada com AR",
                    "value": {
                      "id": "ltr_3Wb6Jn9Pd4Ys",
                      "object": "letter",
                      "status": "received",
                      "to": {
                        "name": "Destinatário Exemplo",
                        "street": "Praça da Sé",
                        "number": "128",
                        "complement": "Ap. 52",
                        "neighborhood": "Sé",
                        "city": "São Paulo",
                        "state": "SP",
                        "postal_code": "01001-000"
                      },
                      "from": {
                        "name": "Exemplo Serviços Ltda.",
                        "street": "Avenida Exemplo",
                        "number": "1000",
                        "complement": "Sala 301",
                        "neighborhood": "Bela Vista",
                        "city": "São Paulo",
                        "state": "SP",
                        "postal_code": "01310-100"
                      },
                      "document": {
                        "type": "upload",
                        "filename": "notificacao-contrato-5531.pdf",
                        "variables": null
                      },
                      "color": false,
                      "double_sided": false,
                      "address_placement": "first_page",
                      "postal_services": [
                        "registered",
                        "return_receipt"
                      ],
                      "pages": 1,
                      "sheets": 1,
                      "price": {
                        "currency": "BRL",
                        "total": 3340,
                        "items": [
                          {
                            "type": "base",
                            "quantity": 1,
                            "unit_amount": 990,
                            "amount": 990
                          },
                          {
                            "type": "registered",
                            "quantity": 1,
                            "unit_amount": 1175,
                            "amount": 1175
                          },
                          {
                            "type": "return_receipt",
                            "quantity": 1,
                            "unit_amount": 1175,
                            "amount": 1175
                          }
                        ]
                      },
                      "send_date": null,
                      "cancellation_reason": null,
                      "failure_reason": null,
                      "tracking_code": null,
                      "preview_url": "https://files.cartaflow.com.br/previews/ltr_3Wb6Jn9Pd4Ys.pdf?expires=1760369400&signature=7e3b90a4",
                      "reference": "contrato-5531",
                      "metadata": {},
                      "status_transitions": {
                        "received_at": "2026-10-13T14:20:00Z",
                        "in_production_at": null,
                        "printed_at": null,
                        "posted_at": null,
                        "canceled_at": null,
                        "failed_at": null
                      },
                      "created_at": "2026-10-13T14:20:00Z"
                    }
                  },
                  "scheduled": {
                    "summary": "Agendada",
                    "value": {
                      "id": "ltr_5Mz8Tc1Wq6Nv",
                      "object": "letter",
                      "status": "scheduled",
                      "to": {
                        "name": "Destinatário Exemplo",
                        "street": "Praça da Sé",
                        "number": "128",
                        "complement": "Ap. 52",
                        "neighborhood": "Sé",
                        "city": "São Paulo",
                        "state": "SP",
                        "postal_code": "01001-000"
                      },
                      "from": {
                        "name": "Exemplo Serviços Ltda.",
                        "street": "Avenida Exemplo",
                        "number": "1000",
                        "complement": "Sala 301",
                        "neighborhood": "Bela Vista",
                        "city": "São Paulo",
                        "state": "SP",
                        "postal_code": "01310-100"
                      },
                      "document": {
                        "type": "url",
                        "url": "https://arquivos.exemplo.com.br/faturas/2026-10-0042.pdf",
                        "variables": null
                      },
                      "color": true,
                      "double_sided": false,
                      "address_placement": "first_page",
                      "postal_services": [],
                      "pages": 2,
                      "sheets": 2,
                      "price": {
                        "currency": "BRL",
                        "total": 1135,
                        "items": [
                          {
                            "type": "base",
                            "quantity": 1,
                            "unit_amount": 990,
                            "amount": 990
                          },
                          {
                            "type": "additional_sheets",
                            "quantity": 1,
                            "unit_amount": 75,
                            "amount": 75
                          },
                          {
                            "type": "color",
                            "quantity": 2,
                            "unit_amount": 35,
                            "amount": 70
                          }
                        ]
                      },
                      "send_date": "2026-10-20",
                      "cancellation_reason": null,
                      "failure_reason": null,
                      "tracking_code": null,
                      "preview_url": "https://files.cartaflow.com.br/previews/ltr_8Kq2wX4mN7pR.pdf?expires=1760369400&signature=9c1f2a7d",
                      "reference": "lembrete-revisao-2291",
                      "metadata": {},
                      "status_transitions": {
                        "received_at": null,
                        "in_production_at": null,
                        "printed_at": null,
                        "posted_at": null,
                        "canceled_at": null,
                        "failed_at": null
                      },
                      "created_at": "2026-10-13T14:20:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "O saldo não cobre o preço de uma correspondência enviada na hora. Nada foi criado. Correspondências agendadas com `send_date` não precisam de saldo na criação.",
            "headers": {
              "Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "billing_error",
                    "code": "insufficient_balance",
                    "message": "O saldo disponível (R$ 4,10) não cobre este envio (R$ 11,35). Recarregue o saldo no painel.",
                    "request_id": "req_9Vb4Xk2Lq8Mz",
                    "doc_url": "https://docs.cartaflow.com.br/errors#insufficient_balance",
                    "details": null
                  }
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/IdempotencyConflict"
          },
          "413": {
            "$ref": "#/components/responses/RequestTooLarge"
          },
          "422": {
            "description": "Um ou mais campos têm problemas. Nada foi criado nem cobrado.",
            "headers": {
              "Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "validation_error",
                    "code": "invalid_parameters",
                    "message": "3 campos têm problemas. Veja details.",
                    "request_id": "req_9Vb4Xk2Lq8Mz",
                    "doc_url": "https://docs.cartaflow.com.br/errors#invalid_parameters",
                    "details": [
                      {
                        "param": "to.postal_code",
                        "code": "postal_code_not_found",
                        "message": "Não encontramos o CEP 01001-999. Confira os 8 dígitos."
                      },
                      {
                        "param": "document.url",
                        "code": "address_area_not_blank",
                        "message": "Há conteúdo na área do endereço da primeira página. Deixe a área em branco ou use address_placement: extra_page."
                      },
                      {
                        "param": "postal_services",
                        "code": "requires_registered",
                        "message": "return_receipt só funciona com registered. Inclua registered em postal_services."
                      }
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "get": {
        "operationId": "listLetters",
        "tags": [
          "letters"
        ],
        "summary": "Listar correspondências",
        "description": "Devolve as correspondências da conta, da mais recente para a mais antiga, em páginas. Use os filtros para encontrar, por exemplo, todas as correspondências postadas em outubro, as que falharam ou a correspondência de uma fatura.",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "scheduled",
                "received",
                "in_production",
                "printed",
                "posted",
                "canceled",
                "failed"
              ],
              "description": "Só itens neste status.\n\n**Valores possíveis**\n\n- `scheduled`: A correspondência foi validada e espera a data de `send_date`. Ainda não foi cobrada. Na data, às 06:00 de Brasília, a CartaFlow debita o saldo e a correspondência passa para `received`. Se o saldo não cobrir o preço, ela vai para `canceled`. Pode ser cancelada sem custo.\n- `received`: A CartaFlow validou o documento e o endereço, cobrou o envio do seu saldo e colocou a correspondência na fila de produção. Ainda pode ser cancelada, e o valor volta para o saldo.\n- `in_production`: A correspondência entrou em um lote de impressão. A partir daqui ela não pode mais ser cancelada.\n- `printed`: A correspondência foi impressa, dobrada e colocada no envelope. O próximo passo é a postagem.\n- `posted`: A correspondência foi entregue aos Correios. A partir daqui a entrega segue o serviço postal, e a CartaFlow não recebe novas informações sobre ela. Uma correspondência registrada traz o código de rastreio dos Correios em `tracking_code`.\n- `canceled`: O envio foi cancelado antes da produção e nada foi impresso. `cancellation_reason` diz o motivo: você cancelou, ou o saldo não cobria uma correspondência agendada na data do envio. Se havia cobrança, o valor voltou para o saldo.\n- `failed`: Algo deu errado na produção e a correspondência não será postada. `failure_reason` diz o motivo. O valor voltou para o saldo automaticamente.",
              "x-enumDescriptions": {
                "scheduled": "A correspondência foi validada e espera a data de `send_date`. Ainda não foi cobrada. Na data, às 06:00 de Brasília, a CartaFlow debita o saldo e a correspondência passa para `received`. Se o saldo não cobrir o preço, ela vai para `canceled`. Pode ser cancelada sem custo.",
                "received": "A CartaFlow validou o documento e o endereço, cobrou o envio do seu saldo e colocou a correspondência na fila de produção. Ainda pode ser cancelada, e o valor volta para o saldo.",
                "in_production": "A correspondência entrou em um lote de impressão. A partir daqui ela não pode mais ser cancelada.",
                "printed": "A correspondência foi impressa, dobrada e colocada no envelope. O próximo passo é a postagem.",
                "posted": "A correspondência foi entregue aos Correios. A partir daqui a entrega segue o serviço postal, e a CartaFlow não recebe novas informações sobre ela. Uma correspondência registrada traz o código de rastreio dos Correios em `tracking_code`.",
                "canceled": "O envio foi cancelado antes da produção e nada foi impresso. `cancellation_reason` diz o motivo: você cancelou, ou o saldo não cobria uma correspondência agendada na data do envio. Se havia cobrança, o valor voltou para o saldo.",
                "failed": "Algo deu errado na produção e a correspondência não será postada. `failure_reason` diz o motivo. O valor voltou para o saldo automaticamente."
              }
            },
            "description": "Só itens neste status."
          },
          {
            "$ref": "#/components/parameters/Reference"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/CreatedAfter"
          },
          {
            "$ref": "#/components/parameters/CreatedBefore"
          }
        ],
        "responses": {
          "200": {
            "description": "Uma página de correspondências.",
            "headers": {
              "Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LetterList"
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "id": "ltr_8Kq2wX4mN7pR",
                      "object": "letter",
                      "status": "posted",
                      "to": {
                        "name": "Destinatário Exemplo",
                        "street": "Praça da Sé",
                        "number": "128",
                        "complement": "Ap. 52",
                        "neighborhood": "Sé",
                        "city": "São Paulo",
                        "state": "SP",
                        "postal_code": "01001-000"
                      },
                      "from": {
                        "name": "Exemplo Serviços Ltda.",
                        "street": "Avenida Exemplo",
                        "number": "1000",
                        "complement": "Sala 301",
                        "neighborhood": "Bela Vista",
                        "city": "São Paulo",
                        "state": "SP",
                        "postal_code": "01310-100"
                      },
                      "document": {
                        "type": "url",
                        "url": "https://arquivos.exemplo.com.br/faturas/2026-10-0042.pdf",
                        "variables": null
                      },
                      "color": true,
                      "double_sided": false,
                      "address_placement": "first_page",
                      "postal_services": [],
                      "pages": 2,
                      "sheets": 2,
                      "price": {
                        "currency": "BRL",
                        "total": 1135,
                        "items": [
                          {
                            "type": "base",
                            "quantity": 1,
                            "unit_amount": 990,
                            "amount": 990
                          },
                          {
                            "type": "additional_sheets",
                            "quantity": 1,
                            "unit_amount": 75,
                            "amount": 75
                          },
                          {
                            "type": "color",
                            "quantity": 2,
                            "unit_amount": 35,
                            "amount": 70
                          }
                        ]
                      },
                      "send_date": null,
                      "cancellation_reason": null,
                      "failure_reason": null,
                      "tracking_code": null,
                      "preview_url": "https://files.cartaflow.com.br/previews/ltr_8Kq2wX4mN7pR.pdf?expires=1760369400&signature=9c1f2a7d",
                      "reference": "fatura-2026-10-0042",
                      "metadata": {
                        "customer_id": "1842"
                      },
                      "status_transitions": {
                        "received_at": "2026-10-13T14:20:00Z",
                        "in_production_at": "2026-10-13T21:00:00Z",
                        "printed_at": "2026-10-14T10:42:00Z",
                        "posted_at": "2026-10-14T16:05:00Z",
                        "canceled_at": null,
                        "failed_at": null
                      },
                      "created_at": "2026-10-13T14:20:00Z"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "422": {
            "description": "Um filtro tem valor inválido.",
            "headers": {
              "Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "validation_error",
                    "code": "invalid_parameters",
                    "message": "Um campo tem problema. Veja details.",
                    "request_id": "req_9Vb4Xk2Lq8Mz",
                    "doc_url": "https://docs.cartaflow.com.br/errors#invalid_parameters",
                    "details": [
                      {
                        "param": "status",
                        "code": "invalid_value",
                        "message": "Use um destes valores: scheduled, received, in_production, printed, posted, canceled, failed."
                      }
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/letters/{letter_id}": {
      "get": {
        "operationId": "getLetter",
        "tags": [
          "letters"
        ],
        "summary": "Consultar uma correspondência",
        "description": "Devolve a correspondência com o status atual e um link novo para o PDF em `preview_url`. Para acompanhar muitas correspondências, prefira os webhooks a consultar de tempos em tempos.",
        "parameters": [
          {
            "$ref": "#/components/parameters/LetterId"
          }
        ],
        "responses": {
          "200": {
            "description": "A correspondência.",
            "headers": {
              "Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Letter"
                },
                "examples": {
                  "posted": {
                    "summary": "Postada",
                    "value": {
                      "id": "ltr_8Kq2wX4mN7pR",
                      "object": "letter",
                      "status": "posted",
                      "to": {
                        "name": "Destinatário Exemplo",
                        "street": "Praça da Sé",
                        "number": "128",
                        "complement": "Ap. 52",
                        "neighborhood": "Sé",
                        "city": "São Paulo",
                        "state": "SP",
                        "postal_code": "01001-000"
                      },
                      "from": {
                        "name": "Exemplo Serviços Ltda.",
                        "street": "Avenida Exemplo",
                        "number": "1000",
                        "complement": "Sala 301",
                        "neighborhood": "Bela Vista",
                        "city": "São Paulo",
                        "state": "SP",
                        "postal_code": "01310-100"
                      },
                      "document": {
                        "type": "url",
                        "url": "https://arquivos.exemplo.com.br/faturas/2026-10-0042.pdf",
                        "variables": null
                      },
                      "color": true,
                      "double_sided": false,
                      "address_placement": "first_page",
                      "postal_services": [],
                      "pages": 2,
                      "sheets": 2,
                      "price": {
                        "currency": "BRL",
                        "total": 1135,
                        "items": [
                          {
                            "type": "base",
                            "quantity": 1,
                            "unit_amount": 990,
                            "amount": 990
                          },
                          {
                            "type": "additional_sheets",
                            "quantity": 1,
                            "unit_amount": 75,
                            "amount": 75
                          },
                          {
                            "type": "color",
                            "quantity": 2,
                            "unit_amount": 35,
                            "amount": 70
                          }
                        ]
                      },
                      "send_date": null,
                      "cancellation_reason": null,
                      "failure_reason": null,
                      "tracking_code": null,
                      "preview_url": "https://files.cartaflow.com.br/previews/ltr_8Kq2wX4mN7pR.pdf?expires=1760369400&signature=9c1f2a7d",
                      "reference": "fatura-2026-10-0042",
                      "metadata": {
                        "customer_id": "1842"
                      },
                      "status_transitions": {
                        "received_at": "2026-10-13T14:20:00Z",
                        "in_production_at": "2026-10-13T21:00:00Z",
                        "printed_at": "2026-10-14T10:42:00Z",
                        "posted_at": "2026-10-14T16:05:00Z",
                        "canceled_at": null,
                        "failed_at": null
                      },
                      "created_at": "2026-10-13T14:20:00Z"
                    }
                  },
                  "registered": {
                    "summary": "Carta registrada, postada, com código de rastreio",
                    "value": {
                      "id": "ltr_3Wb6Jn9Pd4Ys",
                      "object": "letter",
                      "status": "posted",
                      "to": {
                        "name": "Destinatário Exemplo",
                        "street": "Praça da Sé",
                        "number": "128",
                        "complement": "Ap. 52",
                        "neighborhood": "Sé",
                        "city": "São Paulo",
                        "state": "SP",
                        "postal_code": "01001-000"
                      },
                      "from": {
                        "name": "Exemplo Serviços Ltda.",
                        "street": "Avenida Exemplo",
                        "number": "1000",
                        "complement": "Sala 301",
                        "neighborhood": "Bela Vista",
                        "city": "São Paulo",
                        "state": "SP",
                        "postal_code": "01310-100"
                      },
                      "document": {
                        "type": "upload",
                        "filename": "notificacao-contrato-5531.pdf",
                        "variables": null
                      },
                      "color": false,
                      "double_sided": false,
                      "address_placement": "first_page",
                      "postal_services": [
                        "registered",
                        "return_receipt"
                      ],
                      "pages": 1,
                      "sheets": 1,
                      "price": {
                        "currency": "BRL",
                        "total": 3340,
                        "items": [
                          {
                            "type": "base",
                            "quantity": 1,
                            "unit_amount": 990,
                            "amount": 990
                          },
                          {
                            "type": "registered",
                            "quantity": 1,
                            "unit_amount": 1175,
                            "amount": 1175
                          },
                          {
                            "type": "return_receipt",
                            "quantity": 1,
                            "unit_amount": 1175,
                            "amount": 1175
                          }
                        ]
                      },
                      "send_date": null,
                      "cancellation_reason": null,
                      "failure_reason": null,
                      "tracking_code": "RA123456785BR",
                      "preview_url": "https://files.cartaflow.com.br/previews/ltr_3Wb6Jn9Pd4Ys.pdf?expires=1760369400&signature=7e3b90a4",
                      "reference": "contrato-5531",
                      "metadata": {},
                      "status_transitions": {
                        "received_at": "2026-10-13T14:20:00Z",
                        "in_production_at": "2026-10-13T21:00:00Z",
                        "printed_at": "2026-10-14T10:42:00Z",
                        "posted_at": "2026-10-14T16:05:00Z",
                        "canceled_at": null,
                        "failed_at": null
                      },
                      "created_at": "2026-10-13T14:20:00Z"
                    }
                  },
                  "failed": {
                    "summary": "Falhou na produção",
                    "value": {
                      "id": "ltr_8Kq2wX4mN7pR",
                      "object": "letter",
                      "status": "failed",
                      "to": {
                        "name": "Destinatário Exemplo",
                        "street": "Praça da Sé",
                        "number": "128",
                        "complement": "Ap. 52",
                        "neighborhood": "Sé",
                        "city": "São Paulo",
                        "state": "SP",
                        "postal_code": "01001-000"
                      },
                      "from": {
                        "name": "Exemplo Serviços Ltda.",
                        "street": "Avenida Exemplo",
                        "number": "1000",
                        "complement": "Sala 301",
                        "neighborhood": "Bela Vista",
                        "city": "São Paulo",
                        "state": "SP",
                        "postal_code": "01310-100"
                      },
                      "document": {
                        "type": "url",
                        "url": "https://arquivos.exemplo.com.br/faturas/2026-10-0042.pdf",
                        "variables": null
                      },
                      "color": true,
                      "double_sided": false,
                      "address_placement": "first_page",
                      "postal_services": [],
                      "pages": 2,
                      "sheets": 2,
                      "price": {
                        "currency": "BRL",
                        "total": 1135,
                        "items": [
                          {
                            "type": "base",
                            "quantity": 1,
                            "unit_amount": 990,
                            "amount": 990
                          },
                          {
                            "type": "additional_sheets",
                            "quantity": 1,
                            "unit_amount": 75,
                            "amount": 75
                          },
                          {
                            "type": "color",
                            "quantity": 2,
                            "unit_amount": 35,
                            "amount": 70
                          }
                        ]
                      },
                      "send_date": null,
                      "cancellation_reason": null,
                      "failure_reason": "damaged_in_production",
                      "tracking_code": null,
                      "preview_url": "https://files.cartaflow.com.br/previews/ltr_8Kq2wX4mN7pR.pdf?expires=1760369400&signature=9c1f2a7d",
                      "reference": "fatura-2026-10-0042",
                      "metadata": {
                        "customer_id": "1842"
                      },
                      "status_transitions": {
                        "received_at": "2026-10-13T14:20:00Z",
                        "in_production_at": "2026-10-13T21:00:00Z",
                        "printed_at": null,
                        "posted_at": null,
                        "canceled_at": null,
                        "failed_at": "2026-10-14T11:30:00Z"
                      },
                      "created_at": "2026-10-13T14:20:00Z"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/letters/{letter_id}/cancel": {
      "post": {
        "operationId": "cancelLetter",
        "tags": [
          "letters"
        ],
        "summary": "Cancelar uma correspondência",
        "description": "Cancela uma correspondência que está em `scheduled` ou `received`. Nada é impresso. Se ela já tinha sido cobrada, o valor volta para o saldo na hora; se estava agendada, nada foi cobrado. Depois que ela entra em produção (ou se ela falhou), a API responde 409 com `letter_not_cancelable`. Cancelar uma correspondência que já está cancelada devolve a mesma correspondência, sem erro.",
        "parameters": [
          {
            "$ref": "#/components/parameters/LetterId"
          }
        ],
        "responses": {
          "200": {
            "description": "A correspondência cancelada.",
            "headers": {
              "Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Letter"
                },
                "example": {
                  "id": "ltr_8Kq2wX4mN7pR",
                  "object": "letter",
                  "status": "canceled",
                  "to": {
                    "name": "Destinatário Exemplo",
                    "street": "Praça da Sé",
                    "number": "128",
                    "complement": "Ap. 52",
                    "neighborhood": "Sé",
                    "city": "São Paulo",
                    "state": "SP",
                    "postal_code": "01001-000"
                  },
                  "from": {
                    "name": "Exemplo Serviços Ltda.",
                    "street": "Avenida Exemplo",
                    "number": "1000",
                    "complement": "Sala 301",
                    "neighborhood": "Bela Vista",
                    "city": "São Paulo",
                    "state": "SP",
                    "postal_code": "01310-100"
                  },
                  "document": {
                    "type": "url",
                    "url": "https://arquivos.exemplo.com.br/faturas/2026-10-0042.pdf",
                    "variables": null
                  },
                  "color": true,
                  "double_sided": false,
                  "address_placement": "first_page",
                  "postal_services": [],
                  "pages": 2,
                  "sheets": 2,
                  "price": {
                    "currency": "BRL",
                    "total": 1135,
                    "items": [
                      {
                        "type": "base",
                        "quantity": 1,
                        "unit_amount": 990,
                        "amount": 990
                      },
                      {
                        "type": "additional_sheets",
                        "quantity": 1,
                        "unit_amount": 75,
                        "amount": 75
                      },
                      {
                        "type": "color",
                        "quantity": 2,
                        "unit_amount": 35,
                        "amount": 70
                      }
                    ]
                  },
                  "send_date": null,
                  "cancellation_reason": "requested",
                  "failure_reason": null,
                  "tracking_code": null,
                  "preview_url": "https://files.cartaflow.com.br/previews/ltr_8Kq2wX4mN7pR.pdf?expires=1760369400&signature=9c1f2a7d",
                  "reference": "fatura-2026-10-0042",
                  "metadata": {
                    "customer_id": "1842"
                  },
                  "status_transitions": {
                    "received_at": "2026-10-13T14:20:00Z",
                    "in_production_at": null,
                    "printed_at": null,
                    "posted_at": null,
                    "canceled_at": "2026-10-13T14:31:00Z",
                    "failed_at": null
                  },
                  "created_at": "2026-10-13T14:20:00Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "A correspondência já entrou em produção e não pode ser cancelada.",
            "headers": {
              "Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "conflict_error",
                    "code": "letter_not_cancelable",
                    "message": "A correspondência está em in_production e não pode mais ser cancelada.",
                    "request_id": "req_9Vb4Xk2Lq8Mz",
                    "doc_url": "https://docs.cartaflow.com.br/errors#letter_not_cancelable",
                    "details": null
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/letters/quote": {
      "post": {
        "operationId": "createQuote",
        "tags": [
          "letters"
        ],
        "summary": "Calcular o preço",
        "description": "Simula uma correspondência sem criá-la. O corpo é exatamente o mesmo de POST /v1/letters, em JSON ou em multipart/form-data com o arquivo: a API valida tudo, completa o endereço pelo CEP, conta as páginas do documento e devolve o preço no plano atual da conta, com os serviços dos Correios escolhidos em `postal_services`. Nada é criado, cobrado ou guardado, e o saldo não precisa cobrir o valor. Um upload usado na simulação (`document.type: upload`) continua disponível para a criação.\n\nUse para mostrar o preço ao seu usuário antes de enviar, para conferir o endereço completo ou para conferir um documento sem custo. Se a simulação passar, a criação com o mesmo corpo também passa, desde que haja saldo.",
        "requestBody": {
          "required": true,
          "description": "Dois formatos, com os mesmos campos: **application/json**, com o PDF em `document` (URL, upload em duas etapas ou base64), ou **multipart/form-data**, com o arquivo do PDF no campo `file` (até 4 MB). Troque o formato no seletor do quadro abaixo.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateLetterRequest"
              },
              "examples": {
                "pdf_url": {
                  "summary": "PDF por URL",
                  "value": {
                    "to": {
                      "name": "Destinatário Exemplo",
                      "postal_code": "01001-000",
                      "number": "128",
                      "complement": "Ap. 52"
                    },
                    "document": {
                      "type": "url",
                      "url": "https://arquivos.exemplo.com.br/faturas/2026-10-0042.pdf"
                    },
                    "color": true
                  }
                },
                "registered": {
                  "summary": "Carta registrada com AR",
                  "value": {
                    "to": {
                      "name": "Destinatário Exemplo",
                      "postal_code": "01001-000",
                      "number": "128",
                      "complement": "Ap. 52"
                    },
                    "document": {
                      "type": "upload",
                      "upload_id": "upl_6Np3Vx8Rk2Tq"
                    },
                    "postal_services": [
                      "registered",
                      "return_receipt"
                    ]
                  }
                }
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/CreateLetterUpload"
              },
              "example": {
                "file": "fatura-outubro.pdf",
                "to": {
                  "name": "Destinatário Exemplo",
                  "postal_code": "01001-000",
                  "number": "128",
                  "complement": "Ap. 52"
                },
                "color": true,
                "reference": "fatura-2026-10-0042"
              },
              "encoding": {
                "file": {
                  "contentType": "application/pdf"
                },
                "to": {
                  "style": "deepObject",
                  "explode": true
                },
                "from": {
                  "style": "deepObject",
                  "explode": true
                },
                "variables": {
                  "style": "deepObject",
                  "explode": true
                },
                "metadata": {
                  "style": "deepObject",
                  "explode": true
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "O preço e o endereço completo.",
            "headers": {
              "Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Quote"
                },
                "example": {
                  "object": "quote",
                  "plan": "essential",
                  "to": {
                    "name": "Destinatário Exemplo",
                    "street": "Praça da Sé",
                    "number": "128",
                    "complement": "Ap. 52",
                    "neighborhood": "Sé",
                    "city": "São Paulo",
                    "state": "SP",
                    "postal_code": "01001-000"
                  },
                  "pages": 2,
                  "sheets": 2,
                  "price": {
                    "currency": "BRL",
                    "total": 1135,
                    "items": [
                      {
                        "type": "base",
                        "quantity": 1,
                        "unit_amount": 990,
                        "amount": 990
                      },
                      {
                        "type": "additional_sheets",
                        "quantity": 1,
                        "unit_amount": 75,
                        "amount": 75
                      },
                      {
                        "type": "color",
                        "quantity": 2,
                        "unit_amount": 35,
                        "amount": 70
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "413": {
            "$ref": "#/components/responses/RequestTooLarge"
          },
          "422": {
            "description": "O corpo tem os mesmos problemas que teria na criação.",
            "headers": {
              "Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "validation_error",
                    "code": "invalid_parameters",
                    "message": "Um campo tem problema. Veja details.",
                    "request_id": "req_9Vb4Xk2Lq8Mz",
                    "doc_url": "https://docs.cartaflow.com.br/errors#invalid_parameters",
                    "details": [
                      {
                        "param": "document.url",
                        "code": "too_many_sheets",
                        "message": "O documento tem 9 páginas, o que daria 9 folhas. O máximo é 6. Use double_sided: true."
                      }
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/uploads": {
      "post": {
        "operationId": "createUpload",
        "tags": [
          "uploads"
        ],
        "summary": "Criar um upload",
        "description": "Primeira etapa para enviar um PDF grande, de até 10 MB, que não cabe numa requisição (o corpo tem até 4,5 MB, então o multipart aceita PDFs de até 4 MB). Funciona em três passos:\n\n1. Chame este endpoint com o nome e o tamanho do arquivo. A resposta traz o `id` do upload e um `upload_url` assinado.\n2. Envie os bytes do PDF com `PUT` para o `upload_url`, com o cabeçalho `Content-Type: application/pdf` e **sem** o cabeçalho `Authorization`: a assinatura já está na URL. O link vale por 2 horas.\n3. Crie a correspondência com `document: { \"type\": \"upload\", \"upload_id\": \"upl_...\" }`, em até 24 horas.\n\n```bash\ncurl -X PUT \"$UPLOAD_URL\" \\\n  -H \"Content-Type: application/pdf\" \\\n  --data-binary \"@fatura-outubro.pdf\"\n```\n\nO arquivo é conferido quando a correspondência é criada, com as mesmas regras de qualquer PDF (A4, sem senha, área do endereço). Cada upload pertence à sua conta e serve para uma correspondência só: uma segunda correspondência com o mesmo `upload_id` recebe 422 com `upload_already_used`. Uma simulação com POST /v1/letters/quote não consome o upload.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateUploadRequest"
              },
              "example": {
                "filename": "fatura-outubro.pdf",
                "size": 7340032
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "O upload foi criado. Envie o arquivo para `upload_url` em até 2 horas.",
            "headers": {
              "Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              },
              "Idempotent-Replayed": {
                "$ref": "#/components/headers/IdempotentReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Upload"
                },
                "example": {
                  "id": "upl_6Np3Vx8Rk2Tq",
                  "object": "upload",
                  "filename": "fatura-outubro.pdf",
                  "size": 7340032,
                  "upload_url": "https://files.cartaflow.com.br/uploads/upl_6Np3Vx8Rk2Tq?token=4f8a2c91d7",
                  "upload_url_expires_at": "2026-10-13T16:20:00Z",
                  "expires_at": "2026-10-14T14:20:00Z",
                  "created_at": "2026-10-13T14:20:00Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "409": {
            "$ref": "#/components/responses/IdempotencyConflict"
          },
          "422": {
            "description": "Um ou mais campos têm problemas. Nada foi criado.",
            "headers": {
              "Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "validation_error",
                    "code": "invalid_parameters",
                    "message": "Um campo tem problema. Veja details.",
                    "request_id": "req_9Vb4Xk2Lq8Mz",
                    "doc_url": "https://docs.cartaflow.com.br/errors#invalid_parameters",
                    "details": [
                      {
                        "param": "size",
                        "code": "out_of_range",
                        "message": "O arquivo pode ter até 10485760 bytes (10 MB)."
                      }
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/verifications": {
      "post": {
        "operationId": "createVerification",
        "tags": [
          "verifications"
        ],
        "summary": "Criar uma verificação",
        "description": "Envia para o endereço uma correspondência com a sua marca e um código de 6 dígitos. Quando a pessoa confirma o código, a verificação passa para `verified` e você recebe o evento `verification.verified`. O preço é debitado do saldo na criação.\n\nEscolha em `method` como a pessoa confirma:\n\n- `hosted_page`: ela escaneia o QR code, ou abre o endereço impresso e digita o código, numa página com a sua marca, hospedada pela CartaFlow.\n- `code`: ela digita o código no seu site ou app, e o seu servidor confere com POST /v1/verifications/{verification_id}/check.\n\nA correspondência pode sair de duas formas:\n\n| Forma | Como | Preço |\n| --- | --- | --- |\n| Modelo da CartaFlow (padrão) | Sem `document`. Personalize título, texto, rodapé, QR code e endereço da página em `letter`; o que você não enviar vem do modelo padrão da sua empresa, salvo no painel. | Um envio simples |\n| O seu PDF | `document` com `url`, `upload` ou `base64`. O PDF precisa ter a marcação `{{OTP_CODE}}` e pode ter `{{VERIFICATION_URL}}` e `{{QR_CODE}}`. Aceita `color`, `double_sided` e `address_placement`. | O de uma correspondência com as mesmas opções |\n\nEste endpoint aceita só JSON. Para enviar o arquivo do seu PDF, use o upload em duas etapas (POST /v1/uploads).\n\nO código nunca aparece na API nem no painel: ele só existe na correspondência que a CartaFlow imprime. `preview_url` mostra a correspondência com o código escondido (`000 000`).",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateVerificationRequest"
              },
              "examples": {
                "hosted_page": {
                  "summary": "Página hospedada, modelo padrão",
                  "value": {
                    "to": {
                      "name": "Destinatário Exemplo",
                      "postal_code": "01001-000",
                      "number": "128",
                      "complement": "Ap. 52"
                    },
                    "method": "hosted_page",
                    "return_url": "https://www.exemplo.com.br/conta",
                    "reference": "cliente-1842"
                  }
                },
                "letter": {
                  "summary": "Modelo da CartaFlow personalizado",
                  "value": {
                    "to": {
                      "name": "Destinatário Exemplo",
                      "postal_code": "01001-000",
                      "number": "128",
                      "complement": "Ap. 52"
                    },
                    "method": "hosted_page",
                    "letter": {
                      "title": "Confirme seu endereço, {{nome}}",
                      "body": "{{empresa}} precisa confirmar o endereço do seu cadastro. Use o código abaixo.",
                      "include_page_url": false
                    },
                    "reference": "cliente-1842"
                  }
                },
                "code": {
                  "summary": "Código digitado no seu app",
                  "value": {
                    "to": {
                      "name": "Destinatário Exemplo",
                      "postal_code": "01001-000",
                      "number": "128",
                      "complement": "Ap. 52"
                    },
                    "method": "code",
                    "instructions": "Abra o app, vá em Perfil > Endereço e digite o código.",
                    "reference": "cliente-1842"
                  }
                },
                "own_pdf": {
                  "summary": "O seu PDF, com {{OTP_CODE}}",
                  "value": {
                    "to": {
                      "name": "Destinatário Exemplo",
                      "postal_code": "01001-000",
                      "number": "128",
                      "complement": "Ap. 52"
                    },
                    "method": "hosted_page",
                    "document": {
                      "type": "upload",
                      "upload_id": "upl_6Np3Vx8Rk2Tq",
                      "variables": {
                        "nome": "Destinatário Exemplo"
                      }
                    },
                    "color": true,
                    "reference": "cliente-2210"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "A verificação foi criada e cobrada. Status `received`.",
            "headers": {
              "Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Verification"
                },
                "examples": {
                  "template": {
                    "summary": "Modelo da CartaFlow",
                    "value": {
                      "id": "ver_3Hd9Kp2qZ6tW",
                      "object": "verification",
                      "status": "received",
                      "method": "hosted_page",
                      "source": "api",
                      "to": {
                        "name": "Destinatário Exemplo",
                        "street": "Praça da Sé",
                        "number": "128",
                        "complement": "Ap. 52",
                        "neighborhood": "Sé",
                        "city": "São Paulo",
                        "state": "SP",
                        "postal_code": "01001-000"
                      },
                      "document": {
                        "type": "template",
                        "title": "Confirme o seu endereço",
                        "body": "{{empresa}} pediu a confirmação de que você recebe correspondência neste endereço. Use o código abaixo para confirmar.",
                        "footer": "O código vale por 60 dias depois da postagem e só funciona para este endereço. Não compartilhe este código com ninguém.",
                        "include_qr_code": true,
                        "include_page_url": true
                      },
                      "instructions": null,
                      "return_url": "https://www.exemplo.com.br/conta",
                      "hosted_page_url": "https://verifica.cartaflow.com.br/acc_7Jw3Nf8Xq2Lp/9Qx2Lm7Tp4Rb8Kd3Wn6Yc1",
                      "attempts_remaining": 5,
                      "expires_at": null,
                      "confirmation": null,
                      "preview_url": "https://files.cartaflow.com.br/previews/ver_3Hd9Kp2qZ6tW.pdf?expires=1760369400&signature=5d2e81b3",
                      "price": {
                        "currency": "BRL",
                        "total": 990,
                        "items": [
                          {
                            "type": "base",
                            "quantity": 1,
                            "unit_amount": 990,
                            "amount": 990
                          }
                        ]
                      },
                      "reference": "cliente-1842",
                      "metadata": {},
                      "status_transitions": {
                        "in_production_at": null,
                        "awaiting_code_at": null,
                        "verified_at": null,
                        "failed_at": null,
                        "expired_at": null,
                        "canceled_at": null,
                        "revoked_at": null
                      },
                      "created_at": "2026-10-13T14:20:00Z"
                    }
                  },
                  "own_pdf": {
                    "summary": "O seu PDF",
                    "value": {
                      "id": "ver_5Tc7Gm1Xs9Hq",
                      "object": "verification",
                      "status": "received",
                      "method": "hosted_page",
                      "source": "api",
                      "to": {
                        "name": "Destinatário Exemplo",
                        "street": "Praça da Sé",
                        "number": "128",
                        "complement": "Ap. 52",
                        "neighborhood": "Sé",
                        "city": "São Paulo",
                        "state": "SP",
                        "postal_code": "01001-000"
                      },
                      "document": {
                        "type": "upload",
                        "filename": "verificacao-endereco.pdf",
                        "variables": {
                          "nome": "Destinatário Exemplo"
                        }
                      },
                      "instructions": null,
                      "return_url": "https://www.exemplo.com.br/conta",
                      "hosted_page_url": "https://verifica.cartaflow.com.br/acc_7Jw3Nf8Xq2Lp/4Fz8Np2Kw6Qr1Lt9Ds3Hm7",
                      "attempts_remaining": 5,
                      "expires_at": null,
                      "confirmation": null,
                      "preview_url": "https://files.cartaflow.com.br/previews/ver_5Tc7Gm1Xs9Hq.pdf?expires=1760369400&signature=c3f9d518",
                      "price": {
                        "currency": "BRL",
                        "total": 1025,
                        "items": [
                          {
                            "type": "base",
                            "quantity": 1,
                            "unit_amount": 990,
                            "amount": 990
                          },
                          {
                            "type": "color",
                            "quantity": 1,
                            "unit_amount": 35,
                            "amount": 35
                          }
                        ]
                      },
                      "reference": "cliente-2210",
                      "metadata": {},
                      "status_transitions": {
                        "in_production_at": null,
                        "awaiting_code_at": null,
                        "verified_at": null,
                        "failed_at": null,
                        "expired_at": null,
                        "canceled_at": null,
                        "revoked_at": null
                      },
                      "created_at": "2026-10-13T14:20:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientBalance"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/IdempotencyConflict"
          },
          "422": {
            "description": "Um ou mais campos têm problemas. Nada foi criado nem cobrado.",
            "headers": {
              "Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "validation_error",
                    "code": "invalid_parameters",
                    "message": "2 campos têm problemas. Veja details.",
                    "request_id": "req_9Vb4Xk2Lq8Mz",
                    "doc_url": "https://docs.cartaflow.com.br/errors#invalid_parameters",
                    "details": [
                      {
                        "param": "to.street",
                        "code": "address_incomplete",
                        "message": "O CEP 13165-000 vale para a cidade inteira e não informa o logradouro. Envie street e neighborhood."
                      },
                      {
                        "param": "document.upload_id",
                        "code": "otp_code_missing",
                        "message": "O PDF precisa ter a marcação {{OTP_CODE}}, onde imprimimos o código."
                      }
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      },
      "get": {
        "operationId": "listVerifications",
        "tags": [
          "verifications"
        ],
        "summary": "Listar verificações",
        "description": "Devolve as verificações da conta, criadas pela API e pelo painel, da mais recente para a mais antiga.",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "received",
                "in_production",
                "awaiting_code",
                "verified",
                "failed",
                "expired",
                "canceled",
                "revoked"
              ],
              "description": "Só itens neste status.\n\n**Valores possíveis**\n\n- `received`: A CartaFlow recebeu o pedido, cobrou o preço do seu saldo e colocou a correspondência com o código na fila de produção. Se você cancelar agora, nada é impresso e o valor volta para o saldo.\n- `in_production`: A correspondência com o código está sendo impressa e envelopada. Cancelar agora revoga a verificação (`revoked`), sem devolução do valor.\n- `awaiting_code`: A correspondência foi postada. Agora esperamos a pessoa confirmar o código. Ela tem 60 dias a partir da postagem (veja `expires_at`). Cancelar agora revoga a verificação, sem devolução do valor.\n- `verified`: A pessoa confirmou o código certo. Ela recebe correspondência no endereço informado. `confirmation` diz como e quando. Você ainda pode revogar a verificação, e ela passa para `revoked`.\n- `failed`: Foram digitados 5 códigos errados. A verificação foi bloqueada para impedir tentativas aleatórias. Crie uma nova verificação se quiser tentar de novo.\n- `expired`: Passaram 60 dias desde a postagem sem que a pessoa confirmasse o código.\n- `canceled`: A verificação foi cancelada antes da postagem e o valor voltou para o seu saldo. Ou você cancelou enquanto ela estava em `received`, ou a CartaFlow cancelou porque a correspondência não pôde ser produzida.\n- `revoked`: Você cancelou a verificação depois que a produção começou: em produção, aguardando código ou já verificada. O valor não volta para o saldo, porque a produção já começou, e uma correspondência que estava em produção ainda é postada. O código deixa de funcionar, na página e na API, e a verificação nunca mais aparece como `verified`.",
              "x-enumDescriptions": {
                "received": "A CartaFlow recebeu o pedido, cobrou o preço do seu saldo e colocou a correspondência com o código na fila de produção. Se você cancelar agora, nada é impresso e o valor volta para o saldo.",
                "in_production": "A correspondência com o código está sendo impressa e envelopada. Cancelar agora revoga a verificação (`revoked`), sem devolução do valor.",
                "awaiting_code": "A correspondência foi postada. Agora esperamos a pessoa confirmar o código. Ela tem 60 dias a partir da postagem (veja `expires_at`). Cancelar agora revoga a verificação, sem devolução do valor.",
                "verified": "A pessoa confirmou o código certo. Ela recebe correspondência no endereço informado. `confirmation` diz como e quando. Você ainda pode revogar a verificação, e ela passa para `revoked`.",
                "failed": "Foram digitados 5 códigos errados. A verificação foi bloqueada para impedir tentativas aleatórias. Crie uma nova verificação se quiser tentar de novo.",
                "expired": "Passaram 60 dias desde a postagem sem que a pessoa confirmasse o código.",
                "canceled": "A verificação foi cancelada antes da postagem e o valor voltou para o seu saldo. Ou você cancelou enquanto ela estava em `received`, ou a CartaFlow cancelou porque a correspondência não pôde ser produzida.",
                "revoked": "Você cancelou a verificação depois que a produção começou: em produção, aguardando código ou já verificada. O valor não volta para o saldo, porque a produção já começou, e uma correspondência que estava em produção ainda é postada. O código deixa de funcionar, na página e na API, e a verificação nunca mais aparece como `verified`."
              }
            },
            "description": "Só itens neste status."
          },
          {
            "$ref": "#/components/parameters/Reference"
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/CreatedAfter"
          },
          {
            "$ref": "#/components/parameters/CreatedBefore"
          }
        ],
        "responses": {
          "200": {
            "description": "Uma página de verificações.",
            "headers": {
              "Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VerificationList"
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "id": "ver_3Hd9Kp2qZ6tW",
                      "object": "verification",
                      "status": "awaiting_code",
                      "method": "hosted_page",
                      "source": "api",
                      "to": {
                        "name": "Destinatário Exemplo",
                        "street": "Praça da Sé",
                        "number": "128",
                        "complement": "Ap. 52",
                        "neighborhood": "Sé",
                        "city": "São Paulo",
                        "state": "SP",
                        "postal_code": "01001-000"
                      },
                      "document": {
                        "type": "template",
                        "title": "Confirme o seu endereço",
                        "body": "{{empresa}} pediu a confirmação de que você recebe correspondência neste endereço. Use o código abaixo para confirmar.",
                        "footer": "O código vale por 60 dias depois da postagem e só funciona para este endereço. Não compartilhe este código com ninguém.",
                        "include_qr_code": true,
                        "include_page_url": true
                      },
                      "instructions": null,
                      "return_url": "https://www.exemplo.com.br/conta",
                      "hosted_page_url": "https://verifica.cartaflow.com.br/acc_7Jw3Nf8Xq2Lp/9Qx2Lm7Tp4Rb8Kd3Wn6Yc1",
                      "attempts_remaining": 5,
                      "expires_at": "2026-12-14T16:05:00Z",
                      "confirmation": null,
                      "preview_url": "https://files.cartaflow.com.br/previews/ver_3Hd9Kp2qZ6tW.pdf?expires=1760369400&signature=5d2e81b3",
                      "price": {
                        "currency": "BRL",
                        "total": 990,
                        "items": [
                          {
                            "type": "base",
                            "quantity": 1,
                            "unit_amount": 990,
                            "amount": 990
                          }
                        ]
                      },
                      "reference": "cliente-1842",
                      "metadata": {},
                      "status_transitions": {
                        "in_production_at": "2026-10-13T21:00:00Z",
                        "awaiting_code_at": "2026-10-15T16:05:00Z",
                        "verified_at": null,
                        "failed_at": null,
                        "expired_at": null,
                        "canceled_at": null,
                        "revoked_at": null
                      },
                      "created_at": "2026-10-13T14:20:00Z"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/verifications/{verification_id}": {
      "get": {
        "operationId": "getVerification",
        "tags": [
          "verifications"
        ],
        "summary": "Consultar uma verificação",
        "description": "Devolve a verificação com o status atual e, quando confirmada, como foi a confirmação (`confirmation`). Cada consulta traz um `preview_url` novo.",
        "parameters": [
          {
            "$ref": "#/components/parameters/VerificationId"
          }
        ],
        "responses": {
          "200": {
            "description": "A verificação.",
            "headers": {
              "Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Verification"
                },
                "examples": {
                  "awaiting_code": {
                    "summary": "Aguardando código",
                    "value": {
                      "id": "ver_3Hd9Kp2qZ6tW",
                      "object": "verification",
                      "status": "awaiting_code",
                      "method": "hosted_page",
                      "source": "api",
                      "to": {
                        "name": "Destinatário Exemplo",
                        "street": "Praça da Sé",
                        "number": "128",
                        "complement": "Ap. 52",
                        "neighborhood": "Sé",
                        "city": "São Paulo",
                        "state": "SP",
                        "postal_code": "01001-000"
                      },
                      "document": {
                        "type": "template",
                        "title": "Confirme o seu endereço",
                        "body": "{{empresa}} pediu a confirmação de que você recebe correspondência neste endereço. Use o código abaixo para confirmar.",
                        "footer": "O código vale por 60 dias depois da postagem e só funciona para este endereço. Não compartilhe este código com ninguém.",
                        "include_qr_code": true,
                        "include_page_url": true
                      },
                      "instructions": null,
                      "return_url": "https://www.exemplo.com.br/conta",
                      "hosted_page_url": "https://verifica.cartaflow.com.br/acc_7Jw3Nf8Xq2Lp/9Qx2Lm7Tp4Rb8Kd3Wn6Yc1",
                      "attempts_remaining": 5,
                      "expires_at": "2026-12-14T16:05:00Z",
                      "confirmation": null,
                      "preview_url": "https://files.cartaflow.com.br/previews/ver_3Hd9Kp2qZ6tW.pdf?expires=1760369400&signature=5d2e81b3",
                      "price": {
                        "currency": "BRL",
                        "total": 990,
                        "items": [
                          {
                            "type": "base",
                            "quantity": 1,
                            "unit_amount": 990,
                            "amount": 990
                          }
                        ]
                      },
                      "reference": "cliente-1842",
                      "metadata": {},
                      "status_transitions": {
                        "in_production_at": "2026-10-13T21:00:00Z",
                        "awaiting_code_at": "2026-10-15T16:05:00Z",
                        "verified_at": null,
                        "failed_at": null,
                        "expired_at": null,
                        "canceled_at": null,
                        "revoked_at": null
                      },
                      "created_at": "2026-10-13T14:20:00Z"
                    }
                  },
                  "verified": {
                    "summary": "Verificada pela página",
                    "value": {
                      "id": "ver_3Hd9Kp2qZ6tW",
                      "object": "verification",
                      "status": "verified",
                      "method": "hosted_page",
                      "source": "api",
                      "to": {
                        "name": "Destinatário Exemplo",
                        "street": "Praça da Sé",
                        "number": "128",
                        "complement": "Ap. 52",
                        "neighborhood": "Sé",
                        "city": "São Paulo",
                        "state": "SP",
                        "postal_code": "01001-000"
                      },
                      "document": {
                        "type": "template",
                        "title": "Confirme o seu endereço",
                        "body": "{{empresa}} pediu a confirmação de que você recebe correspondência neste endereço. Use o código abaixo para confirmar.",
                        "footer": "O código vale por 60 dias depois da postagem e só funciona para este endereço. Não compartilhe este código com ninguém.",
                        "include_qr_code": true,
                        "include_page_url": true
                      },
                      "instructions": null,
                      "return_url": "https://www.exemplo.com.br/conta",
                      "hosted_page_url": "https://verifica.cartaflow.com.br/acc_7Jw3Nf8Xq2Lp/9Qx2Lm7Tp4Rb8Kd3Wn6Yc1",
                      "attempts_remaining": 5,
                      "expires_at": "2026-12-14T16:05:00Z",
                      "confirmation": {
                        "method": "hosted_page",
                        "hosted_page_entry": "qr_code",
                        "confirmed_at": "2026-10-21T19:32:00Z",
                        "ip": "198.51.100.23",
                        "location": {
                          "city": "São Paulo",
                          "region": "SP",
                          "country": "BR",
                          "postal_code": "01000",
                          "latitude": -23.5475,
                          "longitude": -46.6361
                        },
                        "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1",
                        "device": {
                          "type": "mobile",
                          "os": {
                            "name": "iOS",
                            "version": "17.5"
                          },
                          "browser": {
                            "name": "Safari",
                            "version": "17.5"
                          }
                        },
                        "client": {
                          "language": "pt-BR",
                          "accept_language": "pt-BR,pt;q=0.9",
                          "timezone": "America/Sao_Paulo",
                          "screen": {
                            "width": 390,
                            "height": 844,
                            "pixel_ratio": 3
                          },
                          "time_on_page_ms": 8100
                        },
                        "precise_location": {
                          "latitude": -23.5489,
                          "longitude": -46.6388,
                          "accuracy_m": 14.5,
                          "distance_m": 606,
                          "shared_at": "2026-10-21T19:32:40Z",
                          "ip": "198.51.100.23",
                          "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1",
                          "address_coordinates": {
                            "latitude": -23.5503898,
                            "longitude": -46.633081
                          }
                        }
                      },
                      "preview_url": "https://files.cartaflow.com.br/previews/ver_3Hd9Kp2qZ6tW.pdf?expires=1760369400&signature=5d2e81b3",
                      "price": {
                        "currency": "BRL",
                        "total": 990,
                        "items": [
                          {
                            "type": "base",
                            "quantity": 1,
                            "unit_amount": 990,
                            "amount": 990
                          }
                        ]
                      },
                      "reference": "cliente-1842",
                      "metadata": {},
                      "status_transitions": {
                        "in_production_at": "2026-10-13T21:00:00Z",
                        "awaiting_code_at": "2026-10-15T16:05:00Z",
                        "verified_at": "2026-10-21T19:32:00Z",
                        "failed_at": null,
                        "expired_at": null,
                        "canceled_at": null,
                        "revoked_at": null
                      },
                      "created_at": "2026-10-13T14:20:00Z"
                    }
                  },
                  "revoked": {
                    "summary": "Revogada depois de verificada",
                    "value": {
                      "id": "ver_3Hd9Kp2qZ6tW",
                      "object": "verification",
                      "status": "revoked",
                      "method": "hosted_page",
                      "source": "api",
                      "to": {
                        "name": "Destinatário Exemplo",
                        "street": "Praça da Sé",
                        "number": "128",
                        "complement": "Ap. 52",
                        "neighborhood": "Sé",
                        "city": "São Paulo",
                        "state": "SP",
                        "postal_code": "01001-000"
                      },
                      "document": {
                        "type": "template",
                        "title": "Confirme o seu endereço",
                        "body": "{{empresa}} pediu a confirmação de que você recebe correspondência neste endereço. Use o código abaixo para confirmar.",
                        "footer": "O código vale por 60 dias depois da postagem e só funciona para este endereço. Não compartilhe este código com ninguém.",
                        "include_qr_code": true,
                        "include_page_url": true
                      },
                      "instructions": null,
                      "return_url": "https://www.exemplo.com.br/conta",
                      "hosted_page_url": "https://verifica.cartaflow.com.br/acc_7Jw3Nf8Xq2Lp/9Qx2Lm7Tp4Rb8Kd3Wn6Yc1",
                      "attempts_remaining": 5,
                      "expires_at": "2026-12-14T16:05:00Z",
                      "confirmation": {
                        "method": "hosted_page",
                        "hosted_page_entry": "qr_code",
                        "confirmed_at": "2026-10-21T19:32:00Z",
                        "ip": "198.51.100.23",
                        "location": {
                          "city": "São Paulo",
                          "region": "SP",
                          "country": "BR",
                          "postal_code": "01000",
                          "latitude": -23.5475,
                          "longitude": -46.6361
                        },
                        "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1",
                        "device": {
                          "type": "mobile",
                          "os": {
                            "name": "iOS",
                            "version": "17.5"
                          },
                          "browser": {
                            "name": "Safari",
                            "version": "17.5"
                          }
                        },
                        "client": {
                          "language": "pt-BR",
                          "accept_language": "pt-BR,pt;q=0.9",
                          "timezone": "America/Sao_Paulo",
                          "screen": {
                            "width": 390,
                            "height": 844,
                            "pixel_ratio": 3
                          },
                          "time_on_page_ms": 8100
                        },
                        "precise_location": {
                          "latitude": -23.5489,
                          "longitude": -46.6388,
                          "accuracy_m": 14.5,
                          "distance_m": 606,
                          "shared_at": "2026-10-21T19:32:40Z",
                          "ip": "198.51.100.23",
                          "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1",
                          "address_coordinates": {
                            "latitude": -23.5503898,
                            "longitude": -46.633081
                          }
                        }
                      },
                      "preview_url": "https://files.cartaflow.com.br/previews/ver_3Hd9Kp2qZ6tW.pdf?expires=1760369400&signature=5d2e81b3",
                      "price": {
                        "currency": "BRL",
                        "total": 990,
                        "items": [
                          {
                            "type": "base",
                            "quantity": 1,
                            "unit_amount": 990,
                            "amount": 990
                          }
                        ]
                      },
                      "reference": "cliente-1842",
                      "metadata": {},
                      "status_transitions": {
                        "in_production_at": "2026-10-13T21:00:00Z",
                        "awaiting_code_at": "2026-10-15T16:05:00Z",
                        "verified_at": "2026-10-21T19:32:00Z",
                        "failed_at": null,
                        "expired_at": null,
                        "canceled_at": null,
                        "revoked_at": "2026-10-23T12:10:00Z"
                      },
                      "created_at": "2026-10-13T14:20:00Z"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/verifications/{verification_id}/check": {
      "post": {
        "operationId": "checkVerification",
        "tags": [
          "verifications"
        ],
        "summary": "Conferir um código",
        "description": "Confere o código que a pessoa digitou no seu site ou app. Funciona quando o status é `awaiting_code`. Faça a chamada do seu servidor: um código certo registra em `confirmation` o IP de quem chamou a API.\n\nUm código errado não é um erro da API: a resposta é 200 com `correct: false` e `attempts_remaining` menor. Depois de 5 códigos errados, contando os da página, a verificação passa para `failed`. Mostre à pessoa quantas tentativas restam.\n\nUma verificação cancelada ou revogada não aceita mais códigos: a resposta é 409.",
        "parameters": [
          {
            "$ref": "#/components/parameters/VerificationId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CheckVerificationRequest"
              },
              "example": {
                "code": "482917"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "O resultado da conferência. Veja `correct`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VerificationCheck"
                },
                "examples": {
                  "correct": {
                    "summary": "Código certo",
                    "value": {
                      "object": "verification_check",
                      "correct": true,
                      "verification": {
                        "id": "ver_8Wn2Rt6Yk4Js",
                        "object": "verification",
                        "status": "verified",
                        "method": "code",
                        "source": "api",
                        "to": {
                          "name": "Destinatário Exemplo",
                          "street": "Praça da Sé",
                          "number": "128",
                          "complement": "Ap. 52",
                          "neighborhood": "Sé",
                          "city": "São Paulo",
                          "state": "SP",
                          "postal_code": "01001-000"
                        },
                        "document": {
                          "type": "template",
                          "title": "Confirme o seu endereço",
                          "body": "{{empresa}} pediu a confirmação de que você recebe correspondência neste endereço. Use o código abaixo para confirmar.",
                          "footer": "O código vale por 60 dias depois da postagem e só funciona para este endereço. Não compartilhe este código com ninguém.",
                          "include_qr_code": false,
                          "include_page_url": false
                        },
                        "instructions": "Abra o app, vá em Perfil > Endereço e digite o código.",
                        "return_url": null,
                        "hosted_page_url": null,
                        "attempts_remaining": 5,
                        "expires_at": "2026-12-14T16:05:00Z",
                        "confirmation": {
                          "method": "api",
                          "hosted_page_entry": null,
                          "confirmed_at": "2026-10-21T19:32:00Z",
                          "ip": "203.0.113.10",
                          "location": null,
                          "user_agent": "node",
                          "device": null,
                          "client": null,
                          "precise_location": null
                        },
                        "preview_url": "https://files.cartaflow.com.br/previews/ver_8Wn2Rt6Yk4Js.pdf?expires=1760369400&signature=a17c4e20",
                        "price": {
                          "currency": "BRL",
                          "total": 990,
                          "items": [
                            {
                              "type": "base",
                              "quantity": 1,
                              "unit_amount": 990,
                              "amount": 990
                            }
                          ]
                        },
                        "reference": "cliente-1842",
                        "metadata": {},
                        "status_transitions": {
                          "in_production_at": "2026-10-13T21:00:00Z",
                          "awaiting_code_at": "2026-10-15T16:05:00Z",
                          "verified_at": "2026-10-21T19:32:00Z",
                          "failed_at": null,
                          "expired_at": null,
                          "canceled_at": null,
                          "revoked_at": null
                        },
                        "created_at": "2026-10-13T14:20:00Z"
                      }
                    }
                  },
                  "wrong": {
                    "summary": "Código errado",
                    "value": {
                      "object": "verification_check",
                      "correct": false,
                      "verification": {
                        "id": "ver_8Wn2Rt6Yk4Js",
                        "object": "verification",
                        "status": "awaiting_code",
                        "method": "code",
                        "source": "api",
                        "to": {
                          "name": "Destinatário Exemplo",
                          "street": "Praça da Sé",
                          "number": "128",
                          "complement": "Ap. 52",
                          "neighborhood": "Sé",
                          "city": "São Paulo",
                          "state": "SP",
                          "postal_code": "01001-000"
                        },
                        "document": {
                          "type": "template",
                          "title": "Confirme o seu endereço",
                          "body": "{{empresa}} pediu a confirmação de que você recebe correspondência neste endereço. Use o código abaixo para confirmar.",
                          "footer": "O código vale por 60 dias depois da postagem e só funciona para este endereço. Não compartilhe este código com ninguém.",
                          "include_qr_code": false,
                          "include_page_url": false
                        },
                        "instructions": "Abra o app, vá em Perfil > Endereço e digite o código.",
                        "return_url": null,
                        "hosted_page_url": null,
                        "attempts_remaining": 4,
                        "expires_at": "2026-12-14T16:05:00Z",
                        "confirmation": null,
                        "preview_url": "https://files.cartaflow.com.br/previews/ver_8Wn2Rt6Yk4Js.pdf?expires=1760369400&signature=a17c4e20",
                        "price": {
                          "currency": "BRL",
                          "total": 990,
                          "items": [
                            {
                              "type": "base",
                              "quantity": 1,
                              "unit_amount": 990,
                              "amount": 990
                            }
                          ]
                        },
                        "reference": "cliente-1842",
                        "metadata": {},
                        "status_transitions": {
                          "in_production_at": "2026-10-13T21:00:00Z",
                          "awaiting_code_at": "2026-10-15T16:05:00Z",
                          "verified_at": null,
                          "failed_at": null,
                          "expired_at": null,
                          "canceled_at": null,
                          "revoked_at": null
                        },
                        "created_at": "2026-10-13T14:20:00Z"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "A verificação não está esperando código: ainda não foi postada, já terminou, foi cancelada ou foi revogada.",
            "headers": {
              "Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "conflict_error",
                    "code": "verification_not_awaiting_code",
                    "message": "A verificação não está esperando código (status atual: revoked).",
                    "request_id": "req_9Vb4Xk2Lq8Mz",
                    "doc_url": "https://docs.cartaflow.com.br/errors#verification_not_awaiting_code",
                    "details": null
                  }
                }
              }
            }
          },
          "422": {
            "description": "O código não tem 6 dígitos.",
            "headers": {
              "Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "validation_error",
                    "code": "invalid_parameters",
                    "message": "Um campo tem problema. Veja details.",
                    "request_id": "req_9Vb4Xk2Lq8Mz",
                    "doc_url": "https://docs.cartaflow.com.br/errors#invalid_parameters",
                    "details": [
                      {
                        "param": "code",
                        "code": "invalid_format",
                        "message": "O código tem 6 dígitos, só números."
                      }
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/verifications/{verification_id}/cancel": {
      "post": {
        "operationId": "cancelVerification",
        "tags": [
          "verifications"
        ],
        "summary": "Cancelar ou revogar uma verificação",
        "description": "O que acontece depende do status:\n\n| Status | Resultado | Valor |\n| --- | --- | --- |\n| `received` | `canceled`: nada é impresso. | Volta para o saldo. |\n| `in_production`, `awaiting_code` ou `verified` | `revoked`: o código deixa de funcionar, na página e na API, e a verificação nunca mais aparece como `verified`. Uma correspondência que já estava em produção ainda é postada. | Não volta. |\n| `canceled` ou `revoked` | Nada muda: a resposta traz a mesma verificação, sem erro. | |\n| `failed` ou `expired` | 409 com `verification_not_cancelable`. | |\n\nRevogue quando o endereço não deve mais contar como verificado, por exemplo quando o cadastro foi encerrado ou você suspeita de fraude. Se a pessoa abrir a página de confirmação depois disso, ela vê um aviso para falar com a sua empresa.",
        "parameters": [
          {
            "$ref": "#/components/parameters/VerificationId"
          }
        ],
        "responses": {
          "200": {
            "description": "A verificação cancelada (`canceled`) ou revogada (`revoked`).",
            "headers": {
              "Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Verification"
                },
                "examples": {
                  "canceled": {
                    "summary": "Cancelada em received, com devolução",
                    "value": {
                      "id": "ver_3Hd9Kp2qZ6tW",
                      "object": "verification",
                      "status": "canceled",
                      "method": "hosted_page",
                      "source": "api",
                      "to": {
                        "name": "Destinatário Exemplo",
                        "street": "Praça da Sé",
                        "number": "128",
                        "complement": "Ap. 52",
                        "neighborhood": "Sé",
                        "city": "São Paulo",
                        "state": "SP",
                        "postal_code": "01001-000"
                      },
                      "document": {
                        "type": "template",
                        "title": "Confirme o seu endereço",
                        "body": "{{empresa}} pediu a confirmação de que você recebe correspondência neste endereço. Use o código abaixo para confirmar.",
                        "footer": "O código vale por 60 dias depois da postagem e só funciona para este endereço. Não compartilhe este código com ninguém.",
                        "include_qr_code": true,
                        "include_page_url": true
                      },
                      "instructions": null,
                      "return_url": "https://www.exemplo.com.br/conta",
                      "hosted_page_url": "https://verifica.cartaflow.com.br/acc_7Jw3Nf8Xq2Lp/9Qx2Lm7Tp4Rb8Kd3Wn6Yc1",
                      "attempts_remaining": 5,
                      "expires_at": null,
                      "confirmation": null,
                      "preview_url": "https://files.cartaflow.com.br/previews/ver_3Hd9Kp2qZ6tW.pdf?expires=1760369400&signature=5d2e81b3",
                      "price": {
                        "currency": "BRL",
                        "total": 990,
                        "items": [
                          {
                            "type": "base",
                            "quantity": 1,
                            "unit_amount": 990,
                            "amount": 990
                          }
                        ]
                      },
                      "reference": "cliente-1842",
                      "metadata": {},
                      "status_transitions": {
                        "in_production_at": null,
                        "awaiting_code_at": null,
                        "verified_at": null,
                        "failed_at": null,
                        "expired_at": null,
                        "canceled_at": "2026-10-13T14:40:00Z",
                        "revoked_at": null
                      },
                      "created_at": "2026-10-13T14:20:00Z"
                    }
                  },
                  "revoked": {
                    "summary": "Revogada depois de verificada, sem devolução",
                    "value": {
                      "id": "ver_3Hd9Kp2qZ6tW",
                      "object": "verification",
                      "status": "revoked",
                      "method": "hosted_page",
                      "source": "api",
                      "to": {
                        "name": "Destinatário Exemplo",
                        "street": "Praça da Sé",
                        "number": "128",
                        "complement": "Ap. 52",
                        "neighborhood": "Sé",
                        "city": "São Paulo",
                        "state": "SP",
                        "postal_code": "01001-000"
                      },
                      "document": {
                        "type": "template",
                        "title": "Confirme o seu endereço",
                        "body": "{{empresa}} pediu a confirmação de que você recebe correspondência neste endereço. Use o código abaixo para confirmar.",
                        "footer": "O código vale por 60 dias depois da postagem e só funciona para este endereço. Não compartilhe este código com ninguém.",
                        "include_qr_code": true,
                        "include_page_url": true
                      },
                      "instructions": null,
                      "return_url": "https://www.exemplo.com.br/conta",
                      "hosted_page_url": "https://verifica.cartaflow.com.br/acc_7Jw3Nf8Xq2Lp/9Qx2Lm7Tp4Rb8Kd3Wn6Yc1",
                      "attempts_remaining": 5,
                      "expires_at": "2026-12-14T16:05:00Z",
                      "confirmation": {
                        "method": "hosted_page",
                        "hosted_page_entry": "qr_code",
                        "confirmed_at": "2026-10-21T19:32:00Z",
                        "ip": "198.51.100.23",
                        "location": {
                          "city": "São Paulo",
                          "region": "SP",
                          "country": "BR",
                          "postal_code": "01000",
                          "latitude": -23.5475,
                          "longitude": -46.6361
                        },
                        "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1",
                        "device": {
                          "type": "mobile",
                          "os": {
                            "name": "iOS",
                            "version": "17.5"
                          },
                          "browser": {
                            "name": "Safari",
                            "version": "17.5"
                          }
                        },
                        "client": {
                          "language": "pt-BR",
                          "accept_language": "pt-BR,pt;q=0.9",
                          "timezone": "America/Sao_Paulo",
                          "screen": {
                            "width": 390,
                            "height": 844,
                            "pixel_ratio": 3
                          },
                          "time_on_page_ms": 8100
                        },
                        "precise_location": {
                          "latitude": -23.5489,
                          "longitude": -46.6388,
                          "accuracy_m": 14.5,
                          "distance_m": 606,
                          "shared_at": "2026-10-21T19:32:40Z",
                          "ip": "198.51.100.23",
                          "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1",
                          "address_coordinates": {
                            "latitude": -23.5503898,
                            "longitude": -46.633081
                          }
                        }
                      },
                      "preview_url": "https://files.cartaflow.com.br/previews/ver_3Hd9Kp2qZ6tW.pdf?expires=1760369400&signature=5d2e81b3",
                      "price": {
                        "currency": "BRL",
                        "total": 990,
                        "items": [
                          {
                            "type": "base",
                            "quantity": 1,
                            "unit_amount": 990,
                            "amount": 990
                          }
                        ]
                      },
                      "reference": "cliente-1842",
                      "metadata": {},
                      "status_transitions": {
                        "in_production_at": "2026-10-13T21:00:00Z",
                        "awaiting_code_at": "2026-10-15T16:05:00Z",
                        "verified_at": "2026-10-21T19:32:00Z",
                        "failed_at": null,
                        "expired_at": null,
                        "canceled_at": null,
                        "revoked_at": "2026-10-23T12:10:00Z"
                      },
                      "created_at": "2026-10-13T14:20:00Z"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "A verificação terminou sem confirmação (`failed` ou `expired`).",
            "headers": {
              "Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "conflict_error",
                    "code": "verification_not_cancelable",
                    "message": "A verificação está em expired e não pode ser cancelada nem revogada.",
                    "request_id": "req_9Vb4Xk2Lq8Mz",
                    "doc_url": "https://docs.cartaflow.com.br/errors#verification_not_cancelable",
                    "details": null
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/postal-codes/{postal_code}": {
      "get": {
        "operationId": "getPostalCode",
        "tags": [
          "postal_codes"
        ],
        "summary": "Consultar um CEP",
        "description": "Devolve o logradouro, o bairro, a cidade e a UF de um CEP. É a mesma consulta que a API faz para completar os endereços das correspondências. Use para preencher o formulário do seu cliente a partir do CEP. Não tem custo.",
        "parameters": [
          {
            "name": "postal_code",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{5}-?[0-9]{3}$",
              "example": "01001-000"
            },
            "description": "O CEP, com ou sem hífen."
          }
        ],
        "responses": {
          "200": {
            "description": "O endereço do CEP.",
            "headers": {
              "Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PostalCode"
                },
                "example": {
                  "object": "postal_code",
                  "postal_code": "01001-000",
                  "street": "Praça da Sé",
                  "neighborhood": "Sé",
                  "city": "São Paulo",
                  "state": "SP"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "O CEP não existe na base dos Correios.",
            "headers": {
              "Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "not_found_error",
                    "code": "postal_code_not_found",
                    "message": "Não encontramos o CEP 01001-999. Confira os 8 dígitos.",
                    "request_id": "req_9Vb4Xk2Lq8Mz",
                    "doc_url": "https://docs.cartaflow.com.br/errors#postal_code_not_found",
                    "details": null
                  }
                }
              }
            }
          },
          "422": {
            "description": "O CEP não tem 8 dígitos.",
            "headers": {
              "Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "type": "validation_error",
                    "code": "invalid_parameters",
                    "message": "Um campo tem problema. Veja details.",
                    "request_id": "req_9Vb4Xk2Lq8Mz",
                    "doc_url": "https://docs.cartaflow.com.br/errors#invalid_parameters",
                    "details": [
                      {
                        "param": "postal_code",
                        "code": "invalid_format",
                        "message": "O CEP tem 8 dígitos, com ou sem hífen."
                      }
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/account": {
      "get": {
        "operationId": "getAccount",
        "tags": [
          "account"
        ],
        "summary": "Consultar a conta",
        "description": "Devolve os dados da conta dona da chave de API: empresa, CNPJ, plano e remetente padrão. Útil para confirmar a qual conta uma chave pertence, por exemplo em integrações que atendem vários clientes.",
        "responses": {
          "200": {
            "description": "A conta.",
            "headers": {
              "Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Account"
                },
                "example": {
                  "id": "acc_7Jw3Nf8Xq2Lp",
                  "object": "account",
                  "legal_name": "Exemplo Serviços Ltda.",
                  "trade_name": "Exemplo",
                  "cnpj": "12.345.678/0001-90",
                  "plan": "essential",
                  "default_sender": {
                    "name": "Exemplo Serviços Ltda.",
                    "street": "Avenida Exemplo",
                    "number": "1000",
                    "complement": "Sala 301",
                    "neighborhood": "Bela Vista",
                    "city": "São Paulo",
                    "state": "SP",
                    "postal_code": "01310-100"
                  },
                  "created_at": "2026-09-01T12:00:00Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/balance": {
      "get": {
        "operationId": "getBalance",
        "tags": [
          "account"
        ],
        "summary": "Consultar o saldo",
        "description": "Devolve o saldo disponível para novos envios. Consulte antes de um envio grande: uma correspondência só é criada quando o saldo cobre o preço.",
        "responses": {
          "200": {
            "description": "O saldo.",
            "headers": {
              "Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Balance"
                },
                "example": {
                  "object": "balance",
                  "currency": "BRL",
                  "available": 48865,
                  "pending": 0
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/balance/transactions": {
      "get": {
        "operationId": "listBalanceTransactions",
        "tags": [
          "account"
        ],
        "summary": "Listar movimentações do saldo",
        "description": "Devolve as entradas e saídas do saldo, da mais recente para a mais antiga: recargas, débitos de correspondências e verificações, devoluções de cancelamentos, créditos e ajustes. Use para conciliar o custo de cada envio.",
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "top_up",
                "letter",
                "verification",
                "refund",
                "credit",
                "adjustment"
              ],
              "description": "Só movimentações deste tipo.\n\n**Valores possíveis**\n\n- `top_up`: Recargas.\n- `letter`: Débitos de correspondências.\n- `verification`: Débitos de verificações.\n- `refund`: Devoluções de cancelamentos.\n- `credit`: Créditos da CartaFlow.\n- `adjustment`: Ajustes do suporte.",
              "x-enumDescriptions": {
                "top_up": "Recargas.",
                "letter": "Débitos de correspondências.",
                "verification": "Débitos de verificações.",
                "refund": "Devoluções de cancelamentos.",
                "credit": "Créditos da CartaFlow.",
                "adjustment": "Ajustes do suporte."
              }
            },
            "description": "Só movimentações deste tipo."
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/CreatedAfter"
          },
          {
            "$ref": "#/components/parameters/CreatedBefore"
          }
        ],
        "responses": {
          "200": {
            "description": "Uma página de movimentações.",
            "headers": {
              "Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BalanceTransactionList"
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "id": "btx_4Lm8Qw2Zx9Kd",
                      "object": "balance_transaction",
                      "type": "letter",
                      "amount": -1135,
                      "currency": "BRL",
                      "balance_after": 48865,
                      "source_id": "ltr_8Kq2wX4mN7pR",
                      "description": null,
                      "created_at": "2026-10-13T14:20:00Z"
                    },
                    {
                      "id": "btx_1Gs5Vb7Nc3Pf",
                      "object": "balance_transaction",
                      "type": "top_up",
                      "amount": 50000,
                      "currency": "BRL",
                      "balance_after": 50000,
                      "source_id": null,
                      "description": null,
                      "created_at": "2026-10-12T11:02:00Z"
                    }
                  ],
                  "has_more": true,
                  "next_cursor": "eyJpZCI6ImJ0eF8xR3M1VmI3TmMzUGYifQ"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/events": {
      "get": {
        "operationId": "listEvents",
        "tags": [
          "events"
        ],
        "summary": "Listar eventos",
        "description": "Devolve os eventos dos últimos 30 dias, do mais recente para o mais antigo. São os mesmos que os webhooks entregam. Use para recuperar eventos que o seu servidor perdeu, por exemplo durante uma queda, ou para ver a história de um objeto com `object_id`.",
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "letter.scheduled",
                "letter.received",
                "letter.in_production",
                "letter.printed",
                "letter.posted",
                "letter.canceled",
                "letter.failed",
                "letter.updated",
                "verification.received",
                "verification.in_production",
                "verification.awaiting_code",
                "verification.verified",
                "verification.failed",
                "verification.expired",
                "verification.canceled",
                "verification.revoked"
              ],
              "description": "Só eventos deste tipo.\n\n**Valores possíveis**\n\n- `letter.scheduled`: Uma correspondência foi agendada com `send_date`. Ainda não foi cobrada.\n- `letter.received`: Uma correspondência foi cobrada e entrou na fila de produção: logo depois de criada ou, se foi agendada, na data do envio. Vale para correspondências criadas pela API e pelo painel.\n- `letter.in_production`: A correspondência entrou em um lote de impressão e não pode mais ser cancelada.\n- `letter.printed`: A correspondência foi impressa e envelopada.\n- `letter.posted`: A correspondência foi entregue aos Correios. É o último evento de uma correspondência enviada.\n- `letter.canceled`: A correspondência foi cancelada. Veja `cancellation_reason`: `requested` quando você cancelou, `insufficient_balance` quando uma correspondência agendada não pôde ser cobrada na data.\n- `letter.failed`: A correspondência falhou na produção e não será postada. O valor voltou para o saldo automaticamente. Veja `failure_reason`.\n- `letter.updated`: A correspondência foi alterada no painel antes da produção, sem mudar de status: data de envio, endereço, arquivo, variáveis, impressão, serviços dos Correios ou referência. `data` traz a correspondência como ficou. Se a mudança alterou o preço de uma correspondência agendada, `price` traz o novo valor.\n- `verification.received`: Uma verificação foi criada, pela API ou pelo painel (veja `source`), e a correspondência com o código está na fila de produção.\n- `verification.in_production`: A correspondência com o código está sendo impressa. A partir daqui, cancelar revoga a verificação, sem devolução.\n- `verification.awaiting_code`: A correspondência com o código foi postada. A pessoa já pode confirmar quando receber.\n- `verification.verified`: A pessoa confirmou o código certo. O endereço está verificado.\n- `verification.failed`: Foram digitados 5 códigos errados e a verificação foi bloqueada.\n- `verification.expired`: A pessoa não confirmou o código em 60 dias desde a postagem.\n- `verification.canceled`: A verificação foi cancelada antes da postagem, por você ou pela CartaFlow, e o valor voltou para o saldo.\n- `verification.revoked`: Você cancelou a verificação depois que a produção começou. O código deixou de funcionar e o valor não volta para o saldo. Se ela estava `verified`, trate o endereço como não verificado.",
              "x-enumDescriptions": {
                "letter.scheduled": "Uma correspondência foi agendada com `send_date`. Ainda não foi cobrada.",
                "letter.received": "Uma correspondência foi cobrada e entrou na fila de produção: logo depois de criada ou, se foi agendada, na data do envio. Vale para correspondências criadas pela API e pelo painel.",
                "letter.in_production": "A correspondência entrou em um lote de impressão e não pode mais ser cancelada.",
                "letter.printed": "A correspondência foi impressa e envelopada.",
                "letter.posted": "A correspondência foi entregue aos Correios. É o último evento de uma correspondência enviada.",
                "letter.canceled": "A correspondência foi cancelada. Veja `cancellation_reason`: `requested` quando você cancelou, `insufficient_balance` quando uma correspondência agendada não pôde ser cobrada na data.",
                "letter.failed": "A correspondência falhou na produção e não será postada. O valor voltou para o saldo automaticamente. Veja `failure_reason`.",
                "letter.updated": "A correspondência foi alterada no painel antes da produção, sem mudar de status: data de envio, endereço, arquivo, variáveis, impressão, serviços dos Correios ou referência. `data` traz a correspondência como ficou. Se a mudança alterou o preço de uma correspondência agendada, `price` traz o novo valor.",
                "verification.received": "Uma verificação foi criada, pela API ou pelo painel (veja `source`), e a correspondência com o código está na fila de produção.",
                "verification.in_production": "A correspondência com o código está sendo impressa. A partir daqui, cancelar revoga a verificação, sem devolução.",
                "verification.awaiting_code": "A correspondência com o código foi postada. A pessoa já pode confirmar quando receber.",
                "verification.verified": "A pessoa confirmou o código certo. O endereço está verificado.",
                "verification.failed": "Foram digitados 5 códigos errados e a verificação foi bloqueada.",
                "verification.expired": "A pessoa não confirmou o código em 60 dias desde a postagem.",
                "verification.canceled": "A verificação foi cancelada antes da postagem, por você ou pela CartaFlow, e o valor voltou para o saldo.",
                "verification.revoked": "Você cancelou a verificação depois que a produção começou. O código deixou de funcionar e o valor não volta para o saldo. Se ela estava `verified`, trate o endereço como não verificado."
              }
            },
            "description": "Só eventos deste tipo."
          },
          {
            "name": "object_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "example": "ltr_8Kq2wX4mN7pR"
            },
            "description": "Só eventos deste objeto, como uma correspondência (`ltr_`) ou uma verificação (`ver_`)."
          },
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Cursor"
          },
          {
            "$ref": "#/components/parameters/CreatedAfter"
          },
          {
            "$ref": "#/components/parameters/CreatedBefore"
          }
        ],
        "responses": {
          "200": {
            "description": "Uma página de eventos.",
            "headers": {
              "Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventList"
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "id": "evt_6Tq1Yz8Wm3Rb",
                      "object": "event",
                      "type": "letter.posted",
                      "data": {
                        "id": "ltr_8Kq2wX4mN7pR",
                        "object": "letter",
                        "status": "posted",
                        "to": {
                          "name": "Destinatário Exemplo",
                          "street": "Praça da Sé",
                          "number": "128",
                          "complement": "Ap. 52",
                          "neighborhood": "Sé",
                          "city": "São Paulo",
                          "state": "SP",
                          "postal_code": "01001-000"
                        },
                        "from": {
                          "name": "Exemplo Serviços Ltda.",
                          "street": "Avenida Exemplo",
                          "number": "1000",
                          "complement": "Sala 301",
                          "neighborhood": "Bela Vista",
                          "city": "São Paulo",
                          "state": "SP",
                          "postal_code": "01310-100"
                        },
                        "document": {
                          "type": "url",
                          "url": "https://arquivos.exemplo.com.br/faturas/2026-10-0042.pdf",
                          "variables": null
                        },
                        "color": true,
                        "double_sided": false,
                        "address_placement": "first_page",
                        "postal_services": [],
                        "pages": 2,
                        "sheets": 2,
                        "price": {
                          "currency": "BRL",
                          "total": 1135,
                          "items": [
                            {
                              "type": "base",
                              "quantity": 1,
                              "unit_amount": 990,
                              "amount": 990
                            },
                            {
                              "type": "additional_sheets",
                              "quantity": 1,
                              "unit_amount": 75,
                              "amount": 75
                            },
                            {
                              "type": "color",
                              "quantity": 2,
                              "unit_amount": 35,
                              "amount": 70
                            }
                          ]
                        },
                        "send_date": null,
                        "cancellation_reason": null,
                        "failure_reason": null,
                        "tracking_code": null,
                        "preview_url": "https://files.cartaflow.com.br/previews/ltr_8Kq2wX4mN7pR.pdf?expires=1760369400&signature=9c1f2a7d",
                        "reference": "fatura-2026-10-0042",
                        "metadata": {
                          "customer_id": "1842"
                        },
                        "status_transitions": {
                          "received_at": "2026-10-13T14:20:00Z",
                          "in_production_at": "2026-10-13T21:00:00Z",
                          "printed_at": "2026-10-14T10:42:00Z",
                          "posted_at": "2026-10-14T16:05:00Z",
                          "canceled_at": null,
                          "failed_at": null
                        },
                        "created_at": "2026-10-13T14:20:00Z"
                      },
                      "created_at": "2026-10-14T16:05:00Z"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/events/{event_id}": {
      "get": {
        "operationId": "getEvent",
        "tags": [
          "events"
        ],
        "summary": "Consultar um evento",
        "description": "Devolve um evento. O objeto em `data` é uma foto do momento do evento, não o estado atual: para o estado atual, consulte o objeto pelo id.",
        "parameters": [
          {
            "$ref": "#/components/parameters/EventId"
          }
        ],
        "responses": {
          "200": {
            "description": "O evento.",
            "headers": {
              "Request-Id": {
                "$ref": "#/components/headers/RequestId"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Event"
                },
                "example": {
                  "id": "evt_6Tq1Yz8Wm3Rb",
                  "object": "event",
                  "type": "letter.posted",
                  "data": {
                    "id": "ltr_8Kq2wX4mN7pR",
                    "object": "letter",
                    "status": "posted",
                    "to": {
                      "name": "Destinatário Exemplo",
                      "street": "Praça da Sé",
                      "number": "128",
                      "complement": "Ap. 52",
                      "neighborhood": "Sé",
                      "city": "São Paulo",
                      "state": "SP",
                      "postal_code": "01001-000"
                    },
                    "from": {
                      "name": "Exemplo Serviços Ltda.",
                      "street": "Avenida Exemplo",
                      "number": "1000",
                      "complement": "Sala 301",
                      "neighborhood": "Bela Vista",
                      "city": "São Paulo",
                      "state": "SP",
                      "postal_code": "01310-100"
                    },
                    "document": {
                      "type": "url",
                      "url": "https://arquivos.exemplo.com.br/faturas/2026-10-0042.pdf",
                      "variables": null
                    },
                    "color": true,
                    "double_sided": false,
                    "address_placement": "first_page",
                    "postal_services": [],
                    "pages": 2,
                    "sheets": 2,
                    "price": {
                      "currency": "BRL",
                      "total": 1135,
                      "items": [
                        {
                          "type": "base",
                          "quantity": 1,
                          "unit_amount": 990,
                          "amount": 990
                        },
                        {
                          "type": "additional_sheets",
                          "quantity": 1,
                          "unit_amount": 75,
                          "amount": 75
                        },
                        {
                          "type": "color",
                          "quantity": 2,
                          "unit_amount": 35,
                          "amount": 70
                        }
                      ]
                    },
                    "send_date": null,
                    "cancellation_reason": null,
                    "failure_reason": null,
                    "tracking_code": null,
                    "preview_url": "https://files.cartaflow.com.br/previews/ltr_8Kq2wX4mN7pR.pdf?expires=1760369400&signature=9c1f2a7d",
                    "reference": "fatura-2026-10-0042",
                    "metadata": {
                      "customer_id": "1842"
                    },
                    "status_transitions": {
                      "received_at": "2026-10-13T14:20:00Z",
                      "in_production_at": "2026-10-13T21:00:00Z",
                      "printed_at": "2026-10-14T10:42:00Z",
                      "posted_at": "2026-10-14T16:05:00Z",
                      "canceled_at": null,
                      "failed_at": null
                    },
                    "created_at": "2026-10-13T14:20:00Z"
                  },
                  "created_at": "2026-10-14T16:05:00Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    }
  },
  "webhooks": {
    "letter-events": {
      "post": {
        "operationId": "letterEvents",
        "tags": [
          "webhooks"
        ],
        "summary": "Eventos de correspondência",
        "description": "A CartaFlow faz um POST para a URL do seu webhook a cada mudança de status de uma correspondência, e com `letter.updated` quando ela é alterada no painel antes da produção, com o evento no corpo. `data` traz a correspondência inteira, então você não precisa consultar a API depois.",
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "evt_6Tq1Yz8Wm3Rb"
            },
            "description": "Id do evento. Igual em todas as tentativas de entrega do mesmo evento: use para ignorar repetições."
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "1760457900"
            },
            "description": "Momento do envio em segundos Unix. Recuse entregas com mais de 5 minutos de diferença do seu relógio."
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "v1,K5oZfzN95Z9UVu1EsfQmfVNQhnkZ2pj9o9NDN/H/pI4="
            },
            "description": "Assinatura HMAC-SHA256 no padrão Standard Webhooks. Confira antes de confiar no conteúdo; veja o guia Webhooks."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/Event"
                  }
                ],
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": [
                      "letter.scheduled",
                      "letter.received",
                      "letter.in_production",
                      "letter.printed",
                      "letter.posted",
                      "letter.canceled",
                      "letter.failed",
                      "letter.updated"
                    ],
                    "description": "O tipo do evento.\n\n**Valores possíveis**\n\n- `letter.scheduled`: Uma correspondência foi agendada com `send_date`. Ainda não foi cobrada.\n- `letter.received`: Uma correspondência foi cobrada e entrou na fila de produção: logo depois de criada ou, se foi agendada, na data do envio. Vale para correspondências criadas pela API e pelo painel.\n- `letter.in_production`: A correspondência entrou em um lote de impressão e não pode mais ser cancelada.\n- `letter.printed`: A correspondência foi impressa e envelopada.\n- `letter.posted`: A correspondência foi entregue aos Correios. É o último evento de uma correspondência enviada.\n- `letter.canceled`: A correspondência foi cancelada. Veja `cancellation_reason`: `requested` quando você cancelou, `insufficient_balance` quando uma correspondência agendada não pôde ser cobrada na data.\n- `letter.failed`: A correspondência falhou na produção e não será postada. O valor voltou para o saldo automaticamente. Veja `failure_reason`.\n- `letter.updated`: A correspondência foi alterada no painel antes da produção, sem mudar de status: data de envio, endereço, arquivo, variáveis, impressão, serviços dos Correios ou referência. `data` traz a correspondência como ficou. Se a mudança alterou o preço de uma correspondência agendada, `price` traz o novo valor.",
                    "x-enumDescriptions": {
                      "letter.scheduled": "Uma correspondência foi agendada com `send_date`. Ainda não foi cobrada.",
                      "letter.received": "Uma correspondência foi cobrada e entrou na fila de produção: logo depois de criada ou, se foi agendada, na data do envio. Vale para correspondências criadas pela API e pelo painel.",
                      "letter.in_production": "A correspondência entrou em um lote de impressão e não pode mais ser cancelada.",
                      "letter.printed": "A correspondência foi impressa e envelopada.",
                      "letter.posted": "A correspondência foi entregue aos Correios. É o último evento de uma correspondência enviada.",
                      "letter.canceled": "A correspondência foi cancelada. Veja `cancellation_reason`: `requested` quando você cancelou, `insufficient_balance` quando uma correspondência agendada não pôde ser cobrada na data.",
                      "letter.failed": "A correspondência falhou na produção e não será postada. O valor voltou para o saldo automaticamente. Veja `failure_reason`.",
                      "letter.updated": "A correspondência foi alterada no painel antes da produção, sem mudar de status: data de envio, endereço, arquivo, variáveis, impressão, serviços dos Correios ou referência. `data` traz a correspondência como ficou. Se a mudança alterou o preço de uma correspondência agendada, `price` traz o novo valor."
                    }
                  },
                  "data": {
                    "$ref": "#/components/schemas/Letter"
                  }
                }
              },
              "example": {
                "id": "evt_6Tq1Yz8Wm3Rb",
                "object": "event",
                "type": "letter.posted",
                "data": {
                  "id": "ltr_8Kq2wX4mN7pR",
                  "object": "letter",
                  "status": "posted",
                  "to": {
                    "name": "Destinatário Exemplo",
                    "street": "Praça da Sé",
                    "number": "128",
                    "complement": "Ap. 52",
                    "neighborhood": "Sé",
                    "city": "São Paulo",
                    "state": "SP",
                    "postal_code": "01001-000"
                  },
                  "from": {
                    "name": "Exemplo Serviços Ltda.",
                    "street": "Avenida Exemplo",
                    "number": "1000",
                    "complement": "Sala 301",
                    "neighborhood": "Bela Vista",
                    "city": "São Paulo",
                    "state": "SP",
                    "postal_code": "01310-100"
                  },
                  "document": {
                    "type": "url",
                    "url": "https://arquivos.exemplo.com.br/faturas/2026-10-0042.pdf",
                    "variables": null
                  },
                  "color": true,
                  "double_sided": false,
                  "address_placement": "first_page",
                  "postal_services": [],
                  "pages": 2,
                  "sheets": 2,
                  "price": {
                    "currency": "BRL",
                    "total": 1135,
                    "items": [
                      {
                        "type": "base",
                        "quantity": 1,
                        "unit_amount": 990,
                        "amount": 990
                      },
                      {
                        "type": "additional_sheets",
                        "quantity": 1,
                        "unit_amount": 75,
                        "amount": 75
                      },
                      {
                        "type": "color",
                        "quantity": 2,
                        "unit_amount": 35,
                        "amount": 70
                      }
                    ]
                  },
                  "send_date": null,
                  "cancellation_reason": null,
                  "failure_reason": null,
                  "tracking_code": null,
                  "preview_url": "https://files.cartaflow.com.br/previews/ltr_8Kq2wX4mN7pR.pdf?expires=1760369400&signature=9c1f2a7d",
                  "reference": "fatura-2026-10-0042",
                  "metadata": {
                    "customer_id": "1842"
                  },
                  "status_transitions": {
                    "received_at": "2026-10-13T14:20:00Z",
                    "in_production_at": "2026-10-13T21:00:00Z",
                    "printed_at": "2026-10-14T10:42:00Z",
                    "posted_at": "2026-10-14T16:05:00Z",
                    "canceled_at": null,
                    "failed_at": null
                  },
                  "created_at": "2026-10-13T14:20:00Z"
                },
                "created_at": "2026-10-14T16:05:00Z"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Responda com qualquer status 2xx em até 15 segundos para confirmar o recebimento. Faça o processamento demorado depois de responder."
          },
          "default": {
            "description": "Qualquer outra resposta, ou nenhuma resposta a tempo, faz a CartaFlow tentar de novo mais tarde."
          }
        }
      }
    },
    "verification-events": {
      "post": {
        "operationId": "verificationEvents",
        "tags": [
          "webhooks"
        ],
        "summary": "Eventos de verificação",
        "description": "A CartaFlow faz um POST para a URL do seu webhook a cada mudança de status de uma verificação, criada pela API ou pelo painel. O evento mais importante é `verification.verified`: o endereço foi confirmado, e `data.confirmation` diz como. Trate também `verification.revoked`: uma verificação revogada, mesmo que tenha sido confirmada, não conta mais como verificada. `data.preview_url` vem `null`: consulte a verificação para receber o link.",
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "evt_6Tq1Yz8Wm3Rb"
            },
            "description": "Id do evento. Igual em todas as tentativas de entrega do mesmo evento: use para ignorar repetições."
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "1760457900"
            },
            "description": "Momento do envio em segundos Unix. Recuse entregas com mais de 5 minutos de diferença do seu relógio."
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "v1,K5oZfzN95Z9UVu1EsfQmfVNQhnkZ2pj9o9NDN/H/pI4="
            },
            "description": "Assinatura HMAC-SHA256 no padrão Standard Webhooks. Confira antes de confiar no conteúdo; veja o guia Webhooks."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/Event"
                  }
                ],
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": [
                      "verification.received",
                      "verification.in_production",
                      "verification.awaiting_code",
                      "verification.verified",
                      "verification.failed",
                      "verification.expired",
                      "verification.canceled",
                      "verification.revoked"
                    ],
                    "description": "O tipo do evento.\n\n**Valores possíveis**\n\n- `verification.received`: Uma verificação foi criada, pela API ou pelo painel (veja `source`), e a correspondência com o código está na fila de produção.\n- `verification.in_production`: A correspondência com o código está sendo impressa. A partir daqui, cancelar revoga a verificação, sem devolução.\n- `verification.awaiting_code`: A correspondência com o código foi postada. A pessoa já pode confirmar quando receber.\n- `verification.verified`: A pessoa confirmou o código certo. O endereço está verificado.\n- `verification.failed`: Foram digitados 5 códigos errados e a verificação foi bloqueada.\n- `verification.expired`: A pessoa não confirmou o código em 60 dias desde a postagem.\n- `verification.canceled`: A verificação foi cancelada antes da postagem, por você ou pela CartaFlow, e o valor voltou para o saldo.\n- `verification.revoked`: Você cancelou a verificação depois que a produção começou. O código deixou de funcionar e o valor não volta para o saldo. Se ela estava `verified`, trate o endereço como não verificado.",
                    "x-enumDescriptions": {
                      "verification.received": "Uma verificação foi criada, pela API ou pelo painel (veja `source`), e a correspondência com o código está na fila de produção.",
                      "verification.in_production": "A correspondência com o código está sendo impressa. A partir daqui, cancelar revoga a verificação, sem devolução.",
                      "verification.awaiting_code": "A correspondência com o código foi postada. A pessoa já pode confirmar quando receber.",
                      "verification.verified": "A pessoa confirmou o código certo. O endereço está verificado.",
                      "verification.failed": "Foram digitados 5 códigos errados e a verificação foi bloqueada.",
                      "verification.expired": "A pessoa não confirmou o código em 60 dias desde a postagem.",
                      "verification.canceled": "A verificação foi cancelada antes da postagem, por você ou pela CartaFlow, e o valor voltou para o saldo.",
                      "verification.revoked": "Você cancelou a verificação depois que a produção começou. O código deixou de funcionar e o valor não volta para o saldo. Se ela estava `verified`, trate o endereço como não verificado."
                    }
                  },
                  "data": {
                    "$ref": "#/components/schemas/Verification"
                  }
                }
              },
              "examples": {
                "verified": {
                  "summary": "Verificada",
                  "value": {
                    "id": "evt_2Kp9Xc4Vn7Ld",
                    "object": "event",
                    "type": "verification.verified",
                    "data": {
                      "id": "ver_3Hd9Kp2qZ6tW",
                      "object": "verification",
                      "status": "verified",
                      "method": "hosted_page",
                      "source": "api",
                      "to": {
                        "name": "Destinatário Exemplo",
                        "street": "Praça da Sé",
                        "number": "128",
                        "complement": "Ap. 52",
                        "neighborhood": "Sé",
                        "city": "São Paulo",
                        "state": "SP",
                        "postal_code": "01001-000"
                      },
                      "document": {
                        "type": "template",
                        "title": "Confirme o seu endereço",
                        "body": "{{empresa}} pediu a confirmação de que você recebe correspondência neste endereço. Use o código abaixo para confirmar.",
                        "footer": "O código vale por 60 dias depois da postagem e só funciona para este endereço. Não compartilhe este código com ninguém.",
                        "include_qr_code": true,
                        "include_page_url": true
                      },
                      "instructions": null,
                      "return_url": "https://www.exemplo.com.br/conta",
                      "hosted_page_url": "https://verifica.cartaflow.com.br/acc_7Jw3Nf8Xq2Lp/9Qx2Lm7Tp4Rb8Kd3Wn6Yc1",
                      "attempts_remaining": 5,
                      "expires_at": "2026-12-14T16:05:00Z",
                      "confirmation": {
                        "method": "hosted_page",
                        "hosted_page_entry": "qr_code",
                        "confirmed_at": "2026-10-21T19:32:00Z",
                        "ip": "198.51.100.23",
                        "location": {
                          "city": "São Paulo",
                          "region": "SP",
                          "country": "BR",
                          "postal_code": "01000",
                          "latitude": -23.5475,
                          "longitude": -46.6361
                        },
                        "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1",
                        "device": {
                          "type": "mobile",
                          "os": {
                            "name": "iOS",
                            "version": "17.5"
                          },
                          "browser": {
                            "name": "Safari",
                            "version": "17.5"
                          }
                        },
                        "client": {
                          "language": "pt-BR",
                          "accept_language": "pt-BR,pt;q=0.9",
                          "timezone": "America/Sao_Paulo",
                          "screen": {
                            "width": 390,
                            "height": 844,
                            "pixel_ratio": 3
                          },
                          "time_on_page_ms": 8100
                        },
                        "precise_location": {
                          "latitude": -23.5489,
                          "longitude": -46.6388,
                          "accuracy_m": 14.5,
                          "distance_m": 606,
                          "shared_at": "2026-10-21T19:32:40Z",
                          "ip": "198.51.100.23",
                          "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1",
                          "address_coordinates": {
                            "latitude": -23.5503898,
                            "longitude": -46.633081
                          }
                        }
                      },
                      "preview_url": null,
                      "price": {
                        "currency": "BRL",
                        "total": 990,
                        "items": [
                          {
                            "type": "base",
                            "quantity": 1,
                            "unit_amount": 990,
                            "amount": 990
                          }
                        ]
                      },
                      "reference": "cliente-1842",
                      "metadata": {},
                      "status_transitions": {
                        "in_production_at": "2026-10-13T21:00:00Z",
                        "awaiting_code_at": "2026-10-15T16:05:00Z",
                        "verified_at": "2026-10-21T19:32:00Z",
                        "failed_at": null,
                        "expired_at": null,
                        "canceled_at": null,
                        "revoked_at": null
                      },
                      "created_at": "2026-10-13T14:20:00Z"
                    },
                    "created_at": "2026-10-21T19:32:00Z"
                  }
                },
                "revoked": {
                  "summary": "Revogada",
                  "value": {
                    "id": "evt_9Rm3Hb6Tx1Wf",
                    "object": "event",
                    "type": "verification.revoked",
                    "data": {
                      "id": "ver_3Hd9Kp2qZ6tW",
                      "object": "verification",
                      "status": "revoked",
                      "method": "hosted_page",
                      "source": "api",
                      "to": {
                        "name": "Destinatário Exemplo",
                        "street": "Praça da Sé",
                        "number": "128",
                        "complement": "Ap. 52",
                        "neighborhood": "Sé",
                        "city": "São Paulo",
                        "state": "SP",
                        "postal_code": "01001-000"
                      },
                      "document": {
                        "type": "template",
                        "title": "Confirme o seu endereço",
                        "body": "{{empresa}} pediu a confirmação de que você recebe correspondência neste endereço. Use o código abaixo para confirmar.",
                        "footer": "O código vale por 60 dias depois da postagem e só funciona para este endereço. Não compartilhe este código com ninguém.",
                        "include_qr_code": true,
                        "include_page_url": true
                      },
                      "instructions": null,
                      "return_url": "https://www.exemplo.com.br/conta",
                      "hosted_page_url": "https://verifica.cartaflow.com.br/acc_7Jw3Nf8Xq2Lp/9Qx2Lm7Tp4Rb8Kd3Wn6Yc1",
                      "attempts_remaining": 5,
                      "expires_at": "2026-12-14T16:05:00Z",
                      "confirmation": {
                        "method": "hosted_page",
                        "hosted_page_entry": "qr_code",
                        "confirmed_at": "2026-10-21T19:32:00Z",
                        "ip": "198.51.100.23",
                        "location": {
                          "city": "São Paulo",
                          "region": "SP",
                          "country": "BR",
                          "postal_code": "01000",
                          "latitude": -23.5475,
                          "longitude": -46.6361
                        },
                        "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1",
                        "device": {
                          "type": "mobile",
                          "os": {
                            "name": "iOS",
                            "version": "17.5"
                          },
                          "browser": {
                            "name": "Safari",
                            "version": "17.5"
                          }
                        },
                        "client": {
                          "language": "pt-BR",
                          "accept_language": "pt-BR,pt;q=0.9",
                          "timezone": "America/Sao_Paulo",
                          "screen": {
                            "width": 390,
                            "height": 844,
                            "pixel_ratio": 3
                          },
                          "time_on_page_ms": 8100
                        },
                        "precise_location": {
                          "latitude": -23.5489,
                          "longitude": -46.6388,
                          "accuracy_m": 14.5,
                          "distance_m": 606,
                          "shared_at": "2026-10-21T19:32:40Z",
                          "ip": "198.51.100.23",
                          "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1",
                          "address_coordinates": {
                            "latitude": -23.5503898,
                            "longitude": -46.633081
                          }
                        }
                      },
                      "preview_url": null,
                      "price": {
                        "currency": "BRL",
                        "total": 990,
                        "items": [
                          {
                            "type": "base",
                            "quantity": 1,
                            "unit_amount": 990,
                            "amount": 990
                          }
                        ]
                      },
                      "reference": "cliente-1842",
                      "metadata": {},
                      "status_transitions": {
                        "in_production_at": "2026-10-13T21:00:00Z",
                        "awaiting_code_at": "2026-10-15T16:05:00Z",
                        "verified_at": "2026-10-21T19:32:00Z",
                        "failed_at": null,
                        "expired_at": null,
                        "canceled_at": null,
                        "revoked_at": "2026-10-23T12:10:00Z"
                      },
                      "created_at": "2026-10-13T14:20:00Z"
                    },
                    "created_at": "2026-10-23T12:10:00Z"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Responda com qualquer status 2xx em até 15 segundos para confirmar o recebimento. Faça o processamento demorado depois de responder."
          },
          "default": {
            "description": "Qualquer outra resposta, ou nenhuma resposta a tempo, faz a CartaFlow tentar de novo mais tarde."
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "Chave de API no cabeçalho `Authorization: Bearer cf_live_...`. Crie e revogue chaves no painel, em Desenvolvedores > Chaves de API."
      }
    },
    "schemas": {
      "AddressInput": {
        "type": "object",
        "title": "AddressInput",
        "description": "Um endereço no Brasil. Só `name`, `postal_code` e `number` são obrigatórios: os campos que você não enviar são preenchidos a partir do CEP, e os que você enviar são usados como vieram. Por exemplo, com o CEP e o bairro, usamos o seu bairro e buscamos o logradouro, a cidade e a UF pelo CEP. Se um campo não vier e o CEP não o informar, a API responde 422 com `address_incomplete` e nada é criado.",
        "required": [
          "name",
          "number",
          "postal_code"
        ],
        "additionalProperties": false,
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 60,
            "description": "Nome da pessoa ou da empresa, como deve aparecer no envelope. Até 60 caracteres.",
            "example": "Destinatário Exemplo"
          },
          "postal_code": {
            "type": "string",
            "pattern": "^[0-9]{5}-?[0-9]{3}$",
            "description": "CEP com 8 dígitos, com ou sem hífen: `01001-000` ou `01001000`. Precisa existir na base de CEPs; é dele que vêm os campos que você não enviar. Nas respostas ele sempre volta com hífen.",
            "example": "01001-000"
          },
          "number": {
            "type": "string",
            "minLength": 1,
            "maxLength": 10,
            "description": "Número do imóvel. É texto porque alguns números têm letras, como `128A`. Use `S/N` quando o endereço não tem número. Até 10 caracteres.",
            "example": "128"
          },
          "complement": {
            "type": "string",
            "maxLength": 60,
            "description": "Complemento: apartamento, bloco, sala, andar. Até 60 caracteres.",
            "example": "Ap. 52"
          },
          "street": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "description": "Logradouro, com o tipo e o nome: rua, avenida, travessa, praça. Sem o número. Até 100 caracteres. Opcional: quando você não envia, preenchemos a partir do CEP. Quando envia, usamos o seu valor.",
            "example": "Praça da Sé"
          },
          "neighborhood": {
            "type": "string",
            "minLength": 1,
            "maxLength": 60,
            "description": "Bairro. Até 60 caracteres. Opcional: quando você não envia, preenchemos a partir do CEP. Quando envia, usamos o seu valor.",
            "example": "Sé"
          },
          "city": {
            "type": "string",
            "minLength": 1,
            "maxLength": 60,
            "description": "Cidade. Até 60 caracteres. Opcional: quando você não envia, preenchemos a partir do CEP. Quando envia, usamos o seu valor.",
            "example": "São Paulo"
          },
          "state": {
            "type": "string",
            "enum": [
              "AC",
              "AL",
              "AP",
              "AM",
              "BA",
              "CE",
              "DF",
              "ES",
              "GO",
              "MA",
              "MT",
              "MS",
              "MG",
              "PA",
              "PB",
              "PR",
              "PE",
              "PI",
              "RJ",
              "RN",
              "RS",
              "RO",
              "RR",
              "SC",
              "SP",
              "SE",
              "TO"
            ],
            "description": "UF: a sigla do estado, com duas letras maiúsculas.\n\nOpcional: quando você não envia, preenchemos a partir do CEP. Quando envia, usamos o seu valor.\n\n**Valores possíveis**\n\n- `AC`: Acre\n- `AL`: Alagoas\n- `AP`: Amapá\n- `AM`: Amazonas\n- `BA`: Bahia\n- `CE`: Ceará\n- `DF`: Distrito Federal\n- `ES`: Espírito Santo\n- `GO`: Goiás\n- `MA`: Maranhão\n- `MT`: Mato Grosso\n- `MS`: Mato Grosso do Sul\n- `MG`: Minas Gerais\n- `PA`: Pará\n- `PB`: Paraíba\n- `PR`: Paraná\n- `PE`: Pernambuco\n- `PI`: Piauí\n- `RJ`: Rio de Janeiro\n- `RN`: Rio Grande do Norte\n- `RS`: Rio Grande do Sul\n- `RO`: Rondônia\n- `RR`: Roraima\n- `SC`: Santa Catarina\n- `SP`: São Paulo\n- `SE`: Sergipe\n- `TO`: Tocantins",
            "x-enumDescriptions": {
              "AC": "Acre",
              "AL": "Alagoas",
              "AP": "Amapá",
              "AM": "Amazonas",
              "BA": "Bahia",
              "CE": "Ceará",
              "DF": "Distrito Federal",
              "ES": "Espírito Santo",
              "GO": "Goiás",
              "MA": "Maranhão",
              "MT": "Mato Grosso",
              "MS": "Mato Grosso do Sul",
              "MG": "Minas Gerais",
              "PA": "Pará",
              "PB": "Paraíba",
              "PR": "Paraná",
              "PE": "Pernambuco",
              "PI": "Piauí",
              "RJ": "Rio de Janeiro",
              "RN": "Rio Grande do Norte",
              "RS": "Rio Grande do Sul",
              "RO": "Rondônia",
              "RR": "Roraima",
              "SC": "Santa Catarina",
              "SP": "São Paulo",
              "SE": "Sergipe",
              "TO": "Tocantins"
            },
            "example": "SP"
          }
        },
        "example": {
          "name": "Destinatário Exemplo",
          "postal_code": "01001-000",
          "number": "128",
          "complement": "Ap. 52"
        }
      },
      "Address": {
        "type": "object",
        "title": "Address",
        "description": "Um endereço no Brasil, completo, como a CartaFlow imprime: os campos que você enviou e os que preenchemos a partir do CEP.",
        "required": [
          "name",
          "street",
          "number",
          "complement",
          "neighborhood",
          "city",
          "state",
          "postal_code"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 60,
            "description": "Nome da pessoa ou da empresa, como deve aparecer no envelope. Até 60 caracteres.",
            "example": "Destinatário Exemplo"
          },
          "street": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "description": "Logradouro, com o tipo e o nome: rua, avenida, travessa, praça. Sem o número. Até 100 caracteres.",
            "example": "Praça da Sé"
          },
          "number": {
            "type": "string",
            "minLength": 1,
            "maxLength": 10,
            "description": "Número do imóvel. É texto porque alguns números têm letras, como `128A`. Use `S/N` quando o endereço não tem número. Até 10 caracteres.",
            "example": "128"
          },
          "complement": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 60,
            "description": "Complemento: apartamento, bloco, sala, andar. `null` quando o endereço não tem.",
            "example": "Ap. 52"
          },
          "neighborhood": {
            "type": "string",
            "minLength": 1,
            "maxLength": 60,
            "description": "Bairro. Até 60 caracteres.",
            "example": "Sé"
          },
          "city": {
            "type": "string",
            "minLength": 1,
            "maxLength": 60,
            "description": "Cidade. Até 60 caracteres.",
            "example": "São Paulo"
          },
          "state": {
            "type": "string",
            "enum": [
              "AC",
              "AL",
              "AP",
              "AM",
              "BA",
              "CE",
              "DF",
              "ES",
              "GO",
              "MA",
              "MT",
              "MS",
              "MG",
              "PA",
              "PB",
              "PR",
              "PE",
              "PI",
              "RJ",
              "RN",
              "RS",
              "RO",
              "RR",
              "SC",
              "SP",
              "SE",
              "TO"
            ],
            "description": "UF: a sigla do estado.\n\n**Valores possíveis**\n\n- `AC`: Acre\n- `AL`: Alagoas\n- `AP`: Amapá\n- `AM`: Amazonas\n- `BA`: Bahia\n- `CE`: Ceará\n- `DF`: Distrito Federal\n- `ES`: Espírito Santo\n- `GO`: Goiás\n- `MA`: Maranhão\n- `MT`: Mato Grosso\n- `MS`: Mato Grosso do Sul\n- `MG`: Minas Gerais\n- `PA`: Pará\n- `PB`: Paraíba\n- `PR`: Paraná\n- `PE`: Pernambuco\n- `PI`: Piauí\n- `RJ`: Rio de Janeiro\n- `RN`: Rio Grande do Norte\n- `RS`: Rio Grande do Sul\n- `RO`: Rondônia\n- `RR`: Roraima\n- `SC`: Santa Catarina\n- `SP`: São Paulo\n- `SE`: Sergipe\n- `TO`: Tocantins",
            "x-enumDescriptions": {
              "AC": "Acre",
              "AL": "Alagoas",
              "AP": "Amapá",
              "AM": "Amazonas",
              "BA": "Bahia",
              "CE": "Ceará",
              "DF": "Distrito Federal",
              "ES": "Espírito Santo",
              "GO": "Goiás",
              "MA": "Maranhão",
              "MT": "Mato Grosso",
              "MS": "Mato Grosso do Sul",
              "MG": "Minas Gerais",
              "PA": "Pará",
              "PB": "Paraíba",
              "PR": "Paraná",
              "PE": "Pernambuco",
              "PI": "Piauí",
              "RJ": "Rio de Janeiro",
              "RN": "Rio Grande do Norte",
              "RS": "Rio Grande do Sul",
              "RO": "Rondônia",
              "RR": "Roraima",
              "SC": "Santa Catarina",
              "SP": "São Paulo",
              "SE": "Sergipe",
              "TO": "Tocantins"
            },
            "example": "SP"
          },
          "postal_code": {
            "type": "string",
            "pattern": "^[0-9]{5}-[0-9]{3}$",
            "description": "CEP, sempre no formato `00000-000`.",
            "example": "01001-000"
          }
        }
      },
      "PriceItem": {
        "type": "object",
        "title": "PriceItem",
        "description": "Uma linha do preço.",
        "required": [
          "type",
          "quantity",
          "unit_amount",
          "amount"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "base",
              "additional_sheets",
              "color",
              "registered",
              "return_receipt",
              "restricted_delivery"
            ],
            "description": "O que esta linha cobra.\n\n**Valores possíveis**\n\n- `base`: Envio simples (carta simples): a primeira folha impressa em preto e branco, o envelope e a postagem. Uma por correspondência ou verificação.\n- `additional_sheets`: Folhas do documento além da primeira, cobradas por folha. O endereço nunca é cobrado, mesmo quando `extra_page` acrescenta uma folha. `quantity` é o número de folhas adicionais.\n- `color`: Impressão colorida, cobrada por página impressa: cada lado impresso de uma folha conta como uma página. `quantity` é o número de páginas impressas em cores. O lado do endereço nunca é colorido nem cobrado.\n- `registered`: Carta registrada, com código de rastreio dos Correios. `quantity` é sempre 1.\n- `return_receipt`: Aviso de recebimento (AR). `quantity` é sempre 1.\n- `restricted_delivery`: Mão própria (MP). `quantity` é sempre 1.",
            "x-enumDescriptions": {
              "base": "Envio simples (carta simples): a primeira folha impressa em preto e branco, o envelope e a postagem. Uma por correspondência ou verificação.",
              "additional_sheets": "Folhas do documento além da primeira, cobradas por folha. O endereço nunca é cobrado, mesmo quando `extra_page` acrescenta uma folha. `quantity` é o número de folhas adicionais.",
              "color": "Impressão colorida, cobrada por página impressa: cada lado impresso de uma folha conta como uma página. `quantity` é o número de páginas impressas em cores. O lado do endereço nunca é colorido nem cobrado.",
              "registered": "Carta registrada, com código de rastreio dos Correios. `quantity` é sempre 1.",
              "return_receipt": "Aviso de recebimento (AR). `quantity` é sempre 1.",
              "restricted_delivery": "Mão própria (MP). `quantity` é sempre 1."
            }
          },
          "quantity": {
            "type": "integer",
            "minimum": 1,
            "description": "Quantidade cobrada nesta linha.",
            "example": 1
          },
          "unit_amount": {
            "type": "integer",
            "description": "Preço de uma unidade, conforme o plano da conta. Em centavos: `1590` são R$ 15,90.",
            "example": 990
          },
          "amount": {
            "type": "integer",
            "description": "`quantity` vezes `unit_amount`. Em centavos: `1590` são R$ 15,90.",
            "example": 990
          }
        }
      },
      "Price": {
        "type": "object",
        "title": "Price",
        "description": "O preço de um envio, linha por linha. Não depende do destino: o preço é o mesmo para qualquer CEP do Brasil. Os valores dos exemplos são ilustrativos; o preço real depende do plano da conta.",
        "required": [
          "currency",
          "total",
          "items"
        ],
        "properties": {
          "currency": {
            "type": "string",
            "const": "BRL",
            "description": "Moeda dos valores. Sempre `BRL` (real brasileiro).",
            "example": "BRL"
          },
          "total": {
            "type": "integer",
            "description": "Soma de todas as linhas. É o valor debitado do saldo. Em centavos: `1590` são R$ 15,90.",
            "example": 4865
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PriceItem"
            },
            "description": "As linhas do preço, sempre na ordem base, additional_sheets, color, registered, return_receipt, restricted_delivery. Linhas com valor zero não aparecem."
          }
        },
        "example": {
          "currency": "BRL",
          "total": 4865,
          "items": [
            {
              "type": "base",
              "quantity": 1,
              "unit_amount": 990,
              "amount": 990
            },
            {
              "type": "additional_sheets",
              "quantity": 1,
              "unit_amount": 75,
              "amount": 75
            },
            {
              "type": "color",
              "quantity": 2,
              "unit_amount": 35,
              "amount": 70
            },
            {
              "type": "registered",
              "quantity": 1,
              "unit_amount": 1175,
              "amount": 1175
            },
            {
              "type": "return_receipt",
              "quantity": 1,
              "unit_amount": 1175,
              "amount": 1175
            },
            {
              "type": "restricted_delivery",
              "quantity": 1,
              "unit_amount": 1380,
              "amount": 1380
            }
          ]
        }
      },
      "LetterDocumentInput": {
        "title": "LetterDocumentInput",
        "description": "O conteúdo a imprimir, em JSON. Escolha a forma pelo campo `type`: `url` (até 10 MB), `upload` (um arquivo enviado antes com POST /v1/uploads, até 10 MB) ou `base64` (até 3 MB). Para enviar o arquivo do PDF junto com a requisição, use multipart/form-data em vez de JSON (campo `file`, até 4 MB). O PDF precisa ser A4 em retrato e caber em 6 folhas. Veja o guia Documento e área do endereço.",
        "oneOf": [
          {
            "$ref": "#/components/schemas/DocumentFromUrl"
          },
          {
            "$ref": "#/components/schemas/DocumentFromUpload"
          },
          {
            "$ref": "#/components/schemas/DocumentFromBase64"
          }
        ],
        "discriminator": {
          "propertyName": "type",
          "mapping": {
            "url": "#/components/schemas/DocumentFromUrl",
            "upload": "#/components/schemas/DocumentFromUpload",
            "base64": "#/components/schemas/DocumentFromBase64"
          }
        }
      },
      "DocumentFromUrl": {
        "type": "object",
        "title": "PDF por URL",
        "description": "A CartaFlow baixa o PDF de uma URL sua, uma única vez, no momento da criação. Bom quando o PDF já está em um armazenamento como S3, Google Cloud Storage ou Azure.",
        "required": [
          "type",
          "url"
        ],
        "additionalProperties": false,
        "properties": {
          "type": {
            "type": "string",
            "const": "url",
            "description": "Sempre `url`.",
            "example": "url"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "maxLength": 2048,
            "description": "URL HTTPS de um arquivo PDF. Pode ser pública ou assinada (com validade de pelo menos 10 minutos). Esperamos até 10 segundos pelo download.",
            "example": "https://arquivos.exemplo.com.br/faturas/2026-10-0042.pdf"
          },
          "variables": {
            "type": "object",
            "maxProperties": 100,
            "propertyNames": {
              "pattern": "^[A-Za-z0-9_]+$",
              "maxLength": 60
            },
            "additionalProperties": {
              "type": [
                "string",
                "number"
              ],
              "maxLength": 500
            },
            "description": "Valores para as marcações do PDF, como `{{nome}}` escrito num documento do Word e exportado em PDF. Cada valor é escrito no lugar da sua marcação, no mesmo tamanho e cor, e o resto da linha se ajusta a ele, como se o valor tivesse sido digitado ali. O valor não quebra linha: se não couber, o resto da linha é apertado um pouco e, se ainda assim não couber, passa da margem; confira no `preview_url`. Até 100 variáveis; nomes com letras, números e sublinhado, com até 60 caracteres; valores em texto ou número, numa linha só, com até 500 caracteres. O PDF precisa ter texto selecionável (não pode ser imagem ou digitalização), senão a API responde `document_text_unreadable`. Envie exatamente as marcações do PDF: se faltar uma, `variable_missing`; se sobrar uma, `variable_not_found`. Sem este campo, o PDF é impresso como está.",
            "example": {
              "nome": "Destinatário Exemplo",
              "valor": "R$ 189,90",
              "vencimento": "20/10/2026"
            }
          }
        }
      },
      "DocumentFromBase64": {
        "type": "object",
        "title": "PDF em base64",
        "description": "O PDF vai dentro do JSON, codificado em base64. Bom para PDFs pequenos que o seu sistema gera em memória, quando você prefere manter tudo em JSON. Até 3 MB de PDF; para arquivos maiores, use `url` ou `upload`.",
        "required": [
          "type",
          "data"
        ],
        "additionalProperties": false,
        "properties": {
          "type": {
            "type": "string",
            "const": "base64",
            "description": "Sempre `base64`.",
            "example": "base64"
          },
          "data": {
            "type": "string",
            "contentEncoding": "base64",
            "contentMediaType": "application/pdf",
            "description": "O conteúdo do PDF em base64 padrão, sem o prefixo `data:application/pdf;base64,`. Até 3 MB depois de decodificado (cerca de 4 MB de texto em base64), para que o corpo inteiro caiba no limite de 4,5 MB por requisição. Para PDFs maiores, use `url` ou `upload`, que aceitam até 10 MB.",
            "example": "JVBERi0xLjcKJcfsj6IKNSAwIG9iago8PC9MZW5ndGggNiAwIFI..."
          },
          "variables": {
            "type": "object",
            "maxProperties": 100,
            "propertyNames": {
              "pattern": "^[A-Za-z0-9_]+$",
              "maxLength": 60
            },
            "additionalProperties": {
              "type": [
                "string",
                "number"
              ],
              "maxLength": 500
            },
            "description": "Valores para as marcações do PDF, como `{{nome}}` escrito num documento do Word e exportado em PDF. Cada valor é escrito no lugar da sua marcação, no mesmo tamanho e cor, e o resto da linha se ajusta a ele, como se o valor tivesse sido digitado ali. O valor não quebra linha: se não couber, o resto da linha é apertado um pouco e, se ainda assim não couber, passa da margem; confira no `preview_url`. Até 100 variáveis; nomes com letras, números e sublinhado, com até 60 caracteres; valores em texto ou número, numa linha só, com até 500 caracteres. O PDF precisa ter texto selecionável (não pode ser imagem ou digitalização), senão a API responde `document_text_unreadable`. Envie exatamente as marcações do PDF: se faltar uma, `variable_missing`; se sobrar uma, `variable_not_found`. Sem este campo, o PDF é impresso como está.",
            "example": {
              "nome": "Destinatário Exemplo",
              "valor": "R$ 189,90",
              "vencimento": "20/10/2026"
            }
          }
        }
      },
      "DocumentFromUpload": {
        "type": "object",
        "title": "PDF enviado com POST /v1/uploads",
        "description": "Um PDF que você enviou antes, em duas etapas: crie um upload com POST /v1/uploads, envie o arquivo com PUT para o `upload_url` e use o `id` do upload aqui. Bom para PDFs grandes, de até 10 MB, que não cabem numa requisição (o corpo tem até 4,5 MB). Cada upload serve para uma correspondência só e precisa ser usado em até 24 horas.",
        "required": [
          "type",
          "upload_id"
        ],
        "additionalProperties": false,
        "properties": {
          "type": {
            "type": "string",
            "const": "upload",
            "description": "Sempre `upload`.",
            "example": "upload"
          },
          "upload_id": {
            "type": "string",
            "description": "Id do upload devolvido por POST /v1/uploads. Sempre começa com `upl_`. O arquivo precisa ter sido enviado para o `upload_url`. O upload é da sua conta, vale por 24 horas e é consumido pela correspondência criada com ele. Uma simulação com POST /v1/letters/quote não consome o upload. Erros possíveis: `upload_not_found`, `upload_expired`, `upload_already_used` e `upload_file_missing`.",
            "pattern": "^upl_[A-Za-z0-9]+$",
            "example": "upl_6Np3Vx8Rk2Tq"
          },
          "variables": {
            "type": "object",
            "maxProperties": 100,
            "propertyNames": {
              "pattern": "^[A-Za-z0-9_]+$",
              "maxLength": 60
            },
            "additionalProperties": {
              "type": [
                "string",
                "number"
              ],
              "maxLength": 500
            },
            "description": "Valores para as marcações do PDF, como `{{nome}}` escrito num documento do Word e exportado em PDF. Cada valor é escrito no lugar da sua marcação, no mesmo tamanho e cor, e o resto da linha se ajusta a ele, como se o valor tivesse sido digitado ali. O valor não quebra linha: se não couber, o resto da linha é apertado um pouco e, se ainda assim não couber, passa da margem; confira no `preview_url`. Até 100 variáveis; nomes com letras, números e sublinhado, com até 60 caracteres; valores em texto ou número, numa linha só, com até 500 caracteres. O PDF precisa ter texto selecionável (não pode ser imagem ou digitalização), senão a API responde `document_text_unreadable`. Envie exatamente as marcações do PDF: se faltar uma, `variable_missing`; se sobrar uma, `variable_not_found`. Sem este campo, o PDF é impresso como está.",
            "example": {
              "nome": "Destinatário Exemplo",
              "valor": "R$ 189,90",
              "vencimento": "20/10/2026"
            }
          }
        }
      },
      "LetterDocument": {
        "title": "LetterDocument",
        "description": "De onde veio o conteúdo da correspondência. O PDF final está em `preview_url`.",
        "oneOf": [
          {
            "type": "object",
            "title": "Upload do PDF",
            "required": [
              "type",
              "filename",
              "variables"
            ],
            "properties": {
              "type": {
                "type": "string",
                "const": "upload",
                "description": "O PDF foi enviado como arquivo: em multipart/form-data, no campo `file`, ou em duas etapas, com POST /v1/uploads e `document.type: upload`."
              },
              "filename": {
                "type": "string",
                "description": "O nome do arquivo enviado: o do campo `file` no multipart, ou o `filename` do upload.",
                "example": "fatura-outubro.pdf"
              },
              "variables": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": true,
                "description": "As variáveis escritas no PDF. `null` quando o PDF foi impresso como veio.",
                "example": null
              }
            }
          },
          {
            "type": "object",
            "title": "PDF por URL",
            "required": [
              "type",
              "url",
              "variables"
            ],
            "properties": {
              "type": {
                "type": "string",
                "const": "url",
                "description": "O PDF veio de uma URL."
              },
              "url": {
                "type": "string",
                "format": "uri",
                "description": "A URL de onde baixamos o PDF.",
                "example": "https://arquivos.exemplo.com.br/faturas/2026-10-0042.pdf"
              },
              "variables": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": true,
                "description": "As variáveis escritas no PDF. `null` quando o PDF foi impresso como veio.",
                "example": null
              }
            }
          },
          {
            "type": "object",
            "title": "PDF em base64",
            "required": [
              "type",
              "variables"
            ],
            "properties": {
              "type": {
                "type": "string",
                "const": "base64",
                "description": "O PDF veio dentro do JSON. O conteúdo não é devolvido; use `preview_url`."
              },
              "variables": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": true,
                "description": "As variáveis escritas no PDF. `null` quando o PDF foi impresso como veio.",
                "example": null
              }
            }
          }
        ],
        "discriminator": {
          "propertyName": "type"
        }
      },
      "CreateLetterRequest": {
        "type": "object",
        "title": "CreateLetterRequest",
        "required": [
          "to",
          "document"
        ],
        "additionalProperties": false,
        "properties": {
          "to": {
            "type": "object",
            "title": "AddressInput",
            "description": "Destinatário. A CartaFlow imprime estes dados na área do endereço, que aparece pela janela do envelope.",
            "required": [
              "name",
              "number",
              "postal_code"
            ],
            "additionalProperties": false,
            "properties": {
              "name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Nome da pessoa ou da empresa, como deve aparecer no envelope. Até 60 caracteres.",
                "example": "Destinatário Exemplo"
              },
              "postal_code": {
                "type": "string",
                "pattern": "^[0-9]{5}-?[0-9]{3}$",
                "description": "CEP com 8 dígitos, com ou sem hífen: `01001-000` ou `01001000`. Precisa existir na base de CEPs; é dele que vêm os campos que você não enviar. Nas respostas ele sempre volta com hífen.",
                "example": "01001-000"
              },
              "number": {
                "type": "string",
                "minLength": 1,
                "maxLength": 10,
                "description": "Número do imóvel. É texto porque alguns números têm letras, como `128A`. Use `S/N` quando o endereço não tem número. Até 10 caracteres.",
                "example": "128"
              },
              "complement": {
                "type": "string",
                "maxLength": 60,
                "description": "Complemento: apartamento, bloco, sala, andar. Até 60 caracteres.",
                "example": "Ap. 52"
              },
              "street": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100,
                "description": "Logradouro, com o tipo e o nome: rua, avenida, travessa, praça. Sem o número. Até 100 caracteres. Opcional: quando você não envia, preenchemos a partir do CEP. Quando envia, usamos o seu valor.",
                "example": "Praça da Sé"
              },
              "neighborhood": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Bairro. Até 60 caracteres. Opcional: quando você não envia, preenchemos a partir do CEP. Quando envia, usamos o seu valor.",
                "example": "Sé"
              },
              "city": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Cidade. Até 60 caracteres. Opcional: quando você não envia, preenchemos a partir do CEP. Quando envia, usamos o seu valor.",
                "example": "São Paulo"
              },
              "state": {
                "type": "string",
                "enum": [
                  "AC",
                  "AL",
                  "AP",
                  "AM",
                  "BA",
                  "CE",
                  "DF",
                  "ES",
                  "GO",
                  "MA",
                  "MT",
                  "MS",
                  "MG",
                  "PA",
                  "PB",
                  "PR",
                  "PE",
                  "PI",
                  "RJ",
                  "RN",
                  "RS",
                  "RO",
                  "RR",
                  "SC",
                  "SP",
                  "SE",
                  "TO"
                ],
                "description": "UF: a sigla do estado, com duas letras maiúsculas.\n\nOpcional: quando você não envia, preenchemos a partir do CEP. Quando envia, usamos o seu valor.\n\n**Valores possíveis**\n\n- `AC`: Acre\n- `AL`: Alagoas\n- `AP`: Amapá\n- `AM`: Amazonas\n- `BA`: Bahia\n- `CE`: Ceará\n- `DF`: Distrito Federal\n- `ES`: Espírito Santo\n- `GO`: Goiás\n- `MA`: Maranhão\n- `MT`: Mato Grosso\n- `MS`: Mato Grosso do Sul\n- `MG`: Minas Gerais\n- `PA`: Pará\n- `PB`: Paraíba\n- `PR`: Paraná\n- `PE`: Pernambuco\n- `PI`: Piauí\n- `RJ`: Rio de Janeiro\n- `RN`: Rio Grande do Norte\n- `RS`: Rio Grande do Sul\n- `RO`: Rondônia\n- `RR`: Roraima\n- `SC`: Santa Catarina\n- `SP`: São Paulo\n- `SE`: Sergipe\n- `TO`: Tocantins",
                "x-enumDescriptions": {
                  "AC": "Acre",
                  "AL": "Alagoas",
                  "AP": "Amapá",
                  "AM": "Amazonas",
                  "BA": "Bahia",
                  "CE": "Ceará",
                  "DF": "Distrito Federal",
                  "ES": "Espírito Santo",
                  "GO": "Goiás",
                  "MA": "Maranhão",
                  "MT": "Mato Grosso",
                  "MS": "Mato Grosso do Sul",
                  "MG": "Minas Gerais",
                  "PA": "Pará",
                  "PB": "Paraíba",
                  "PR": "Paraná",
                  "PE": "Pernambuco",
                  "PI": "Piauí",
                  "RJ": "Rio de Janeiro",
                  "RN": "Rio Grande do Norte",
                  "RS": "Rio Grande do Sul",
                  "RO": "Rondônia",
                  "RR": "Roraima",
                  "SC": "Santa Catarina",
                  "SP": "São Paulo",
                  "SE": "Sergipe",
                  "TO": "Tocantins"
                },
                "example": "SP"
              }
            },
            "example": {
              "name": "Destinatário Exemplo",
              "postal_code": "01001-000",
              "number": "128",
              "complement": "Ap. 52"
            }
          },
          "from": {
            "type": "object",
            "title": "AddressInput",
            "description": "Remetente, impresso em uma linha acima do destinatário. É para onde os Correios devolvem a correspondência quando não conseguem entregar, e para onde vai o aviso de recebimento (`return_receipt`). Se você não enviar, usamos o remetente padrão da conta, definido no painel em Configurações > Empresa.",
            "required": [
              "name",
              "number",
              "postal_code"
            ],
            "additionalProperties": false,
            "properties": {
              "name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Nome da pessoa ou da empresa, como deve aparecer no envelope. Até 60 caracteres.",
                "example": "Destinatário Exemplo"
              },
              "postal_code": {
                "type": "string",
                "pattern": "^[0-9]{5}-?[0-9]{3}$",
                "description": "CEP com 8 dígitos, com ou sem hífen: `01001-000` ou `01001000`. Precisa existir na base de CEPs; é dele que vêm os campos que você não enviar. Nas respostas ele sempre volta com hífen.",
                "example": "01001-000"
              },
              "number": {
                "type": "string",
                "minLength": 1,
                "maxLength": 10,
                "description": "Número do imóvel. É texto porque alguns números têm letras, como `128A`. Use `S/N` quando o endereço não tem número. Até 10 caracteres.",
                "example": "128"
              },
              "complement": {
                "type": "string",
                "maxLength": 60,
                "description": "Complemento: apartamento, bloco, sala, andar. Até 60 caracteres.",
                "example": "Ap. 52"
              },
              "street": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100,
                "description": "Logradouro, com o tipo e o nome: rua, avenida, travessa, praça. Sem o número. Até 100 caracteres. Opcional: quando você não envia, preenchemos a partir do CEP. Quando envia, usamos o seu valor.",
                "example": "Praça da Sé"
              },
              "neighborhood": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Bairro. Até 60 caracteres. Opcional: quando você não envia, preenchemos a partir do CEP. Quando envia, usamos o seu valor.",
                "example": "Sé"
              },
              "city": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Cidade. Até 60 caracteres. Opcional: quando você não envia, preenchemos a partir do CEP. Quando envia, usamos o seu valor.",
                "example": "São Paulo"
              },
              "state": {
                "type": "string",
                "enum": [
                  "AC",
                  "AL",
                  "AP",
                  "AM",
                  "BA",
                  "CE",
                  "DF",
                  "ES",
                  "GO",
                  "MA",
                  "MT",
                  "MS",
                  "MG",
                  "PA",
                  "PB",
                  "PR",
                  "PE",
                  "PI",
                  "RJ",
                  "RN",
                  "RS",
                  "RO",
                  "RR",
                  "SC",
                  "SP",
                  "SE",
                  "TO"
                ],
                "description": "UF: a sigla do estado, com duas letras maiúsculas.\n\nOpcional: quando você não envia, preenchemos a partir do CEP. Quando envia, usamos o seu valor.\n\n**Valores possíveis**\n\n- `AC`: Acre\n- `AL`: Alagoas\n- `AP`: Amapá\n- `AM`: Amazonas\n- `BA`: Bahia\n- `CE`: Ceará\n- `DF`: Distrito Federal\n- `ES`: Espírito Santo\n- `GO`: Goiás\n- `MA`: Maranhão\n- `MT`: Mato Grosso\n- `MS`: Mato Grosso do Sul\n- `MG`: Minas Gerais\n- `PA`: Pará\n- `PB`: Paraíba\n- `PR`: Paraná\n- `PE`: Pernambuco\n- `PI`: Piauí\n- `RJ`: Rio de Janeiro\n- `RN`: Rio Grande do Norte\n- `RS`: Rio Grande do Sul\n- `RO`: Rondônia\n- `RR`: Roraima\n- `SC`: Santa Catarina\n- `SP`: São Paulo\n- `SE`: Sergipe\n- `TO`: Tocantins",
                "x-enumDescriptions": {
                  "AC": "Acre",
                  "AL": "Alagoas",
                  "AP": "Amapá",
                  "AM": "Amazonas",
                  "BA": "Bahia",
                  "CE": "Ceará",
                  "DF": "Distrito Federal",
                  "ES": "Espírito Santo",
                  "GO": "Goiás",
                  "MA": "Maranhão",
                  "MT": "Mato Grosso",
                  "MS": "Mato Grosso do Sul",
                  "MG": "Minas Gerais",
                  "PA": "Pará",
                  "PB": "Paraíba",
                  "PR": "Paraná",
                  "PE": "Pernambuco",
                  "PI": "Piauí",
                  "RJ": "Rio de Janeiro",
                  "RN": "Rio Grande do Norte",
                  "RS": "Rio Grande do Sul",
                  "RO": "Rondônia",
                  "RR": "Roraima",
                  "SC": "Santa Catarina",
                  "SP": "São Paulo",
                  "SE": "Sergipe",
                  "TO": "Tocantins"
                },
                "example": "SP"
              }
            },
            "example": {
              "name": "Destinatário Exemplo",
              "postal_code": "01001-000",
              "number": "128",
              "complement": "Ap. 52"
            }
          },
          "document": {
            "$ref": "#/components/schemas/LetterDocumentInput"
          },
          "color": {
            "type": "boolean",
            "default": false,
            "description": "`true` imprime em cores. `false` imprime em preto e branco: um PDF colorido sai em tons de cinza. A impressão colorida tem acréscimo por página impressa (cada lado impresso conta como uma página).",
            "example": false
          },
          "double_sided": {
            "type": "boolean",
            "default": false,
            "description": "`true` imprime frente e verso: cada folha leva duas páginas do documento, então a correspondência usa menos folhas e custa menos. `false` imprime só a frente de cada folha.",
            "example": false
          },
          "address_placement": {
            "type": "string",
            "enum": [
              "first_page",
              "extra_page"
            ],
            "description": "Onde a CartaFlow imprime o endereço do destinatário.\n\n**Valores possíveis**\n\n- `first_page`: Na área do endereço da primeira página do seu documento (90 x 45 mm, a 20 mm da esquerda e 45 mm do topo). Essa área precisa estar em branco no seu PDF. Padrão.\n- `extra_page`: Num lado só dele, o primeiro, que aparece pela janela do envelope. Use quando o seu layout ocupa a área do endereço. Ele ocupa um lado que ficaria em branco, quando há um: o verso da primeira página, só frente, ou o lado que sobra, em frente e verso com número ímpar de páginas. Em frente e verso com número par de páginas, entra uma folha a mais no início. O endereço nunca é cobrado.",
            "x-enumDescriptions": {
              "first_page": "Na área do endereço da primeira página do seu documento (90 x 45 mm, a 20 mm da esquerda e 45 mm do topo). Essa área precisa estar em branco no seu PDF. Padrão.",
              "extra_page": "Num lado só dele, o primeiro, que aparece pela janela do envelope. Use quando o seu layout ocupa a área do endereço. Ele ocupa um lado que ficaria em branco, quando há um: o verso da primeira página, só frente, ou o lado que sobra, em frente e verso com número ímpar de páginas. Em frente e verso com número par de páginas, entra uma folha a mais no início. O endereço nunca é cobrado."
            },
            "default": "first_page",
            "example": "first_page"
          },
          "postal_services": {
            "type": "array",
            "uniqueItems": true,
            "items": {
              "type": "string",
              "enum": [
                "registered",
                "return_receipt",
                "restricted_delivery"
              ],
              "x-enumDescriptions": {
                "registered": "Carta registrada: a correspondência é postada com registro nos Correios e recebe um código de rastreio, que aparece em `tracking_code` quando ela é postada.",
                "return_receipt": "Aviso de recebimento (AR): os Correios devolvem um comprovante assinado por quem recebeu a correspondência ao remetente impresso no envelope. Exige `registered`.",
                "restricted_delivery": "Mão própria (MP): os Correios entregam só para a pessoa cujo nome está no envelope. Exige `registered`."
              }
            },
            "default": [],
            "description": "Serviços adicionais dos Correios, cada um com o próprio acréscimo no preço (uma linha em `price`). Sem este campo, ou com `[]`, a correspondência vai como carta simples, sem rastreio depois da postagem. `return_receipt` e `restricted_delivery` só funcionam junto com `registered`; sem ele, a API responde 422 com `requires_registered`. Em multipart/form-data, repita o campo `postal_services[]` uma vez para cada serviço.\n\n**Valores possíveis**\n\n- `registered`: Carta registrada: a correspondência é postada com registro nos Correios e recebe um código de rastreio, que aparece em `tracking_code` quando ela é postada.\n- `return_receipt`: Aviso de recebimento (AR): os Correios devolvem um comprovante assinado por quem recebeu a correspondência ao remetente impresso no envelope. Exige `registered`.\n- `restricted_delivery`: Mão própria (MP): os Correios entregam só para a pessoa cujo nome está no envelope. Exige `registered`.",
            "example": [
              "registered",
              "return_receipt"
            ]
          },
          "send_date": {
            "type": "string",
            "format": "date",
            "description": "Agenda o envio para uma data, no formato `AAAA-MM-DD`, de amanhã até 180 dias à frente (horário de Brasília). A correspondência é validada agora, mas só é cobrada na data, às 06:00: nesse momento o saldo precisa cobrir o preço, senão ela é cancelada com `cancellation_reason: insufficient_balance`. Até lá ela fica em `scheduled` e pode ser cancelada sem custo. Para enviar agora, não envie este campo.",
            "example": "2026-10-20"
          },
          "reference": {
            "type": "string",
            "maxLength": 100,
            "description": "Seu identificador para esta correspondência, como o número da fatura ou o id do cliente no seu sistema. Aparece no painel e pode ser usado como filtro nas listagens. Não precisa ser único. Até 100 caracteres.",
            "example": "fatura-2026-10-0042"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "maxLength": 500
            },
            "maxProperties": 20,
            "description": "Pares chave-valor para guardar dados seus junto do objeto, como o id do cliente ou do contrato. Voltam em todas as respostas e webhooks e nunca são impressos. Até 20 chaves; chaves com até 40 caracteres e valores em texto com até 500 caracteres. Não guarde dados sensíveis, como senhas ou números de cartão.",
            "example": {
              "customer_id": "1842",
              "contract": "C-2026-118"
            }
          }
        }
      },
      "Letter": {
        "type": "object",
        "title": "Letter",
        "description": "Uma correspondência física: um documento impresso, envelopado e postado pela CartaFlow para um endereço no Brasil.",
        "required": [
          "id",
          "object",
          "status",
          "to",
          "from",
          "document",
          "color",
          "double_sided",
          "address_placement",
          "postal_services",
          "pages",
          "sheets",
          "price",
          "send_date",
          "cancellation_reason",
          "failure_reason",
          "tracking_code",
          "preview_url",
          "reference",
          "metadata",
          "status_transitions",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Identificador único da correspondência. Sempre começa com `ltr_`.",
            "pattern": "^ltr_[A-Za-z0-9]+$",
            "example": "ltr_8Kq2wX4mN7pR"
          },
          "object": {
            "type": "string",
            "const": "letter",
            "description": "Tipo do objeto. Sempre `letter`.",
            "example": "letter"
          },
          "status": {
            "type": "string",
            "enum": [
              "scheduled",
              "received",
              "in_production",
              "printed",
              "posted",
              "canceled",
              "failed"
            ],
            "description": "Em que etapa a correspondência está. Ela só avança, nunca volta: scheduled (só quando agendada), received, in_production, printed, posted. De scheduled ou received ela pode ir para canceled; de received, in_production ou printed, para failed. Uma reimpressão na produção não muda o status.\n\n**Valores possíveis**\n\n- `scheduled`: A correspondência foi validada e espera a data de `send_date`. Ainda não foi cobrada. Na data, às 06:00 de Brasília, a CartaFlow debita o saldo e a correspondência passa para `received`. Se o saldo não cobrir o preço, ela vai para `canceled`. Pode ser cancelada sem custo.\n- `received`: A CartaFlow validou o documento e o endereço, cobrou o envio do seu saldo e colocou a correspondência na fila de produção. Ainda pode ser cancelada, e o valor volta para o saldo.\n- `in_production`: A correspondência entrou em um lote de impressão. A partir daqui ela não pode mais ser cancelada.\n- `printed`: A correspondência foi impressa, dobrada e colocada no envelope. O próximo passo é a postagem.\n- `posted`: A correspondência foi entregue aos Correios. A partir daqui a entrega segue o serviço postal, e a CartaFlow não recebe novas informações sobre ela. Uma correspondência registrada traz o código de rastreio dos Correios em `tracking_code`.\n- `canceled`: O envio foi cancelado antes da produção e nada foi impresso. `cancellation_reason` diz o motivo: você cancelou, ou o saldo não cobria uma correspondência agendada na data do envio. Se havia cobrança, o valor voltou para o saldo.\n- `failed`: Algo deu errado na produção e a correspondência não será postada. `failure_reason` diz o motivo. O valor voltou para o saldo automaticamente.",
            "x-enumDescriptions": {
              "scheduled": "A correspondência foi validada e espera a data de `send_date`. Ainda não foi cobrada. Na data, às 06:00 de Brasília, a CartaFlow debita o saldo e a correspondência passa para `received`. Se o saldo não cobrir o preço, ela vai para `canceled`. Pode ser cancelada sem custo.",
              "received": "A CartaFlow validou o documento e o endereço, cobrou o envio do seu saldo e colocou a correspondência na fila de produção. Ainda pode ser cancelada, e o valor volta para o saldo.",
              "in_production": "A correspondência entrou em um lote de impressão. A partir daqui ela não pode mais ser cancelada.",
              "printed": "A correspondência foi impressa, dobrada e colocada no envelope. O próximo passo é a postagem.",
              "posted": "A correspondência foi entregue aos Correios. A partir daqui a entrega segue o serviço postal, e a CartaFlow não recebe novas informações sobre ela. Uma correspondência registrada traz o código de rastreio dos Correios em `tracking_code`.",
              "canceled": "O envio foi cancelado antes da produção e nada foi impresso. `cancellation_reason` diz o motivo: você cancelou, ou o saldo não cobria uma correspondência agendada na data do envio. Se havia cobrança, o valor voltou para o saldo.",
              "failed": "Algo deu errado na produção e a correspondência não será postada. `failure_reason` diz o motivo. O valor voltou para o saldo automaticamente."
            },
            "example": "received"
          },
          "to": {
            "type": "object",
            "title": "Address",
            "description": "Destinatário.",
            "required": [
              "name",
              "street",
              "number",
              "complement",
              "neighborhood",
              "city",
              "state",
              "postal_code"
            ],
            "properties": {
              "name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Nome da pessoa ou da empresa, como deve aparecer no envelope. Até 60 caracteres.",
                "example": "Destinatário Exemplo"
              },
              "street": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100,
                "description": "Logradouro, com o tipo e o nome: rua, avenida, travessa, praça. Sem o número. Até 100 caracteres.",
                "example": "Praça da Sé"
              },
              "number": {
                "type": "string",
                "minLength": 1,
                "maxLength": 10,
                "description": "Número do imóvel. É texto porque alguns números têm letras, como `128A`. Use `S/N` quando o endereço não tem número. Até 10 caracteres.",
                "example": "128"
              },
              "complement": {
                "type": [
                  "string",
                  "null"
                ],
                "maxLength": 60,
                "description": "Complemento: apartamento, bloco, sala, andar. `null` quando o endereço não tem.",
                "example": "Ap. 52"
              },
              "neighborhood": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Bairro. Até 60 caracteres.",
                "example": "Sé"
              },
              "city": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Cidade. Até 60 caracteres.",
                "example": "São Paulo"
              },
              "state": {
                "type": "string",
                "enum": [
                  "AC",
                  "AL",
                  "AP",
                  "AM",
                  "BA",
                  "CE",
                  "DF",
                  "ES",
                  "GO",
                  "MA",
                  "MT",
                  "MS",
                  "MG",
                  "PA",
                  "PB",
                  "PR",
                  "PE",
                  "PI",
                  "RJ",
                  "RN",
                  "RS",
                  "RO",
                  "RR",
                  "SC",
                  "SP",
                  "SE",
                  "TO"
                ],
                "description": "UF: a sigla do estado.\n\n**Valores possíveis**\n\n- `AC`: Acre\n- `AL`: Alagoas\n- `AP`: Amapá\n- `AM`: Amazonas\n- `BA`: Bahia\n- `CE`: Ceará\n- `DF`: Distrito Federal\n- `ES`: Espírito Santo\n- `GO`: Goiás\n- `MA`: Maranhão\n- `MT`: Mato Grosso\n- `MS`: Mato Grosso do Sul\n- `MG`: Minas Gerais\n- `PA`: Pará\n- `PB`: Paraíba\n- `PR`: Paraná\n- `PE`: Pernambuco\n- `PI`: Piauí\n- `RJ`: Rio de Janeiro\n- `RN`: Rio Grande do Norte\n- `RS`: Rio Grande do Sul\n- `RO`: Rondônia\n- `RR`: Roraima\n- `SC`: Santa Catarina\n- `SP`: São Paulo\n- `SE`: Sergipe\n- `TO`: Tocantins",
                "x-enumDescriptions": {
                  "AC": "Acre",
                  "AL": "Alagoas",
                  "AP": "Amapá",
                  "AM": "Amazonas",
                  "BA": "Bahia",
                  "CE": "Ceará",
                  "DF": "Distrito Federal",
                  "ES": "Espírito Santo",
                  "GO": "Goiás",
                  "MA": "Maranhão",
                  "MT": "Mato Grosso",
                  "MS": "Mato Grosso do Sul",
                  "MG": "Minas Gerais",
                  "PA": "Pará",
                  "PB": "Paraíba",
                  "PR": "Paraná",
                  "PE": "Pernambuco",
                  "PI": "Piauí",
                  "RJ": "Rio de Janeiro",
                  "RN": "Rio Grande do Norte",
                  "RS": "Rio Grande do Sul",
                  "RO": "Rondônia",
                  "RR": "Roraima",
                  "SC": "Santa Catarina",
                  "SP": "São Paulo",
                  "SE": "Sergipe",
                  "TO": "Tocantins"
                },
                "example": "SP"
              },
              "postal_code": {
                "type": "string",
                "pattern": "^[0-9]{5}-[0-9]{3}$",
                "description": "CEP, sempre no formato `00000-000`.",
                "example": "01001-000"
              }
            }
          },
          "from": {
            "type": "object",
            "title": "Address",
            "description": "Remetente impresso acima do destinatário: o que você enviou ou o remetente padrão da conta.",
            "required": [
              "name",
              "street",
              "number",
              "complement",
              "neighborhood",
              "city",
              "state",
              "postal_code"
            ],
            "properties": {
              "name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Nome da pessoa ou da empresa, como deve aparecer no envelope. Até 60 caracteres.",
                "example": "Destinatário Exemplo"
              },
              "street": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100,
                "description": "Logradouro, com o tipo e o nome: rua, avenida, travessa, praça. Sem o número. Até 100 caracteres.",
                "example": "Praça da Sé"
              },
              "number": {
                "type": "string",
                "minLength": 1,
                "maxLength": 10,
                "description": "Número do imóvel. É texto porque alguns números têm letras, como `128A`. Use `S/N` quando o endereço não tem número. Até 10 caracteres.",
                "example": "128"
              },
              "complement": {
                "type": [
                  "string",
                  "null"
                ],
                "maxLength": 60,
                "description": "Complemento: apartamento, bloco, sala, andar. `null` quando o endereço não tem.",
                "example": "Ap. 52"
              },
              "neighborhood": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Bairro. Até 60 caracteres.",
                "example": "Sé"
              },
              "city": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Cidade. Até 60 caracteres.",
                "example": "São Paulo"
              },
              "state": {
                "type": "string",
                "enum": [
                  "AC",
                  "AL",
                  "AP",
                  "AM",
                  "BA",
                  "CE",
                  "DF",
                  "ES",
                  "GO",
                  "MA",
                  "MT",
                  "MS",
                  "MG",
                  "PA",
                  "PB",
                  "PR",
                  "PE",
                  "PI",
                  "RJ",
                  "RN",
                  "RS",
                  "RO",
                  "RR",
                  "SC",
                  "SP",
                  "SE",
                  "TO"
                ],
                "description": "UF: a sigla do estado.\n\n**Valores possíveis**\n\n- `AC`: Acre\n- `AL`: Alagoas\n- `AP`: Amapá\n- `AM`: Amazonas\n- `BA`: Bahia\n- `CE`: Ceará\n- `DF`: Distrito Federal\n- `ES`: Espírito Santo\n- `GO`: Goiás\n- `MA`: Maranhão\n- `MT`: Mato Grosso\n- `MS`: Mato Grosso do Sul\n- `MG`: Minas Gerais\n- `PA`: Pará\n- `PB`: Paraíba\n- `PR`: Paraná\n- `PE`: Pernambuco\n- `PI`: Piauí\n- `RJ`: Rio de Janeiro\n- `RN`: Rio Grande do Norte\n- `RS`: Rio Grande do Sul\n- `RO`: Rondônia\n- `RR`: Roraima\n- `SC`: Santa Catarina\n- `SP`: São Paulo\n- `SE`: Sergipe\n- `TO`: Tocantins",
                "x-enumDescriptions": {
                  "AC": "Acre",
                  "AL": "Alagoas",
                  "AP": "Amapá",
                  "AM": "Amazonas",
                  "BA": "Bahia",
                  "CE": "Ceará",
                  "DF": "Distrito Federal",
                  "ES": "Espírito Santo",
                  "GO": "Goiás",
                  "MA": "Maranhão",
                  "MT": "Mato Grosso",
                  "MS": "Mato Grosso do Sul",
                  "MG": "Minas Gerais",
                  "PA": "Pará",
                  "PB": "Paraíba",
                  "PR": "Paraná",
                  "PE": "Pernambuco",
                  "PI": "Piauí",
                  "RJ": "Rio de Janeiro",
                  "RN": "Rio Grande do Norte",
                  "RS": "Rio Grande do Sul",
                  "RO": "Rondônia",
                  "RR": "Roraima",
                  "SC": "Santa Catarina",
                  "SP": "São Paulo",
                  "SE": "Sergipe",
                  "TO": "Tocantins"
                },
                "example": "SP"
              },
              "postal_code": {
                "type": "string",
                "pattern": "^[0-9]{5}-[0-9]{3}$",
                "description": "CEP, sempre no formato `00000-000`.",
                "example": "01001-000"
              }
            }
          },
          "document": {
            "$ref": "#/components/schemas/LetterDocument"
          },
          "color": {
            "type": "boolean",
            "description": "`true` quando a impressão é colorida.",
            "example": false
          },
          "double_sided": {
            "type": "boolean",
            "description": "`true` quando a impressão é frente e verso.",
            "example": false
          },
          "address_placement": {
            "type": "string",
            "enum": [
              "first_page",
              "extra_page"
            ],
            "description": "Onde o endereço é impresso.\n\n**Valores possíveis**\n\n- `first_page`: Na área do endereço da primeira página do documento.\n- `extra_page`: Num lado só dele, o primeiro, sem custo.",
            "x-enumDescriptions": {
              "first_page": "Na área do endereço da primeira página do documento.",
              "extra_page": "Num lado só dele, o primeiro, sem custo."
            },
            "example": "first_page"
          },
          "postal_services": {
            "type": "array",
            "uniqueItems": true,
            "items": {
              "type": "string",
              "enum": [
                "registered",
                "return_receipt",
                "restricted_delivery"
              ],
              "x-enumDescriptions": {
                "registered": "Carta registrada: a correspondência é postada com registro nos Correios e recebe um código de rastreio, que aparece em `tracking_code` quando ela é postada.",
                "return_receipt": "Aviso de recebimento (AR): os Correios devolvem um comprovante assinado por quem recebeu a correspondência ao remetente impresso no envelope. Exige `registered`.",
                "restricted_delivery": "Mão própria (MP): os Correios entregam só para a pessoa cujo nome está no envelope. Exige `registered`."
              }
            },
            "description": "Os serviços adicionais dos Correios escolhidos na criação. Sempre uma lista: `[]` numa carta simples.\n\n**Valores possíveis**\n\n- `registered`: Carta registrada: a correspondência é postada com registro nos Correios e recebe um código de rastreio, que aparece em `tracking_code` quando ela é postada.\n- `return_receipt`: Aviso de recebimento (AR): os Correios devolvem um comprovante assinado por quem recebeu a correspondência ao remetente impresso no envelope. Exige `registered`.\n- `restricted_delivery`: Mão própria (MP): os Correios entregam só para a pessoa cujo nome está no envelope. Exige `registered`.",
            "example": []
          },
          "pages": {
            "type": "integer",
            "minimum": 1,
            "description": "Número de páginas do seu documento, sem contar o lado do endereço com `extra_page`.",
            "example": 2
          },
          "sheets": {
            "type": "integer",
            "minimum": 1,
            "maximum": 6,
            "description": "Folhas de papel no envelope. Só frente, é `pages`. Em frente e verso, é metade de `pages` arredondada para cima com `first_page`, e metade de `pages` arredondada para baixo, mais 1, com `extra_page`. Máximo de 6, contando a folha que o endereço acrescenta, que não é cobrada.",
            "example": 2
          },
          "price": {
            "type": "object",
            "title": "Price",
            "description": "O preço da correspondência. É cobrado do saldo na criação ou, se ela foi agendada, na data do envio (com o plano da conta nesse dia). Volta para o saldo se a correspondência for cancelada depois da cobrança ou falhar na produção.",
            "required": [
              "currency",
              "total",
              "items"
            ],
            "properties": {
              "currency": {
                "type": "string",
                "const": "BRL",
                "description": "Moeda dos valores. Sempre `BRL` (real brasileiro).",
                "example": "BRL"
              },
              "total": {
                "type": "integer",
                "description": "Soma de todas as linhas. É o valor debitado do saldo. Em centavos: `1590` são R$ 15,90.",
                "example": 4865
              },
              "items": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PriceItem"
                },
                "description": "As linhas do preço, sempre na ordem base, additional_sheets, color, registered, return_receipt, restricted_delivery. Linhas com valor zero não aparecem."
              }
            },
            "example": {
              "currency": "BRL",
              "total": 4865,
              "items": [
                {
                  "type": "base",
                  "quantity": 1,
                  "unit_amount": 990,
                  "amount": 990
                },
                {
                  "type": "additional_sheets",
                  "quantity": 1,
                  "unit_amount": 75,
                  "amount": 75
                },
                {
                  "type": "color",
                  "quantity": 2,
                  "unit_amount": 35,
                  "amount": 70
                },
                {
                  "type": "registered",
                  "quantity": 1,
                  "unit_amount": 1175,
                  "amount": 1175
                },
                {
                  "type": "return_receipt",
                  "quantity": 1,
                  "unit_amount": 1175,
                  "amount": 1175
                },
                {
                  "type": "restricted_delivery",
                  "quantity": 1,
                  "unit_amount": 1380,
                  "amount": 1380
                }
              ]
            }
          },
          "send_date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "description": "A data agendada para o envio, `AAAA-MM-DD`. `null` quando a correspondência foi enviada na hora.",
            "example": null
          },
          "cancellation_reason": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "requested",
              "insufficient_balance",
              null
            ],
            "description": "Por que a correspondência foi cancelada. `null` quando ela não está cancelada.\n\n**Valores possíveis**\n\n- `requested`: Você cancelou, pela API ou pelo painel.\n- `insufficient_balance`: Era uma correspondência agendada e, na data do envio, o saldo não cobria o preço. Nada foi cobrado.",
            "example": null
          },
          "failure_reason": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "unprintable_document",
              "damaged_in_production",
              "refused_by_carrier",
              "other",
              null
            ],
            "description": "Por que a correspondência falhou na produção. `null` quando ela não está em `failed`. Quando ela falha, o valor volta para o saldo automaticamente.\n\n**Valores possíveis**\n\n- `unprintable_document`: O arquivo passou pela validação, mas não pôde ser impresso como está.\n- `damaged_in_production`: A correspondência foi danificada na impressão, na dobra ou no envelopamento e não pôde ser refeita.\n- `refused_by_carrier`: Os Correios recusaram a correspondência na postagem.\n- `other`: Outro motivo. Fale com o suporte da CartaFlow pelo painel para saber os detalhes.",
            "example": null
          },
          "tracking_code": {
            "type": [
              "string",
              "null"
            ],
            "description": "O código de rastreio dos Correios de uma correspondência registrada (`postal_services` com `registered`), como `RA123456785BR`. Preenchido quando ela é postada. `null` numa carta simples, que não tem rastreio, e antes da postagem.",
            "example": null
          },
          "preview_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "description": "Link para o PDF final, exatamente como será impresso, já com o endereço. O link vale por 60 minutos: consulte a correspondência de novo para receber um link novo. O arquivo fica disponível por pelo menos 90 dias depois da criação (ou depois da data do envio, numa correspondência agendada); `null` só depois desse prazo, se o arquivo deixar de estar disponível. Numa correspondência em preto e branco, o PDF mantém as cores do original: a conversão para tons de cinza acontece na impressão.",
            "example": "https://files.cartaflow.com.br/previews/ltr_8Kq2wX4mN7pR.pdf?expires=1760369400&signature=9c1f..."
          },
          "reference": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 100,
            "description": "Seu identificador para esta correspondência, como o número da fatura ou o id do cliente no seu sistema. Aparece no painel e pode ser usado como filtro nas listagens. Não precisa ser único. Até 100 caracteres. `null` quando você não enviou.",
            "example": "fatura-2026-10-0042"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "maxLength": 500
            },
            "maxProperties": 20,
            "description": "Pares chave-valor para guardar dados seus junto do objeto, como o id do cliente ou do contrato. Voltam em todas as respostas e webhooks e nunca são impressos. Até 20 chaves; chaves com até 40 caracteres e valores em texto com até 500 caracteres. Não guarde dados sensíveis, como senhas ou números de cartão. Objeto vazio `{}` quando você não enviou.",
            "example": {
              "customer_id": "1842",
              "contract": "C-2026-118"
            }
          },
          "status_transitions": {
            "type": "object",
            "title": "LetterStatusTransitions",
            "description": "Quando a correspondência chegou a cada status. `null` para os status pelos quais ela ainda não passou. Uma correspondência agendada nasce em scheduled, no momento de `created_at`.",
            "required": [
              "received_at",
              "in_production_at",
              "printed_at",
              "posted_at",
              "canceled_at",
              "failed_at"
            ],
            "properties": {
              "received_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "Quando foi cobrada e entrou na fila de produção: igual a `created_at`, ou a data do envio se foi agendada.",
                "example": "2026-10-13T14:20:00Z"
              },
              "in_production_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "Quando entrou em produção.",
                "example": null
              },
              "printed_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "Quando foi impressa e envelopada.",
                "example": null
              },
              "posted_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "Quando foi entregue aos Correios.",
                "example": null
              },
              "canceled_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "Quando foi cancelada.",
                "example": null
              },
              "failed_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "Quando falhou na produção.",
                "example": null
              }
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Quando a correspondência foi criada e recebida, em UTC.",
            "example": "2026-10-13T14:20:00Z"
          }
        }
      },
      "Quote": {
        "type": "object",
        "title": "Quote",
        "description": "O resultado de uma simulação: o preço da correspondência, no plano atual da conta, e o endereço completo como seria impresso. Nada é criado, cobrado ou guardado. O valor cobrado de verdade é o do momento da cobrança.",
        "required": [
          "object",
          "plan",
          "to",
          "pages",
          "sheets",
          "price"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "quote",
            "description": "Tipo do objeto. Sempre `quote`.",
            "example": "quote"
          },
          "plan": {
            "type": "string",
            "enum": [
              "pay_as_you_go",
              "essential",
              "professional",
              "scale",
              "enterprise"
            ],
            "description": "O plano usado no cálculo.\n\n**Valores possíveis**\n\n- `pay_as_you_go`: Avulso. Sem mensalidade, preço por envio mais alto.\n- `essential`: Essencial.\n- `professional`: Profissional.\n- `scale`: Escala.\n- `enterprise`: Enterprise. Contrato de 12 meses com volume mensal combinado.",
            "x-enumDescriptions": {
              "pay_as_you_go": "Avulso. Sem mensalidade, preço por envio mais alto.",
              "essential": "Essencial.",
              "professional": "Profissional.",
              "scale": "Escala.",
              "enterprise": "Enterprise. Contrato de 12 meses com volume mensal combinado."
            },
            "example": "essential"
          },
          "to": {
            "type": "object",
            "title": "Address",
            "description": "O destinatário completo, já com os campos preenchidos a partir do CEP. Confira antes de enviar.",
            "required": [
              "name",
              "street",
              "number",
              "complement",
              "neighborhood",
              "city",
              "state",
              "postal_code"
            ],
            "properties": {
              "name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Nome da pessoa ou da empresa, como deve aparecer no envelope. Até 60 caracteres.",
                "example": "Destinatário Exemplo"
              },
              "street": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100,
                "description": "Logradouro, com o tipo e o nome: rua, avenida, travessa, praça. Sem o número. Até 100 caracteres.",
                "example": "Praça da Sé"
              },
              "number": {
                "type": "string",
                "minLength": 1,
                "maxLength": 10,
                "description": "Número do imóvel. É texto porque alguns números têm letras, como `128A`. Use `S/N` quando o endereço não tem número. Até 10 caracteres.",
                "example": "128"
              },
              "complement": {
                "type": [
                  "string",
                  "null"
                ],
                "maxLength": 60,
                "description": "Complemento: apartamento, bloco, sala, andar. `null` quando o endereço não tem.",
                "example": "Ap. 52"
              },
              "neighborhood": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Bairro. Até 60 caracteres.",
                "example": "Sé"
              },
              "city": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Cidade. Até 60 caracteres.",
                "example": "São Paulo"
              },
              "state": {
                "type": "string",
                "enum": [
                  "AC",
                  "AL",
                  "AP",
                  "AM",
                  "BA",
                  "CE",
                  "DF",
                  "ES",
                  "GO",
                  "MA",
                  "MT",
                  "MS",
                  "MG",
                  "PA",
                  "PB",
                  "PR",
                  "PE",
                  "PI",
                  "RJ",
                  "RN",
                  "RS",
                  "RO",
                  "RR",
                  "SC",
                  "SP",
                  "SE",
                  "TO"
                ],
                "description": "UF: a sigla do estado.\n\n**Valores possíveis**\n\n- `AC`: Acre\n- `AL`: Alagoas\n- `AP`: Amapá\n- `AM`: Amazonas\n- `BA`: Bahia\n- `CE`: Ceará\n- `DF`: Distrito Federal\n- `ES`: Espírito Santo\n- `GO`: Goiás\n- `MA`: Maranhão\n- `MT`: Mato Grosso\n- `MS`: Mato Grosso do Sul\n- `MG`: Minas Gerais\n- `PA`: Pará\n- `PB`: Paraíba\n- `PR`: Paraná\n- `PE`: Pernambuco\n- `PI`: Piauí\n- `RJ`: Rio de Janeiro\n- `RN`: Rio Grande do Norte\n- `RS`: Rio Grande do Sul\n- `RO`: Rondônia\n- `RR`: Roraima\n- `SC`: Santa Catarina\n- `SP`: São Paulo\n- `SE`: Sergipe\n- `TO`: Tocantins",
                "x-enumDescriptions": {
                  "AC": "Acre",
                  "AL": "Alagoas",
                  "AP": "Amapá",
                  "AM": "Amazonas",
                  "BA": "Bahia",
                  "CE": "Ceará",
                  "DF": "Distrito Federal",
                  "ES": "Espírito Santo",
                  "GO": "Goiás",
                  "MA": "Maranhão",
                  "MT": "Mato Grosso",
                  "MS": "Mato Grosso do Sul",
                  "MG": "Minas Gerais",
                  "PA": "Pará",
                  "PB": "Paraíba",
                  "PR": "Paraná",
                  "PE": "Pernambuco",
                  "PI": "Piauí",
                  "RJ": "Rio de Janeiro",
                  "RN": "Rio Grande do Norte",
                  "RS": "Rio Grande do Sul",
                  "RO": "Rondônia",
                  "RR": "Roraima",
                  "SC": "Santa Catarina",
                  "SP": "São Paulo",
                  "SE": "Sergipe",
                  "TO": "Tocantins"
                },
                "example": "SP"
              },
              "postal_code": {
                "type": "string",
                "pattern": "^[0-9]{5}-[0-9]{3}$",
                "description": "CEP, sempre no formato `00000-000`.",
                "example": "01001-000"
              }
            }
          },
          "pages": {
            "type": "integer",
            "description": "Páginas do documento.",
            "example": 2
          },
          "sheets": {
            "type": "integer",
            "description": "Folhas que a correspondência usaria.",
            "example": 2
          },
          "price": {
            "$ref": "#/components/schemas/Price"
          }
        }
      },
      "VerificationLetterInput": {
        "type": "object",
        "title": "VerificationLetterInput",
        "description": "Personaliza a correspondência do modelo da CartaFlow, só nesta verificação. Cada campo que você não envia vem do modelo padrão da sua empresa, salvo no painel, e, quando a empresa não salvou um, do padrão da CartaFlow. Os textos ficam abaixo da janela do envelope. Os textos padrão e as partes fixas, como \"Seu código\" e a instrução do QR code, são em português. O logo, o nome da sua empresa, o endereço e o código são sempre impressos e não mudam por aqui. Não use junto com `document`: a API responde 422 com `invalid_value`.",
        "additionalProperties": false,
        "properties": {
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80,
            "description": "O título da correspondência, em destaque. Pode usar `{{empresa}}` (o nome da sua empresa: o nome fantasia, ou a razão social quando não há um) e `{{nome}}` (o nome do destinatário, de `to.name`). Qualquer outra marcação entre chaves dá 422 com `invalid_value`. Até 80 caracteres.",
            "default": "Confirme o seu endereço",
            "example": "Confirme seu endereço, {{nome}}"
          },
          "body": {
            "type": "string",
            "minLength": 1,
            "maxLength": 1200,
            "description": "O texto logo abaixo do título, antes do código. Quebras de linha (`\\n`) começam um novo parágrafo. Pode usar `{{empresa}}` (o nome da sua empresa: o nome fantasia, ou a razão social quando não há um) e `{{nome}}` (o nome do destinatário, de `to.name`). Qualquer outra marcação entre chaves dá 422 com `invalid_value`. Até 1200 caracteres.",
            "default": "{{empresa}} pediu a confirmação de que você recebe correspondência neste endereço. Use o código abaixo para confirmar.",
            "example": "{{empresa}} precisa confirmar o endereço do seu cadastro. Use o código abaixo."
          },
          "footer": {
            "type": "string",
            "minLength": 1,
            "maxLength": 300,
            "description": "O texto menor no pé da página. Pode usar `{{empresa}}` (o nome da sua empresa: o nome fantasia, ou a razão social quando não há um) e `{{nome}}` (o nome do destinatário, de `to.name`). Qualquer outra marcação entre chaves dá 422 com `invalid_value`. Até 300 caracteres.",
            "default": "O código vale por 60 dias depois da postagem e só funciona para este endereço. Não compartilhe este código com ninguém.",
            "example": "Dúvidas? Fale com {{empresa}} pelos canais de atendimento do aplicativo."
          },
          "include_qr_code": {
            "type": "boolean",
            "default": true,
            "description": "Imprime o QR code que abre a página de confirmação já com o código: a pessoa só toca em Confirmar. Só vale com `method: hosted_page`; com `method: code`, o QR code nunca é impresso.",
            "example": true
          },
          "include_page_url": {
            "type": "boolean",
            "default": true,
            "description": "Imprime o endereço da página de confirmação (`hosted_page_url`), para a pessoa abrir no navegador e digitar o código. Só vale com `method: hosted_page`; com `method: code`, o endereço nunca é impresso.",
            "example": true
          }
        }
      },
      "VerificationDocumentInput": {
        "title": "VerificationDocumentInput",
        "description": "O seu próprio PDF, no lugar do modelo da CartaFlow. Escolha a forma pelo campo `type`: `url` (até 10 MB), `upload` (um arquivo enviado antes com POST /v1/uploads, até 10 MB) ou `base64` (até 3 MB). Este endpoint aceita só JSON: para mandar o arquivo, use o upload em duas etapas.\n\nO PDF segue as regras de uma correspondência (A4 em retrato, até 6 folhas, área do endereço em branco com `address_placement: first_page`, texto selecionável) e tem marcações reservadas, que a CartaFlow preenche:\n\n- `{{OTP_CODE}}`: obrigatória. O lugar onde o código é impresso, no formato `123 456`, com a fonte, o tamanho e a cor da marcação. Sem ela, a API responde 422 com `otp_code_missing`.\n- `{{VERIFICATION_URL}}`: opcional. O endereço da página de confirmação (`hosted_page_url`), sem o código.\n- `{{QR_CODE}}`: opcional. Um QR code de 25 x 25 mm que abre a página já com o código. O canto superior esquerdo fica onde começa a marcação: deixe esse espaço em branco, à direita e abaixo dela.\n\n`{{VERIFICATION_URL}}` e `{{QR_CODE}}` só valem com `method: hosted_page`; com `method: code`, a API responde 422 com `invalid_value`. Escreva as marcações em maiúsculas, com as chaves. As outras marcações, como `{{nome}}`, funcionam como numa correspondência: envie os valores em `variables`, sem incluir as reservadas (`variable_not_found`).",
        "oneOf": [
          {
            "$ref": "#/components/schemas/DocumentFromUrl"
          },
          {
            "$ref": "#/components/schemas/DocumentFromUpload"
          },
          {
            "$ref": "#/components/schemas/DocumentFromBase64"
          }
        ],
        "discriminator": {
          "propertyName": "type",
          "mapping": {
            "url": "#/components/schemas/DocumentFromUrl",
            "upload": "#/components/schemas/DocumentFromUpload",
            "base64": "#/components/schemas/DocumentFromBase64"
          }
        }
      },
      "CreateVerificationRequest": {
        "type": "object",
        "title": "CreateVerificationRequest",
        "description": "A correspondência sai do modelo da CartaFlow, que você pode personalizar em `letter`, ou do seu próprio PDF, em `document`. Envie um ou outro, nunca os dois. Uma verificação vai sempre como carta simples: não há `postal_services` aqui.",
        "required": [
          "to",
          "method"
        ],
        "additionalProperties": false,
        "properties": {
          "to": {
            "type": "object",
            "title": "AddressInput",
            "description": "O endereço a verificar e o nome de quem mora ou trabalha nele.",
            "required": [
              "name",
              "number",
              "postal_code"
            ],
            "additionalProperties": false,
            "properties": {
              "name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Nome da pessoa ou da empresa, como deve aparecer no envelope. Até 60 caracteres.",
                "example": "Destinatário Exemplo"
              },
              "postal_code": {
                "type": "string",
                "pattern": "^[0-9]{5}-?[0-9]{3}$",
                "description": "CEP com 8 dígitos, com ou sem hífen: `01001-000` ou `01001000`. Precisa existir na base de CEPs; é dele que vêm os campos que você não enviar. Nas respostas ele sempre volta com hífen.",
                "example": "01001-000"
              },
              "number": {
                "type": "string",
                "minLength": 1,
                "maxLength": 10,
                "description": "Número do imóvel. É texto porque alguns números têm letras, como `128A`. Use `S/N` quando o endereço não tem número. Até 10 caracteres.",
                "example": "128"
              },
              "complement": {
                "type": "string",
                "maxLength": 60,
                "description": "Complemento: apartamento, bloco, sala, andar. Até 60 caracteres.",
                "example": "Ap. 52"
              },
              "street": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100,
                "description": "Logradouro, com o tipo e o nome: rua, avenida, travessa, praça. Sem o número. Até 100 caracteres. Opcional: quando você não envia, preenchemos a partir do CEP. Quando envia, usamos o seu valor.",
                "example": "Praça da Sé"
              },
              "neighborhood": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Bairro. Até 60 caracteres. Opcional: quando você não envia, preenchemos a partir do CEP. Quando envia, usamos o seu valor.",
                "example": "Sé"
              },
              "city": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Cidade. Até 60 caracteres. Opcional: quando você não envia, preenchemos a partir do CEP. Quando envia, usamos o seu valor.",
                "example": "São Paulo"
              },
              "state": {
                "type": "string",
                "enum": [
                  "AC",
                  "AL",
                  "AP",
                  "AM",
                  "BA",
                  "CE",
                  "DF",
                  "ES",
                  "GO",
                  "MA",
                  "MT",
                  "MS",
                  "MG",
                  "PA",
                  "PB",
                  "PR",
                  "PE",
                  "PI",
                  "RJ",
                  "RN",
                  "RS",
                  "RO",
                  "RR",
                  "SC",
                  "SP",
                  "SE",
                  "TO"
                ],
                "description": "UF: a sigla do estado, com duas letras maiúsculas.\n\nOpcional: quando você não envia, preenchemos a partir do CEP. Quando envia, usamos o seu valor.\n\n**Valores possíveis**\n\n- `AC`: Acre\n- `AL`: Alagoas\n- `AP`: Amapá\n- `AM`: Amazonas\n- `BA`: Bahia\n- `CE`: Ceará\n- `DF`: Distrito Federal\n- `ES`: Espírito Santo\n- `GO`: Goiás\n- `MA`: Maranhão\n- `MT`: Mato Grosso\n- `MS`: Mato Grosso do Sul\n- `MG`: Minas Gerais\n- `PA`: Pará\n- `PB`: Paraíba\n- `PR`: Paraná\n- `PE`: Pernambuco\n- `PI`: Piauí\n- `RJ`: Rio de Janeiro\n- `RN`: Rio Grande do Norte\n- `RS`: Rio Grande do Sul\n- `RO`: Rondônia\n- `RR`: Roraima\n- `SC`: Santa Catarina\n- `SP`: São Paulo\n- `SE`: Sergipe\n- `TO`: Tocantins",
                "x-enumDescriptions": {
                  "AC": "Acre",
                  "AL": "Alagoas",
                  "AP": "Amapá",
                  "AM": "Amazonas",
                  "BA": "Bahia",
                  "CE": "Ceará",
                  "DF": "Distrito Federal",
                  "ES": "Espírito Santo",
                  "GO": "Goiás",
                  "MA": "Maranhão",
                  "MT": "Mato Grosso",
                  "MS": "Mato Grosso do Sul",
                  "MG": "Minas Gerais",
                  "PA": "Pará",
                  "PB": "Paraíba",
                  "PR": "Paraná",
                  "PE": "Pernambuco",
                  "PI": "Piauí",
                  "RJ": "Rio de Janeiro",
                  "RN": "Rio Grande do Norte",
                  "RS": "Rio Grande do Sul",
                  "RO": "Rondônia",
                  "RR": "Roraima",
                  "SC": "Santa Catarina",
                  "SP": "São Paulo",
                  "SE": "Sergipe",
                  "TO": "Tocantins"
                },
                "example": "SP"
              }
            },
            "example": {
              "name": "Destinatário Exemplo",
              "postal_code": "01001-000",
              "number": "128",
              "complement": "Ap. 52"
            }
          },
          "method": {
            "type": "string",
            "enum": [
              "hosted_page",
              "code"
            ],
            "description": "Como a pessoa confirma o código. Define também o que vai impresso na correspondência.\n\n**Valores possíveis**\n\n- `hosted_page`: A pessoa confirma em uma página com a sua marca, hospedada pela CartaFlow: pelo QR code, que abre a página já com o código, ou digitando o código no endereço impresso. Você não precisa construir tela nenhuma; o resultado chega por webhook e aparece no painel.\n- `code`: A correspondência traz só o código, sem QR code e sem o endereço da página. A pessoa digita o código no seu site ou aplicativo, e o seu servidor confere com POST /v1/verifications/{verification_id}/check.",
            "x-enumDescriptions": {
              "hosted_page": "A pessoa confirma em uma página com a sua marca, hospedada pela CartaFlow: pelo QR code, que abre a página já com o código, ou digitando o código no endereço impresso. Você não precisa construir tela nenhuma; o resultado chega por webhook e aparece no painel.",
              "code": "A correspondência traz só o código, sem QR code e sem o endereço da página. A pessoa digita o código no seu site ou aplicativo, e o seu servidor confere com POST /v1/verifications/{verification_id}/check."
            },
            "example": "hosted_page"
          },
          "letter": {
            "$ref": "#/components/schemas/VerificationLetterInput"
          },
          "document": {
            "$ref": "#/components/schemas/VerificationDocumentInput"
          },
          "color": {
            "type": "boolean",
            "default": false,
            "description": "`true` imprime em cores. `false` imprime em preto e branco: um PDF colorido sai em tons de cinza. A impressão colorida tem acréscimo por página impressa (cada lado impresso conta como uma página). Só vale com `document`, o seu próprio PDF. A correspondência do modelo da CartaFlow é sempre uma folha em preto e branco: sem `document`, enviar este campo com um valor diferente do padrão dá 422 com `invalid_value`.",
            "example": false
          },
          "double_sided": {
            "type": "boolean",
            "default": false,
            "description": "`true` imprime frente e verso: cada folha leva duas páginas do documento, então a correspondência usa menos folhas e custa menos. `false` imprime só a frente de cada folha. Só vale com `document`, o seu próprio PDF. A correspondência do modelo da CartaFlow é sempre uma folha em preto e branco: sem `document`, enviar este campo com um valor diferente do padrão dá 422 com `invalid_value`.",
            "example": false
          },
          "address_placement": {
            "type": "string",
            "enum": [
              "first_page",
              "extra_page"
            ],
            "description": "Onde a CartaFlow imprime o endereço do destinatário no seu PDF. Só vale com `document`, o seu próprio PDF. A correspondência do modelo da CartaFlow é sempre uma folha em preto e branco: sem `document`, enviar este campo com um valor diferente do padrão dá 422 com `invalid_value`.\n\n**Valores possíveis**\n\n- `first_page`: Na área do endereço da primeira página do seu documento (90 x 45 mm, a 20 mm da esquerda e 45 mm do topo). Essa área precisa estar em branco no seu PDF. Padrão.\n- `extra_page`: Num lado só dele, o primeiro, que aparece pela janela do envelope. Use quando o seu layout ocupa a área do endereço. Ele ocupa um lado que ficaria em branco, quando há um: o verso da primeira página, só frente, ou o lado que sobra, em frente e verso com número ímpar de páginas. Em frente e verso com número par de páginas, entra uma folha a mais no início. O endereço nunca é cobrado.",
            "x-enumDescriptions": {
              "first_page": "Na área do endereço da primeira página do seu documento (90 x 45 mm, a 20 mm da esquerda e 45 mm do topo). Essa área precisa estar em branco no seu PDF. Padrão.",
              "extra_page": "Num lado só dele, o primeiro, que aparece pela janela do envelope. Use quando o seu layout ocupa a área do endereço. Ele ocupa um lado que ficaria em branco, quando há um: o verso da primeira página, só frente, ou o lado que sobra, em frente e verso com número ímpar de páginas. Em frente e verso com número par de páginas, entra uma folha a mais no início. O endereço nunca é cobrado."
            },
            "default": "first_page",
            "example": "first_page"
          },
          "instructions": {
            "type": "string",
            "minLength": 1,
            "maxLength": 300,
            "description": "Texto impresso logo abaixo do código, no modelo da CartaFlow, dizendo onde digitar. Use com `method: code`, por exemplo \"Abra o app, vá em Perfil > Endereço e digite o código\". Também é impresso com `method: hosted_page` quando `letter` desliga o QR code e o endereço da página. Se você não enviar, imprimimos \"Digite este código no site ou aplicativo de\" seguido do nome da sua empresa. Não é impresso no seu próprio PDF: escreva a instrução no documento. Até 300 caracteres.",
            "example": "Abra o app, vá em Perfil > Endereço e digite o código."
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "maxLength": 2048,
            "description": "Só para `method: hosted_page`. Depois de confirmar, a página mostra um botão que leva para esta URL, como a área logada do seu site.",
            "example": "https://www.exemplo.com.br/conta"
          },
          "reference": {
            "type": "string",
            "maxLength": 100,
            "description": "Seu identificador para esta verificação, como o número da fatura ou o id do cliente no seu sistema. Aparece no painel e pode ser usado como filtro nas listagens. Não precisa ser único. Até 100 caracteres.",
            "example": "cliente-1842"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "maxLength": 500
            },
            "maxProperties": 20,
            "description": "Pares chave-valor para guardar dados seus junto do objeto, como o id do cliente ou do contrato. Voltam em todas as respostas e webhooks e nunca são impressos. Até 20 chaves; chaves com até 40 caracteres e valores em texto com até 500 caracteres. Não guarde dados sensíveis, como senhas ou números de cartão.",
            "example": {
              "customer_id": "1842",
              "contract": "C-2026-118"
            }
          }
        }
      },
      "VerificationDocument": {
        "title": "VerificationDocument",
        "description": "Como a correspondência foi feita: o modelo da CartaFlow ou o seu PDF. A cópia dela, com o código escondido (`000 000`), está em `preview_url`.",
        "oneOf": [
          {
            "type": "object",
            "title": "Modelo da CartaFlow",
            "description": "A correspondência do modelo da CartaFlow, com os textos e as opções usados: o padrão da CartaFlow, o modelo da sua empresa e `letter`, nessa ordem. Os textos voltam com `{{empresa}}` e `{{nome}}` sem preencher. Com `method: code`, `include_qr_code` e `include_page_url` são sempre `false`.",
            "required": [
              "type",
              "title",
              "body",
              "footer",
              "include_qr_code",
              "include_page_url"
            ],
            "properties": {
              "type": {
                "type": "string",
                "const": "template",
                "description": "A correspondência saiu do modelo da CartaFlow."
              },
              "title": {
                "type": "string",
                "description": "O título impresso.",
                "example": "Confirme o seu endereço"
              },
              "body": {
                "type": "string",
                "description": "O texto impresso antes do código.",
                "example": "{{empresa}} pediu a confirmação de que você recebe correspondência neste endereço. Use o código abaixo para confirmar."
              },
              "footer": {
                "type": "string",
                "description": "O texto do pé da página.",
                "example": "O código vale por 60 dias depois da postagem e só funciona para este endereço. Não compartilhe este código com ninguém."
              },
              "include_qr_code": {
                "type": "boolean",
                "description": "`true` quando o QR code foi impresso.",
                "example": true
              },
              "include_page_url": {
                "type": "boolean",
                "description": "`true` quando o endereço da página de confirmação foi impresso.",
                "example": true
              }
            }
          },
          {
            "type": "object",
            "title": "Seu PDF, por upload",
            "required": [
              "type",
              "filename",
              "variables"
            ],
            "properties": {
              "type": {
                "type": "string",
                "const": "upload",
                "description": "O seu PDF foi enviado como arquivo: com POST /v1/uploads e `document.type: upload`, ou pelo painel."
              },
              "filename": {
                "type": "string",
                "description": "O nome do arquivo enviado.",
                "example": "verificacao-endereco.pdf"
              },
              "variables": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": true,
                "description": "As variáveis que você enviou, escritas no PDF. `null` quando você não enviou `variables`. As marcações reservadas, como `{{OTP_CODE}}`, são preenchidas pela CartaFlow e nunca aparecem aqui.",
                "example": null
              }
            }
          },
          {
            "type": "object",
            "title": "Seu PDF, por URL",
            "required": [
              "type",
              "url",
              "variables"
            ],
            "properties": {
              "type": {
                "type": "string",
                "const": "url",
                "description": "O seu PDF veio de uma URL."
              },
              "url": {
                "type": "string",
                "format": "uri",
                "description": "A URL de onde baixamos o PDF.",
                "example": "https://arquivos.exemplo.com.br/verificacao/modelo.pdf"
              },
              "variables": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": true,
                "description": "As variáveis que você enviou, escritas no PDF. `null` quando você não enviou `variables`. As marcações reservadas, como `{{OTP_CODE}}`, são preenchidas pela CartaFlow e nunca aparecem aqui.",
                "example": null
              }
            }
          },
          {
            "type": "object",
            "title": "Seu PDF, em base64",
            "required": [
              "type",
              "variables"
            ],
            "properties": {
              "type": {
                "type": "string",
                "const": "base64",
                "description": "O seu PDF veio dentro do JSON. O conteúdo não é devolvido; use `preview_url`."
              },
              "variables": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": true,
                "description": "As variáveis que você enviou, escritas no PDF. `null` quando você não enviou `variables`. As marcações reservadas, como `{{OTP_CODE}}`, são preenchidas pela CartaFlow e nunca aparecem aqui.",
                "example": null
              }
            }
          }
        ],
        "discriminator": {
          "propertyName": "type"
        }
      },
      "VerificationConfirmation": {
        "type": "object",
        "title": "VerificationConfirmation",
        "description": "Como e quando o código certo foi confirmado, com tudo o que foi registrado naquele momento. O IP, a localização e os dados do aparelho são registrados quando estão disponíveis, sem garantia: use como indícios a mais numa análise de fraude, nunca como prova do endereço. A prova é o código, que só chega pela correspondência. Campos que não puderam ser registrados vêm `null`; confirmações registradas antes de 14/10/2026 têm `null` em `user_agent`, `device`, `client` e `precise_location`.",
        "required": [
          "method",
          "hosted_page_entry",
          "confirmed_at",
          "ip",
          "location",
          "user_agent",
          "device",
          "client",
          "precise_location"
        ],
        "properties": {
          "method": {
            "type": "string",
            "enum": [
              "api",
              "hosted_page"
            ],
            "description": "Por onde o código certo chegou.\n\n**Valores possíveis**\n\n- `api`: Pelo seu servidor, com POST /v1/verifications/{verification_id}/check.\n- `hosted_page`: Na página de confirmação hospedada pela CartaFlow.",
            "x-enumDescriptions": {
              "api": "Pelo seu servidor, com POST /v1/verifications/{verification_id}/check.",
              "hosted_page": "Na página de confirmação hospedada pela CartaFlow."
            },
            "example": "hosted_page"
          },
          "hosted_page_entry": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "qr_code",
              "typed",
              null
            ],
            "description": "Como a pessoa chegou ao código na página. `null` quando `method` é `api`.\n\n**Valores possíveis**\n\n- `qr_code`: Escaneou o QR code, que abre a página já com o código.\n- `typed`: Digitou o código na página.",
            "example": "qr_code"
          },
          "confirmed_at": {
            "type": "string",
            "format": "date-time",
            "description": "Quando o código certo foi confirmado. Igual a `status_transitions.verified_at`.",
            "example": "2026-10-21T19:32:00Z"
          },
          "ip": {
            "type": [
              "string",
              "null"
            ],
            "description": "O endereço IP, IPv4 ou IPv6, de onde veio a confirmação. Com `method: hosted_page`, é o IP do aparelho da pessoa. Com `method: api`, é o IP do seu servidor, que chamou a API, e não o da pessoa. `null` quando não foi registrado.",
            "example": "198.51.100.23"
          },
          "location": {
            "type": [
              "object",
              "null"
            ],
            "title": "VerificationConfirmationLocation",
            "description": "A localização aproximada do IP, estimada pela rede no momento da confirmação. Não é GPS nem o endereço verificado: uma rede móvel, uma VPN ou um proxy podem indicar outra cidade ou outro país. Só existe com `method: hosted_page`. `null` com `method: api` ou quando não foi possível estimar.",
            "required": [
              "city",
              "region",
              "country",
              "postal_code",
              "latitude",
              "longitude"
            ],
            "properties": {
              "city": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Cidade, como `São Paulo`. `null` quando não foi estimada.",
                "example": "São Paulo"
              },
              "region": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Código da região dentro do país (ISO 3166-2, sem o código do país). No Brasil, a UF, como `SP`. `null` quando não foi estimada.",
                "example": "SP"
              },
              "country": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Código do país com duas letras (ISO 3166-1), como `BR`. `null` quando não foi estimado.",
                "example": "BR"
              },
              "postal_code": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "O código postal estimado para o IP, como a rede o informa (no Brasil, muitas vezes só o começo do CEP, como `01000`). Não é o CEP verificado. `null` quando não foi estimado.",
                "example": "01000"
              },
              "latitude": {
                "type": [
                  "number",
                  "null"
                ],
                "minimum": -90,
                "maximum": 90,
                "description": "Latitude estimada para o IP, em graus. Aproximada: em geral o centro da cidade ou da região. `null` quando não foi estimada.",
                "example": -23.5475
              },
              "longitude": {
                "type": [
                  "number",
                  "null"
                ],
                "minimum": -180,
                "maximum": 180,
                "description": "Longitude estimada para o IP, em graus. `null` quando não foi estimada.",
                "example": -46.6361
              }
            },
            "example": {
              "city": "São Paulo",
              "region": "SP",
              "country": "BR",
              "postal_code": "01000",
              "latitude": -23.5475,
              "longitude": -46.6361
            }
          },
          "user_agent": {
            "type": [
              "string",
              "null"
            ],
            "description": "O user agent do navegador que confirmou, como ele foi enviado. Com `method: api`, é o do seu servidor. `null` quando não foi enviado.",
            "example": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1"
          },
          "device": {
            "type": [
              "object",
              "null"
            ],
            "title": "VerificationDevice",
            "description": "O aparelho, o sistema e o navegador, lidos do `user_agent`. Um navegador pode informar outra coisa; trate como indício. `null` quando o `user_agent` não diz nada que reconheçamos (por exemplo, o de um servidor, com `method: api`).",
            "required": [
              "type",
              "os",
              "browser"
            ],
            "properties": {
              "type": {
                "type": [
                  "string",
                  "null"
                ],
                "enum": [
                  "mobile",
                  "tablet",
                  "desktop",
                  null
                ],
                "description": "O tipo de aparelho. `null` quando não foi possível saber.\n\n**Valores possíveis**\n\n- `mobile`: Celular.\n- `tablet`: Tablet.\n- `desktop`: Computador.",
                "example": "mobile"
              },
              "os": {
                "type": [
                  "object",
                  "null"
                ],
                "title": "VerificationDeviceOs",
                "description": "O sistema operacional. `null` quando não foi reconhecido.",
                "required": [
                  "name",
                  "version"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Nome, como `iOS`, `iPadOS`, `Android`, `Windows`, `macOS`, `Linux` ou `ChromeOS`.",
                    "example": "iOS"
                  },
                  "version": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Versão, como `17.5`. `null` quando o navegador não informa.",
                    "example": "17.5"
                  }
                }
              },
              "browser": {
                "type": [
                  "object",
                  "null"
                ],
                "title": "VerificationDeviceBrowser",
                "description": "O navegador. Inclui navegadores de dentro de apps, como `Instagram` e `Facebook`, e `WebView` quando um app do iPhone abre a página sem dizer qual é. `null` quando não foi reconhecido.",
                "required": [
                  "name",
                  "version"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Nome, como `Safari`, `Chrome`, `Samsung Internet`, `Firefox` ou `Edge`.",
                    "example": "Safari"
                  },
                  "version": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Versão, como `17.5`. `null` quando o navegador não informa.",
                    "example": "17.5"
                  }
                }
              }
            },
            "example": {
              "type": "mobile",
              "os": {
                "name": "iOS",
                "version": "17.5"
              },
              "browser": {
                "name": "Safari",
                "version": "17.5"
              }
            }
          },
          "client": {
            "type": [
              "object",
              "null"
            ],
            "title": "VerificationClient",
            "description": "O que o navegador informou à página: idioma, fuso horário, tela e tempo na página, além do cabeçalho `Accept-Language`. Com `method: api`, só `accept_language`, o do seu servidor. `null` quando nada foi informado.",
            "required": [
              "language",
              "accept_language",
              "timezone",
              "screen",
              "time_on_page_ms"
            ],
            "properties": {
              "language": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "O idioma do navegador (BCP 47), como `pt-BR`. `null` quando não foi informado.",
                "example": "pt-BR"
              },
              "accept_language": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "O cabeçalho `Accept-Language` da requisição, como foi enviado (até 200 caracteres). `null` quando não foi enviado.",
                "example": "pt-BR,pt;q=0.9"
              },
              "timezone": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "O fuso horário do aparelho (IANA), como `America/Sao_Paulo`. `null` quando não foi informado.",
                "example": "America/Sao_Paulo"
              },
              "screen": {
                "type": [
                  "object",
                  "null"
                ],
                "title": "VerificationClientScreen",
                "description": "A tela do aparelho. `null` quando não foi informada.",
                "required": [
                  "width",
                  "height",
                  "pixel_ratio"
                ],
                "properties": {
                  "width": {
                    "type": "integer",
                    "minimum": 1,
                    "description": "Largura, em pixels CSS.",
                    "example": 390
                  },
                  "height": {
                    "type": "integer",
                    "minimum": 1,
                    "description": "Altura, em pixels CSS.",
                    "example": 844
                  },
                  "pixel_ratio": {
                    "type": "number",
                    "exclusiveMinimum": 0,
                    "description": "Pixels físicos por pixel CSS, como `3`.",
                    "example": 3
                  }
                }
              },
              "time_on_page_ms": {
                "type": [
                  "integer",
                  "null"
                ],
                "minimum": 0,
                "description": "Quanto tempo, em milissegundos, passou entre abrir a página e enviar o código. `null` quando não foi informado.",
                "example": 8100
              }
            },
            "example": {
              "language": "pt-BR",
              "accept_language": "pt-BR,pt;q=0.9",
              "timezone": "America/Sao_Paulo",
              "screen": {
                "width": 390,
                "height": 844,
                "pixel_ratio": 3
              },
              "time_on_page_ms": 8100
            }
          },
          "precise_location": {
            "type": [
              "object",
              "null"
            ],
            "title": "VerificationPreciseLocation",
            "description": "A localização do aparelho, quando a pessoa escolheu compartilhar depois de confirmar o código na página (o navegador pede a permissão). É opcional, nunca é pedida antes do código e só é aceita até 30 minutos depois da confirmação, uma vez. A precisão depende do aparelho. `null` quando a pessoa não compartilhou e sempre com `method: api`.",
            "required": [
              "latitude",
              "longitude",
              "accuracy_m",
              "distance_m",
              "shared_at",
              "ip",
              "user_agent",
              "address_coordinates"
            ],
            "properties": {
              "latitude": {
                "type": "number",
                "minimum": -90,
                "maximum": 90,
                "description": "Latitude informada pelo aparelho, em graus.",
                "example": -23.5489
              },
              "longitude": {
                "type": "number",
                "minimum": -180,
                "maximum": 180,
                "description": "Longitude informada pelo aparelho, em graus.",
                "example": -46.6388
              },
              "accuracy_m": {
                "type": "number",
                "minimum": 0,
                "description": "A precisão informada pelo aparelho, em metros: a posição real está, com boa chance, dentro desse raio.",
                "example": 14.5
              },
              "distance_m": {
                "type": [
                  "integer",
                  "null"
                ],
                "minimum": 0,
                "description": "A distância em linha reta, em metros, entre essa localização e as coordenadas do CEP do endereço verificado (`address_coordinates`). O CEP marca uma rua ou um trecho, não o número: em geral, algumas centenas de metros são normais. `null` quando não temos as coordenadas desse CEP.",
                "example": 606
              },
              "shared_at": {
                "type": "string",
                "format": "date-time",
                "description": "Quando a localização foi compartilhada.",
                "example": "2026-10-21T19:32:40Z"
              },
              "ip": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "O IP de onde a localização foi enviada. Em geral, o mesmo da confirmação.",
                "example": "198.51.100.23"
              },
              "user_agent": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "O user agent do navegador que enviou a localização.",
                "example": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1"
              },
              "address_coordinates": {
                "type": [
                  "object",
                  "null"
                ],
                "title": "VerificationAddressCoordinates",
                "description": "As coordenadas do CEP do endereço verificado, usadas para `distance_m`. `null` quando não as temos.",
                "required": [
                  "latitude",
                  "longitude"
                ],
                "properties": {
                  "latitude": {
                    "type": "number",
                    "minimum": -90,
                    "maximum": 90,
                    "description": "Latitude, em graus.",
                    "example": -23.5503898
                  },
                  "longitude": {
                    "type": "number",
                    "minimum": -180,
                    "maximum": 180,
                    "description": "Longitude, em graus.",
                    "example": -46.633081
                  }
                }
              }
            }
          }
        }
      },
      "Verification": {
        "type": "object",
        "title": "Verification",
        "description": "Uma verificação de endereço físico: a CartaFlow envia uma correspondência com um código, com a sua marca, e o endereço fica verificado quando a pessoa confirma o código. O código nunca aparece neste objeto, nem no painel.",
        "required": [
          "id",
          "object",
          "status",
          "method",
          "source",
          "to",
          "document",
          "instructions",
          "return_url",
          "hosted_page_url",
          "attempts_remaining",
          "expires_at",
          "confirmation",
          "preview_url",
          "price",
          "reference",
          "metadata",
          "status_transitions",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Identificador único da verificação. Sempre começa com `ver_`.",
            "pattern": "^ver_[A-Za-z0-9]+$",
            "example": "ver_3Hd9Kp2qZ6tW"
          },
          "object": {
            "type": "string",
            "const": "verification",
            "description": "Tipo do objeto. Sempre `verification`.",
            "example": "verification"
          },
          "status": {
            "type": "string",
            "enum": [
              "received",
              "in_production",
              "awaiting_code",
              "verified",
              "failed",
              "expired",
              "canceled",
              "revoked"
            ],
            "description": "Em que etapa a verificação está. Ela só avança: received, in_production, awaiting_code, verified. De received ela pode ir para canceled; de in_production, para canceled (pela CartaFlow) ou revoked; de awaiting_code, para failed, expired ou revoked; de verified, para revoked. Só `verified` quer dizer endereço confirmado.\n\n**Valores possíveis**\n\n- `received`: A CartaFlow recebeu o pedido, cobrou o preço do seu saldo e colocou a correspondência com o código na fila de produção. Se você cancelar agora, nada é impresso e o valor volta para o saldo.\n- `in_production`: A correspondência com o código está sendo impressa e envelopada. Cancelar agora revoga a verificação (`revoked`), sem devolução do valor.\n- `awaiting_code`: A correspondência foi postada. Agora esperamos a pessoa confirmar o código. Ela tem 60 dias a partir da postagem (veja `expires_at`). Cancelar agora revoga a verificação, sem devolução do valor.\n- `verified`: A pessoa confirmou o código certo. Ela recebe correspondência no endereço informado. `confirmation` diz como e quando. Você ainda pode revogar a verificação, e ela passa para `revoked`.\n- `failed`: Foram digitados 5 códigos errados. A verificação foi bloqueada para impedir tentativas aleatórias. Crie uma nova verificação se quiser tentar de novo.\n- `expired`: Passaram 60 dias desde a postagem sem que a pessoa confirmasse o código.\n- `canceled`: A verificação foi cancelada antes da postagem e o valor voltou para o seu saldo. Ou você cancelou enquanto ela estava em `received`, ou a CartaFlow cancelou porque a correspondência não pôde ser produzida.\n- `revoked`: Você cancelou a verificação depois que a produção começou: em produção, aguardando código ou já verificada. O valor não volta para o saldo, porque a produção já começou, e uma correspondência que estava em produção ainda é postada. O código deixa de funcionar, na página e na API, e a verificação nunca mais aparece como `verified`.",
            "x-enumDescriptions": {
              "received": "A CartaFlow recebeu o pedido, cobrou o preço do seu saldo e colocou a correspondência com o código na fila de produção. Se você cancelar agora, nada é impresso e o valor volta para o saldo.",
              "in_production": "A correspondência com o código está sendo impressa e envelopada. Cancelar agora revoga a verificação (`revoked`), sem devolução do valor.",
              "awaiting_code": "A correspondência foi postada. Agora esperamos a pessoa confirmar o código. Ela tem 60 dias a partir da postagem (veja `expires_at`). Cancelar agora revoga a verificação, sem devolução do valor.",
              "verified": "A pessoa confirmou o código certo. Ela recebe correspondência no endereço informado. `confirmation` diz como e quando. Você ainda pode revogar a verificação, e ela passa para `revoked`.",
              "failed": "Foram digitados 5 códigos errados. A verificação foi bloqueada para impedir tentativas aleatórias. Crie uma nova verificação se quiser tentar de novo.",
              "expired": "Passaram 60 dias desde a postagem sem que a pessoa confirmasse o código.",
              "canceled": "A verificação foi cancelada antes da postagem e o valor voltou para o seu saldo. Ou você cancelou enquanto ela estava em `received`, ou a CartaFlow cancelou porque a correspondência não pôde ser produzida.",
              "revoked": "Você cancelou a verificação depois que a produção começou: em produção, aguardando código ou já verificada. O valor não volta para o saldo, porque a produção já começou, e uma correspondência que estava em produção ainda é postada. O código deixa de funcionar, na página e na API, e a verificação nunca mais aparece como `verified`."
            },
            "example": "awaiting_code"
          },
          "method": {
            "type": "string",
            "enum": [
              "hosted_page",
              "code"
            ],
            "description": "Como a pessoa confirma o código.\n\n**Valores possíveis**\n\n- `hosted_page`: Na página com a sua marca, pelo QR code ou digitando o código.\n- `code`: Digitando o código no seu site ou aplicativo.",
            "x-enumDescriptions": {
              "hosted_page": "Na página com a sua marca, pelo QR code ou digitando o código.",
              "code": "Digitando o código no seu site ou aplicativo."
            },
            "example": "hosted_page"
          },
          "source": {
            "type": "string",
            "enum": [
              "api",
              "dashboard"
            ],
            "description": "Por onde a verificação foi criada. Não depende de como ela é confirmada (veja `confirmation`).\n\n**Valores possíveis**\n\n- `api`: Pela API, com POST /v1/verifications.\n- `dashboard`: No painel, por alguém da sua equipe.",
            "x-enumDescriptions": {
              "api": "Pela API, com POST /v1/verifications.",
              "dashboard": "No painel, por alguém da sua equipe."
            },
            "example": "api"
          },
          "to": {
            "type": "object",
            "title": "Address",
            "description": "O endereço verificado.",
            "required": [
              "name",
              "street",
              "number",
              "complement",
              "neighborhood",
              "city",
              "state",
              "postal_code"
            ],
            "properties": {
              "name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Nome da pessoa ou da empresa, como deve aparecer no envelope. Até 60 caracteres.",
                "example": "Destinatário Exemplo"
              },
              "street": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100,
                "description": "Logradouro, com o tipo e o nome: rua, avenida, travessa, praça. Sem o número. Até 100 caracteres.",
                "example": "Praça da Sé"
              },
              "number": {
                "type": "string",
                "minLength": 1,
                "maxLength": 10,
                "description": "Número do imóvel. É texto porque alguns números têm letras, como `128A`. Use `S/N` quando o endereço não tem número. Até 10 caracteres.",
                "example": "128"
              },
              "complement": {
                "type": [
                  "string",
                  "null"
                ],
                "maxLength": 60,
                "description": "Complemento: apartamento, bloco, sala, andar. `null` quando o endereço não tem.",
                "example": "Ap. 52"
              },
              "neighborhood": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Bairro. Até 60 caracteres.",
                "example": "Sé"
              },
              "city": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Cidade. Até 60 caracteres.",
                "example": "São Paulo"
              },
              "state": {
                "type": "string",
                "enum": [
                  "AC",
                  "AL",
                  "AP",
                  "AM",
                  "BA",
                  "CE",
                  "DF",
                  "ES",
                  "GO",
                  "MA",
                  "MT",
                  "MS",
                  "MG",
                  "PA",
                  "PB",
                  "PR",
                  "PE",
                  "PI",
                  "RJ",
                  "RN",
                  "RS",
                  "RO",
                  "RR",
                  "SC",
                  "SP",
                  "SE",
                  "TO"
                ],
                "description": "UF: a sigla do estado.\n\n**Valores possíveis**\n\n- `AC`: Acre\n- `AL`: Alagoas\n- `AP`: Amapá\n- `AM`: Amazonas\n- `BA`: Bahia\n- `CE`: Ceará\n- `DF`: Distrito Federal\n- `ES`: Espírito Santo\n- `GO`: Goiás\n- `MA`: Maranhão\n- `MT`: Mato Grosso\n- `MS`: Mato Grosso do Sul\n- `MG`: Minas Gerais\n- `PA`: Pará\n- `PB`: Paraíba\n- `PR`: Paraná\n- `PE`: Pernambuco\n- `PI`: Piauí\n- `RJ`: Rio de Janeiro\n- `RN`: Rio Grande do Norte\n- `RS`: Rio Grande do Sul\n- `RO`: Rondônia\n- `RR`: Roraima\n- `SC`: Santa Catarina\n- `SP`: São Paulo\n- `SE`: Sergipe\n- `TO`: Tocantins",
                "x-enumDescriptions": {
                  "AC": "Acre",
                  "AL": "Alagoas",
                  "AP": "Amapá",
                  "AM": "Amazonas",
                  "BA": "Bahia",
                  "CE": "Ceará",
                  "DF": "Distrito Federal",
                  "ES": "Espírito Santo",
                  "GO": "Goiás",
                  "MA": "Maranhão",
                  "MT": "Mato Grosso",
                  "MS": "Mato Grosso do Sul",
                  "MG": "Minas Gerais",
                  "PA": "Pará",
                  "PB": "Paraíba",
                  "PR": "Paraná",
                  "PE": "Pernambuco",
                  "PI": "Piauí",
                  "RJ": "Rio de Janeiro",
                  "RN": "Rio Grande do Norte",
                  "RS": "Rio Grande do Sul",
                  "RO": "Rondônia",
                  "RR": "Roraima",
                  "SC": "Santa Catarina",
                  "SP": "São Paulo",
                  "SE": "Sergipe",
                  "TO": "Tocantins"
                },
                "example": "SP"
              },
              "postal_code": {
                "type": "string",
                "pattern": "^[0-9]{5}-[0-9]{3}$",
                "description": "CEP, sempre no formato `00000-000`.",
                "example": "01001-000"
              }
            }
          },
          "document": {
            "$ref": "#/components/schemas/VerificationDocument"
          },
          "instructions": {
            "type": [
              "string",
              "null"
            ],
            "description": "O texto que você enviou para imprimir abaixo do código, no modelo da CartaFlow. `null` quando você não enviou.",
            "example": null
          },
          "return_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "description": "Para onde a página leva a pessoa depois da confirmação. `null` quando não se aplica.",
            "example": "https://www.exemplo.com.br/conta"
          },
          "hosted_page_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "description": "O endereço da página de confirmação, com a sua marca (por enquanto no domínio `verifica.cartaflow.com.br`): `https://verifica.cartaflow.com.br/{id da sua conta}/{token da página}`. É o endereço impresso na correspondência e o que o QR code abre; o QR code leva o código junto, mas este link não, então quem abre o link precisa digitar o código. Você pode mandar este link por e-mail ou mostrar no seu app. Trate-o como um endereço opaco: guarde e use como veio. `null` quando `method` é `code`.",
            "example": "https://verifica.cartaflow.com.br/acc_7Jw3Nf8Xq2Lp/9Qx2Lm7Tp4Rb8Kd3Wn6Yc1"
          },
          "attempts_remaining": {
            "type": "integer",
            "minimum": 0,
            "maximum": 5,
            "description": "Quantos códigos errados ainda podem ser digitados. Começa em 5 e diminui a cada erro, pela página ou pela API. Em 0 a verificação vai para `failed`.",
            "example": 5
          },
          "expires_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Prazo para a pessoa confirmar: 60 dias depois da postagem. `null` antes da postagem.",
            "example": "2026-12-14T16:05:00Z"
          },
          "confirmation": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/VerificationConfirmation"
              },
              {
                "type": "null"
              }
            ],
            "description": "Como e quando a pessoa confirmou o código: por onde (`method`), quando, de qual IP e de onde, aproximadamente. `null` enquanto a verificação não foi confirmada. Uma verificação revogada depois de confirmada mantém este registro, mas o status é `revoked`: o endereço não conta mais como verificado.",
            "example": null
          },
          "preview_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "description": "Link para uma cópia da correspondência como ela será impressa, com o endereço, mas sem o código: no lugar dele aparece `000 000`, e no lugar do QR code, um quadro que mostra onde ele será impresso. O código só existe no arquivo que a CartaFlow imprime: nem a API nem o painel conseguem mostrá-lo. O link vale por 60 minutos: consulte a verificação de novo para receber um link novo. `null` nos eventos e webhooks, e quando o arquivo não está disponível.",
            "example": "https://files.cartaflow.com.br/previews/ver_3Hd9Kp2qZ6tW.pdf?expires=1760369400&signature=5d2e81b3"
          },
          "price": {
            "type": "object",
            "title": "Price",
            "description": "O preço cobrado do saldo na criação. Com o modelo da CartaFlow, um envio simples do seu plano: uma linha `base`. Com o seu PDF, o preço de uma correspondência com as mesmas opções: `base`, `additional_sheets` e `color`. Nunca há serviços dos Correios. Volta para o saldo quando a verificação é cancelada (`canceled`); não volta quando ela é revogada (`revoked`).",
            "required": [
              "currency",
              "total",
              "items"
            ],
            "properties": {
              "currency": {
                "type": "string",
                "const": "BRL",
                "description": "Moeda dos valores. Sempre `BRL` (real brasileiro).",
                "example": "BRL"
              },
              "total": {
                "type": "integer",
                "description": "Soma de todas as linhas. É o valor debitado do saldo. Em centavos: `1590` são R$ 15,90.",
                "example": 4865
              },
              "items": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PriceItem"
                },
                "description": "As linhas do preço, sempre na ordem base, additional_sheets, color, registered, return_receipt, restricted_delivery. Linhas com valor zero não aparecem."
              }
            },
            "example": {
              "currency": "BRL",
              "total": 4865,
              "items": [
                {
                  "type": "base",
                  "quantity": 1,
                  "unit_amount": 990,
                  "amount": 990
                },
                {
                  "type": "additional_sheets",
                  "quantity": 1,
                  "unit_amount": 75,
                  "amount": 75
                },
                {
                  "type": "color",
                  "quantity": 2,
                  "unit_amount": 35,
                  "amount": 70
                },
                {
                  "type": "registered",
                  "quantity": 1,
                  "unit_amount": 1175,
                  "amount": 1175
                },
                {
                  "type": "return_receipt",
                  "quantity": 1,
                  "unit_amount": 1175,
                  "amount": 1175
                },
                {
                  "type": "restricted_delivery",
                  "quantity": 1,
                  "unit_amount": 1380,
                  "amount": 1380
                }
              ]
            }
          },
          "reference": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 100,
            "description": "Seu identificador para esta verificação, como o número da fatura ou o id do cliente no seu sistema. Aparece no painel e pode ser usado como filtro nas listagens. Não precisa ser único. Até 100 caracteres. `null` quando você não enviou.",
            "example": "cliente-1842"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "maxLength": 500
            },
            "maxProperties": 20,
            "description": "Pares chave-valor para guardar dados seus junto do objeto, como o id do cliente ou do contrato. Voltam em todas as respostas e webhooks e nunca são impressos. Até 20 chaves; chaves com até 40 caracteres e valores em texto com até 500 caracteres. Não guarde dados sensíveis, como senhas ou números de cartão. Objeto vazio `{}` quando você não enviou.",
            "example": {
              "customer_id": "1842",
              "contract": "C-2026-118"
            }
          },
          "status_transitions": {
            "type": "object",
            "title": "VerificationStatusTransitions",
            "description": "Quando a verificação chegou a cada status. `null` para os status pelos quais ela não passou. O status received é o momento de `created_at`. Uma verificação revogada depois de confirmada mantém `verified_at`.",
            "required": [
              "in_production_at",
              "awaiting_code_at",
              "verified_at",
              "failed_at",
              "expired_at",
              "canceled_at",
              "revoked_at"
            ],
            "properties": {
              "in_production_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "Quando a correspondência entrou em produção.",
                "example": null
              },
              "awaiting_code_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "Quando a correspondência foi postada.",
                "example": "2026-10-15T16:05:00Z"
              },
              "verified_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "Quando a pessoa confirmou o código.",
                "example": null
              },
              "failed_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "Quando a verificação foi bloqueada por códigos errados.",
                "example": null
              },
              "expired_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "Quando o prazo de confirmação acabou.",
                "example": null
              },
              "canceled_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "Quando a verificação foi cancelada.",
                "example": null
              },
              "revoked_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "Quando a verificação foi revogada.",
                "example": null
              }
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Quando a verificação foi criada.",
            "example": "2026-10-13T14:20:00Z"
          }
        }
      },
      "CheckVerificationRequest": {
        "type": "object",
        "title": "CheckVerificationRequest",
        "required": [
          "code"
        ],
        "additionalProperties": false,
        "properties": {
          "code": {
            "type": "string",
            "pattern": "^[0-9]{6}$",
            "description": "O código que a pessoa digitou: 6 dígitos, sem espaços. Remova espaços e traços antes de enviar.",
            "example": "482917"
          }
        }
      },
      "VerificationCheck": {
        "type": "object",
        "title": "VerificationCheck",
        "description": "O resultado de uma conferência de código. Um código errado não é um erro da API: a resposta é 200, com `correct: false`.",
        "required": [
          "object",
          "correct",
          "verification"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "verification_check",
            "description": "Tipo do objeto. Sempre `verification_check`.",
            "example": "verification_check"
          },
          "correct": {
            "type": "boolean",
            "description": "`true` quando o código está certo: a verificação passou para `verified`, com `confirmation.method: api`. `false` quando está errado: `attempts_remaining` diminuiu e, se chegou a 0, a verificação passou para `failed`.",
            "example": true
          },
          "verification": {
            "type": "object",
            "title": "Verification",
            "description": "A verificação já atualizada.",
            "required": [
              "id",
              "object",
              "status",
              "method",
              "source",
              "to",
              "document",
              "instructions",
              "return_url",
              "hosted_page_url",
              "attempts_remaining",
              "expires_at",
              "confirmation",
              "preview_url",
              "price",
              "reference",
              "metadata",
              "status_transitions",
              "created_at"
            ],
            "properties": {
              "id": {
                "type": "string",
                "description": "Identificador único da verificação. Sempre começa com `ver_`.",
                "pattern": "^ver_[A-Za-z0-9]+$",
                "example": "ver_3Hd9Kp2qZ6tW"
              },
              "object": {
                "type": "string",
                "const": "verification",
                "description": "Tipo do objeto. Sempre `verification`.",
                "example": "verification"
              },
              "status": {
                "type": "string",
                "enum": [
                  "received",
                  "in_production",
                  "awaiting_code",
                  "verified",
                  "failed",
                  "expired",
                  "canceled",
                  "revoked"
                ],
                "description": "Em que etapa a verificação está. Ela só avança: received, in_production, awaiting_code, verified. De received ela pode ir para canceled; de in_production, para canceled (pela CartaFlow) ou revoked; de awaiting_code, para failed, expired ou revoked; de verified, para revoked. Só `verified` quer dizer endereço confirmado.\n\n**Valores possíveis**\n\n- `received`: A CartaFlow recebeu o pedido, cobrou o preço do seu saldo e colocou a correspondência com o código na fila de produção. Se você cancelar agora, nada é impresso e o valor volta para o saldo.\n- `in_production`: A correspondência com o código está sendo impressa e envelopada. Cancelar agora revoga a verificação (`revoked`), sem devolução do valor.\n- `awaiting_code`: A correspondência foi postada. Agora esperamos a pessoa confirmar o código. Ela tem 60 dias a partir da postagem (veja `expires_at`). Cancelar agora revoga a verificação, sem devolução do valor.\n- `verified`: A pessoa confirmou o código certo. Ela recebe correspondência no endereço informado. `confirmation` diz como e quando. Você ainda pode revogar a verificação, e ela passa para `revoked`.\n- `failed`: Foram digitados 5 códigos errados. A verificação foi bloqueada para impedir tentativas aleatórias. Crie uma nova verificação se quiser tentar de novo.\n- `expired`: Passaram 60 dias desde a postagem sem que a pessoa confirmasse o código.\n- `canceled`: A verificação foi cancelada antes da postagem e o valor voltou para o seu saldo. Ou você cancelou enquanto ela estava em `received`, ou a CartaFlow cancelou porque a correspondência não pôde ser produzida.\n- `revoked`: Você cancelou a verificação depois que a produção começou: em produção, aguardando código ou já verificada. O valor não volta para o saldo, porque a produção já começou, e uma correspondência que estava em produção ainda é postada. O código deixa de funcionar, na página e na API, e a verificação nunca mais aparece como `verified`.",
                "x-enumDescriptions": {
                  "received": "A CartaFlow recebeu o pedido, cobrou o preço do seu saldo e colocou a correspondência com o código na fila de produção. Se você cancelar agora, nada é impresso e o valor volta para o saldo.",
                  "in_production": "A correspondência com o código está sendo impressa e envelopada. Cancelar agora revoga a verificação (`revoked`), sem devolução do valor.",
                  "awaiting_code": "A correspondência foi postada. Agora esperamos a pessoa confirmar o código. Ela tem 60 dias a partir da postagem (veja `expires_at`). Cancelar agora revoga a verificação, sem devolução do valor.",
                  "verified": "A pessoa confirmou o código certo. Ela recebe correspondência no endereço informado. `confirmation` diz como e quando. Você ainda pode revogar a verificação, e ela passa para `revoked`.",
                  "failed": "Foram digitados 5 códigos errados. A verificação foi bloqueada para impedir tentativas aleatórias. Crie uma nova verificação se quiser tentar de novo.",
                  "expired": "Passaram 60 dias desde a postagem sem que a pessoa confirmasse o código.",
                  "canceled": "A verificação foi cancelada antes da postagem e o valor voltou para o seu saldo. Ou você cancelou enquanto ela estava em `received`, ou a CartaFlow cancelou porque a correspondência não pôde ser produzida.",
                  "revoked": "Você cancelou a verificação depois que a produção começou: em produção, aguardando código ou já verificada. O valor não volta para o saldo, porque a produção já começou, e uma correspondência que estava em produção ainda é postada. O código deixa de funcionar, na página e na API, e a verificação nunca mais aparece como `verified`."
                },
                "example": "awaiting_code"
              },
              "method": {
                "type": "string",
                "enum": [
                  "hosted_page",
                  "code"
                ],
                "description": "Como a pessoa confirma o código.\n\n**Valores possíveis**\n\n- `hosted_page`: Na página com a sua marca, pelo QR code ou digitando o código.\n- `code`: Digitando o código no seu site ou aplicativo.",
                "x-enumDescriptions": {
                  "hosted_page": "Na página com a sua marca, pelo QR code ou digitando o código.",
                  "code": "Digitando o código no seu site ou aplicativo."
                },
                "example": "hosted_page"
              },
              "source": {
                "type": "string",
                "enum": [
                  "api",
                  "dashboard"
                ],
                "description": "Por onde a verificação foi criada. Não depende de como ela é confirmada (veja `confirmation`).\n\n**Valores possíveis**\n\n- `api`: Pela API, com POST /v1/verifications.\n- `dashboard`: No painel, por alguém da sua equipe.",
                "x-enumDescriptions": {
                  "api": "Pela API, com POST /v1/verifications.",
                  "dashboard": "No painel, por alguém da sua equipe."
                },
                "example": "api"
              },
              "to": {
                "type": "object",
                "title": "Address",
                "description": "O endereço verificado.",
                "required": [
                  "name",
                  "street",
                  "number",
                  "complement",
                  "neighborhood",
                  "city",
                  "state",
                  "postal_code"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 60,
                    "description": "Nome da pessoa ou da empresa, como deve aparecer no envelope. Até 60 caracteres.",
                    "example": "Destinatário Exemplo"
                  },
                  "street": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100,
                    "description": "Logradouro, com o tipo e o nome: rua, avenida, travessa, praça. Sem o número. Até 100 caracteres.",
                    "example": "Praça da Sé"
                  },
                  "number": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 10,
                    "description": "Número do imóvel. É texto porque alguns números têm letras, como `128A`. Use `S/N` quando o endereço não tem número. Até 10 caracteres.",
                    "example": "128"
                  },
                  "complement": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 60,
                    "description": "Complemento: apartamento, bloco, sala, andar. `null` quando o endereço não tem.",
                    "example": "Ap. 52"
                  },
                  "neighborhood": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 60,
                    "description": "Bairro. Até 60 caracteres.",
                    "example": "Sé"
                  },
                  "city": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 60,
                    "description": "Cidade. Até 60 caracteres.",
                    "example": "São Paulo"
                  },
                  "state": {
                    "type": "string",
                    "enum": [
                      "AC",
                      "AL",
                      "AP",
                      "AM",
                      "BA",
                      "CE",
                      "DF",
                      "ES",
                      "GO",
                      "MA",
                      "MT",
                      "MS",
                      "MG",
                      "PA",
                      "PB",
                      "PR",
                      "PE",
                      "PI",
                      "RJ",
                      "RN",
                      "RS",
                      "RO",
                      "RR",
                      "SC",
                      "SP",
                      "SE",
                      "TO"
                    ],
                    "description": "UF: a sigla do estado.\n\n**Valores possíveis**\n\n- `AC`: Acre\n- `AL`: Alagoas\n- `AP`: Amapá\n- `AM`: Amazonas\n- `BA`: Bahia\n- `CE`: Ceará\n- `DF`: Distrito Federal\n- `ES`: Espírito Santo\n- `GO`: Goiás\n- `MA`: Maranhão\n- `MT`: Mato Grosso\n- `MS`: Mato Grosso do Sul\n- `MG`: Minas Gerais\n- `PA`: Pará\n- `PB`: Paraíba\n- `PR`: Paraná\n- `PE`: Pernambuco\n- `PI`: Piauí\n- `RJ`: Rio de Janeiro\n- `RN`: Rio Grande do Norte\n- `RS`: Rio Grande do Sul\n- `RO`: Rondônia\n- `RR`: Roraima\n- `SC`: Santa Catarina\n- `SP`: São Paulo\n- `SE`: Sergipe\n- `TO`: Tocantins",
                    "x-enumDescriptions": {
                      "AC": "Acre",
                      "AL": "Alagoas",
                      "AP": "Amapá",
                      "AM": "Amazonas",
                      "BA": "Bahia",
                      "CE": "Ceará",
                      "DF": "Distrito Federal",
                      "ES": "Espírito Santo",
                      "GO": "Goiás",
                      "MA": "Maranhão",
                      "MT": "Mato Grosso",
                      "MS": "Mato Grosso do Sul",
                      "MG": "Minas Gerais",
                      "PA": "Pará",
                      "PB": "Paraíba",
                      "PR": "Paraná",
                      "PE": "Pernambuco",
                      "PI": "Piauí",
                      "RJ": "Rio de Janeiro",
                      "RN": "Rio Grande do Norte",
                      "RS": "Rio Grande do Sul",
                      "RO": "Rondônia",
                      "RR": "Roraima",
                      "SC": "Santa Catarina",
                      "SP": "São Paulo",
                      "SE": "Sergipe",
                      "TO": "Tocantins"
                    },
                    "example": "SP"
                  },
                  "postal_code": {
                    "type": "string",
                    "pattern": "^[0-9]{5}-[0-9]{3}$",
                    "description": "CEP, sempre no formato `00000-000`.",
                    "example": "01001-000"
                  }
                }
              },
              "document": {
                "$ref": "#/components/schemas/VerificationDocument"
              },
              "instructions": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "O texto que você enviou para imprimir abaixo do código, no modelo da CartaFlow. `null` quando você não enviou.",
                "example": null
              },
              "return_url": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "uri",
                "description": "Para onde a página leva a pessoa depois da confirmação. `null` quando não se aplica.",
                "example": "https://www.exemplo.com.br/conta"
              },
              "hosted_page_url": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "uri",
                "description": "O endereço da página de confirmação, com a sua marca (por enquanto no domínio `verifica.cartaflow.com.br`): `https://verifica.cartaflow.com.br/{id da sua conta}/{token da página}`. É o endereço impresso na correspondência e o que o QR code abre; o QR code leva o código junto, mas este link não, então quem abre o link precisa digitar o código. Você pode mandar este link por e-mail ou mostrar no seu app. Trate-o como um endereço opaco: guarde e use como veio. `null` quando `method` é `code`.",
                "example": "https://verifica.cartaflow.com.br/acc_7Jw3Nf8Xq2Lp/9Qx2Lm7Tp4Rb8Kd3Wn6Yc1"
              },
              "attempts_remaining": {
                "type": "integer",
                "minimum": 0,
                "maximum": 5,
                "description": "Quantos códigos errados ainda podem ser digitados. Começa em 5 e diminui a cada erro, pela página ou pela API. Em 0 a verificação vai para `failed`.",
                "example": 5
              },
              "expires_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "Prazo para a pessoa confirmar: 60 dias depois da postagem. `null` antes da postagem.",
                "example": "2026-12-14T16:05:00Z"
              },
              "confirmation": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/VerificationConfirmation"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Como e quando a pessoa confirmou o código: por onde (`method`), quando, de qual IP e de onde, aproximadamente. `null` enquanto a verificação não foi confirmada. Uma verificação revogada depois de confirmada mantém este registro, mas o status é `revoked`: o endereço não conta mais como verificado.",
                "example": null
              },
              "preview_url": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "uri",
                "description": "Link para uma cópia da correspondência como ela será impressa, com o endereço, mas sem o código: no lugar dele aparece `000 000`, e no lugar do QR code, um quadro que mostra onde ele será impresso. O código só existe no arquivo que a CartaFlow imprime: nem a API nem o painel conseguem mostrá-lo. O link vale por 60 minutos: consulte a verificação de novo para receber um link novo. `null` nos eventos e webhooks, e quando o arquivo não está disponível.",
                "example": "https://files.cartaflow.com.br/previews/ver_3Hd9Kp2qZ6tW.pdf?expires=1760369400&signature=5d2e81b3"
              },
              "price": {
                "type": "object",
                "title": "Price",
                "description": "O preço cobrado do saldo na criação. Com o modelo da CartaFlow, um envio simples do seu plano: uma linha `base`. Com o seu PDF, o preço de uma correspondência com as mesmas opções: `base`, `additional_sheets` e `color`. Nunca há serviços dos Correios. Volta para o saldo quando a verificação é cancelada (`canceled`); não volta quando ela é revogada (`revoked`).",
                "required": [
                  "currency",
                  "total",
                  "items"
                ],
                "properties": {
                  "currency": {
                    "type": "string",
                    "const": "BRL",
                    "description": "Moeda dos valores. Sempre `BRL` (real brasileiro).",
                    "example": "BRL"
                  },
                  "total": {
                    "type": "integer",
                    "description": "Soma de todas as linhas. É o valor debitado do saldo. Em centavos: `1590` são R$ 15,90.",
                    "example": 4865
                  },
                  "items": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/PriceItem"
                    },
                    "description": "As linhas do preço, sempre na ordem base, additional_sheets, color, registered, return_receipt, restricted_delivery. Linhas com valor zero não aparecem."
                  }
                },
                "example": {
                  "currency": "BRL",
                  "total": 4865,
                  "items": [
                    {
                      "type": "base",
                      "quantity": 1,
                      "unit_amount": 990,
                      "amount": 990
                    },
                    {
                      "type": "additional_sheets",
                      "quantity": 1,
                      "unit_amount": 75,
                      "amount": 75
                    },
                    {
                      "type": "color",
                      "quantity": 2,
                      "unit_amount": 35,
                      "amount": 70
                    },
                    {
                      "type": "registered",
                      "quantity": 1,
                      "unit_amount": 1175,
                      "amount": 1175
                    },
                    {
                      "type": "return_receipt",
                      "quantity": 1,
                      "unit_amount": 1175,
                      "amount": 1175
                    },
                    {
                      "type": "restricted_delivery",
                      "quantity": 1,
                      "unit_amount": 1380,
                      "amount": 1380
                    }
                  ]
                }
              },
              "reference": {
                "type": [
                  "string",
                  "null"
                ],
                "maxLength": 100,
                "description": "Seu identificador para esta verificação, como o número da fatura ou o id do cliente no seu sistema. Aparece no painel e pode ser usado como filtro nas listagens. Não precisa ser único. Até 100 caracteres. `null` quando você não enviou.",
                "example": "cliente-1842"
              },
              "metadata": {
                "type": "object",
                "additionalProperties": {
                  "type": "string",
                  "maxLength": 500
                },
                "maxProperties": 20,
                "description": "Pares chave-valor para guardar dados seus junto do objeto, como o id do cliente ou do contrato. Voltam em todas as respostas e webhooks e nunca são impressos. Até 20 chaves; chaves com até 40 caracteres e valores em texto com até 500 caracteres. Não guarde dados sensíveis, como senhas ou números de cartão. Objeto vazio `{}` quando você não enviou.",
                "example": {
                  "customer_id": "1842",
                  "contract": "C-2026-118"
                }
              },
              "status_transitions": {
                "type": "object",
                "title": "VerificationStatusTransitions",
                "description": "Quando a verificação chegou a cada status. `null` para os status pelos quais ela não passou. O status received é o momento de `created_at`. Uma verificação revogada depois de confirmada mantém `verified_at`.",
                "required": [
                  "in_production_at",
                  "awaiting_code_at",
                  "verified_at",
                  "failed_at",
                  "expired_at",
                  "canceled_at",
                  "revoked_at"
                ],
                "properties": {
                  "in_production_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date-time",
                    "description": "Quando a correspondência entrou em produção.",
                    "example": null
                  },
                  "awaiting_code_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date-time",
                    "description": "Quando a correspondência foi postada.",
                    "example": "2026-10-15T16:05:00Z"
                  },
                  "verified_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date-time",
                    "description": "Quando a pessoa confirmou o código.",
                    "example": null
                  },
                  "failed_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date-time",
                    "description": "Quando a verificação foi bloqueada por códigos errados.",
                    "example": null
                  },
                  "expired_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date-time",
                    "description": "Quando o prazo de confirmação acabou.",
                    "example": null
                  },
                  "canceled_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date-time",
                    "description": "Quando a verificação foi cancelada.",
                    "example": null
                  },
                  "revoked_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date-time",
                    "description": "Quando a verificação foi revogada.",
                    "example": null
                  }
                }
              },
              "created_at": {
                "type": "string",
                "format": "date-time",
                "description": "Quando a verificação foi criada.",
                "example": "2026-10-13T14:20:00Z"
              }
            }
          }
        }
      },
      "PostalCode": {
        "type": "object",
        "title": "PostalCode",
        "description": "O endereço de um CEP, segundo a base de CEPs dos Correios.",
        "required": [
          "object",
          "postal_code",
          "street",
          "neighborhood",
          "city",
          "state"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "postal_code",
            "description": "Tipo do objeto. Sempre `postal_code`.",
            "example": "postal_code"
          },
          "postal_code": {
            "type": "string",
            "pattern": "^[0-9]{5}-[0-9]{3}$",
            "description": "O CEP no formato `00000-000`.",
            "example": "01001-000"
          },
          "street": {
            "type": [
              "string",
              "null"
            ],
            "description": "Logradouro do CEP. `null` quando o CEP vale para a cidade inteira, comum em cidades pequenas.",
            "example": "Praça da Sé"
          },
          "neighborhood": {
            "type": [
              "string",
              "null"
            ],
            "description": "Bairro do CEP. `null` quando o CEP vale para a cidade inteira.",
            "example": "Sé"
          },
          "city": {
            "type": "string",
            "description": "Cidade do CEP.",
            "example": "São Paulo"
          },
          "state": {
            "type": "string",
            "enum": [
              "AC",
              "AL",
              "AP",
              "AM",
              "BA",
              "CE",
              "DF",
              "ES",
              "GO",
              "MA",
              "MT",
              "MS",
              "MG",
              "PA",
              "PB",
              "PR",
              "PE",
              "PI",
              "RJ",
              "RN",
              "RS",
              "RO",
              "RR",
              "SC",
              "SP",
              "SE",
              "TO"
            ],
            "description": "UF do CEP.\n\n**Valores possíveis**\n\n- `AC`: Acre\n- `AL`: Alagoas\n- `AP`: Amapá\n- `AM`: Amazonas\n- `BA`: Bahia\n- `CE`: Ceará\n- `DF`: Distrito Federal\n- `ES`: Espírito Santo\n- `GO`: Goiás\n- `MA`: Maranhão\n- `MT`: Mato Grosso\n- `MS`: Mato Grosso do Sul\n- `MG`: Minas Gerais\n- `PA`: Pará\n- `PB`: Paraíba\n- `PR`: Paraná\n- `PE`: Pernambuco\n- `PI`: Piauí\n- `RJ`: Rio de Janeiro\n- `RN`: Rio Grande do Norte\n- `RS`: Rio Grande do Sul\n- `RO`: Rondônia\n- `RR`: Roraima\n- `SC`: Santa Catarina\n- `SP`: São Paulo\n- `SE`: Sergipe\n- `TO`: Tocantins",
            "x-enumDescriptions": {
              "AC": "Acre",
              "AL": "Alagoas",
              "AP": "Amapá",
              "AM": "Amazonas",
              "BA": "Bahia",
              "CE": "Ceará",
              "DF": "Distrito Federal",
              "ES": "Espírito Santo",
              "GO": "Goiás",
              "MA": "Maranhão",
              "MT": "Mato Grosso",
              "MS": "Mato Grosso do Sul",
              "MG": "Minas Gerais",
              "PA": "Pará",
              "PB": "Paraíba",
              "PR": "Paraná",
              "PE": "Pernambuco",
              "PI": "Piauí",
              "RJ": "Rio de Janeiro",
              "RN": "Rio Grande do Norte",
              "RS": "Rio Grande do Sul",
              "RO": "Rondônia",
              "RR": "Roraima",
              "SC": "Santa Catarina",
              "SP": "São Paulo",
              "SE": "Sergipe",
              "TO": "Tocantins"
            },
            "example": "SP"
          }
        }
      },
      "Account": {
        "type": "object",
        "title": "Account",
        "description": "A conta CartaFlow dona da chave de API usada na requisição.",
        "required": [
          "id",
          "object",
          "legal_name",
          "trade_name",
          "cnpj",
          "plan",
          "default_sender",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Identificador único da conta. Sempre começa com `acc_`.",
            "pattern": "^acc_[A-Za-z0-9]+$",
            "example": "acc_7Jw3Nf8Xq2Lp"
          },
          "object": {
            "type": "string",
            "const": "account",
            "description": "Tipo do objeto. Sempre `account`.",
            "example": "account"
          },
          "legal_name": {
            "type": "string",
            "description": "Razão social da empresa.",
            "example": "Exemplo Serviços Ltda."
          },
          "trade_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Nome fantasia. É o nome que aparece nas correspondências de verificação, junto com o logo; sem ele, usamos a razão social. Muda no painel, em Configurações > Empresa. `null` quando não foi informado.",
            "example": "Exemplo"
          },
          "cnpj": {
            "type": "string",
            "pattern": "^[0-9A-Z]{2}\\.[0-9A-Z]{3}\\.[0-9A-Z]{3}/[0-9A-Z]{4}-[0-9]{2}$",
            "description": "CNPJ da empresa, formatado. Pode ser alfanumérico (emitido desde julho de 2026): os 12 primeiros caracteres podem ser letras maiúsculas ou dígitos, e os 2 últimos, os dígitos verificadores, são sempre números. Por exemplo `12.345.678/0001-90` ou `12.ABC.345/01DE-35`.",
            "example": "12.345.678/0001-90"
          },
          "plan": {
            "type": "string",
            "enum": [
              "pay_as_you_go",
              "essential",
              "professional",
              "scale",
              "enterprise"
            ],
            "description": "O plano atual. Define o preço de cada envio.\n\n**Valores possíveis**\n\n- `pay_as_you_go`: Avulso. Sem mensalidade, preço por envio mais alto.\n- `essential`: Essencial.\n- `professional`: Profissional.\n- `scale`: Escala.\n- `enterprise`: Enterprise. Contrato de 12 meses com volume mensal combinado.",
            "x-enumDescriptions": {
              "pay_as_you_go": "Avulso. Sem mensalidade, preço por envio mais alto.",
              "essential": "Essencial.",
              "professional": "Profissional.",
              "scale": "Escala.",
              "enterprise": "Enterprise. Contrato de 12 meses com volume mensal combinado."
            },
            "example": "essential"
          },
          "default_sender": {
            "type": "object",
            "title": "Address",
            "description": "Remetente usado quando uma correspondência não traz `from`. Muda no painel, em Configurações > Empresa.",
            "required": [
              "name",
              "street",
              "number",
              "complement",
              "neighborhood",
              "city",
              "state",
              "postal_code"
            ],
            "properties": {
              "name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Nome da pessoa ou da empresa, como deve aparecer no envelope. Até 60 caracteres.",
                "example": "Destinatário Exemplo"
              },
              "street": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100,
                "description": "Logradouro, com o tipo e o nome: rua, avenida, travessa, praça. Sem o número. Até 100 caracteres.",
                "example": "Praça da Sé"
              },
              "number": {
                "type": "string",
                "minLength": 1,
                "maxLength": 10,
                "description": "Número do imóvel. É texto porque alguns números têm letras, como `128A`. Use `S/N` quando o endereço não tem número. Até 10 caracteres.",
                "example": "128"
              },
              "complement": {
                "type": [
                  "string",
                  "null"
                ],
                "maxLength": 60,
                "description": "Complemento: apartamento, bloco, sala, andar. `null` quando o endereço não tem.",
                "example": "Ap. 52"
              },
              "neighborhood": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Bairro. Até 60 caracteres.",
                "example": "Sé"
              },
              "city": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Cidade. Até 60 caracteres.",
                "example": "São Paulo"
              },
              "state": {
                "type": "string",
                "enum": [
                  "AC",
                  "AL",
                  "AP",
                  "AM",
                  "BA",
                  "CE",
                  "DF",
                  "ES",
                  "GO",
                  "MA",
                  "MT",
                  "MS",
                  "MG",
                  "PA",
                  "PB",
                  "PR",
                  "PE",
                  "PI",
                  "RJ",
                  "RN",
                  "RS",
                  "RO",
                  "RR",
                  "SC",
                  "SP",
                  "SE",
                  "TO"
                ],
                "description": "UF: a sigla do estado.\n\n**Valores possíveis**\n\n- `AC`: Acre\n- `AL`: Alagoas\n- `AP`: Amapá\n- `AM`: Amazonas\n- `BA`: Bahia\n- `CE`: Ceará\n- `DF`: Distrito Federal\n- `ES`: Espírito Santo\n- `GO`: Goiás\n- `MA`: Maranhão\n- `MT`: Mato Grosso\n- `MS`: Mato Grosso do Sul\n- `MG`: Minas Gerais\n- `PA`: Pará\n- `PB`: Paraíba\n- `PR`: Paraná\n- `PE`: Pernambuco\n- `PI`: Piauí\n- `RJ`: Rio de Janeiro\n- `RN`: Rio Grande do Norte\n- `RS`: Rio Grande do Sul\n- `RO`: Rondônia\n- `RR`: Roraima\n- `SC`: Santa Catarina\n- `SP`: São Paulo\n- `SE`: Sergipe\n- `TO`: Tocantins",
                "x-enumDescriptions": {
                  "AC": "Acre",
                  "AL": "Alagoas",
                  "AP": "Amapá",
                  "AM": "Amazonas",
                  "BA": "Bahia",
                  "CE": "Ceará",
                  "DF": "Distrito Federal",
                  "ES": "Espírito Santo",
                  "GO": "Goiás",
                  "MA": "Maranhão",
                  "MT": "Mato Grosso",
                  "MS": "Mato Grosso do Sul",
                  "MG": "Minas Gerais",
                  "PA": "Pará",
                  "PB": "Paraíba",
                  "PR": "Paraná",
                  "PE": "Pernambuco",
                  "PI": "Piauí",
                  "RJ": "Rio de Janeiro",
                  "RN": "Rio Grande do Norte",
                  "RS": "Rio Grande do Sul",
                  "RO": "Rondônia",
                  "RR": "Roraima",
                  "SC": "Santa Catarina",
                  "SP": "São Paulo",
                  "SE": "Sergipe",
                  "TO": "Tocantins"
                },
                "example": "SP"
              },
              "postal_code": {
                "type": "string",
                "pattern": "^[0-9]{5}-[0-9]{3}$",
                "description": "CEP, sempre no formato `00000-000`.",
                "example": "01001-000"
              }
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Quando a conta foi criada.",
            "example": "2026-09-01T12:00:00Z"
          }
        }
      },
      "Balance": {
        "type": "object",
        "title": "Balance",
        "description": "O saldo pré-pago da conta. Cada correspondência e cada verificação são debitadas do saldo quando criadas. A mensalidade do plano é cobrada à parte e não sai do saldo.",
        "required": [
          "object",
          "currency",
          "available",
          "pending"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "balance",
            "description": "Tipo do objeto. Sempre `balance`.",
            "example": "balance"
          },
          "currency": {
            "type": "string",
            "const": "BRL",
            "description": "Moeda dos valores. Sempre `BRL` (real brasileiro).",
            "example": "BRL"
          },
          "available": {
            "type": "integer",
            "description": "Valor disponível para novos envios agora. Em centavos: `1590` são R$ 15,90.",
            "example": 48865
          },
          "pending": {
            "type": "integer",
            "description": "Reservado para recargas que dependem da confirmação de um pagamento; entram em `available` quando o pagamento é confirmado. Hoje o saldo é adicionado na hora, então é sempre 0. Em centavos: `1590` são R$ 15,90.",
            "example": 0
          }
        }
      },
      "BalanceTransaction": {
        "type": "object",
        "title": "BalanceTransaction",
        "description": "Uma entrada ou saída do saldo. Use para conciliar o que foi gasto com cada envio.",
        "required": [
          "id",
          "object",
          "type",
          "amount",
          "currency",
          "balance_after",
          "source_id",
          "description",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Identificador único da movimentação. Sempre começa com `btx_`.",
            "pattern": "^btx_[A-Za-z0-9]+$",
            "example": "btx_4Lm8Qw2Zx9Kd"
          },
          "object": {
            "type": "string",
            "const": "balance_transaction",
            "description": "Tipo do objeto. Sempre `balance_transaction`.",
            "example": "balance_transaction"
          },
          "type": {
            "type": "string",
            "enum": [
              "top_up",
              "letter",
              "verification",
              "refund",
              "credit",
              "adjustment"
            ],
            "description": "O que causou a movimentação.\n\n**Valores possíveis**\n\n- `top_up`: Saldo adicionado no painel ou pela equipe da CartaFlow. Valor positivo.\n- `letter`: Débito de uma correspondência. Valor negativo. `source_id` é o id da correspondência.\n- `verification`: Débito de uma verificação. Valor negativo. `source_id` é o id da verificação.\n- `refund`: Devolução de uma correspondência ou verificação cancelada depois da cobrança, ou de uma correspondência que falhou na produção (`failed`). Valor positivo. `source_id` é o id do objeto devolvido. Uma verificação revogada (`revoked`) não tem devolução.\n- `credit`: Crédito dado pela CartaFlow, como o crédito de boas-vindas. Valor positivo.\n- `adjustment`: Ajuste feito pelo suporte da CartaFlow. Positivo ou negativo. `description` explica o motivo.",
            "x-enumDescriptions": {
              "top_up": "Saldo adicionado no painel ou pela equipe da CartaFlow. Valor positivo.",
              "letter": "Débito de uma correspondência. Valor negativo. `source_id` é o id da correspondência.",
              "verification": "Débito de uma verificação. Valor negativo. `source_id` é o id da verificação.",
              "refund": "Devolução de uma correspondência ou verificação cancelada depois da cobrança, ou de uma correspondência que falhou na produção (`failed`). Valor positivo. `source_id` é o id do objeto devolvido. Uma verificação revogada (`revoked`) não tem devolução.",
              "credit": "Crédito dado pela CartaFlow, como o crédito de boas-vindas. Valor positivo.",
              "adjustment": "Ajuste feito pelo suporte da CartaFlow. Positivo ou negativo. `description` explica o motivo."
            },
            "example": "letter"
          },
          "amount": {
            "type": "integer",
            "description": "Valor da movimentação: positivo quando entra no saldo, negativo quando sai. Em centavos: `1590` são R$ 15,90.",
            "example": -1135
          },
          "currency": {
            "type": "string",
            "const": "BRL",
            "description": "Moeda dos valores. Sempre `BRL` (real brasileiro).",
            "example": "BRL"
          },
          "balance_after": {
            "type": "integer",
            "description": "Saldo disponível logo depois desta movimentação. Em centavos: `1590` são R$ 15,90.",
            "example": 48865
          },
          "source_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Id da correspondência (`ltr_`) ou da verificação (`ver_`) ligada à movimentação. `null` em recargas, créditos e ajustes.",
            "example": "ltr_8Kq2wX4mN7pR"
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Explicação do suporte em ajustes. `null` nos outros tipos.",
            "example": null
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Quando a movimentação aconteceu.",
            "example": "2026-10-13T14:20:00Z"
          }
        }
      },
      "Event": {
        "type": "object",
        "title": "Event",
        "description": "Um acontecimento na sua conta, como uma correspondência postada. A CartaFlow envia cada evento para os seus webhooks e guarda por 30 dias.",
        "required": [
          "id",
          "object",
          "type",
          "data",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Identificador único do evento. É o mesmo valor do cabeçalho webhook-id: use para ignorar entregas repetidas. Sempre começa com `evt_`.",
            "pattern": "^evt_[A-Za-z0-9]+$",
            "example": "evt_6Tq1Yz8Wm3Rb"
          },
          "object": {
            "type": "string",
            "const": "event",
            "description": "Tipo do objeto. Sempre `event`.",
            "example": "event"
          },
          "type": {
            "type": "string",
            "enum": [
              "letter.scheduled",
              "letter.received",
              "letter.in_production",
              "letter.printed",
              "letter.posted",
              "letter.canceled",
              "letter.failed",
              "letter.updated",
              "verification.received",
              "verification.in_production",
              "verification.awaiting_code",
              "verification.verified",
              "verification.failed",
              "verification.expired",
              "verification.canceled",
              "verification.revoked"
            ],
            "description": "O que aconteceu. Cada mudança de status gera um evento com o nome `objeto.novo_status`; uma correspondência alterada no painel antes da produção, sem mudar de status, gera `letter.updated`.\n\n**Valores possíveis**\n\n- `letter.scheduled`: Uma correspondência foi agendada com `send_date`. Ainda não foi cobrada.\n- `letter.received`: Uma correspondência foi cobrada e entrou na fila de produção: logo depois de criada ou, se foi agendada, na data do envio. Vale para correspondências criadas pela API e pelo painel.\n- `letter.in_production`: A correspondência entrou em um lote de impressão e não pode mais ser cancelada.\n- `letter.printed`: A correspondência foi impressa e envelopada.\n- `letter.posted`: A correspondência foi entregue aos Correios. É o último evento de uma correspondência enviada.\n- `letter.canceled`: A correspondência foi cancelada. Veja `cancellation_reason`: `requested` quando você cancelou, `insufficient_balance` quando uma correspondência agendada não pôde ser cobrada na data.\n- `letter.failed`: A correspondência falhou na produção e não será postada. O valor voltou para o saldo automaticamente. Veja `failure_reason`.\n- `letter.updated`: A correspondência foi alterada no painel antes da produção, sem mudar de status: data de envio, endereço, arquivo, variáveis, impressão, serviços dos Correios ou referência. `data` traz a correspondência como ficou. Se a mudança alterou o preço de uma correspondência agendada, `price` traz o novo valor.\n- `verification.received`: Uma verificação foi criada, pela API ou pelo painel (veja `source`), e a correspondência com o código está na fila de produção.\n- `verification.in_production`: A correspondência com o código está sendo impressa. A partir daqui, cancelar revoga a verificação, sem devolução.\n- `verification.awaiting_code`: A correspondência com o código foi postada. A pessoa já pode confirmar quando receber.\n- `verification.verified`: A pessoa confirmou o código certo. O endereço está verificado.\n- `verification.failed`: Foram digitados 5 códigos errados e a verificação foi bloqueada.\n- `verification.expired`: A pessoa não confirmou o código em 60 dias desde a postagem.\n- `verification.canceled`: A verificação foi cancelada antes da postagem, por você ou pela CartaFlow, e o valor voltou para o saldo.\n- `verification.revoked`: Você cancelou a verificação depois que a produção começou. O código deixou de funcionar e o valor não volta para o saldo. Se ela estava `verified`, trate o endereço como não verificado.",
            "x-enumDescriptions": {
              "letter.scheduled": "Uma correspondência foi agendada com `send_date`. Ainda não foi cobrada.",
              "letter.received": "Uma correspondência foi cobrada e entrou na fila de produção: logo depois de criada ou, se foi agendada, na data do envio. Vale para correspondências criadas pela API e pelo painel.",
              "letter.in_production": "A correspondência entrou em um lote de impressão e não pode mais ser cancelada.",
              "letter.printed": "A correspondência foi impressa e envelopada.",
              "letter.posted": "A correspondência foi entregue aos Correios. É o último evento de uma correspondência enviada.",
              "letter.canceled": "A correspondência foi cancelada. Veja `cancellation_reason`: `requested` quando você cancelou, `insufficient_balance` quando uma correspondência agendada não pôde ser cobrada na data.",
              "letter.failed": "A correspondência falhou na produção e não será postada. O valor voltou para o saldo automaticamente. Veja `failure_reason`.",
              "letter.updated": "A correspondência foi alterada no painel antes da produção, sem mudar de status: data de envio, endereço, arquivo, variáveis, impressão, serviços dos Correios ou referência. `data` traz a correspondência como ficou. Se a mudança alterou o preço de uma correspondência agendada, `price` traz o novo valor.",
              "verification.received": "Uma verificação foi criada, pela API ou pelo painel (veja `source`), e a correspondência com o código está na fila de produção.",
              "verification.in_production": "A correspondência com o código está sendo impressa. A partir daqui, cancelar revoga a verificação, sem devolução.",
              "verification.awaiting_code": "A correspondência com o código foi postada. A pessoa já pode confirmar quando receber.",
              "verification.verified": "A pessoa confirmou o código certo. O endereço está verificado.",
              "verification.failed": "Foram digitados 5 códigos errados e a verificação foi bloqueada.",
              "verification.expired": "A pessoa não confirmou o código em 60 dias desde a postagem.",
              "verification.canceled": "A verificação foi cancelada antes da postagem, por você ou pela CartaFlow, e o valor voltou para o saldo.",
              "verification.revoked": "Você cancelou a verificação depois que a produção começou. O código deixou de funcionar e o valor não volta para o saldo. Se ela estava `verified`, trate o endereço como não verificado."
            },
            "example": "letter.posted"
          },
          "data": {
            "description": "O objeto inteiro, como estava logo depois do acontecimento: uma correspondência nos eventos `letter.*` e uma verificação nos eventos `verification.*`.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/Letter"
              },
              {
                "$ref": "#/components/schemas/Verification"
              }
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Quando o evento aconteceu.",
            "example": "2026-10-13T14:20:00Z"
          }
        }
      },
      "ErrorDetail": {
        "type": "object",
        "title": "ErrorDetail",
        "required": [
          "param",
          "code",
          "message"
        ],
        "properties": {
          "param": {
            "type": "string",
            "description": "O campo com problema, em notação de pontos. Itens de listas usam o índice: `to.postal_code`, `document.variables.nome`.",
            "example": "to.postal_code"
          },
          "code": {
            "type": "string",
            "enum": [
              "required",
              "unknown_parameter",
              "invalid_type",
              "invalid_value",
              "invalid_format",
              "too_short",
              "too_long",
              "out_of_range",
              "requires_registered",
              "postal_code_not_found",
              "address_incomplete",
              "document_unreachable",
              "upload_not_found",
              "upload_expired",
              "upload_already_used",
              "upload_file_missing",
              "document_invalid",
              "document_encrypted",
              "document_too_large",
              "document_page_size",
              "too_many_sheets",
              "address_area_not_blank",
              "variable_missing",
              "variable_not_found",
              "document_text_unreadable",
              "otp_code_missing"
            ],
            "description": "O problema do campo.\n\n**Valores possíveis**\n\n- `required`: Campo obrigatório ausente.\n- `unknown_parameter`: O campo não existe neste endpoint.\n- `invalid_type`: O tipo do valor está errado, como um texto onde se espera um número.\n- `invalid_value`: O valor não é aceito: não está na lista de valores permitidos ou não combina com outro campo da requisição, como `letter` e `document` juntos numa verificação.\n- `invalid_format`: O formato está errado: URL, data, base64, CEP ou código.\n- `too_short`: O texto ou a lista está abaixo do tamanho mínimo.\n- `too_long`: O texto ou a lista passa do tamanho máximo.\n- `out_of_range`: O número ou a data está fora do intervalo permitido, como um send_date que não seja de amanhã até 180 dias à frente.\n- `requires_registered`: `return_receipt` e `restricted_delivery` só funcionam com `registered`: o aviso de recebimento e a mão própria são serviços da carta registrada.\n- `postal_code_not_found`: O CEP não existe na base dos Correios.\n- `address_incomplete`: Não foi possível completar o endereço: o campo não veio na requisição e o CEP não o informa. Acontece com CEPs que valem para uma cidade inteira, que não têm logradouro nem bairro.\n- `document_unreachable`: Não conseguimos baixar o PDF da URL em 10 segundos, ou o servidor respondeu com erro.\n- `upload_not_found`: Não existe upload com esse id na sua conta.\n- `upload_expired`: O upload foi criado há mais de 24 horas e não pode mais ser usado.\n- `upload_already_used`: O upload já foi usado por outra correspondência. Cada upload serve para uma correspondência só.\n- `upload_file_missing`: O arquivo nunca foi enviado para o upload_url do upload.\n- `document_invalid`: O arquivo não é um PDF válido: está corrompido ou é de outro formato.\n- `document_encrypted`: O PDF está protegido por senha.\n- `document_too_large`: O PDF passa do tamanho máximo da forma de envio: 10 MB por URL ou com POST /v1/uploads, 4 MB em multipart/form-data e 3 MB em base64 (depois de decodificado).\n- `document_page_size`: Alguma página não é A4 em retrato (210 x 297 mm).\n- `too_many_sheets`: A correspondência passaria de 6 folhas, o máximo que cabe em um envelope.\n- `address_area_not_blank`: Há texto ou imagem na área do endereço da primeira página, onde a CartaFlow imprime o destinatário.\n- `variable_missing`: O PDF tem uma marcação, como {{nome}}, que não veio em variables.\n- `variable_not_found`: Você enviou uma variável que o PDF não tem.\n- `document_text_unreadable`: O PDF não tem texto selecionável: é uma imagem ou uma digitalização. Sem texto, não conseguimos encontrar as marcações, como as variáveis ou o `{{OTP_CODE}}` de uma verificação.\n- `otp_code_missing`: O PDF de uma verificação não tem a marcação `{{OTP_CODE}}`, o lugar onde a CartaFlow imprime o código.",
            "x-enumDescriptions": {
              "required": "Campo obrigatório ausente.",
              "unknown_parameter": "O campo não existe neste endpoint.",
              "invalid_type": "O tipo do valor está errado, como um texto onde se espera um número.",
              "invalid_value": "O valor não é aceito: não está na lista de valores permitidos ou não combina com outro campo da requisição, como `letter` e `document` juntos numa verificação.",
              "invalid_format": "O formato está errado: URL, data, base64, CEP ou código.",
              "too_short": "O texto ou a lista está abaixo do tamanho mínimo.",
              "too_long": "O texto ou a lista passa do tamanho máximo.",
              "out_of_range": "O número ou a data está fora do intervalo permitido, como um send_date que não seja de amanhã até 180 dias à frente.",
              "requires_registered": "`return_receipt` e `restricted_delivery` só funcionam com `registered`: o aviso de recebimento e a mão própria são serviços da carta registrada.",
              "postal_code_not_found": "O CEP não existe na base dos Correios.",
              "address_incomplete": "Não foi possível completar o endereço: o campo não veio na requisição e o CEP não o informa. Acontece com CEPs que valem para uma cidade inteira, que não têm logradouro nem bairro.",
              "document_unreachable": "Não conseguimos baixar o PDF da URL em 10 segundos, ou o servidor respondeu com erro.",
              "upload_not_found": "Não existe upload com esse id na sua conta.",
              "upload_expired": "O upload foi criado há mais de 24 horas e não pode mais ser usado.",
              "upload_already_used": "O upload já foi usado por outra correspondência. Cada upload serve para uma correspondência só.",
              "upload_file_missing": "O arquivo nunca foi enviado para o upload_url do upload.",
              "document_invalid": "O arquivo não é um PDF válido: está corrompido ou é de outro formato.",
              "document_encrypted": "O PDF está protegido por senha.",
              "document_too_large": "O PDF passa do tamanho máximo da forma de envio: 10 MB por URL ou com POST /v1/uploads, 4 MB em multipart/form-data e 3 MB em base64 (depois de decodificado).",
              "document_page_size": "Alguma página não é A4 em retrato (210 x 297 mm).",
              "too_many_sheets": "A correspondência passaria de 6 folhas, o máximo que cabe em um envelope.",
              "address_area_not_blank": "Há texto ou imagem na área do endereço da primeira página, onde a CartaFlow imprime o destinatário.",
              "variable_missing": "O PDF tem uma marcação, como {{nome}}, que não veio em variables.",
              "variable_not_found": "Você enviou uma variável que o PDF não tem.",
              "document_text_unreadable": "O PDF não tem texto selecionável: é uma imagem ou uma digitalização. Sem texto, não conseguimos encontrar as marcações, como as variáveis ou o `{{OTP_CODE}}` de uma verificação.",
              "otp_code_missing": "O PDF de uma verificação não tem a marcação `{{OTP_CODE}}`, o lugar onde a CartaFlow imprime o código."
            },
            "example": "postal_code_not_found"
          },
          "message": {
            "type": "string",
            "description": "Explicação para pessoas, no idioma de Accept-Language.",
            "example": "Não encontramos este CEP. Confira os 8 dígitos."
          }
        }
      },
      "Error": {
        "type": "object",
        "title": "Error",
        "description": "Toda resposta de erro tem este formato, em qualquer endpoint.",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "type",
              "code",
              "message",
              "request_id",
              "doc_url",
              "details"
            ],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "invalid_request_error",
                  "authentication_error",
                  "billing_error",
                  "permission_error",
                  "not_found_error",
                  "conflict_error",
                  "validation_error",
                  "rate_limit_error",
                  "api_error"
                ],
                "description": "A categoria do erro. Cada tipo corresponde a um status HTTP.\n\n**Valores possíveis**\n\n- `invalid_request_error`: HTTP 400 ou 413. Não conseguimos ler a requisição: o JSON está malformado, o cabeçalho está errado ou o corpo é grande demais.\n- `authentication_error`: HTTP 401. A chave de API está ausente, inválida ou revogada.\n- `billing_error`: HTTP 402. O saldo da conta não cobre a operação.\n- `permission_error`: HTTP 403. A conta não pode fazer esta operação agora.\n- `not_found_error`: HTTP 404. O objeto ou o endpoint não existe.\n- `conflict_error`: HTTP 409. A requisição é válida, mas o estado atual do objeto não permite a operação.\n- `validation_error`: HTTP 422. Lemos a requisição, mas um ou mais campos têm valores inválidos. A lista `details` diz quais e por quê.\n- `rate_limit_error`: HTTP 429. A conta passou do limite de requisições por segundo.\n- `api_error`: HTTP 500 ou 503. Algo falhou do lado da CartaFlow. Não é um problema da sua requisição.",
                "x-enumDescriptions": {
                  "invalid_request_error": "HTTP 400 ou 413. Não conseguimos ler a requisição: o JSON está malformado, o cabeçalho está errado ou o corpo é grande demais.",
                  "authentication_error": "HTTP 401. A chave de API está ausente, inválida ou revogada.",
                  "billing_error": "HTTP 402. O saldo da conta não cobre a operação.",
                  "permission_error": "HTTP 403. A conta não pode fazer esta operação agora.",
                  "not_found_error": "HTTP 404. O objeto ou o endpoint não existe.",
                  "conflict_error": "HTTP 409. A requisição é válida, mas o estado atual do objeto não permite a operação.",
                  "validation_error": "HTTP 422. Lemos a requisição, mas um ou mais campos têm valores inválidos. A lista `details` diz quais e por quê.",
                  "rate_limit_error": "HTTP 429. A conta passou do limite de requisições por segundo.",
                  "api_error": "HTTP 500 ou 503. Algo falhou do lado da CartaFlow. Não é um problema da sua requisição."
                },
                "example": "validation_error"
              },
              "code": {
                "type": "string",
                "enum": [
                  "invalid_json",
                  "unsupported_content_type",
                  "invalid_idempotency_key",
                  "request_too_large",
                  "api_key_missing",
                  "api_key_invalid",
                  "api_key_revoked",
                  "insufficient_balance",
                  "account_suspended",
                  "resource_not_found",
                  "endpoint_not_found",
                  "postal_code_not_found",
                  "letter_not_cancelable",
                  "verification_not_cancelable",
                  "verification_not_awaiting_code",
                  "idempotency_key_reused",
                  "idempotency_key_in_use",
                  "invalid_parameters",
                  "rate_limit_exceeded",
                  "internal_error",
                  "service_unavailable"
                ],
                "description": "O erro exato. Use este campo no seu código: ele nunca muda de significado. Novos códigos podem ser criados, então trate um código desconhecido pelo `type`.\n\n**Valores possíveis**\n\n- `invalid_json`: O corpo da requisição não é um JSON válido.\n- `unsupported_content_type`: O cabeçalho Content-Type não é aceito neste endpoint.\n- `invalid_idempotency_key`: O cabeçalho Idempotency-Key está vazio ou tem mais de 255 caracteres.\n- `request_too_large`: O corpo da requisição passa de 4,5 MB, o máximo que a API recebe numa requisição.\n- `api_key_missing`: A requisição não tem o cabeçalho Authorization.\n- `api_key_invalid`: A chave não existe ou está escrita de forma errada.\n- `api_key_revoked`: A chave foi revogada no painel.\n- `insufficient_balance`: O saldo disponível é menor que o preço do envio.\n- `account_suspended`: A conta está suspensa e não pode criar envios.\n- `resource_not_found`: Não existe objeto com esse id na sua conta.\n- `endpoint_not_found`: O caminho ou o método HTTP não existe na API.\n- `postal_code_not_found`: O CEP consultado não existe na base de CEPs dos Correios.\n- `letter_not_cancelable`: O status da correspondência não é mais scheduled nem received: ela já entrou em produção, foi postada ou falhou.\n- `verification_not_cancelable`: A verificação terminou sem confirmação (`failed` ou `expired`) e não pode ser cancelada nem revogada.\n- `verification_not_awaiting_code`: A verificação não está esperando código: a correspondência ainda não foi postada, ou a verificação já terminou, foi cancelada ou foi revogada.\n- `idempotency_key_reused`: Essa Idempotency-Key já foi usada com outro corpo ou em outro endpoint nas últimas 24 horas.\n- `idempotency_key_in_use`: Uma requisição com a mesma Idempotency-Key ainda está sendo processada.\n- `invalid_parameters`: Um ou mais campos têm valores inválidos.\n- `rate_limit_exceeded`: A conta fez mais requisições por segundo do que o limite.\n- `internal_error`: Erro inesperado na CartaFlow.\n- `service_unavailable`: A API está temporariamente indisponível, por manutenção ou sobrecarga.",
                "x-enumDescriptions": {
                  "invalid_json": "O corpo da requisição não é um JSON válido.",
                  "unsupported_content_type": "O cabeçalho Content-Type não é aceito neste endpoint.",
                  "invalid_idempotency_key": "O cabeçalho Idempotency-Key está vazio ou tem mais de 255 caracteres.",
                  "request_too_large": "O corpo da requisição passa de 4,5 MB, o máximo que a API recebe numa requisição.",
                  "api_key_missing": "A requisição não tem o cabeçalho Authorization.",
                  "api_key_invalid": "A chave não existe ou está escrita de forma errada.",
                  "api_key_revoked": "A chave foi revogada no painel.",
                  "insufficient_balance": "O saldo disponível é menor que o preço do envio.",
                  "account_suspended": "A conta está suspensa e não pode criar envios.",
                  "resource_not_found": "Não existe objeto com esse id na sua conta.",
                  "endpoint_not_found": "O caminho ou o método HTTP não existe na API.",
                  "postal_code_not_found": "O CEP consultado não existe na base de CEPs dos Correios.",
                  "letter_not_cancelable": "O status da correspondência não é mais scheduled nem received: ela já entrou em produção, foi postada ou falhou.",
                  "verification_not_cancelable": "A verificação terminou sem confirmação (`failed` ou `expired`) e não pode ser cancelada nem revogada.",
                  "verification_not_awaiting_code": "A verificação não está esperando código: a correspondência ainda não foi postada, ou a verificação já terminou, foi cancelada ou foi revogada.",
                  "idempotency_key_reused": "Essa Idempotency-Key já foi usada com outro corpo ou em outro endpoint nas últimas 24 horas.",
                  "idempotency_key_in_use": "Uma requisição com a mesma Idempotency-Key ainda está sendo processada.",
                  "invalid_parameters": "Um ou mais campos têm valores inválidos.",
                  "rate_limit_exceeded": "A conta fez mais requisições por segundo do que o limite.",
                  "internal_error": "Erro inesperado na CartaFlow.",
                  "service_unavailable": "A API está temporariamente indisponível, por manutenção ou sobrecarga."
                },
                "example": "invalid_parameters"
              },
              "message": {
                "type": "string",
                "description": "Explicação para pessoas, em português ou em inglês conforme o cabeçalho Accept-Language. Pode mudar de texto; não use no seu código.",
                "example": "Um campo tem problema. Veja details."
              },
              "request_id": {
                "type": "string",
                "description": "Id desta requisição. Envie ao suporte quando precisar de ajuda. É o mesmo do cabeçalho Request-Id.",
                "example": "req_9Vb4Xk2Lq8Mz"
              },
              "doc_url": {
                "type": "string",
                "format": "uri",
                "description": "Link para a explicação deste código na documentação.",
                "example": "https://docs.cartaflow.com.br/errors#invalid_parameters"
              },
              "details": {
                "type": [
                  "array",
                  "null"
                ],
                "items": {
                  "$ref": "#/components/schemas/ErrorDetail"
                },
                "description": "Os campos com problema, todos de uma vez. Só existe em `validation_error`; `null` nos outros tipos."
              }
            }
          }
        }
      },
      "LetterList": {
        "type": "object",
        "title": "LetterList",
        "description": "Uma página de correspondências, da mais recente para a mais antiga.",
        "required": [
          "object",
          "data",
          "has_more",
          "next_cursor"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "list",
            "description": "Tipo do objeto. Sempre `list`.",
            "example": "list"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Letter"
            },
            "description": "Os itens desta página."
          },
          "has_more": {
            "type": "boolean",
            "description": "`true` quando existem mais itens depois desta página.",
            "example": false
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Envie este valor em `cursor` para buscar a próxima página. `null` quando esta é a última.",
            "example": null
          }
        }
      },
      "VerificationList": {
        "type": "object",
        "title": "VerificationList",
        "description": "Uma página de verificações, da mais recente para a mais antiga.",
        "required": [
          "object",
          "data",
          "has_more",
          "next_cursor"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "list",
            "description": "Tipo do objeto. Sempre `list`.",
            "example": "list"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Verification"
            },
            "description": "Os itens desta página."
          },
          "has_more": {
            "type": "boolean",
            "description": "`true` quando existem mais itens depois desta página.",
            "example": false
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Envie este valor em `cursor` para buscar a próxima página. `null` quando esta é a última.",
            "example": null
          }
        }
      },
      "BalanceTransactionList": {
        "type": "object",
        "title": "BalanceTransactionList",
        "description": "Uma página de movimentações do saldo, da mais recente para a mais antiga.",
        "required": [
          "object",
          "data",
          "has_more",
          "next_cursor"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "list",
            "description": "Tipo do objeto. Sempre `list`.",
            "example": "list"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BalanceTransaction"
            },
            "description": "Os itens desta página."
          },
          "has_more": {
            "type": "boolean",
            "description": "`true` quando existem mais itens depois desta página.",
            "example": false
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Envie este valor em `cursor` para buscar a próxima página. `null` quando esta é a última.",
            "example": null
          }
        }
      },
      "EventList": {
        "type": "object",
        "title": "EventList",
        "description": "Uma página de eventos, da mais recente para a mais antiga.",
        "required": [
          "object",
          "data",
          "has_more",
          "next_cursor"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "list",
            "description": "Tipo do objeto. Sempre `list`.",
            "example": "list"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Event"
            },
            "description": "Os itens desta página."
          },
          "has_more": {
            "type": "boolean",
            "description": "`true` quando existem mais itens depois desta página.",
            "example": false
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Envie este valor em `cursor` para buscar a próxima página. `null` quando esta é a última.",
            "example": null
          }
        }
      },
      "CreateLetterUpload": {
        "type": "object",
        "title": "CreateLetterUpload",
        "description": "O mesmo corpo da versão em JSON, em multipart/form-data, com o arquivo do PDF no campo `file` no lugar de `document`. Use quando você tem o arquivo e quer enviá-lo junto com os dados, numa requisição só.\n\nEm multipart/form-data, campos aninhados usam colchetes: `to[name]`, `to[postal_code]`, `variables[nome]`, `metadata[customer_id]`. Listas repetem o campo com `[]`: `postal_services[]=registered`. Booleanos vão como `true` ou `false`.",
        "required": [
          "file",
          "to"
        ],
        "additionalProperties": false,
        "properties": {
          "file": {
            "type": "string",
            "format": "binary",
            "contentMediaType": "application/pdf",
            "description": "O documento a imprimir. Um arquivo PDF, A4 em retrato, até 4 MB: o corpo inteiro da requisição tem até 4,5 MB. Para PDFs maiores, de até 10 MB, use JSON com `document.type: url` ou envie o arquivo antes com POST /v1/uploads e use `document.type: upload`."
          },
          "to": {
            "type": "object",
            "title": "AddressInput",
            "description": "Destinatário. A CartaFlow imprime estes dados na área do endereço, que aparece pela janela do envelope.",
            "required": [
              "name",
              "number",
              "postal_code"
            ],
            "additionalProperties": false,
            "properties": {
              "name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Nome da pessoa ou da empresa, como deve aparecer no envelope. Até 60 caracteres.",
                "example": "Destinatário Exemplo"
              },
              "postal_code": {
                "type": "string",
                "pattern": "^[0-9]{5}-?[0-9]{3}$",
                "description": "CEP com 8 dígitos, com ou sem hífen: `01001-000` ou `01001000`. Precisa existir na base de CEPs; é dele que vêm os campos que você não enviar. Nas respostas ele sempre volta com hífen.",
                "example": "01001-000"
              },
              "number": {
                "type": "string",
                "minLength": 1,
                "maxLength": 10,
                "description": "Número do imóvel. É texto porque alguns números têm letras, como `128A`. Use `S/N` quando o endereço não tem número. Até 10 caracteres.",
                "example": "128"
              },
              "complement": {
                "type": "string",
                "maxLength": 60,
                "description": "Complemento: apartamento, bloco, sala, andar. Até 60 caracteres.",
                "example": "Ap. 52"
              },
              "street": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100,
                "description": "Logradouro, com o tipo e o nome: rua, avenida, travessa, praça. Sem o número. Até 100 caracteres. Opcional: quando você não envia, preenchemos a partir do CEP. Quando envia, usamos o seu valor.",
                "example": "Praça da Sé"
              },
              "neighborhood": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Bairro. Até 60 caracteres. Opcional: quando você não envia, preenchemos a partir do CEP. Quando envia, usamos o seu valor.",
                "example": "Sé"
              },
              "city": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Cidade. Até 60 caracteres. Opcional: quando você não envia, preenchemos a partir do CEP. Quando envia, usamos o seu valor.",
                "example": "São Paulo"
              },
              "state": {
                "type": "string",
                "enum": [
                  "AC",
                  "AL",
                  "AP",
                  "AM",
                  "BA",
                  "CE",
                  "DF",
                  "ES",
                  "GO",
                  "MA",
                  "MT",
                  "MS",
                  "MG",
                  "PA",
                  "PB",
                  "PR",
                  "PE",
                  "PI",
                  "RJ",
                  "RN",
                  "RS",
                  "RO",
                  "RR",
                  "SC",
                  "SP",
                  "SE",
                  "TO"
                ],
                "description": "UF: a sigla do estado, com duas letras maiúsculas.\n\nOpcional: quando você não envia, preenchemos a partir do CEP. Quando envia, usamos o seu valor.\n\n**Valores possíveis**\n\n- `AC`: Acre\n- `AL`: Alagoas\n- `AP`: Amapá\n- `AM`: Amazonas\n- `BA`: Bahia\n- `CE`: Ceará\n- `DF`: Distrito Federal\n- `ES`: Espírito Santo\n- `GO`: Goiás\n- `MA`: Maranhão\n- `MT`: Mato Grosso\n- `MS`: Mato Grosso do Sul\n- `MG`: Minas Gerais\n- `PA`: Pará\n- `PB`: Paraíba\n- `PR`: Paraná\n- `PE`: Pernambuco\n- `PI`: Piauí\n- `RJ`: Rio de Janeiro\n- `RN`: Rio Grande do Norte\n- `RS`: Rio Grande do Sul\n- `RO`: Rondônia\n- `RR`: Roraima\n- `SC`: Santa Catarina\n- `SP`: São Paulo\n- `SE`: Sergipe\n- `TO`: Tocantins",
                "x-enumDescriptions": {
                  "AC": "Acre",
                  "AL": "Alagoas",
                  "AP": "Amapá",
                  "AM": "Amazonas",
                  "BA": "Bahia",
                  "CE": "Ceará",
                  "DF": "Distrito Federal",
                  "ES": "Espírito Santo",
                  "GO": "Goiás",
                  "MA": "Maranhão",
                  "MT": "Mato Grosso",
                  "MS": "Mato Grosso do Sul",
                  "MG": "Minas Gerais",
                  "PA": "Pará",
                  "PB": "Paraíba",
                  "PR": "Paraná",
                  "PE": "Pernambuco",
                  "PI": "Piauí",
                  "RJ": "Rio de Janeiro",
                  "RN": "Rio Grande do Norte",
                  "RS": "Rio Grande do Sul",
                  "RO": "Rondônia",
                  "RR": "Roraima",
                  "SC": "Santa Catarina",
                  "SP": "São Paulo",
                  "SE": "Sergipe",
                  "TO": "Tocantins"
                },
                "example": "SP"
              }
            },
            "example": {
              "name": "Destinatário Exemplo",
              "postal_code": "01001-000",
              "number": "128",
              "complement": "Ap. 52"
            }
          },
          "from": {
            "type": "object",
            "title": "AddressInput",
            "description": "Remetente, impresso em uma linha acima do destinatário. É para onde os Correios devolvem a correspondência quando não conseguem entregar, e para onde vai o aviso de recebimento (`return_receipt`). Se você não enviar, usamos o remetente padrão da conta, definido no painel em Configurações > Empresa.",
            "required": [
              "name",
              "number",
              "postal_code"
            ],
            "additionalProperties": false,
            "properties": {
              "name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Nome da pessoa ou da empresa, como deve aparecer no envelope. Até 60 caracteres.",
                "example": "Destinatário Exemplo"
              },
              "postal_code": {
                "type": "string",
                "pattern": "^[0-9]{5}-?[0-9]{3}$",
                "description": "CEP com 8 dígitos, com ou sem hífen: `01001-000` ou `01001000`. Precisa existir na base de CEPs; é dele que vêm os campos que você não enviar. Nas respostas ele sempre volta com hífen.",
                "example": "01001-000"
              },
              "number": {
                "type": "string",
                "minLength": 1,
                "maxLength": 10,
                "description": "Número do imóvel. É texto porque alguns números têm letras, como `128A`. Use `S/N` quando o endereço não tem número. Até 10 caracteres.",
                "example": "128"
              },
              "complement": {
                "type": "string",
                "maxLength": 60,
                "description": "Complemento: apartamento, bloco, sala, andar. Até 60 caracteres.",
                "example": "Ap. 52"
              },
              "street": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100,
                "description": "Logradouro, com o tipo e o nome: rua, avenida, travessa, praça. Sem o número. Até 100 caracteres. Opcional: quando você não envia, preenchemos a partir do CEP. Quando envia, usamos o seu valor.",
                "example": "Praça da Sé"
              },
              "neighborhood": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Bairro. Até 60 caracteres. Opcional: quando você não envia, preenchemos a partir do CEP. Quando envia, usamos o seu valor.",
                "example": "Sé"
              },
              "city": {
                "type": "string",
                "minLength": 1,
                "maxLength": 60,
                "description": "Cidade. Até 60 caracteres. Opcional: quando você não envia, preenchemos a partir do CEP. Quando envia, usamos o seu valor.",
                "example": "São Paulo"
              },
              "state": {
                "type": "string",
                "enum": [
                  "AC",
                  "AL",
                  "AP",
                  "AM",
                  "BA",
                  "CE",
                  "DF",
                  "ES",
                  "GO",
                  "MA",
                  "MT",
                  "MS",
                  "MG",
                  "PA",
                  "PB",
                  "PR",
                  "PE",
                  "PI",
                  "RJ",
                  "RN",
                  "RS",
                  "RO",
                  "RR",
                  "SC",
                  "SP",
                  "SE",
                  "TO"
                ],
                "description": "UF: a sigla do estado, com duas letras maiúsculas.\n\nOpcional: quando você não envia, preenchemos a partir do CEP. Quando envia, usamos o seu valor.\n\n**Valores possíveis**\n\n- `AC`: Acre\n- `AL`: Alagoas\n- `AP`: Amapá\n- `AM`: Amazonas\n- `BA`: Bahia\n- `CE`: Ceará\n- `DF`: Distrito Federal\n- `ES`: Espírito Santo\n- `GO`: Goiás\n- `MA`: Maranhão\n- `MT`: Mato Grosso\n- `MS`: Mato Grosso do Sul\n- `MG`: Minas Gerais\n- `PA`: Pará\n- `PB`: Paraíba\n- `PR`: Paraná\n- `PE`: Pernambuco\n- `PI`: Piauí\n- `RJ`: Rio de Janeiro\n- `RN`: Rio Grande do Norte\n- `RS`: Rio Grande do Sul\n- `RO`: Rondônia\n- `RR`: Roraima\n- `SC`: Santa Catarina\n- `SP`: São Paulo\n- `SE`: Sergipe\n- `TO`: Tocantins",
                "x-enumDescriptions": {
                  "AC": "Acre",
                  "AL": "Alagoas",
                  "AP": "Amapá",
                  "AM": "Amazonas",
                  "BA": "Bahia",
                  "CE": "Ceará",
                  "DF": "Distrito Federal",
                  "ES": "Espírito Santo",
                  "GO": "Goiás",
                  "MA": "Maranhão",
                  "MT": "Mato Grosso",
                  "MS": "Mato Grosso do Sul",
                  "MG": "Minas Gerais",
                  "PA": "Pará",
                  "PB": "Paraíba",
                  "PR": "Paraná",
                  "PE": "Pernambuco",
                  "PI": "Piauí",
                  "RJ": "Rio de Janeiro",
                  "RN": "Rio Grande do Norte",
                  "RS": "Rio Grande do Sul",
                  "RO": "Rondônia",
                  "RR": "Roraima",
                  "SC": "Santa Catarina",
                  "SP": "São Paulo",
                  "SE": "Sergipe",
                  "TO": "Tocantins"
                },
                "example": "SP"
              }
            },
            "example": {
              "name": "Destinatário Exemplo",
              "postal_code": "01001-000",
              "number": "128",
              "complement": "Ap. 52"
            }
          },
          "variables": {
            "type": "object",
            "maxProperties": 100,
            "propertyNames": {
              "pattern": "^[A-Za-z0-9_]+$",
              "maxLength": 60
            },
            "additionalProperties": {
              "type": [
                "string",
                "number"
              ],
              "maxLength": 500
            },
            "description": "Valores para as marcações do PDF, como `{{nome}}` escrito num documento do Word e exportado em PDF. Cada valor é escrito no lugar da sua marcação, no mesmo tamanho e cor, e o resto da linha se ajusta a ele, como se o valor tivesse sido digitado ali. O valor não quebra linha: se não couber, o resto da linha é apertado um pouco e, se ainda assim não couber, passa da margem; confira no `preview_url`. Até 100 variáveis; nomes com letras, números e sublinhado, com até 60 caracteres; valores em texto ou número, numa linha só, com até 500 caracteres. O PDF precisa ter texto selecionável (não pode ser imagem ou digitalização), senão a API responde `document_text_unreadable`. Envie exatamente as marcações do PDF: se faltar uma, `variable_missing`; se sobrar uma, `variable_not_found`. Sem este campo, o PDF é impresso como está.",
            "example": {
              "nome": "Destinatário Exemplo",
              "valor": "R$ 189,90",
              "vencimento": "20/10/2026"
            }
          },
          "color": {
            "type": "boolean",
            "default": false,
            "description": "`true` imprime em cores. `false` imprime em preto e branco: um PDF colorido sai em tons de cinza. A impressão colorida tem acréscimo por página impressa (cada lado impresso conta como uma página).",
            "example": false
          },
          "double_sided": {
            "type": "boolean",
            "default": false,
            "description": "`true` imprime frente e verso: cada folha leva duas páginas do documento, então a correspondência usa menos folhas e custa menos. `false` imprime só a frente de cada folha.",
            "example": false
          },
          "address_placement": {
            "type": "string",
            "enum": [
              "first_page",
              "extra_page"
            ],
            "description": "Onde a CartaFlow imprime o endereço do destinatário.\n\n**Valores possíveis**\n\n- `first_page`: Na área do endereço da primeira página do seu documento (90 x 45 mm, a 20 mm da esquerda e 45 mm do topo). Essa área precisa estar em branco no seu PDF. Padrão.\n- `extra_page`: Num lado só dele, o primeiro, que aparece pela janela do envelope. Use quando o seu layout ocupa a área do endereço. Ele ocupa um lado que ficaria em branco, quando há um: o verso da primeira página, só frente, ou o lado que sobra, em frente e verso com número ímpar de páginas. Em frente e verso com número par de páginas, entra uma folha a mais no início. O endereço nunca é cobrado.",
            "x-enumDescriptions": {
              "first_page": "Na área do endereço da primeira página do seu documento (90 x 45 mm, a 20 mm da esquerda e 45 mm do topo). Essa área precisa estar em branco no seu PDF. Padrão.",
              "extra_page": "Num lado só dele, o primeiro, que aparece pela janela do envelope. Use quando o seu layout ocupa a área do endereço. Ele ocupa um lado que ficaria em branco, quando há um: o verso da primeira página, só frente, ou o lado que sobra, em frente e verso com número ímpar de páginas. Em frente e verso com número par de páginas, entra uma folha a mais no início. O endereço nunca é cobrado."
            },
            "default": "first_page",
            "example": "first_page"
          },
          "postal_services": {
            "type": "array",
            "uniqueItems": true,
            "items": {
              "type": "string",
              "enum": [
                "registered",
                "return_receipt",
                "restricted_delivery"
              ],
              "x-enumDescriptions": {
                "registered": "Carta registrada: a correspondência é postada com registro nos Correios e recebe um código de rastreio, que aparece em `tracking_code` quando ela é postada.",
                "return_receipt": "Aviso de recebimento (AR): os Correios devolvem um comprovante assinado por quem recebeu a correspondência ao remetente impresso no envelope. Exige `registered`.",
                "restricted_delivery": "Mão própria (MP): os Correios entregam só para a pessoa cujo nome está no envelope. Exige `registered`."
              }
            },
            "default": [],
            "description": "Serviços adicionais dos Correios, cada um com o próprio acréscimo no preço (uma linha em `price`). Sem este campo, ou com `[]`, a correspondência vai como carta simples, sem rastreio depois da postagem. `return_receipt` e `restricted_delivery` só funcionam junto com `registered`; sem ele, a API responde 422 com `requires_registered`. Em multipart/form-data, repita o campo `postal_services[]` uma vez para cada serviço.\n\n**Valores possíveis**\n\n- `registered`: Carta registrada: a correspondência é postada com registro nos Correios e recebe um código de rastreio, que aparece em `tracking_code` quando ela é postada.\n- `return_receipt`: Aviso de recebimento (AR): os Correios devolvem um comprovante assinado por quem recebeu a correspondência ao remetente impresso no envelope. Exige `registered`.\n- `restricted_delivery`: Mão própria (MP): os Correios entregam só para a pessoa cujo nome está no envelope. Exige `registered`.",
            "example": [
              "registered",
              "return_receipt"
            ]
          },
          "send_date": {
            "type": "string",
            "format": "date",
            "description": "Agenda o envio para uma data, no formato `AAAA-MM-DD`, de amanhã até 180 dias à frente (horário de Brasília). A correspondência é validada agora, mas só é cobrada na data, às 06:00: nesse momento o saldo precisa cobrir o preço, senão ela é cancelada com `cancellation_reason: insufficient_balance`. Até lá ela fica em `scheduled` e pode ser cancelada sem custo. Para enviar agora, não envie este campo.",
            "example": "2026-10-20"
          },
          "reference": {
            "type": "string",
            "maxLength": 100,
            "description": "Seu identificador para esta correspondência, como o número da fatura ou o id do cliente no seu sistema. Aparece no painel e pode ser usado como filtro nas listagens. Não precisa ser único. Até 100 caracteres.",
            "example": "fatura-2026-10-0042"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "maxLength": 500
            },
            "maxProperties": 20,
            "description": "Pares chave-valor para guardar dados seus junto do objeto, como o id do cliente ou do contrato. Voltam em todas as respostas e webhooks e nunca são impressos. Até 20 chaves; chaves com até 40 caracteres e valores em texto com até 500 caracteres. Não guarde dados sensíveis, como senhas ou números de cartão.",
            "example": {
              "customer_id": "1842",
              "contract": "C-2026-118"
            }
          }
        }
      },
      "CreateUploadRequest": {
        "type": "object",
        "title": "CreateUploadRequest",
        "description": "Os dados do PDF que você vai enviar. A resposta traz um `upload_url` para onde você envia o arquivo com PUT; depois, use o `id` do upload numa correspondência com `document.type: upload`.",
        "required": [
          "filename",
          "size"
        ],
        "additionalProperties": false,
        "properties": {
          "filename": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "O nome do arquivo PDF, como `fatura-outubro.pdf`. Aparece em `document.filename` da correspondência e no painel. De 1 a 255 caracteres.",
            "example": "fatura-outubro.pdf"
          },
          "size": {
            "type": "integer",
            "minimum": 1,
            "maximum": 10485760,
            "description": "O tamanho do arquivo em bytes, de 1 a 10485760 (10 MB). Acima disso, a API responde 422 com `out_of_range`.",
            "example": 7340032
          }
        }
      },
      "Upload": {
        "type": "object",
        "title": "Upload",
        "description": "Um lugar para enviar um PDF grande antes de criar a correspondência. Envie o arquivo com PUT para `upload_url` em até 2 horas e use o `id` numa correspondência em até 24 horas. Cada upload pertence à sua conta e serve para uma correspondência só.",
        "required": [
          "id",
          "object",
          "filename",
          "size",
          "upload_url",
          "upload_url_expires_at",
          "expires_at",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Identificador único do upload. Use em `document.upload_id` ao criar a correspondência. Sempre começa com `upl_`.",
            "pattern": "^upl_[A-Za-z0-9]+$",
            "example": "upl_6Np3Vx8Rk2Tq"
          },
          "object": {
            "type": "string",
            "const": "upload",
            "description": "Tipo do objeto. Sempre `upload`.",
            "example": "upload"
          },
          "filename": {
            "type": "string",
            "description": "O nome do arquivo, como você enviou.",
            "example": "fatura-outubro.pdf"
          },
          "size": {
            "type": "integer",
            "description": "O tamanho do arquivo em bytes, como você informou.",
            "example": 7340032
          },
          "upload_url": {
            "type": "string",
            "format": "uri",
            "description": "URL HTTPS assinada para enviar o arquivo. Envie os bytes do PDF no corpo de um PUT, com o cabeçalho `Content-Type: application/pdf` e sem o cabeçalho `Authorization`: a assinatura já está na URL. Uma resposta 2xx confirma que o arquivo chegou. Vale por 2 horas (até `upload_url_expires_at`). Trate a URL como um segredo e não a guarde: ela não aparece em nenhum outro lugar.",
            "example": "https://files.cartaflow.com.br/uploads/upl_6Np3Vx8Rk2Tq?token=4f8a2c91d7"
          },
          "upload_url_expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "Até quando `upload_url` aceita o arquivo: 2 horas depois da criação. Se passar do prazo sem enviar, crie outro upload.",
            "example": "2026-10-13T14:35:00Z"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "Até quando o upload pode ser usado numa correspondência: 24 horas depois da criação. Depois disso, `document.upload_id` recebe 422 com `upload_expired`.",
            "example": "2026-10-14T14:20:00Z"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Quando o upload foi criado.",
            "example": "2026-10-13T14:20:00Z"
          }
        }
      }
    },
    "parameters": {
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "schema": {
          "type": "string",
          "maxLength": 255,
          "example": "fatura-2026-10-0042"
        },
        "description": "Um valor único por operação, como o id da fatura no seu sistema ou um UUID. Se você repetir a requisição com a mesma chave em até 24 horas, a API devolve a resposta da primeira vez em vez de criar outro objeto. Recomendado em todo POST. Até 255 caracteres."
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 20,
          "example": 20
        },
        "description": "Quantos itens devolver por página, de 1 a 100. Padrão: 20."
      },
      "Cursor": {
        "name": "cursor",
        "in": "query",
        "required": false,
        "schema": {
          "type": "string",
          "example": "eyJpZCI6Imx0cl84S3Eyd1g0bU43cFIifQ"
        },
        "description": "O `next_cursor` da página anterior. Omita para buscar a primeira página."
      },
      "CreatedAfter": {
        "name": "created_after",
        "in": "query",
        "required": false,
        "schema": {
          "type": "string",
          "format": "date-time",
          "example": "2026-10-01T00:00:00Z"
        },
        "description": "Só itens criados a partir deste momento, inclusive. Data e hora ISO 8601."
      },
      "CreatedBefore": {
        "name": "created_before",
        "in": "query",
        "required": false,
        "schema": {
          "type": "string",
          "format": "date-time",
          "example": "2026-11-01T00:00:00Z"
        },
        "description": "Só itens criados antes deste momento. Data e hora ISO 8601."
      },
      "Reference": {
        "name": "reference",
        "in": "query",
        "required": false,
        "schema": {
          "type": "string",
          "example": "fatura-2026-10-0042"
        },
        "description": "Só itens com exatamente esta `reference`."
      },
      "LetterId": {
        "name": "letter_id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "example": "ltr_8Kq2wX4mN7pR"
        },
        "description": "O id da correspondência, que começa com `ltr_`."
      },
      "VerificationId": {
        "name": "verification_id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "example": "ver_3Hd9Kp2qZ6tW"
        },
        "description": "O id da verificação, que começa com `ver_`."
      },
      "EventId": {
        "name": "event_id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "example": "evt_6Tq1Yz8Wm3Rb"
        },
        "description": "O id do evento, que começa com `evt_`."
      }
    },
    "responses": {
      "InvalidRequest": {
        "description": "A requisição não pôde ser lida: JSON malformado, Content-Type errado ou Idempotency-Key inválida.",
        "headers": {
          "Request-Id": {
            "$ref": "#/components/headers/RequestId"
          },
          "RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "type": "invalid_request_error",
                "code": "invalid_json",
                "message": "O corpo da requisição não é um JSON válido.",
                "request_id": "req_9Vb4Xk2Lq8Mz",
                "doc_url": "https://docs.cartaflow.com.br/errors#invalid_json",
                "details": null
              }
            }
          }
        }
      },
      "Unauthorized": {
        "description": "A chave de API está ausente, inválida ou revogada.",
        "headers": {
          "Request-Id": {
            "$ref": "#/components/headers/RequestId"
          },
          "RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "type": "authentication_error",
                "code": "api_key_invalid",
                "message": "Esta chave de API não existe. Copie a chave de novo no painel.",
                "request_id": "req_9Vb4Xk2Lq8Mz",
                "doc_url": "https://docs.cartaflow.com.br/errors#api_key_invalid",
                "details": null
              }
            }
          }
        }
      },
      "InsufficientBalance": {
        "description": "O saldo não cobre o preço. Nada foi criado nem cobrado.",
        "headers": {
          "Request-Id": {
            "$ref": "#/components/headers/RequestId"
          },
          "RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "type": "billing_error",
                "code": "insufficient_balance",
                "message": "O saldo disponível (R$ 4,10) não cobre este envio (R$ 9,90). Recarregue o saldo no painel.",
                "request_id": "req_9Vb4Xk2Lq8Mz",
                "doc_url": "https://docs.cartaflow.com.br/errors#insufficient_balance",
                "details": null
              }
            }
          }
        }
      },
      "Forbidden": {
        "description": "A conta está suspensa.",
        "headers": {
          "Request-Id": {
            "$ref": "#/components/headers/RequestId"
          },
          "RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "type": "permission_error",
                "code": "account_suspended",
                "message": "Esta conta está suspensa. Fale com o suporte pelo painel.",
                "request_id": "req_9Vb4Xk2Lq8Mz",
                "doc_url": "https://docs.cartaflow.com.br/errors#account_suspended",
                "details": null
              }
            }
          }
        }
      },
      "NotFound": {
        "description": "Não existe objeto com esse id na sua conta.",
        "headers": {
          "Request-Id": {
            "$ref": "#/components/headers/RequestId"
          },
          "RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "type": "not_found_error",
                "code": "resource_not_found",
                "message": "Não existe correspondência com o id ltr_8Kq2wX4mN7pR nesta conta.",
                "request_id": "req_9Vb4Xk2Lq8Mz",
                "doc_url": "https://docs.cartaflow.com.br/errors#resource_not_found",
                "details": null
              }
            }
          }
        }
      },
      "RequestTooLarge": {
        "description": "O corpo da requisição passa de 4,5 MB. Nada foi criado. Envie o PDF por URL ou com POST /v1/uploads.",
        "headers": {
          "Request-Id": {
            "$ref": "#/components/headers/RequestId"
          },
          "RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "type": "invalid_request_error",
                "code": "request_too_large",
                "message": "O corpo da requisição passa de 4,5 MB. Envie o PDF por URL ou com POST /v1/uploads, que aceitam até 10 MB.",
                "request_id": "req_9Vb4Xk2Lq8Mz",
                "doc_url": "https://docs.cartaflow.com.br/errors#request_too_large",
                "details": null
              }
            }
          }
        }
      },
      "IdempotencyConflict": {
        "description": "A Idempotency-Key já foi usada com outro corpo, ou a primeira requisição com ela ainda está em andamento.",
        "headers": {
          "Request-Id": {
            "$ref": "#/components/headers/RequestId"
          },
          "RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "type": "conflict_error",
                "code": "idempotency_key_reused",
                "message": "Esta Idempotency-Key já foi usada com outros parâmetros. Use uma chave nova para uma operação diferente.",
                "request_id": "req_9Vb4Xk2Lq8Mz",
                "doc_url": "https://docs.cartaflow.com.br/errors#idempotency_key_reused",
                "details": null
              }
            }
          }
        }
      },
      "RateLimited": {
        "description": "Limite de requisições excedido (50 por segundo por conta). Espere o tempo de Retry-After.",
        "headers": {
          "Request-Id": {
            "$ref": "#/components/headers/RequestId"
          },
          "RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          },
          "Retry-After": {
            "description": "Segundos para esperar antes de repetir.",
            "schema": {
              "type": "integer",
              "example": 1
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "type": "rate_limit_error",
                "code": "rate_limit_exceeded",
                "message": "Muitas requisições. Tente de novo em 1 segundo.",
                "request_id": "req_9Vb4Xk2Lq8Mz",
                "doc_url": "https://docs.cartaflow.com.br/errors#rate_limit_exceeded",
                "details": null
              }
            }
          }
        }
      },
      "ServerError": {
        "description": "Erro do lado da CartaFlow. Repita com a mesma Idempotency-Key.",
        "headers": {
          "Request-Id": {
            "$ref": "#/components/headers/RequestId"
          },
          "RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "type": "api_error",
                "code": "internal_error",
                "message": "Erro inesperado. Tente de novo; se continuar, envie o request_id ao suporte.",
                "request_id": "req_9Vb4Xk2Lq8Mz",
                "doc_url": "https://docs.cartaflow.com.br/errors#internal_error",
                "details": null
              }
            }
          }
        }
      }
    },
    "headers": {
      "RequestId": {
        "description": "Id desta requisição, como `req_9Vb4Xk2Lq8Mz`. Envie ao suporte quando precisar de ajuda.",
        "schema": {
          "type": "string",
          "example": "req_9Vb4Xk2Lq8Mz"
        }
      },
      "RateLimitLimit": {
        "description": "Quantas requisições por segundo a conta pode fazer, somando todas as chaves.",
        "schema": {
          "type": "integer",
          "example": 50
        }
      },
      "RateLimitRemaining": {
        "description": "Quantas requisições ainda cabem na janela atual.",
        "schema": {
          "type": "integer",
          "example": 49
        }
      },
      "RateLimitReset": {
        "description": "Segundos até a janela atual recomeçar.",
        "schema": {
          "type": "integer",
          "example": 1
        }
      },
      "IdempotentReplayed": {
        "description": "`true` quando esta resposta é a repetição de uma requisição anterior com a mesma Idempotency-Key.",
        "schema": {
          "type": "boolean",
          "example": true
        }
      }
    }
  }
}
