{
    "openapi": "3.1.0",
    "info": {
        "title": "MULTI DIRECT - API de contenido",
        "summary": "Consulta de solo lectura del contenido publicado de multidirect.es.",
        "description": "API pública de solo lectura sobre el contenido publicado de multidirect.es (MULTI DIRECT, marca de Rapid Services Enterprise, S.L.). MULTI DIRECT, marca de Rapid Services Enterprise, S.L., gestiona solicitudes de reparaciones, reformas y servicios técnicos para hogares, comunidades y negocios en 21 ciudades e islas de España y las pasa a una amplia red de profesionales colaboradores. MULTI DIRECT recibe la solicitud, entiende qué se necesita y la pasa a un profesional colaborador de su red, del oficio adecuado y de la provincia. MULTI DIRECT no hace los trabajos con técnicos propios, no dirige ni supervisa la obra y no es parte del contrato entre el cliente y el profesional.\n\nSirve para: localizar la página que trata un servicio o un problema (search_pages, con el texto en el parámetro query), leer su texto en Markdown (read_page) y obtener los datos de la empresa, cómo contactar y el catálogo de servicios y ciudades (get_company_info).\n\nEjemplo: GET https://multidirect.es/wp-json/agentes/v1/search_pages?query=fontanero%20Madrid\n\nNO sirve para reservar, contratar ni pagar: no hay ninguna operación de escritura y el sitio no vende en línea.\n\nAutenticación: opcional. Todas las operaciones de contenido responden igual sin token. Registrarse (POST https://multidirect.es/oauth/register, automático y gratuito) sube la cuota de 60 a 600 peticiones por minuto y da acceso a /quota.\n\nGetting started (English): free to use, no paid plans and no trial that expires. No API key is needed to read. Self-serve API keys: POST https://multidirect.es/oauth/register returns a client_id and client_secret instantly, with no human approval or sales contact; exchange them at https://multidirect.es/oauth/token (client_credentials) for a higher rate limit. Sandbox: the API is read-only, so production is safe to test against and doubles as the sandbox (https://multidirect.es/api/sandbox).\n\nDeprecation and sunset policy (English): this is v1, in the path and in the API-Version header. Backward-compatible changes ship within v1; breaking changes ship as v2, and v1 keeps working for at least 90 days after its deprecation is announced with the Deprecation (RFC 9745) and Sunset (RFC 8594) headers. Policy: https://multidirect.es/desarrolladores/#versionado\n\nCuota: cada respuesta trae RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, RateLimit y RateLimit-Policy; un 429 añade Retry-After.\n\nEmpezar: es gratis, la lectura funciona sin claves, las claves son de autoservicio (sin aprobación humana ni ventas) y no hay sandbox aparte porque la API es de solo lectura: producción es inocua de probar (https://multidirect.es/api/sandbox).\n\nVersionado y retirada (deprecation and sunset policy): esta es la v1, en la ruta y en la cabecera API-Version. Los cambios compatibles entran en v1; los incompatibles salen como v2 y v1 sigue viva al menos 90 días tras anunciar su retirada, con las cabeceras Deprecation (RFC 9745) y Sunset (RFC 8594). Política: https://multidirect.es/desarrolladores/#versionado\n\nLas mismas operaciones están disponibles como herramientas MCP en POST https://multidirect.es/mcp.",
        "version": "1.0.0",
        "contact": {
            "name": "MULTI DIRECT",
            "url": "https://multidirect.es/contacto/",
            "email": "info@rapidservicesenterprise.com"
        },
        "x-api-lifecycle": {
            "version": "v1",
            "deprecation_policy": "https://multidirect.es/desarrolladores/#versionado",
            "minimum_notice_days": 90,
            "signals": [
                "Deprecation (RFC 9745)",
                "Sunset (RFC 8594)",
                "Link rel=deprecation"
            ],
            "deprecated_versions": []
        },
        "x-sandbox": {
            "url": "https://multidirect.es/api/sandbox",
            "required": false,
            "note": "Read-only API: production is safe to test against."
        }
    },
    "servers": [
        {
            "url": "https://multidirect.es/wp-json/agentes/v1",
            "description": "Producción"
        }
    ],
    "externalDocs": {
        "description": "Documentación para desarrolladores y agentes",
        "url": "https://multidirect.es/desarrolladores/"
    },
    "tags": [
        {
            "name": "contenido",
            "description": "Lectura del contenido publicado: búsqueda, páginas, catálogo y datos de la empresa. No exige token."
        },
        {
            "name": "cuenta",
            "description": "Estado del cliente identificado. Exige token."
        }
    ],
    "security": [
        {},
        {
            "oauth2": [
                "content:read"
            ]
        }
    ],
    "paths": {
        "/search_pages": {
            "get": {
                "operationId": "search_pages",
                "summary": "Buscar páginas del sitio",
                "description": "Busca en las páginas publicadas de MULTI DIRECT por servicio, problema o ciudad y devuelve las URLs más relevantes con un extracto. Es el punto de entrada normal: pasa después la URL a read_page. Si hay más resultados, la respuesta trae next_cursor para pedir la página siguiente.",
                "tags": [
                    "contenido"
                ],
                "security": [
                    {},
                    {
                        "oauth2": [
                            "content:read"
                        ]
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Resultado de la operación.",
                        "headers": {
                            "RateLimit": {
                                "description": "Campo estructurado del borrador del IETF: r = peticiones que quedan, t = segundos hasta el reinicio.",
                                "schema": {
                                    "type": "string",
                                    "examples": [
                                        "\"anonimo\";r=57;t=34"
                                    ]
                                }
                            },
                            "RateLimit-Policy": {
                                "description": "La política aplicada: q = cuota por ventana, w = ventana en segundos.",
                                "schema": {
                                    "type": "string",
                                    "examples": [
                                        "\"anonimo\";q=60;w=60"
                                    ]
                                }
                            },
                            "RateLimit-Limit": {
                                "description": "Peticiones admitidas en la ventana (forma clásica).",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "RateLimit-Remaining": {
                                "description": "Peticiones que quedan en la ventana en curso.",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "RateLimit-Reset": {
                                "description": "Segundos que faltan para que el contador vuelva a empezar.",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "API-Version": {
                                "description": "Versión mayor de la API que ha respondido.",
                                "schema": {
                                    "type": "string",
                                    "examples": [
                                        "1"
                                    ]
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "total": {
                                            "type": "integer",
                                            "description": "Resultados en esta página."
                                        },
                                        "results": {
                                            "type": "array",
                                            "items": {
                                                "type": "object",
                                                "properties": {
                                                    "title": {
                                                        "type": "string"
                                                    },
                                                    "url": {
                                                        "type": "string"
                                                    },
                                                    "city": {
                                                        "type": "string",
                                                        "description": "Slug de la ciudad de la página; vacío si es general."
                                                    },
                                                    "excerpt": {
                                                        "type": "string"
                                                    }
                                                },
                                                "required": [
                                                    "title",
                                                    "url",
                                                    "city",
                                                    "excerpt"
                                                ]
                                            }
                                        },
                                        "next_cursor": {
                                            "type": [
                                                "string",
                                                "null"
                                            ],
                                            "description": "Para pedir la página siguiente; null si no hay más resultados."
                                        }
                                    },
                                    "required": [
                                        "total",
                                        "results",
                                        "next_cursor"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Parámetros inválidos; data.hint dice cuál.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Se ha mandado un bearer token que no vale o ha caducado. Sin token, la operación responde 200.",
                        "headers": {
                            "WWW-Authenticate": {
                                "description": "Lleva resource_metadata con la URL de los metadatos del recurso (RFC 9728).",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Operación o página inexistente.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Cuota agotada. Espera lo que diga Retry-After.",
                        "headers": {
                            "RateLimit": {
                                "description": "Campo estructurado del borrador del IETF: r = peticiones que quedan, t = segundos hasta el reinicio.",
                                "schema": {
                                    "type": "string",
                                    "examples": [
                                        "\"anonimo\";r=57;t=34"
                                    ]
                                }
                            },
                            "RateLimit-Policy": {
                                "description": "La política aplicada: q = cuota por ventana, w = ventana en segundos.",
                                "schema": {
                                    "type": "string",
                                    "examples": [
                                        "\"anonimo\";q=60;w=60"
                                    ]
                                }
                            },
                            "RateLimit-Limit": {
                                "description": "Peticiones admitidas en la ventana (forma clásica).",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "RateLimit-Remaining": {
                                "description": "Peticiones que quedan en la ventana en curso.",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "RateLimit-Reset": {
                                "description": "Segundos que faltan para que el contador vuelva a empezar.",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "API-Version": {
                                "description": "Versión mayor de la API que ha respondido.",
                                "schema": {
                                    "type": "string",
                                    "examples": [
                                        "1"
                                    ]
                                }
                            },
                            "Retry-After": {
                                "description": "Segundos que hay que esperar antes de volver a intentarlo.",
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "500": {
                        "description": "Error interno.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "query",
                        "in": "query",
                        "required": true,
                        "description": "Texto en español, por ejemplo \"fontanero Madrid\". Funciona mejor con el servicio o el problema concreto que con frases largas.",
                        "schema": {
                            "type": "string",
                            "minLength": 2,
                            "maxLength": 200
                        }
                    },
                    {
                        "name": "city",
                        "in": "query",
                        "required": false,
                        "description": "Ciudad por su slug, el que aparece en las URLs (por ejemplo \"madrid\"), o \"todas\" para no filtrar. Por defecto, todas.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "tenerife",
                                "las-palmas",
                                "mallorca",
                                "madrid",
                                "barcelona",
                                "valencia",
                                "sevilla",
                                "malaga",
                                "bilbao",
                                "murcia",
                                "zaragoza",
                                "alicante",
                                "valladolid",
                                "cordoba",
                                "vigo",
                                "gijon",
                                "a-coruna",
                                "elche",
                                "granada",
                                "oviedo",
                                "pamplona",
                                "todas"
                            ]
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "description": "Resultados por página, de 1 a 25. Por defecto, 8.",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 25
                        }
                    },
                    {
                        "name": "cursor",
                        "in": "query",
                        "required": false,
                        "description": "El next_cursor de la respuesta anterior, para pedir la página siguiente de resultados.",
                        "schema": {
                            "type": "string",
                            "maxLength": 12
                        }
                    }
                ]
            }
        },
        "/read_page": {
            "get": {
                "operationId": "read_page",
                "summary": "Leer una página en Markdown",
                "description": "Devuelve el texto completo de una página publicada de MULTI DIRECT, convertido a Markdown y sin menús ni pie. Acepta la URL completa, la ruta o el slug.",
                "tags": [
                    "contenido"
                ],
                "security": [
                    {},
                    {
                        "oauth2": [
                            "content:read"
                        ]
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Resultado de la operación.",
                        "headers": {
                            "RateLimit": {
                                "description": "Campo estructurado del borrador del IETF: r = peticiones que quedan, t = segundos hasta el reinicio.",
                                "schema": {
                                    "type": "string",
                                    "examples": [
                                        "\"anonimo\";r=57;t=34"
                                    ]
                                }
                            },
                            "RateLimit-Policy": {
                                "description": "La política aplicada: q = cuota por ventana, w = ventana en segundos.",
                                "schema": {
                                    "type": "string",
                                    "examples": [
                                        "\"anonimo\";q=60;w=60"
                                    ]
                                }
                            },
                            "RateLimit-Limit": {
                                "description": "Peticiones admitidas en la ventana (forma clásica).",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "RateLimit-Remaining": {
                                "description": "Peticiones que quedan en la ventana en curso.",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "RateLimit-Reset": {
                                "description": "Segundos que faltan para que el contador vuelva a empezar.",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "API-Version": {
                                "description": "Versión mayor de la API que ha respondido.",
                                "schema": {
                                    "type": "string",
                                    "examples": [
                                        "1"
                                    ]
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "title": {
                                            "type": "string"
                                        },
                                        "url": {
                                            "type": "string"
                                        },
                                        "markdown": {
                                            "type": "string"
                                        },
                                        "truncated": {
                                            "type": "boolean"
                                        }
                                    },
                                    "required": [
                                        "title",
                                        "url",
                                        "markdown",
                                        "truncated"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Parámetros inválidos; data.hint dice cuál.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Se ha mandado un bearer token que no vale o ha caducado. Sin token, la operación responde 200.",
                        "headers": {
                            "WWW-Authenticate": {
                                "description": "Lleva resource_metadata con la URL de los metadatos del recurso (RFC 9728).",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Operación o página inexistente.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Cuota agotada. Espera lo que diga Retry-After.",
                        "headers": {
                            "RateLimit": {
                                "description": "Campo estructurado del borrador del IETF: r = peticiones que quedan, t = segundos hasta el reinicio.",
                                "schema": {
                                    "type": "string",
                                    "examples": [
                                        "\"anonimo\";r=57;t=34"
                                    ]
                                }
                            },
                            "RateLimit-Policy": {
                                "description": "La política aplicada: q = cuota por ventana, w = ventana en segundos.",
                                "schema": {
                                    "type": "string",
                                    "examples": [
                                        "\"anonimo\";q=60;w=60"
                                    ]
                                }
                            },
                            "RateLimit-Limit": {
                                "description": "Peticiones admitidas en la ventana (forma clásica).",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "RateLimit-Remaining": {
                                "description": "Peticiones que quedan en la ventana en curso.",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "RateLimit-Reset": {
                                "description": "Segundos que faltan para que el contador vuelva a empezar.",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "API-Version": {
                                "description": "Versión mayor de la API que ha respondido.",
                                "schema": {
                                    "type": "string",
                                    "examples": [
                                        "1"
                                    ]
                                }
                            },
                            "Retry-After": {
                                "description": "Segundos que hay que esperar antes de volver a intentarlo.",
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "500": {
                        "description": "Error interno.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "url",
                        "in": "query",
                        "required": true,
                        "description": "URL completa (https://multidirect.es/contacto/), ruta (/contacto/) o slug (contacto) de una página de este sitio.",
                        "schema": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 300
                        }
                    }
                ]
            }
        },
        "/get_company_info": {
            "get": {
                "operationId": "get_company_info",
                "summary": "Datos de la empresa, servicios y cobertura",
                "description": "Marca, razón social, NIF, domicilio, contacto y horario de MULTI DIRECT, su modelo de servicio (quién hace, presupuesta, factura y garantiza el trabajo), impuestos, precios orientativos y la lista de servicios y ciudades con sus URLs. Úsalo para verificar quién está detrás del sitio o para decirle al usuario cómo pedir un servicio. Con section se pide solo una parte.",
                "tags": [
                    "contenido"
                ],
                "security": [
                    {},
                    {
                        "oauth2": [
                            "content:read"
                        ]
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Resultado de la operación.",
                        "headers": {
                            "RateLimit": {
                                "description": "Campo estructurado del borrador del IETF: r = peticiones que quedan, t = segundos hasta el reinicio.",
                                "schema": {
                                    "type": "string",
                                    "examples": [
                                        "\"anonimo\";r=57;t=34"
                                    ]
                                }
                            },
                            "RateLimit-Policy": {
                                "description": "La política aplicada: q = cuota por ventana, w = ventana en segundos.",
                                "schema": {
                                    "type": "string",
                                    "examples": [
                                        "\"anonimo\";q=60;w=60"
                                    ]
                                }
                            },
                            "RateLimit-Limit": {
                                "description": "Peticiones admitidas en la ventana (forma clásica).",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "RateLimit-Remaining": {
                                "description": "Peticiones que quedan en la ventana en curso.",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "RateLimit-Reset": {
                                "description": "Segundos que faltan para que el contador vuelva a empezar.",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "API-Version": {
                                "description": "Versión mayor de la API que ha respondido.",
                                "schema": {
                                    "type": "string",
                                    "examples": [
                                        "1"
                                    ]
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "brand": {
                                            "type": "string"
                                        },
                                        "legal_name": {
                                            "type": "string"
                                        },
                                        "tax_id": {
                                            "type": "string",
                                            "description": "NIF de la sociedad."
                                        },
                                        "address": {
                                            "type": "string"
                                        },
                                        "phone": {
                                            "type": "string",
                                            "description": "Vacío si el sitio no publica teléfono."
                                        },
                                        "email": {
                                            "type": "string"
                                        },
                                        "whatsapp": {
                                            "type": "string",
                                            "description": "Vacío si el sitio no publica WhatsApp."
                                        },
                                        "hours": {
                                            "type": "string"
                                        },
                                        "website": {
                                            "type": "string"
                                        },
                                        "coverage": {
                                            "type": "string"
                                        },
                                        "tax": {
                                            "type": "string"
                                        },
                                        "prices": {
                                            "type": "string"
                                        },
                                        "service_model": {
                                            "type": "object",
                                            "properties": {
                                                "description": {
                                                    "type": "string"
                                                },
                                                "performed_by": {
                                                    "type": "string"
                                                },
                                                "quoted_by": {
                                                    "type": "string"
                                                },
                                                "invoiced_by": {
                                                    "type": "string"
                                                },
                                                "warranty": {
                                                    "type": "string"
                                                },
                                                "online_booking": {
                                                    "type": "boolean",
                                                    "description": "false: no se contrata ni se paga en línea desde este sitio."
                                                }
                                            },
                                            "required": [
                                                "description",
                                                "online_booking"
                                            ]
                                        },
                                        "services": {
                                            "type": "array",
                                            "items": {
                                                "type": "object",
                                                "properties": {
                                                    "name": {
                                                        "type": "string"
                                                    },
                                                    "url": {
                                                        "type": "string"
                                                    }
                                                },
                                                "required": [
                                                    "name",
                                                    "url"
                                                ]
                                            }
                                        },
                                        "cities": {
                                            "type": "array",
                                            "items": {
                                                "type": "object",
                                                "properties": {
                                                    "slug": {
                                                        "type": "string"
                                                    },
                                                    "name": {
                                                        "type": "string"
                                                    },
                                                    "url": {
                                                        "type": "string"
                                                    }
                                                },
                                                "required": [
                                                    "slug",
                                                    "name",
                                                    "url"
                                                ]
                                            }
                                        },
                                        "pages": {
                                            "type": "object",
                                            "additionalProperties": {
                                                "type": "string"
                                            }
                                        }
                                    },
                                    "required": [
                                        "brand",
                                        "website"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Parámetros inválidos; data.hint dice cuál.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Se ha mandado un bearer token que no vale o ha caducado. Sin token, la operación responde 200.",
                        "headers": {
                            "WWW-Authenticate": {
                                "description": "Lleva resource_metadata con la URL de los metadatos del recurso (RFC 9728).",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Operación o página inexistente.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Cuota agotada. Espera lo que diga Retry-After.",
                        "headers": {
                            "RateLimit": {
                                "description": "Campo estructurado del borrador del IETF: r = peticiones que quedan, t = segundos hasta el reinicio.",
                                "schema": {
                                    "type": "string",
                                    "examples": [
                                        "\"anonimo\";r=57;t=34"
                                    ]
                                }
                            },
                            "RateLimit-Policy": {
                                "description": "La política aplicada: q = cuota por ventana, w = ventana en segundos.",
                                "schema": {
                                    "type": "string",
                                    "examples": [
                                        "\"anonimo\";q=60;w=60"
                                    ]
                                }
                            },
                            "RateLimit-Limit": {
                                "description": "Peticiones admitidas en la ventana (forma clásica).",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "RateLimit-Remaining": {
                                "description": "Peticiones que quedan en la ventana en curso.",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "RateLimit-Reset": {
                                "description": "Segundos que faltan para que el contador vuelva a empezar.",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "API-Version": {
                                "description": "Versión mayor de la API que ha respondido.",
                                "schema": {
                                    "type": "string",
                                    "examples": [
                                        "1"
                                    ]
                                }
                            },
                            "Retry-After": {
                                "description": "Segundos que hay que esperar antes de volver a intentarlo.",
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "500": {
                        "description": "Error interno.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "section",
                        "in": "query",
                        "required": false,
                        "description": "Qué parte devolver: all (todo, por defecto), contact (contacto y horario), service_model (cómo funciona el servicio, precios e impuestos), coverage (ciudades con su URL) o services (servicios con su URL).",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "all",
                                "contact",
                                "service_model",
                                "coverage",
                                "services"
                            ]
                        }
                    }
                ]
            }
        },
        "/quota": {
            "get": {
                "operationId": "get_quota",
                "summary": "Cuota del cliente identificado",
                "description": "Devuelve la cuota del cliente identificado: política, límite por minuto, peticiones consumidas y segundos hasta el reinicio. Es la única operación que exige token (scope quota:read).",
                "tags": [
                    "cuenta"
                ],
                "security": [
                    {
                        "oauth2": [
                            "quota:read"
                        ]
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Cuota del cliente identificado.",
                        "headers": {
                            "RateLimit": {
                                "description": "Campo estructurado del borrador del IETF: r = peticiones que quedan, t = segundos hasta el reinicio.",
                                "schema": {
                                    "type": "string",
                                    "examples": [
                                        "\"anonimo\";r=57;t=34"
                                    ]
                                }
                            },
                            "RateLimit-Policy": {
                                "description": "La política aplicada: q = cuota por ventana, w = ventana en segundos.",
                                "schema": {
                                    "type": "string",
                                    "examples": [
                                        "\"anonimo\";q=60;w=60"
                                    ]
                                }
                            },
                            "RateLimit-Limit": {
                                "description": "Peticiones admitidas en la ventana (forma clásica).",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "RateLimit-Remaining": {
                                "description": "Peticiones que quedan en la ventana en curso.",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "RateLimit-Reset": {
                                "description": "Segundos que faltan para que el contador vuelva a empezar.",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "API-Version": {
                                "description": "Versión mayor de la API que ha respondido.",
                                "schema": {
                                    "type": "string",
                                    "examples": [
                                        "1"
                                    ]
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "client_id": {
                                            "type": "string"
                                        },
                                        "scope": {
                                            "type": "string"
                                        },
                                        "policy": {
                                            "type": "string",
                                            "enum": [
                                                "anonimo",
                                                "identificado"
                                            ]
                                        },
                                        "limit": {
                                            "type": "integer",
                                            "description": "Peticiones admitidas por ventana."
                                        },
                                        "window_seconds": {
                                            "type": "integer"
                                        },
                                        "used": {
                                            "type": "integer"
                                        },
                                        "remaining": {
                                            "type": "integer"
                                        },
                                        "reset_seconds": {
                                            "type": "integer"
                                        }
                                    },
                                    "required": [
                                        "client_id",
                                        "policy",
                                        "limit",
                                        "remaining",
                                        "reset_seconds"
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Falta el token o no vale.",
                        "headers": {
                            "WWW-Authenticate": {
                                "description": "Lleva resource_metadata (RFC 9728).",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "El token no tiene el scope quota:read.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Cuota agotada.",
                        "headers": {
                            "RateLimit": {
                                "description": "Campo estructurado del borrador del IETF: r = peticiones que quedan, t = segundos hasta el reinicio.",
                                "schema": {
                                    "type": "string",
                                    "examples": [
                                        "\"anonimo\";r=57;t=34"
                                    ]
                                }
                            },
                            "RateLimit-Policy": {
                                "description": "La política aplicada: q = cuota por ventana, w = ventana en segundos.",
                                "schema": {
                                    "type": "string",
                                    "examples": [
                                        "\"anonimo\";q=60;w=60"
                                    ]
                                }
                            },
                            "RateLimit-Limit": {
                                "description": "Peticiones admitidas en la ventana (forma clásica).",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "RateLimit-Remaining": {
                                "description": "Peticiones que quedan en la ventana en curso.",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "RateLimit-Reset": {
                                "description": "Segundos que faltan para que el contador vuelva a empezar.",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "API-Version": {
                                "description": "Versión mayor de la API que ha respondido.",
                                "schema": {
                                    "type": "string",
                                    "examples": [
                                        "1"
                                    ]
                                }
                            },
                            "Retry-After": {
                                "description": "Segundos que hay que esperar antes de volver a intentarlo.",
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "components": {
        "securitySchemes": {
            "oauth2": {
                "type": "oauth2",
                "description": "OAuth 2.0 con client_credentials. Alta automática y gratuita (RFC 7591): POST https://multidirect.es/oauth/register. Identificarse no abre contenido nuevo: sube la cuota de 60 a 600 peticiones por minuto. Metadatos en https://multidirect.es/.well-known/oauth-authorization-server.",
                "flows": {
                    "clientCredentials": {
                        "tokenUrl": "https://multidirect.es/oauth/token",
                        "scopes": {
                            "content:read": "Leer el contenido publicado con la cuota ampliada. Los mismos datos que la API sirve sin token.",
                            "quota:read": "Consultar la cuota del propio cliente en /wp-json/agentes/v1/quota."
                        }
                    }
                }
            }
        },
        "schemas": {
            "Error": {
                "type": "object",
                "description": "Error estructurado. Siempre JSON, nunca HTML.",
                "properties": {
                    "code": {
                        "type": "string",
                        "description": "Identificador estable del error."
                    },
                    "message": {
                        "type": "string",
                        "description": "Explicación legible de qué ha fallado."
                    },
                    "data": {
                        "type": "object",
                        "properties": {
                            "status": {
                                "type": "integer",
                                "description": "Código HTTP."
                            },
                            "hint": {
                                "type": "string",
                                "description": "Qué hacer para arreglarlo."
                            }
                        },
                        "required": [
                            "status"
                        ]
                    }
                },
                "required": [
                    "code",
                    "message"
                ]
            }
        }
    }
}