{
    "openapi": "3.0.0",
    "info": {
        "title": "Quotes API — Islamic Network",
        "description": "The quotes.islamic.network corpus: each quote is an utterance in one original language plus translations of it, with its author from the shared people registry and its verbatim citation. Every response is wrapped in the `{code, status, data}` envelope shared across Islamic Network APIs; list endpoints add a `meta` sibling. Language keys are BCP 47 tags; empty values are omitted entirely.",
        "contact": {
            "url": "https://islamic.network",
            "email": "hello@islamic.network"
        },
        "version": "1.0.0"
    },
    "servers": [
        {
            "url": "https://quotes.api.islamic.network/v1",
            "description": "Production"
        }
    ],
    "paths": {
        "/documentation/openapi/{format}": {
            "get": {
                "tags": [
                    "documentation"
                ],
                "summary": "This specification, as OpenAPI 3",
                "operationId": "getOpenApiSpec",
                "parameters": [
                    {
                        "name": "format",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "yaml",
                                "json"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The OpenAPI document."
                    }
                }
            }
        },
        "/people/{slug}/quotes": {
            "get": {
                "tags": [
                    "people"
                ],
                "summary": "A person's quotes",
                "description": "The endpoint the People API aggregates. Items are summaries (id, original, source); the full renditions live at /quotes/{id}. `registry` points at the canonical person record on the People API.",
                "operationId": "getPersonQuotes",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/slug"
                    },
                    {
                        "$ref": "#/components/parameters/page"
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The person and their quotes.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "properties": {
                                                "meta": {
                                                    "$ref": "#/components/schemas/Meta"
                                                },
                                                "data": {
                                                    "properties": {
                                                        "person": {
                                                            "$ref": "#/components/schemas/PersonBlock"
                                                        },
                                                        "quotes": {
                                                            "type": "array",
                                                            "items": {
                                                                "$ref": "#/components/schemas/QuoteSummary"
                                                            }
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/Error"
                    }
                }
            }
        },
        "/quotes": {
            "get": {
                "tags": [
                    "quotes"
                ],
                "summary": "All quotes (full entries), legacy-id order",
                "description": "Entries are full — quotes are small, there is nothing to summarize away. Ids are the original quotes.islamic.network numeric ids, preserving URL continuity.",
                "operationId": "listQuotes",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/author"
                    },
                    {
                        "$ref": "#/components/parameters/tag"
                    },
                    {
                        "$ref": "#/components/parameters/lang"
                    },
                    {
                        "$ref": "#/components/parameters/original"
                    },
                    {
                        "$ref": "#/components/parameters/page"
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated quotes.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "properties": {
                                                "meta": {
                                                    "$ref": "#/components/schemas/Meta"
                                                },
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Quote"
                                                    }
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/quotes/random": {
            "get": {
                "tags": [
                    "quotes"
                ],
                "summary": "One random quote — the site's raison d'être",
                "description": "Same shape as /quotes/{id}; accepts the same filters as the list. Served with no-store cache headers — every request draws afresh.",
                "operationId": "getRandomQuote",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/author"
                    },
                    {
                        "$ref": "#/components/parameters/tag"
                    },
                    {
                        "$ref": "#/components/parameters/lang"
                    },
                    {
                        "$ref": "#/components/parameters/original"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A quote from the filtered set.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Quote"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/Error"
                    }
                }
            }
        },
        "/quotes/{id}": {
            "get": {
                "tags": [
                    "quotes"
                ],
                "summary": "Single quote",
                "operationId": "getQuote",
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "description": "The quote's public numeric id.",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The quote.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/Quote"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/Error"
                    }
                }
            }
        },
        "/search": {
            "get": {
                "tags": [
                    "search"
                ],
                "summary": "Diacritic-folded search across quotes",
                "description": "Matching is diacritic-folded (Ṣ→s, ā→a, ʿ/ʾ dropped, Arabic tashkīl stripped) across the original text, every translation, sources and tags — `bistami`, `Bisṭāmī` and `الْبِسْطَامِي` all match. Multiple query words AND together.",
                "operationId": "search",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "description": "The query; at least 2 characters.",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "example": "remembrance",
                            "minLength": 2
                        }
                    },
                    {
                        "$ref": "#/components/parameters/page"
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Matching quotes as summaries with the field paths that matched.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "properties": {
                                                "meta": {
                                                    "$ref": "#/components/schemas/Meta"
                                                },
                                                "data": {
                                                    "properties": {
                                                        "query": {
                                                            "type": "string"
                                                        },
                                                        "total": {
                                                            "type": "integer"
                                                        },
                                                        "results": {
                                                            "type": "array",
                                                            "items": {
                                                                "$ref": "#/components/schemas/SearchResult"
                                                            }
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/Error"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "Name": {
                "description": "Language-keyed text. Keys are BCP 47 tags; `ar-Latn` is the transliteration. Only non-empty languages appear.",
                "type": "object",
                "example": {
                    "ar": "بَايَزِيد الْبِسْطَامِي",
                    "ar-Latn": "Bāyazīd al-Bisṭāmī",
                    "en": "Bayazid Bistami"
                },
                "additionalProperties": {
                    "type": "string"
                }
            },
            "Original": {
                "description": "The quote as uttered or written — identity (\"this is the source\"), unlike translations which carry provenance (\"this is how the copy was made\").",
                "required": [
                    "language",
                    "text"
                ],
                "properties": {
                    "language": {
                        "description": "BCP 47 tag.",
                        "type": "string",
                        "example": "en"
                    },
                    "text": {
                        "type": "string"
                    }
                },
                "type": "object"
            },
            "Translations": {
                "description": "Renditions keyed by BCP 47 tag; the original never appears here. Adding a language is a translation row in the CMS — it appears additively.",
                "type": "object",
                "additionalProperties": {
                    "required": [
                        "text"
                    ],
                    "properties": {
                        "text": {
                            "type": "string"
                        },
                        "provenance": {
                            "description": "How the rendition was produced; omitted when unknown.",
                            "type": "string",
                            "example": "claude-retranslation-from-en"
                        }
                    },
                    "type": "object"
                }
            },
            "Author": {
                "description": "The author from the shared people registry; omitted for anonymous and scriptural quotes — the verbatim citation always survives in `source`.",
                "required": [
                    "slug",
                    "name",
                    "url"
                ],
                "properties": {
                    "slug": {
                        "type": "string",
                        "example": "bayazid-bistami"
                    },
                    "name": {
                        "$ref": "#/components/schemas/Name"
                    },
                    "honorific": {
                        "$ref": "#/components/schemas/Name"
                    },
                    "kind": {
                        "type": "string",
                        "example": "wali"
                    },
                    "url": {
                        "description": "The canonical person record on the People API.",
                        "type": "string"
                    }
                },
                "type": "object"
            },
            "Meta": {
                "description": "Pagination block, sibling of `data` on list endpoints.",
                "required": [
                    "total",
                    "page",
                    "limit",
                    "pages"
                ],
                "properties": {
                    "total": {
                        "type": "integer"
                    },
                    "page": {
                        "type": "integer"
                    },
                    "limit": {
                        "type": "integer"
                    },
                    "pages": {
                        "type": "integer"
                    }
                },
                "type": "object"
            },
            "Envelope": {
                "required": [
                    "code",
                    "status"
                ],
                "properties": {
                    "code": {
                        "type": "integer",
                        "example": 200
                    },
                    "status": {
                        "type": "string",
                        "example": "OK"
                    }
                },
                "type": "object"
            },
            "Quote": {
                "description": "A quote in full — lists, items and /quotes/random all serve this shape.",
                "required": [
                    "id",
                    "url",
                    "original"
                ],
                "properties": {
                    "id": {
                        "description": "The original quotes.islamic.network numeric id, preserving URL continuity.",
                        "type": "integer",
                        "example": 1
                    },
                    "url": {
                        "type": "string"
                    },
                    "original": {
                        "$ref": "#/components/schemas/Original"
                    },
                    "translations": {
                        "$ref": "#/components/schemas/Translations"
                    },
                    "author": {
                        "$ref": "#/components/schemas/Author"
                    },
                    "tags": {
                        "description": "Shared-taxonomy topic slugs; omitted while untagged.",
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "source": {
                        "description": "The citation exactly as authored.",
                        "type": "string",
                        "example": "Bāyazīd Bisṭāmī ق"
                    }
                },
                "type": "object"
            },
            "QuoteSummary": {
                "description": "A person's quote as listed on /people/{slug}/quotes.",
                "required": [
                    "id",
                    "original",
                    "url"
                ],
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "original": {
                        "$ref": "#/components/schemas/Original"
                    },
                    "source": {
                        "type": "string"
                    },
                    "url": {
                        "type": "string"
                    }
                },
                "type": "object"
            },
            "PersonBlock": {
                "required": [
                    "slug",
                    "name",
                    "registry"
                ],
                "properties": {
                    "slug": {
                        "type": "string"
                    },
                    "name": {
                        "$ref": "#/components/schemas/Name"
                    },
                    "honorific": {
                        "$ref": "#/components/schemas/Name"
                    },
                    "kind": {
                        "type": "string"
                    },
                    "registry": {
                        "description": "The canonical person record on the People API.",
                        "type": "string"
                    }
                },
                "type": "object"
            },
            "SearchResult": {
                "required": [
                    "type",
                    "matched_in",
                    "id",
                    "original",
                    "url"
                ],
                "properties": {
                    "type": {
                        "type": "string",
                        "enum": [
                            "quote"
                        ]
                    },
                    "matched_in": {
                        "description": "Rendition paths that matched, e.g. `original.text`, `translations.fa.text`, `source`, `tags`.",
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "id": {
                        "type": "integer"
                    },
                    "original": {
                        "$ref": "#/components/schemas/Original"
                    },
                    "source": {
                        "type": "string"
                    },
                    "url": {
                        "type": "string"
                    }
                },
                "type": "object"
            }
        },
        "responses": {
            "Error": {
                "description": "Error — the envelope with a message string as `data`.",
                "content": {
                    "application/json": {
                        "schema": {
                            "required": [
                                "code",
                                "status",
                                "data"
                            ],
                            "properties": {
                                "code": {
                                    "type": "integer",
                                    "example": 404
                                },
                                "status": {
                                    "type": "string",
                                    "example": "NOT FOUND"
                                },
                                "data": {
                                    "type": "string",
                                    "example": "Quote not found."
                                }
                            },
                            "type": "object"
                        }
                    }
                }
            }
        },
        "parameters": {
            "page": {
                "name": "page",
                "in": "query",
                "description": "Page number (default 1).",
                "schema": {
                    "type": "integer",
                    "default": 1,
                    "minimum": 1
                }
            },
            "limit": {
                "name": "limit",
                "in": "query",
                "description": "Records per page (default 50, max 200).",
                "schema": {
                    "type": "integer",
                    "default": 50,
                    "maximum": 200,
                    "minimum": 1
                }
            },
            "slug": {
                "name": "slug",
                "in": "path",
                "description": "The person's canonical, ecosystem-wide slug.",
                "required": true,
                "schema": {
                    "type": "string"
                }
            },
            "author": {
                "name": "author",
                "in": "query",
                "description": "Only quotes by this person (registry slug).",
                "schema": {
                    "type": "string",
                    "example": "bayazid-bistami"
                }
            },
            "tag": {
                "name": "tag",
                "in": "query",
                "description": "Only quotes carrying this topic tag.",
                "schema": {
                    "type": "string",
                    "example": "knowledge"
                }
            },
            "lang": {
                "name": "lang",
                "in": "query",
                "description": "Only quotes having this rendition (as original or translation).",
                "schema": {
                    "type": "string",
                    "example": "ur"
                }
            },
            "original": {
                "name": "original",
                "in": "query",
                "description": "Only quotes uttered/written in this language.",
                "schema": {
                    "type": "string",
                    "example": "ar"
                }
            }
        }
    },
    "tags": [
        {
            "name": "quotes",
            "description": "The quotes themselves"
        },
        {
            "name": "people",
            "description": "Quotes by author (shared registry slugs)"
        },
        {
            "name": "search",
            "description": "Diacritic-folded search"
        },
        {
            "name": "documentation",
            "description": "This specification"
        }
    ]
}