{
    "openapi": "3.1.0",
    "info": {
        "title": "Servicio Técnico Gran Canaria - API de contenido",
        "summary": "Consulta de solo lectura del contenido publicado de serviciotecnicograncanaria.es.",
        "description": "API pública de solo lectura sobre el contenido publicado de serviciotecnicograncanaria.es (Servicio Técnico Gran Canaria). Servicio Técnico Gran Canaria atiende las 24 horas, todos los días, solicitudes de servicio técnico de electrodomésticos y del hogar en Las Palmas de Gran Canaria y el resto de Gran Canaria. Cada reparación la hace un técnico independiente de Gran Canaria, que no es el servicio técnico oficial de ninguna marca. Antes de empezar dice su nombre y da el presupuesto por escrito; cuando termina, factura directamente y responde de la garantía. Servicio Técnico Gran Canaria atiende y orienta; el trabajo lo presupuesta, hace, factura y garantiza el profesional. Quién hace cada trabajo: en los aparatos, un técnico independiente; en mudanzas, una empresa de mudanzas; en plagas, una empresa de control de plagas; en el boletín eléctrico, una empresa instaladora en baja tensión; en reformas, una empresa de reformas, y en los demás oficios, un profesional de ese oficio. Cada uno presupuesta, factura y responde de su parte. Cada reparación la hace un técnico independiente de Gran Canaria, que no es el servicio técnico oficial de ninguna marca. Antes de empezar dice su nombre y da el presupuesto por escrito; cuando termina, factura directamente y responde de la garantía.\n\nSirve para: localizar la página que trata un servicio, un problema o una zona (search_pages, con el texto en el parámetro query), leer su texto en Markdown (read_page) y saber cómo funciona el servicio, cómo pedirlo y qué servicios y zonas tienen página (get_company_info).\n\nEjemplo: GET https://serviciotecnicograncanaria.es/wp-json/agentes/v1/search_pages?query=lavadora\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. El alta automática (POST https://serviciotecnicograncanaria.es/oauth/register, sin aprobación humana) sube la cuota de 60 a 600 peticiones por minuto y da acceso a /quota.\n\nGetting started (English): no API key is needed to read. Self-serve API keys: POST https://serviciotecnicograncanaria.es/oauth/register returns a client_id and client_secret instantly, with no human approval or sales contact; exchange them at https://serviciotecnicograncanaria.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://serviciotecnicograncanaria.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://serviciotecnicograncanaria.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: la lectura no exige claves ni registro, 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://serviciotecnicograncanaria.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://serviciotecnicograncanaria.es/desarrolladores/#versionado\n\nLas mismas operaciones están disponibles como herramientas MCP en POST https://serviciotecnicograncanaria.es/mcp.",
        "version": "1.0.0",
        "contact": {
            "name": "Servicio Técnico Gran Canaria",
            "url": "https://serviciotecnicograncanaria.es/contacto/"
        },
        "x-api-lifecycle": {
            "version": "v1",
            "deprecation_policy": "https://serviciotecnicograncanaria.es/desarrolladores/#versionado",
            "minimum_notice_days": 90,
            "signals": [
                "Deprecation (RFC 9745)",
                "Sunset (RFC 8594)",
                "Link rel=deprecation"
            ],
            "deprecated_versions": []
        },
        "x-sandbox": {
            "url": "https://serviciotecnicograncanaria.es/api/sandbox",
            "required": false,
            "note": "Read-only API: production is safe to test against."
        }
    },
    "servers": [
        {
            "url": "https://serviciotecnicograncanaria.es/wp-json/agentes/v1",
            "description": "Producción"
        }
    ],
    "externalDocs": {
        "description": "Documentación para desarrolladores y agentes",
        "url": "https://serviciotecnicograncanaria.es/desarrolladores/"
    },
    "tags": [
        {
            "name": "contenido",
            "description": "Lectura del contenido publicado: búsqueda, páginas, servicios y zonas, y cómo funciona el servicio. 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 Servicio Técnico Gran Canaria por servicio, problema o zona de Gran Canaria y devuelve las URL 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"
                                                    },
                                                    "excerpt": {
                                                        "type": "string"
                                                    }
                                                },
                                                "required": [
                                                    "title",
                                                    "url",
                                                    "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 \"lavadora\". Funciona mejor con el servicio, el problema o la zona que con frases largas.",
                        "schema": {
                            "type": "string",
                            "minLength": 2,
                            "maxLength": 200
                        }
                    },
                    {
                        "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 Servicio Técnico Gran Canaria, convertido a Markdown y sin menús, pie ni llamadas a la acción. 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://serviciotecnicograncanaria.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": "Cómo funciona el servicio, servicios y zonas",
                "description": "Qué atiende Servicio Técnico Gran Canaria, su horario de atención y su cobertura, cómo pedir un servicio, el modelo de servicio (quién hace, presupuesta, factura y garantiza el trabajo), los impuestos, la nota de precios y la lista de servicios y zonas con su URL. Úsalo para explicar al usuario cómo funciona el servicio y cómo pedirlo. 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"
                                        },
                                        "website": {
                                            "type": "string"
                                        },
                                        "description": {
                                            "type": "string"
                                        },
                                        "hours": {
                                            "type": "string"
                                        },
                                        "coverage": {
                                            "type": "string"
                                        },
                                        "how_to_ask": {
                                            "type": "string",
                                            "description": "Cómo se pide un servicio. Este sitio no publica teléfono ni correo en estos datos."
                                        },
                                        "contact_page": {
                                            "type": "string"
                                        },
                                        "legal_notice": {
                                            "type": "string",
                                            "description": "Aviso legal, con los datos del titular."
                                        },
                                        "tax": {
                                            "type": "string"
                                        },
                                        "prices": {
                                            "type": "string"
                                        },
                                        "prices_page": {
                                            "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"
                                                ]
                                            }
                                        },
                                        "areas": {
                                            "type": "array",
                                            "items": {
                                                "type": "object",
                                                "properties": {
                                                    "name": {
                                                        "type": "string"
                                                    },
                                                    "url": {
                                                        "type": "string"
                                                    }
                                                },
                                                "required": [
                                                    "name",
                                                    "url"
                                                ]
                                            },
                                            "description": "Zonas de Gran Canaria con página propia."
                                        },
                                        "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 (cómo pedir un servicio y horario), service_model (cómo funciona el servicio, precios e impuestos), coverage (zonas 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": {
        "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"
                ]
            }
        },
        "securitySchemes": {
            "oauth2": {
                "type": "oauth2",
                "description": "OAuth 2.0 con client_credentials. Alta automática (RFC 7591), sin aprobación humana: POST https://serviciotecnicograncanaria.es/oauth/register. Identificarse no abre contenido nuevo: sube la cuota de 60 a 600 peticiones por minuto. Metadatos en https://serviciotecnicograncanaria.es/.well-known/oauth-authorization-server.",
                "flows": {
                    "clientCredentials": {
                        "tokenUrl": "https://serviciotecnicograncanaria.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."
                        }
                    }
                }
            }
        }
    }
}