{
    "openapi": "3.0.0",
    "info": {
        "title": "People API — Islamic Network",
        "description": "The ecosystem's canonical people registry: person slugs minted here are the identifiers referenced by events, quotes, stories and any future service. Each person carries a biography plus sync-time aggregations of what the ecosystem knows about them. 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 (`ar`, `en`, `ur`, …, and `ar-Latn` for transliteration); empty values are omitted entirely. Lists summarize, item endpoints expand.",
        "contact": {
            "url": "https://islamic.network",
            "email": "hello@islamic.network"
        },
        "version": "1.0.0"
    },
    "servers": [
        {
            "url": "https://people.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": {
            "get": {
                "tags": [
                    "people"
                ],
                "summary": "The registry (summaries), slug order",
                "description": "Person slugs minted here are the ecosystem-wide identifiers referenced by events, quotes, stories and any future service.",
                "operationId": "listPeople",
                "parameters": [
                    {
                        "name": "kind",
                        "in": "query",
                        "description": "Only people of one kind. The enum is additive; more values may be introduced.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "prophet",
                                "wali",
                                "family-of-the-prophet",
                                "companion",
                                "scholar",
                                "ruler",
                                "other"
                            ]
                        }
                    },
                    {
                        "$ref": "#/components/parameters/page"
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated person summaries.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "properties": {
                                                "meta": {
                                                    "$ref": "#/components/schemas/Meta"
                                                },
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/PersonSummary"
                                                    }
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/people/{slug}": {
            "get": {
                "tags": [
                    "people"
                ],
                "summary": "Full person: biography + what the ecosystem knows",
                "description": "The aggregation blocks (events, quotes, stories) carry counts, a preview of up to 3 records and the URL of the full list; they are omitted when the ecosystem has nothing. Aggregations are assembled at sync time — one snapshot version, one coherent set of cross-links.",
                "operationId": "getPerson",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/slug"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The person, expanded.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "properties": {
                                                "data": {
                                                    "$ref": "#/components/schemas/PersonDetail"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/Error"
                    }
                }
            }
        },
        "/people/{slug}/events": {
            "get": {
                "tags": [
                    "people"
                ],
                "summary": "The person's full event list",
                "operationId": "getPersonEvents",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/slug"
                    },
                    {
                        "$ref": "#/components/parameters/page"
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The person and their events.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "properties": {
                                                "meta": {
                                                    "$ref": "#/components/schemas/Meta"
                                                },
                                                "data": {
                                                    "properties": {
                                                        "person": {
                                                            "$ref": "#/components/schemas/PersonSummary"
                                                        },
                                                        "events": {
                                                            "type": "array",
                                                            "items": {
                                                                "$ref": "#/components/schemas/EventRef"
                                                            }
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/Error"
                    }
                }
            }
        },
        "/people/{slug}/quotes": {
            "get": {
                "tags": [
                    "people"
                ],
                "summary": "The person's full quote list",
                "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/PersonSummary"
                                                        },
                                                        "quotes": {
                                                            "type": "array",
                                                            "items": {
                                                                "$ref": "#/components/schemas/QuoteRef"
                                                            }
                                                        }
                                                    },
                                                    "type": "object"
                                                }
                                            },
                                            "type": "object"
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/Error"
                    }
                }
            }
        },
        "/search": {
            "get": {
                "tags": [
                    "search"
                ],
                "summary": "Diacritic-folded search across people",
                "description": "Matching is diacritic-folded (Ṣ→s, ā→a, ʿ/ʾ dropped, Arabic tashkīl stripped) across every language key of names, honorifics and biographies — `husayn`, `Ḥusayn` 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": "husayn",
                            "minLength": 2
                        }
                    },
                    {
                        "$ref": "#/components/parameters/page"
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Matching people 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": "Ḥusayn ibn ʿAlī",
                    "en": "Husayn ibn Ali"
                },
                "additionalProperties": {
                    "type": "string"
                }
            },
            "Prose": {
                "description": "Language-keyed prose. `raw` is the authored Markdown; `html` is rendered from it (Arabic-script runs wrapped in `<span lang=\"ar\">`).",
                "type": "object",
                "additionalProperties": {
                    "required": [
                        "raw",
                        "html"
                    ],
                    "properties": {
                        "raw": {
                            "description": "OpenAPI document root and shared components. Endpoint annotations live on\nthe v1 controllers; the assembled spec is served by\nGET /v1/documentation/openapi/{yaml|json}.",
                            "type": "string"
                        },
                        "html": {
                            "type": "string"
                        }
                    },
                    "type": "object"
                }
            },
            "Year": {
                "description": "A year pair; either calendar may be absent (pre-Hijra years have only `gregorian`). Consumers compose lifespan displays (\"4 – 61 AH\") themselves.",
                "properties": {
                    "hijri": {
                        "type": "integer",
                        "example": 61
                    },
                    "gregorian": {
                        "type": "integer",
                        "example": 680
                    }
                },
                "type": "object"
            },
            "Kind": {
                "description": "What kind of person this is. Additive; more values may be introduced.",
                "type": "string",
                "enum": [
                    "prophet",
                    "wali",
                    "family-of-the-prophet",
                    "companion",
                    "scholar",
                    "ruler",
                    "other"
                ]
            },
            "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"
            },
            "PersonSummary": {
                "required": [
                    "slug",
                    "name",
                    "kind",
                    "url"
                ],
                "properties": {
                    "slug": {
                        "type": "string",
                        "example": "husayn-ibn-ali"
                    },
                    "name": {
                        "$ref": "#/components/schemas/Name"
                    },
                    "honorific": {
                        "$ref": "#/components/schemas/Name"
                    },
                    "kind": {
                        "$ref": "#/components/schemas/Kind"
                    },
                    "url": {
                        "type": "string"
                    }
                },
                "type": "object"
            },
            "PersonDetail": {
                "required": [
                    "id",
                    "slug",
                    "url",
                    "name",
                    "kind"
                ],
                "properties": {
                    "id": {
                        "type": "string"
                    },
                    "slug": {
                        "type": "string"
                    },
                    "url": {
                        "type": "string"
                    },
                    "name": {
                        "$ref": "#/components/schemas/Name"
                    },
                    "honorific": {
                        "$ref": "#/components/schemas/Name"
                    },
                    "kind": {
                        "$ref": "#/components/schemas/Kind"
                    },
                    "birth": {
                        "$ref": "#/components/schemas/Year"
                    },
                    "death": {
                        "$ref": "#/components/schemas/Year"
                    },
                    "biography": {
                        "$ref": "#/components/schemas/Prose"
                    },
                    "events": {
                        "description": "Omitted when the ecosystem has none. The url is this API's /people/{slug}/events.",
                        "properties": {
                            "total": {
                                "type": "integer"
                            },
                            "url": {
                                "type": "string"
                            },
                            "preview": {
                                "description": "Up to 3 records.",
                                "type": "array",
                                "items": {
                                    "$ref": "#/components/schemas/EventRef"
                                }
                            }
                        },
                        "type": "object"
                    },
                    "quotes": {
                        "description": "Omitted when the ecosystem has none. The url is this API's /people/{slug}/quotes.",
                        "properties": {
                            "total": {
                                "type": "integer"
                            },
                            "url": {
                                "type": "string"
                            },
                            "preview": {
                                "type": "array",
                                "items": {
                                    "$ref": "#/components/schemas/QuoteRef"
                                }
                            }
                        },
                        "type": "object"
                    },
                    "stories": {
                        "description": "Omitted when the ecosystem has none. The url is the stories API's ?person= filter.",
                        "properties": {
                            "total": {
                                "type": "integer"
                            },
                            "url": {
                                "type": "string"
                            },
                            "preview": {
                                "type": "array",
                                "items": {
                                    "$ref": "#/components/schemas/StoryRef"
                                }
                            }
                        },
                        "type": "object"
                    }
                },
                "type": "object"
            },
            "EventRef": {
                "description": "An event involving the person — the events API's summary shape.",
                "required": [
                    "slug",
                    "title",
                    "date",
                    "url"
                ],
                "properties": {
                    "slug": {
                        "type": "string"
                    },
                    "title": {
                        "$ref": "#/components/schemas/Name"
                    },
                    "date": {
                        "required": [
                            "month",
                            "day"
                        ],
                        "properties": {
                            "month": {
                                "type": "integer",
                                "maximum": 12,
                                "minimum": 1
                            },
                            "day": {
                                "type": "integer",
                                "maximum": 30,
                                "minimum": 1
                            }
                        },
                        "type": "object"
                    },
                    "year": {
                        "$ref": "#/components/schemas/Year"
                    },
                    "url": {
                        "description": "The canonical event on the events API.",
                        "type": "string"
                    }
                },
                "type": "object"
            },
            "QuoteRef": {
                "description": "A quote by the person.",
                "required": [
                    "id",
                    "original",
                    "url"
                ],
                "properties": {
                    "id": {
                        "type": "integer",
                        "example": 91
                    },
                    "original": {
                        "required": [
                            "language",
                            "text"
                        ],
                        "properties": {
                            "language": {
                                "type": "string",
                                "example": "en"
                            },
                            "text": {
                                "type": "string"
                            }
                        },
                        "type": "object"
                    },
                    "source": {
                        "type": "string"
                    },
                    "url": {
                        "description": "The canonical quote on the quotes API.",
                        "type": "string"
                    }
                },
                "type": "object"
            },
            "StoryRef": {
                "description": "A story about the person.",
                "required": [
                    "slug",
                    "title",
                    "published",
                    "url"
                ],
                "properties": {
                    "slug": {
                        "type": "string"
                    },
                    "title": {
                        "$ref": "#/components/schemas/Name"
                    },
                    "published": {
                        "type": "string",
                        "format": "date"
                    },
                    "url": {
                        "description": "The canonical story on the stories API.",
                        "type": "string"
                    }
                },
                "type": "object"
            },
            "SearchResult": {
                "required": [
                    "type",
                    "matched_in",
                    "id",
                    "slug",
                    "name",
                    "kind",
                    "url"
                ],
                "properties": {
                    "type": {
                        "type": "string",
                        "enum": [
                            "person"
                        ]
                    },
                    "matched_in": {
                        "description": "Language-keyed field paths that matched, e.g. `name.ar-Latn`.",
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "id": {
                        "type": "string"
                    },
                    "slug": {
                        "type": "string"
                    },
                    "name": {
                        "$ref": "#/components/schemas/Name"
                    },
                    "honorific": {
                        "$ref": "#/components/schemas/Name"
                    },
                    "kind": {
                        "$ref": "#/components/schemas/Kind"
                    },
                    "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": "Person 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"
                }
            }
        }
    },
    "tags": [
        {
            "name": "people",
            "description": "The registry and per-person aggregations"
        },
        {
            "name": "search",
            "description": "Diacritic-folded search"
        },
        {
            "name": "documentation",
            "description": "This specification"
        }
    ]
}