{
    "openapi": "3.1.0",
    "info": {
        "title": "API — Lista de Agências",
        "version": "1.0.0",
        "description": "API de leitura do diretório de agências digitais do Brasil e de envio de pedidos de orçamento, para agentes de IA e integradores: os mesmos dados e as mesmas regras de visibilidade do site (listadeagencias.com.br). Disponível mediante contratação — fale com fale@maturidade.digital. Todo endpoint, exceto esta especificação, exige um token Bearer válido; sem ele, 401. Um token válido libera os campos restritos (site, LinkedIn, Instagram e as entidades associadas). E-mail, telefone e WhatsApp de agência nunca aparecem, para ninguém.\n\nLimites de taxa: 60 requisições por minuto na leitura, por conta (ou por IP); 30 tentativas por minuto por IP com token inválido; no envio de pedidos, 5 requisições de POST a cada 10 minutos por IP e até 3 pedidos aceitos a cada 10 minutos por IP, somando site, API e MCP. Toda resposta limitada traz `X-RateLimit-Limit` e `X-RateLimit-Remaining`; ao passar do limite, 429 com `Retry-After`. Veja também `x-rate-limits`.",
        "termsOfService": "https://www.listadeagencias.com.br/termos",
        "contact": {
            "name": "Lista de Agências",
            "url": "https://www.listadeagencias.com.br/sobre"
        },
        "license": {
            "name": "Uso mediante contrato; condições nos termos de uso",
            "url": "https://www.listadeagencias.com.br/termos"
        },
        "x-rate-limits": [
            {
                "scope": "leitura (GET)",
                "limit": 60,
                "window": "1 minuto",
                "key": "conta do token, ou IP"
            },
            {
                "scope": "token inválido ou expirado",
                "limit": 30,
                "window": "1 minuto",
                "key": "IP"
            },
            {
                "scope": "POST /quote-requests (requisições)",
                "limit": 5,
                "window": "10 minutos",
                "key": "IP"
            },
            {
                "scope": "pedidos de orçamento aceitos (site, API e MCP somados)",
                "limit": 3,
                "window": "10 minutos",
                "key": "IP"
            }
        ]
    },
    "servers": [
        {
            "url": "https://www.listadeagencias.com.br/api/v1",
            "description": "Lista de Agências"
        }
    ],
    "tags": [
        {
            "name": "Agências",
            "description": "Diretório de agências digitais."
        },
        {
            "name": "Serviços",
            "description": "Catálogo de serviços digitais, por categoria."
        },
        {
            "name": "Categorias",
            "description": "As 5 categorias de serviço."
        },
        {
            "name": "Estados",
            "description": "UFs com agências no diretório."
        },
        {
            "name": "Orçamento",
            "description": "Envio de pedido de orçamento."
        },
        {
            "name": "Documentação",
            "description": "Especificação da própria API."
        }
    ],
    "paths": {
        "/openapi.json": {
            "get": {
                "tags": [
                    "Documentação"
                ],
                "summary": "Especificação OpenAPI desta API",
                "operationId": "getOpenApiSpec",
                "security": [],
                "responses": {
                    "200": {
                        "description": "Este documento, em OpenAPI 3.1.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/agencies": {
            "get": {
                "tags": [
                    "Agências"
                ],
                "summary": "Lista agências publicadas, com filtros",
                "description": "Retorna agências publicadas do diretório, paginadas. Exige um token Bearer válido (API mediante contratação); com ele, os campos restritos (site, LinkedIn, Instagram, entidades) aparecem preenchidos, inclusive o filtro `association`. E-mail, telefone e WhatsApp de agência nunca aparecem, para ninguém.",
                "operationId": "listAgencies",
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "description": "Busca textual por nome ou descrição.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "growth"
                    },
                    {
                        "name": "category",
                        "in": "query",
                        "description": "Slug da categoria de serviço.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "estrategia-de-marketing"
                    },
                    {
                        "name": "service",
                        "in": "query",
                        "description": "Slug do serviço.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "otimizacao-de-seo"
                    },
                    {
                        "name": "state",
                        "in": "query",
                        "description": "UF (2 letras).",
                        "schema": {
                            "type": "string",
                            "pattern": "^[A-Za-z]{2}$"
                        },
                        "example": "SP"
                    },
                    {
                        "name": "city",
                        "in": "query",
                        "description": "Slug da cidade.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "sao-paulo"
                    },
                    {
                        "name": "association",
                        "in": "query",
                        "description": "Slug da entidade associativa (só com token; a lista de slugs fica na área logada do site).",
                        "schema": {
                            "type": "string",
                            "pattern": "^[a-z0-9-]+$"
                        }
                    },
                    {
                        "name": "platform",
                        "in": "query",
                        "description": "Slug da plataforma parceira (e-commerce, CRM ou automação de marketing). Traz só as agências que aparecem no diretório público de parceiros dessa plataforma.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "nuvemshop",
                                "loja-integrada",
                                "magazord",
                                "tray",
                                "edrone",
                                "shopify",
                                "rd-station"
                            ]
                        },
                        "example": "shopify"
                    },
                    {
                        "name": "member",
                        "in": "query",
                        "description": "`true` para listar só agências membro da Lista de Agências (selo pago de destaque).",
                        "schema": {
                            "type": "boolean"
                        },
                        "example": true
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "description": "Página (a partir de 1). Um valor além da última página devolve uma lista vazia, nunca erro.",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "default": 1
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "description": "Itens por página, de 1 a 50.",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 50,
                            "default": 24
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Lista paginada de agências.",
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/AgencyListResponse"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                }
            }
        },
        "/agencies/{slug}": {
            "get": {
                "tags": [
                    "Agências"
                ],
                "summary": "Perfil de uma agência",
                "operationId": "getAgency",
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "slug",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "example": "beta-lab"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A agência.",
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "oneOf": [
                                                {
                                                    "$ref": "#/components/schemas/Agency"
                                                },
                                                {
                                                    "$ref": "#/components/schemas/AgencyRestricted"
                                                }
                                            ]
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Slug inexistente, ou agência não publicada.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                }
            }
        },
        "/services": {
            "get": {
                "tags": [
                    "Serviços"
                ],
                "summary": "Lista os serviços digitais do catálogo",
                "description": "Não há campo restrito num serviço, mas o endpoint exige um token Bearer válido como qualquer outro endpoint de leitura (API mediante contratação).",
                "operationId": "listServices",
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Todos os serviços, agrupáveis pelo campo `category`.",
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Service"
                                            }
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                }
            }
        },
        "/services/{slug}": {
            "get": {
                "tags": [
                    "Serviços"
                ],
                "summary": "Detalhe de um serviço (conteúdo completo e perguntas frequentes)",
                "operationId": "getService",
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "slug",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "example": "otimizacao-de-seo"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "O serviço.",
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/ServiceDetail"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Slug inexistente.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                }
            }
        },
        "/categories": {
            "get": {
                "tags": [
                    "Categorias"
                ],
                "summary": "Lista as 5 categorias de serviço",
                "operationId": "listCategories",
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "As categorias.",
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Category"
                                            }
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                }
            }
        },
        "/states": {
            "get": {
                "tags": [
                    "Estados"
                ],
                "summary": "Lista as UFs com ao menos uma agência publicada",
                "operationId": "listStates",
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Estados com agências.",
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/State"
                                            }
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    }
                }
            }
        },
        "/quote-requests": {
            "post": {
                "tags": [
                    "Orçamento"
                ],
                "summary": "Envia um pedido de orçamento",
                "description": "Cria um pedido de orçamento. Exige um token Bearer válido (API mediante contratação). Com um token cuja habilidade `quote:create` está presente, o pedido é vinculado à conta do token e, quando o `email` do pedido é o mesmo do dono do token *e* esse e-mail já está verificado, o pedido nasce já `confirmed` — nos demais casos, o pedido fica pendente de confirmação por e-mail (`pending_verification`) até quem preencheu o `email` clicar no link enviado. Um token sem `quote:create` continua liberado para enviar o pedido, só não fica vinculado a nenhuma conta.",
                "operationId": "createQuoteRequest",
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/QuoteRequestInput"
                            }
                        }
                    }
                },
                "responses": {
                    "202": {
                        "description": "Pedido registrado.",
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/QuoteRequestAccepted"
                                },
                                "example": {
                                    "id": 501,
                                    "status": "pending_verification",
                                    "message": "Pedido registrado. Confirme pelo link enviado ao e-mail informado."
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Dados inválidos. Nada é gravado.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                },
                                "example": {
                                    "message": "Escolha ao menos um serviço.",
                                    "errors": {
                                        "services": [
                                            "Escolha ao menos um serviço."
                                        ]
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Mais de 3 pedidos aceitos do mesmo IP em 10 minutos (limite somado entre site, API e MCP — mensagem \"Muitos pedidos em sequência...\"), ou mais de 5 requisições de POST por IP em 10 minutos, aceitas ou não (mensagem genérica \"Muitas requisições...\").",
                        "headers": {
                            "Retry-After": {
                                "schema": {
                                    "type": "integer"
                                },
                                "description": "Segundos até a próxima tentativa."
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                },
                                "example": {
                                    "message": "Muitos pedidos em sequência. Tente novamente em alguns minutos.",
                                    "errors": {}
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    }
                }
            }
        }
    },
    "components": {
        "headers": {
            "X-RateLimit-Limit": {
                "description": "Requisições permitidas na janela do limite.",
                "schema": {
                    "type": "integer"
                }
            },
            "X-RateLimit-Remaining": {
                "description": "Requisições que ainda restam na janela atual.",
                "schema": {
                    "type": "integer"
                }
            }
        },
        "responses": {
            "Unauthorized": {
                "description": "Sem token: \"API disponível mediante contratação. Fale com fale@maturidade.digital.\" Token presente, porém inválido ou expirado: \"Token inválido ou expirado.\" Nunca vira anônimo silenciosamente.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "example": {
                            "message": "API disponível mediante contratação. Fale com fale@maturidade.digital.",
                            "errors": {}
                        }
                    }
                }
            },
            "TooManyRequests": {
                "description": "Limite de requisições excedido (60/min de leitura por conta ou IP; tentativas com token inválido também são limitadas, 30/min por IP).",
                "headers": {
                    "Retry-After": {
                        "schema": {
                            "type": "integer"
                        },
                        "description": "Segundos até a próxima tentativa."
                    }
                },
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "example": {
                            "message": "Muitas requisições. Tente novamente em 42 segundos.",
                            "errors": {}
                        }
                    }
                }
            }
        },
        "securitySchemes": {
            "bearerAuth": {
                "type": "http",
                "scheme": "bearer",
                "description": "API disponível mediante contratação — fale com fale@maturidade.digital para obter um token. Todo endpoint, exceto GET /openapi.json, exige um token Bearer válido; sem ele, 401. Envie como `Authorization: Bearer {token}`. Todo token dá os mesmos direitos de leitura de uma sessão logada no site — libera os campos restritos da agência em qualquer endpoint de leitura, sem precisar de uma habilidade específica para isso. A única habilidade opcional é `quote:create`, que vincula à conta do token os pedidos de orçamento enviados com ele (ver POST /quote-requests). Um token presente mas inválido ou expirado nunca é tratado como anônimo — a chamada responde 401."
            }
        },
        "schemas": {
            "Error": {
                "type": "object",
                "description": "Formato único de erro da API.",
                "properties": {
                    "message": {
                        "type": "string",
                        "example": "Dados inválidos."
                    },
                    "errors": {
                        "type": "object",
                        "additionalProperties": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            }
                        },
                        "example": {}
                    }
                },
                "required": [
                    "message",
                    "errors"
                ]
            },
            "AgencyService": {
                "type": "object",
                "properties": {
                    "slug": {
                        "type": "string",
                        "example": "otimizacao-de-seo"
                    },
                    "name": {
                        "type": "string",
                        "example": "Otimização de SEO"
                    },
                    "category": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "example": "Gestão de Marca"
                    }
                }
            },
            "AgencyPlatform": {
                "type": "object",
                "description": "Parceria pública com uma plataforma, como a própria plataforma a publica no diretório de parceiros. Fonte e data da coleta são internas e nunca aparecem aqui.",
                "properties": {
                    "slug": {
                        "type": "string",
                        "example": "shopify"
                    },
                    "name": {
                        "type": "string",
                        "example": "Shopify"
                    },
                    "tier": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Nível da parceria exatamente como a plataforma publica (Plus, Gold, Platinum...), ou null quando o diretório não mostra nível.",
                        "example": "Plus"
                    }
                },
                "required": [
                    "slug",
                    "name",
                    "tier"
                ]
            },
            "Agency": {
                "type": "object",
                "description": "Agência sem os campos restritos: nunca aparecem, nem como `null` — a chave `restricted` lista os nomes que foram omitidos. E-mail, telefone e WhatsApp de agência nunca aparecem, para ninguém, em nenhuma das duas formas deste objeto.",
                "properties": {
                    "slug": {
                        "type": "string",
                        "example": "beta-lab"
                    },
                    "name": {
                        "type": "string",
                        "example": "Beta Lab"
                    },
                    "description": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "city": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "example": "São Paulo"
                    },
                    "state": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "example": "SP"
                    },
                    "logo_url": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uri"
                    },
                    "is_member": {
                        "type": "boolean",
                        "description": "Agência membro da Lista de Agências (selo pago de destaque). Não tem relação com entidades do setor."
                    },
                    "url": {
                        "type": "string",
                        "format": "uri",
                        "example": "https://listadeagencias.com.br/agencias/beta-lab"
                    },
                    "services": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/AgencyService"
                        }
                    },
                    "platforms": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/AgencyPlatform"
                        }
                    },
                    "restricted": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "example": [
                            "associations",
                            "website",
                            "linkedin",
                            "instagram"
                        ]
                    }
                },
                "required": [
                    "slug",
                    "name",
                    "city",
                    "state",
                    "logo_url",
                    "is_member",
                    "url",
                    "services",
                    "platforms",
                    "restricted"
                ]
            },
            "AgencyAssociation": {
                "type": "object",
                "description": "Fonte e data da coleta são internas e nunca aparecem aqui.",
                "properties": {
                    "slug": {
                        "type": "string"
                    },
                    "acronym": {
                        "type": "string"
                    },
                    "name": {
                        "type": "string"
                    }
                }
            },
            "AgencyRestricted": {
                "type": "object",
                "description": "Agência para uma chamada com token Bearer válido: os mesmos campos públicos, mais os restritos preenchidos (associations, website, linkedin, instagram). E-mail, telefone e WhatsApp de agência nunca aparecem, mesmo com token.",
                "properties": {
                    "slug": {
                        "type": "string"
                    },
                    "name": {
                        "type": "string"
                    },
                    "description": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "city": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "state": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "logo_url": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uri"
                    },
                    "is_member": {
                        "type": "boolean",
                        "description": "Agência membro da Lista de Agências (selo pago de destaque). Não tem relação com entidades do setor."
                    },
                    "url": {
                        "type": "string",
                        "format": "uri"
                    },
                    "services": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/AgencyService"
                        }
                    },
                    "platforms": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/AgencyPlatform"
                        }
                    },
                    "associations": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/AgencyAssociation"
                        }
                    },
                    "website": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uri"
                    },
                    "linkedin": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uri"
                    },
                    "instagram": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uri"
                    }
                },
                "required": [
                    "slug",
                    "name",
                    "city",
                    "state",
                    "logo_url",
                    "is_member",
                    "url",
                    "services",
                    "platforms",
                    "associations",
                    "website",
                    "linkedin",
                    "instagram"
                ]
            },
            "PaginationMeta": {
                "type": "object",
                "properties": {
                    "total": {
                        "type": "integer",
                        "example": 214
                    },
                    "page": {
                        "type": "integer",
                        "example": 1
                    },
                    "per_page": {
                        "type": "integer",
                        "example": 24
                    },
                    "last_page": {
                        "type": "integer",
                        "example": 9
                    }
                },
                "required": [
                    "total",
                    "page",
                    "per_page",
                    "last_page"
                ]
            },
            "PaginationLinks": {
                "type": "object",
                "properties": {
                    "next": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uri"
                    },
                    "prev": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uri"
                    }
                },
                "required": [
                    "next",
                    "prev"
                ]
            },
            "AgencyListResponse": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "array",
                        "items": {
                            "oneOf": [
                                {
                                    "$ref": "#/components/schemas/Agency"
                                },
                                {
                                    "$ref": "#/components/schemas/AgencyRestricted"
                                }
                            ]
                        }
                    },
                    "meta": {
                        "$ref": "#/components/schemas/PaginationMeta"
                    },
                    "links": {
                        "$ref": "#/components/schemas/PaginationLinks"
                    }
                },
                "required": [
                    "data",
                    "meta",
                    "links"
                ]
            },
            "Service": {
                "type": "object",
                "description": "Só dado público: sem conteúdo completo nem perguntas frequentes (ver ServiceDetail).",
                "properties": {
                    "name": {
                        "type": "string",
                        "example": "Otimização de SEO"
                    },
                    "slug": {
                        "type": "string",
                        "example": "otimizacao-de-seo"
                    },
                    "category": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Slug da categoria.",
                        "example": "gestao-de-marca"
                    },
                    "summary": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "url": {
                        "type": "string",
                        "format": "uri",
                        "example": "https://listadeagencias.com.br/servicos/gestao-de-marca/otimizacao-de-seo"
                    },
                    "markdown_url": {
                        "type": "string",
                        "format": "uri",
                        "example": "https://listadeagencias.com.br/servicos/gestao-de-marca/otimizacao-de-seo.md"
                    },
                    "agency_count": {
                        "type": "integer",
                        "example": 38
                    }
                },
                "required": [
                    "name",
                    "slug",
                    "category",
                    "summary",
                    "url",
                    "markdown_url",
                    "agency_count"
                ]
            },
            "ServiceFaqItem": {
                "type": "object",
                "properties": {
                    "question": {
                        "type": "string"
                    },
                    "answer": {
                        "type": "string"
                    }
                }
            },
            "ServiceDetail": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/Service"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "body_markdown": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "description": "Conteúdo completo da página do serviço, em Markdown."
                            },
                            "faq": {
                                "type": "array",
                                "items": {
                                    "$ref": "#/components/schemas/ServiceFaqItem"
                                }
                            }
                        }
                    }
                ]
            },
            "Category": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string",
                        "example": "Gestão de Marca"
                    },
                    "slug": {
                        "type": "string",
                        "example": "gestao-de-marca"
                    },
                    "summary": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "url": {
                        "type": "string",
                        "format": "uri"
                    },
                    "markdown_url": {
                        "type": "string",
                        "format": "uri"
                    },
                    "agency_count": {
                        "type": "integer",
                        "example": 96
                    }
                },
                "required": [
                    "name",
                    "slug",
                    "summary",
                    "url",
                    "markdown_url",
                    "agency_count"
                ]
            },
            "State": {
                "type": "object",
                "properties": {
                    "uf": {
                        "type": "string",
                        "example": "SP"
                    },
                    "name": {
                        "type": "string",
                        "example": "São Paulo"
                    },
                    "agency_count": {
                        "type": "integer",
                        "example": 84
                    }
                },
                "required": [
                    "uf",
                    "name",
                    "agency_count"
                ]
            },
            "QuoteRequestInput": {
                "type": "object",
                "description": "Origem `api`: serviços e agência preferida por slug (não por id).",
                "properties": {
                    "company_name": {
                        "type": "string",
                        "maxLength": 160
                    },
                    "contact_name": {
                        "type": "string",
                        "maxLength": 120
                    },
                    "email": {
                        "type": "string",
                        "format": "email",
                        "maxLength": 190
                    },
                    "phone": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "maxLength": 40
                    },
                    "description": {
                        "type": "string",
                        "minLength": 30,
                        "maxLength": 5000
                    },
                    "services": {
                        "type": "array",
                        "minItems": 1,
                        "maxItems": 20,
                        "items": {
                            "type": "string"
                        },
                        "example": [
                            "otimizacao-de-seo",
                            "gestao-de-midias-sociais"
                        ]
                    },
                    "budget_range": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "enum": [
                            "ate-10k",
                            "10-30k",
                            "30-100k",
                            "acima-100k",
                            "nao-sei",
                            null
                        ]
                    },
                    "deadline": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "enum": [
                            "imediato",
                            "1-3m",
                            "3-6m",
                            "sem-pressa",
                            null
                        ]
                    },
                    "company_size": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "enum": [
                            "1-10",
                            "11-50",
                            "51-200",
                            "201-1000",
                            "acima-1000",
                            null
                        ]
                    },
                    "state": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "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",
                            null
                        ]
                    },
                    "city": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "maxLength": 120
                    },
                    "preferred_agency": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Slug de uma agência publicada e membro do diretório. Um slug de agência publicada que não é membro é rejeitado com 422 (mesmo erro de uma agência inexistente ou despublicada).",
                        "example": "beta-lab"
                    },
                    "accept": {
                        "type": "boolean",
                        "description": "Consentimento para encaminhar os dados a agências membro. Precisa ser `true`.",
                        "example": true
                    }
                },
                "required": [
                    "company_name",
                    "contact_name",
                    "email",
                    "description",
                    "services",
                    "accept"
                ]
            },
            "QuoteRequestAccepted": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer",
                        "example": 501
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "pending_verification",
                            "confirmed"
                        ]
                    },
                    "message": {
                        "type": "string"
                    }
                },
                "required": [
                    "id",
                    "status",
                    "message"
                ]
            }
        }
    }
}