{
    "openapi": "3.1.0",
    "info": {
        "title": "Life of Research public API",
        "version": "1.0.0",
        "summary": "Open metadata for a free, open-access research repository.",
        "description": "Read-only access to published records. No authentication. Metadata may be reused for any purpose, including text and data mining. Documentation with examples: https://lifeofresearch.com/developers",
        "contact": {
            "name": "Life of Research",
            "url": "https://lifeofresearch.com/developers",
            "email": "contact@lifeofresearch.com"
        }
    },
    "servers": [
        {
            "url": "https://lifeofresearch.com"
        }
    ],
    "externalDocs": {
        "description": "Developer documentation",
        "url": "https://lifeofresearch.com/developers"
    },
    "paths": {
        "/api/records": {
            "get": {
                "operationId": "listRecords",
                "summary": "List or search published records",
                "description": "Published records, newest deposit first, 20 per page. The q parameter matches titles, abstracts, keywords and author names.",
                "tags": [
                    "Records"
                ],
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "required": false,
                        "description": "Search words.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "description": "Page number, starting at 1.",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "default": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of records",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/RecordList"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/records/{id}": {
            "get": {
                "operationId": "getRecord",
                "summary": "Get one published record with its files",
                "tags": [
                    "Records"
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Numeric record id (LOR-00042 is id 42).",
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The record",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/RecordDetail"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/stats.json": {
            "get": {
                "operationId": "getStatistics",
                "summary": "Repository statistics",
                "description": "Aggregate figures over published records, recomputed at most every 10 minutes.",
                "tags": [
                    "Statistics"
                ],
                "responses": {
                    "200": {
                        "description": "Statistics",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Statistics"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/mcp": {
            "post": {
                "operationId": "mcp",
                "summary": "Model Context Protocol endpoint (JSON-RPC 2.0 over Streamable HTTP)",
                "description": "Read-only MCP server. Supports protocol revision 2026-07-28 (per-request _meta, server/discover) and the initialize handshake of 2025-11-25, 2025-06-18, 2025-03-26. Tools: search_records, get_record, get_citation, list_recent, list_subjects. See https://lifeofresearch.com/developers#mcp.",
                "tags": [
                    "MCP"
                ],
                "parameters": [
                    {
                        "name": "MCP-Protocol-Version",
                        "in": "header",
                        "required": false,
                        "description": "Required on every request from protocol 2025-06-18 on; must equal the _meta protocol version in 2026-07-28.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "Mcp-Method",
                        "in": "header",
                        "required": false,
                        "description": "Required from 2026-07-28: mirrors the JSON-RPC method.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "Mcp-Name",
                        "in": "header",
                        "required": false,
                        "description": "Required from 2026-07-28 on tools/call: mirrors params.name.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/JsonRpcMessage"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "JSON-RPC response",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "202": {
                        "description": "Notification accepted (no body)"
                    },
                    "400": {
                        "description": "Malformed message, unsupported protocol version or header mismatch (JSON-RPC error body)"
                    },
                    "403": {
                        "description": "Origin header not allowed"
                    },
                    "404": {
                        "description": "Unknown method (protocol 2026-07-28)"
                    },
                    "429": {
                        "description": "Rate limit exceeded; see Retry-After"
                    }
                }
            }
        },
        "/oai2": {
            "get": {
                "operationId": "oaiPmh",
                "summary": "OAI-PMH 2.0 endpoint",
                "description": "Standard metadata harvesting. Formats: oai_dc, oai_datacite. Sets: type:<type> and openaire. Paged by resumptionToken.",
                "tags": [
                    "Harvesting"
                ],
                "parameters": [
                    {
                        "name": "verb",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "Identify",
                                "ListMetadataFormats",
                                "ListSets",
                                "ListIdentifiers",
                                "ListRecords",
                                "GetRecord"
                            ]
                        }
                    },
                    {
                        "name": "metadataPrefix",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "oai_dc",
                                "oai_datacite"
                            ]
                        }
                    },
                    {
                        "name": "identifier",
                        "in": "query",
                        "required": false,
                        "description": "oai:lifeofresearch.com:<id>",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "set",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "from",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "until",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "resumptionToken",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OAI-PMH XML response (errors are reported inside the XML, as the protocol requires)",
                        "content": {
                            "text/xml": {
                                "schema": {
                                    "type": "string"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/feed.xml": {
            "get": {
                "operationId": "getFeed",
                "summary": "Atom feed of the 50 most recent records",
                "tags": [
                    "Feeds"
                ],
                "responses": {
                    "200": {
                        "description": "Atom feed of the 50 most recent records",
                        "content": {
                            "application/atom+xml": {
                                "schema": {
                                    "type": "string"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/sitemap.xml": {
            "get": {
                "operationId": "getSitemap",
                "summary": "XML sitemap of every indexable page",
                "tags": [
                    "Feeds"
                ],
                "responses": {
                    "200": {
                        "description": "XML sitemap of every indexable page",
                        "content": {
                            "application/xml": {
                                "schema": {
                                    "type": "string"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/llms.txt": {
            "get": {
                "operationId": "getLlmsTxt",
                "summary": "Plain-text site summary for language models",
                "tags": [
                    "Feeds"
                ],
                "responses": {
                    "200": {
                        "description": "Plain-text site summary for language models",
                        "content": {
                            "text/plain": {
                                "schema": {
                                    "type": "string"
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "Author": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string"
                    },
                    "affiliation": {
                        "type": "string"
                    },
                    "orcid": {
                        "type": "string"
                    }
                }
            },
            "Record": {
                "type": "object",
                "required": [
                    "id",
                    "identifier",
                    "url",
                    "title",
                    "type"
                ],
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "identifier": {
                        "type": "string",
                        "examples": [
                            "LOR-00042"
                        ]
                    },
                    "url": {
                        "type": "string",
                        "format": "uri"
                    },
                    "title": {
                        "type": "string"
                    },
                    "abstract": {
                        "type": "string"
                    },
                    "authors": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Author"
                        }
                    },
                    "type": {
                        "type": "string",
                        "enum": [
                            "article",
                            "preprint",
                            "dataset",
                            "thesis",
                            "report",
                            "poster",
                            "presentation",
                            "software",
                            "other"
                        ]
                    },
                    "license": {
                        "type": "string",
                        "enum": [
                            "CC-BY-4.0",
                            "CC-BY-SA-4.0",
                            "CC-BY-NC-4.0",
                            "CC0-1.0",
                            "MIT",
                            "ARR"
                        ]
                    },
                    "keywords": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "publication_date": {
                        "type": "string",
                        "format": "date"
                    },
                    "version": {
                        "type": "integer"
                    },
                    "views": {
                        "type": "integer"
                    },
                    "downloads": {
                        "type": "integer"
                    },
                    "created_at": {
                        "type": "string"
                    },
                    "doi": {
                        "type": "string",
                        "description": "DOI registered elsewhere, bare form; empty when none."
                    },
                    "source": {
                        "type": "string"
                    },
                    "source_url": {
                        "type": "string"
                    }
                }
            },
            "RecordDetail": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/Record"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "files": {
                                "type": "array",
                                "items": {
                                    "type": "object",
                                    "properties": {
                                        "id": {
                                            "type": "integer"
                                        },
                                        "name": {
                                            "type": "string"
                                        },
                                        "size": {
                                            "type": "integer"
                                        },
                                        "mime": {
                                            "type": "string"
                                        },
                                        "downloads": {
                                            "type": "integer"
                                        },
                                        "download_url": {
                                            "type": "string",
                                            "format": "uri"
                                        }
                                    }
                                }
                            }
                        }
                    }
                ]
            },
            "RecordList": {
                "type": "object",
                "required": [
                    "total",
                    "page",
                    "per_page",
                    "records"
                ],
                "properties": {
                    "total": {
                        "type": "integer"
                    },
                    "page": {
                        "type": "integer"
                    },
                    "per_page": {
                        "type": "integer"
                    },
                    "records": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Record"
                        }
                    }
                }
            },
            "Statistics": {
                "type": "object",
                "properties": {
                    "generated_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "records": {
                        "type": "integer"
                    },
                    "views": {
                        "type": "integer"
                    },
                    "downloads": {
                        "type": "integer"
                    },
                    "by_type": {
                        "type": "array",
                        "items": {
                            "type": "object"
                        }
                    },
                    "by_year": {
                        "type": "array",
                        "items": {
                            "type": "object"
                        }
                    },
                    "by_month": {
                        "type": "array",
                        "items": {
                            "type": "object"
                        }
                    },
                    "top_subjects": {
                        "type": "array",
                        "items": {
                            "type": "object"
                        }
                    }
                }
            },
            "JsonRpcMessage": {
                "type": "object",
                "required": [
                    "jsonrpc",
                    "method"
                ],
                "properties": {
                    "jsonrpc": {
                        "const": "2.0"
                    },
                    "id": {
                        "type": [
                            "string",
                            "integer"
                        ]
                    },
                    "method": {
                        "type": "string"
                    },
                    "params": {
                        "type": "object"
                    }
                }
            },
            "Error": {
                "type": "object",
                "properties": {
                    "error": {
                        "type": "string"
                    }
                }
            }
        }
    }
}