{
    "openapi": "3.1.1",
    "info": {
        "title": "GBU Published Timetable API",
        "version": "1.1.0",
        "description": "Read-only published timetable snapshots. No OAuth or credential issuance. Local class times use Asia/Kolkata. The source does not supply publication timestamps; sync records observation time. Pagination is not snapshot-isolated; restart full reads after a publication."
    },
    "servers": [
        {
            "url": "https://api.mygbu.in"
        }
    ],
    "security": [],
    "paths": {
        "/": {
            "get": {
                "operationId": "getApiInformation",
                "responses": {
                    "200": {
                        "description": "Successful response",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "405": {
                        "description": "Unsupported method; Allow: GET, HEAD",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                }
            },
            "head": {
                "operationId": "headgetApiInformation",
                "description": "Same status/headers as GET; no response body.",
                "responses": {
                    "200": {
                        "description": "Successful response"
                    },
                    "405": {
                        "description": "Unsupported method; Allow: GET, HEAD"
                    }
                }
            }
        },
        "/health": {
            "get": {
                "operationId": "getHealth",
                "responses": {
                    "200": {
                        "description": "Successful response",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "service",
                                        "status",
                                        "api_version",
                                        "oauth_operational"
                                    ],
                                    "properties": {
                                        "service": {
                                            "type": "string"
                                        },
                                        "status": {
                                            "const": "ok"
                                        },
                                        "api_version": {
                                            "const": "1.1"
                                        },
                                        "oauth_operational": {
                                            "const": false
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "405": {
                        "description": "Unsupported method; Allow: GET, HEAD",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "description": "Process liveness only; does not test database or upstream feed."
            },
            "head": {
                "operationId": "headgetHealth",
                "description": "Same status/headers as GET; no response body.",
                "responses": {
                    "200": {
                        "description": "Successful response"
                    },
                    "405": {
                        "description": "Unsupported method; Allow: GET, HEAD"
                    }
                }
            }
        },
        "/openapi.json": {
            "get": {
                "operationId": "getOpenApi",
                "responses": {
                    "200": {
                        "description": "Successful response",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "405": {
                        "description": "Unsupported method; Allow: GET, HEAD",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                }
            },
            "head": {
                "operationId": "headgetOpenApi",
                "description": "Same status/headers as GET; no response body.",
                "responses": {
                    "200": {
                        "description": "Successful response"
                    },
                    "405": {
                        "description": "Unsupported method; Allow: GET, HEAD"
                    }
                }
            }
        },
        "/v1/timetable": {
            "get": {
                "operationId": "listPublishedTimetable",
                "responses": {
                    "200": {
                        "description": "Successful response",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/TimetablePage"
                                }
                            }
                        }
                    },
                    "405": {
                        "description": "Unsupported method; Allow: GET, HEAD",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Invalid query parameters",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "503": {
                        "description": "Database unavailable",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 500,
                            "default": 100
                        }
                    },
                    {
                        "name": "after",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 0,
                            "default": 0
                        }
                    },
                    {
                        "name": "day",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 7
                        }
                    },
                    {
                        "name": "publication_id",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        }
                    },
                    {
                        "name": "course",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 160
                        }
                    },
                    {
                        "name": "room",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 100
                        }
                    }
                ]
            },
            "head": {
                "operationId": "headlistPublishedTimetable",
                "description": "Same status/headers as GET; no response body.",
                "parameters": [
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 500,
                            "default": 100
                        }
                    },
                    {
                        "name": "after",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 0,
                            "default": 0
                        }
                    },
                    {
                        "name": "day",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 7
                        }
                    },
                    {
                        "name": "publication_id",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        }
                    },
                    {
                        "name": "course",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 160
                        }
                    },
                    {
                        "name": "room",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 100
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful response"
                    },
                    "405": {
                        "description": "Unsupported method; Allow: GET, HEAD"
                    },
                    "422": {
                        "description": "Invalid query parameters"
                    },
                    "503": {
                        "description": "Database unavailable"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "TimetableEntry": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                    "id",
                    "publication_id",
                    "title",
                    "day_of_week",
                    "starts_at",
                    "ends_at",
                    "course",
                    "room"
                ],
                "properties": {
                    "id": {
                        "type": "integer",
                        "minimum": 1
                    },
                    "publication_id": {
                        "type": "integer",
                        "minimum": 1
                    },
                    "title": {
                        "type": "string"
                    },
                    "day_of_week": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 7,
                        "description": "Monday=1, Sunday=7"
                    },
                    "starts_at": {
                        "type": "string",
                        "pattern": "^(?:[01][0-9]|2[0-3]):[0-5][0-9]:00$"
                    },
                    "ends_at": {
                        "type": "string",
                        "pattern": "^(?:[01][0-9]|2[0-3]):[0-5][0-9]:00$"
                    },
                    "course": {
                        "type": "string"
                    },
                    "room": {
                        "type": "string",
                        "description": "Unassigned when the published source has no room."
                    }
                }
            },
            "TimetablePage": {
                "type": "object",
                "required": [
                    "data",
                    "next_after",
                    "visibility",
                    "timezone",
                    "meta",
                    "links"
                ],
                "properties": {
                    "data": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/TimetableEntry"
                        }
                    },
                    "next_after": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "minimum": 1
                    },
                    "visibility": {
                        "const": "published only"
                    },
                    "timezone": {
                        "const": "Asia/Kolkata"
                    },
                    "meta": {
                        "type": "object",
                        "required": [
                            "api_version",
                            "count",
                            "pagination",
                            "request_id"
                        ],
                        "properties": {
                            "api_version": {
                                "const": "1.1"
                            },
                            "count": {
                                "type": "integer",
                                "minimum": 0
                            },
                            "pagination": {
                                "type": "object",
                                "required": [
                                    "limit",
                                    "after",
                                    "has_more",
                                    "next_after"
                                ],
                                "properties": {
                                    "limit": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 500
                                    },
                                    "after": {
                                        "type": "integer",
                                        "minimum": 0
                                    },
                                    "has_more": {
                                        "type": "boolean"
                                    },
                                    "next_after": {
                                        "type": [
                                            "integer",
                                            "null"
                                        ],
                                        "minimum": 1
                                    }
                                }
                            },
                            "request_id": {
                                "type": "string",
                                "pattern": "^[a-f0-9]{32}$"
                            }
                        }
                    },
                    "links": {
                        "type": "object",
                        "required": [
                            "self",
                            "next"
                        ],
                        "properties": {
                            "self": {
                                "type": "string",
                                "format": "uri-reference"
                            },
                            "next": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "format": "uri-reference"
                            }
                        }
                    }
                }
            },
            "Problem": {
                "type": "object",
                "required": [
                    "type",
                    "title",
                    "status",
                    "detail",
                    "instance",
                    "request_id"
                ],
                "properties": {
                    "type": {
                        "type": "string",
                        "format": "uri-reference"
                    },
                    "title": {
                        "type": "string"
                    },
                    "status": {
                        "type": "integer",
                        "minimum": 400,
                        "maximum": 599
                    },
                    "detail": {
                        "type": "string"
                    },
                    "instance": {
                        "type": "string"
                    },
                    "request_id": {
                        "type": "string"
                    },
                    "error": {
                        "type": "string",
                        "description": "Compatibility extension; prefer detail."
                    }
                }
            }
        },
        "responses": {
            "NotFound": {
                "description": "Unknown route, including unimplemented OAuth routes",
                "content": {
                    "application/problem+json": {
                        "schema": {
                            "$ref": "#/components/schemas/Problem"
                        }
                    }
                }
            }
        }
    }
}