{
  "openapi": "3.1.0",
  "info": {
    "title": "Consumer API",
    "version": "1.0.0",
    "description": "API-key authenticated Legaciti API for publication discovery and person browsing. The ingestion entrypoint is documented separately because it is intended for controlled clients."
  },
  "servers": [
    {
      "url": "https://api.legaciti.org",
      "description": "Consumer API domain"
    }
  ],
  "tags": [
    {
      "name": "Health",
      "description": "Health endpoints"
    },
    {
      "name": "Publications",
      "description": "Public publication endpoints"
    },
    {
      "name": "Projects",
      "description": "Public project endpoints"
    },
    {
      "name": "People",
      "description": "Installation-authenticated people endpoints"
    },
    {
      "name": "Ingestion",
      "description": "Public ingestion request endpoint"
    },
    {
      "name": "Partners",
      "description": "Authenticated partner write endpoints"
    }
  ],
  "components": {
    "securitySchemes": {
      "consumerApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Scoped API key for consumer API authentication. Write endpoints require a super-admin full-access key issued from Admin Workspace; regular workspace keys are read-only."
      },
      "integrationApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Installation credential for integration consumers. Requires a verified installation and endpoint-specific scopes."
      }
    },
    "schemas": {
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "details": {
            "oneOf": [
              {
                "type": "object",
                "additionalProperties": true
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "error"
        ],
        "additionalProperties": true
      }
    }
  },
  "paths": {
    "/health": {
      "get": {
        "summary": "Health check",
        "description": "Simple worker health endpoint.",
        "tags": [
          "Health"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Worker health response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "ok"
                      ]
                    }
                  },
                  "required": [
                    "status"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/ingest": {
      "post": {
        "summary": "Queue public ingestion",
        "description": "Queues one or more ORCID ingestion jobs from the public API surface. Requires a super-admin full-access key.",
        "tags": [
          "Ingestion"
        ],
        "security": [
          {
            "consumerApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "orcid_ids": {
                    "minItems": 1,
                    "maxItems": 100,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1
                    }
                  }
                },
                "required": [
                  "orcid_ids"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Queued public ingestion requests.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "queued": {
                      "type": "integer"
                    },
                    "requested": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "queued",
                    "requested"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "details": {
                      "oneOf": [
                        {
                          "type": "object",
                          "additionalProperties": true
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": true
                }
              }
            }
          },
          "403": {
            "description": "API key is inactive or missing required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "details": {
                      "oneOf": [
                        {
                          "type": "object",
                          "additionalProperties": true
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": true
                }
              }
            }
          },
          "429": {
            "description": "API key rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "details": {
                      "oneOf": [
                        {
                          "type": "object",
                          "additionalProperties": true
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": true
                }
              }
            }
          },
          "500": {
            "description": "API key logging or migration setup is incomplete.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "details": {
                      "oneOf": [
                        {
                          "type": "object",
                          "additionalProperties": true
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/api/partners/people/{orcid}/membership": {
      "post": {
        "summary": "Update person CESAM membership",
        "description": "Updates membership status for an existing person. Restricted to CESAM entity transitions and requires a super-admin full-access key.",
        "tags": [
          "Partners"
        ],
        "security": [
          {
            "consumerApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "orcid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Person ORCID identifier."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "entity_id": {
                    "type": "string",
                    "const": "cesam"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "cesam",
                      "external"
                    ]
                  },
                  "starts_at": {
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  }
                },
                "required": [
                  "entity_id",
                  "status"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Membership transition applied.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "affiliation": {
                      "type": "object",
                      "properties": {
                        "person_orcid": {
                          "type": "string"
                        },
                        "entity_id": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "cesam",
                            "external"
                          ]
                        },
                        "starts_at": {
                          "type": "integer"
                        },
                        "ends_at": {
                          "type": "null"
                        }
                      },
                      "required": [
                        "person_orcid",
                        "entity_id",
                        "status",
                        "starts_at",
                        "ends_at"
                      ]
                    }
                  },
                  "required": [
                    "success",
                    "affiliation"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid ORCID or request body.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "details": {
                      "oneOf": [
                        {
                          "type": "object",
                          "additionalProperties": true
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": true
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "details": {
                      "oneOf": [
                        {
                          "type": "object",
                          "additionalProperties": true
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": true
                }
              }
            }
          },
          "403": {
            "description": "API key is inactive or missing required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "details": {
                      "oneOf": [
                        {
                          "type": "object",
                          "additionalProperties": true
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": true
                }
              }
            }
          },
          "404": {
            "description": "Person or entity not found.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "details": {
                      "oneOf": [
                        {
                          "type": "object",
                          "additionalProperties": true
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": true
                }
              }
            }
          },
          "429": {
            "description": "API key rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "details": {
                      "oneOf": [
                        {
                          "type": "object",
                          "additionalProperties": true
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": true
                }
              }
            }
          },
          "500": {
            "description": "API key logging or migration setup is incomplete.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "details": {
                      "oneOf": [
                        {
                          "type": "object",
                          "additionalProperties": true
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/v1/publications": {
      "get": {
        "summary": "List visible publications",
        "description": "Returns public publications with search, sort, and metadata filters.",
        "tags": [
          "Publications"
        ],
        "security": [],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": true,
            "description": "1-based page number.",
            "schema": {
              "default": 1,
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "required": true,
            "description": "Items per page.",
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Title search term.",
            "schema": {
              "default": "",
              "type": "string"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": true,
            "description": "Sort field.",
            "schema": {
              "default": "last_fetched_at",
              "type": "string",
              "enum": [
                "last_fetched_at",
                "publication_date",
                "cited_by_count"
              ]
            }
          },
          {
            "name": "dir",
            "in": "query",
            "required": true,
            "description": "Sort direction.",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "publication_type",
            "in": "query",
            "required": false,
            "description": "Publication type filter.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "publication_year",
            "in": "query",
            "required": false,
            "description": "Publication year filter.",
            "schema": {
              "type": "integer",
              "minimum": 1000,
              "maximum": 3000
            }
          },
          {
            "name": "min_cited_by",
            "in": "query",
            "required": false,
            "description": "Minimum citation count filter.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated public publication list.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "publications": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "doi": {
                            "type": "string"
                          },
                          "title": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "doi_url": {
                            "type": "string"
                          },
                          "publication_date": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "publication_year": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "publication_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "cited_by_count": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "last_fetched_at": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "doi",
                          "doi_url",
                          "last_fetched_at"
                        ]
                      }
                    },
                    "page": {
                      "type": "integer"
                    },
                    "per_page": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "pages": {
                      "type": "integer"
                    },
                    "sort": {
                      "type": "string"
                    },
                    "dir": {
                      "type": "string"
                    },
                    "q": {
                      "type": "string"
                    },
                    "publication_type": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "publication_year": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "min_cited_by": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "publications",
                    "page",
                    "per_page",
                    "total",
                    "pages",
                    "sort",
                    "dir",
                    "q"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameters.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "details": {
                      "oneOf": [
                        {
                          "type": "object",
                          "additionalProperties": true
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/v1/doi/{doi}": {
      "get": {
        "summary": "Get visible publication by DOI",
        "description": "Returns the merged visible publication payload for a DOI when the record is public.",
        "tags": [
          "Publications"
        ],
        "security": [],
        "parameters": [
          {
            "name": "doi",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "DOI path parameter, URL-encoded if necessary."
          }
        ],
        "responses": {
          "200": {
            "description": "Public publication detail payload.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "doi": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "publication_date": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "publication_year": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "publication_type": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "cited_by_count": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "is_retracted": {
                      "type": "boolean"
                    },
                    "open_access_status": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "enriched_metadata": {
                      "oneOf": [
                        {
                          "type": "object",
                          "additionalProperties": true
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "last_fetched_at": {
                      "type": "integer"
                    },
                    "last_edited_at": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "edit_count": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "doi",
                    "data",
                    "is_retracted",
                    "last_fetched_at",
                    "edit_count"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Publication not found or not public.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "details": {
                      "oneOf": [
                        {
                          "type": "object",
                          "additionalProperties": true
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/v1/projects": {
      "get": {
        "summary": "List public projects",
        "description": "Returns visible, non-deleted projects with pagination, search, and sorting.",
        "tags": [
          "Projects"
        ],
        "security": [],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": true,
            "description": "1-based page number.",
            "schema": {
              "default": 1,
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "required": true,
            "description": "Items per page.",
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Search term for programme, title, or abstract.",
            "schema": {
              "default": "",
              "type": "string"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": true,
            "description": "Sort field.",
            "schema": {
              "default": "created_at",
              "type": "string",
              "enum": [
                "created_at",
                "start_date",
                "end_date"
              ]
            }
          },
          {
            "name": "dir",
            "in": "query",
            "required": true,
            "description": "Sort direction.",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "funding_currency",
            "in": "query",
            "required": false,
            "description": "Funding currency filter.",
            "schema": {
              "type": "string",
              "enum": [
                "EUR",
                "USD"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated public project list.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "projects": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "programme": {
                            "type": "string"
                          },
                          "title": {
                            "type": "string"
                          },
                          "abstract": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "start_date": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "end_date": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "href": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "programme",
                          "title",
                          "href"
                        ]
                      }
                    },
                    "page": {
                      "type": "integer"
                    },
                    "per_page": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "pages": {
                      "type": "integer"
                    },
                    "sort": {
                      "type": "string"
                    },
                    "dir": {
                      "type": "string"
                    },
                    "q": {
                      "type": "string"
                    },
                    "funding_currency": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "projects",
                    "page",
                    "per_page",
                    "total",
                    "pages",
                    "sort",
                    "dir",
                    "q"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameters.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "details": {
                      "oneOf": [
                        {
                          "type": "object",
                          "additionalProperties": true
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/v1/projects/{id}": {
      "get": {
        "summary": "Get public project by ID",
        "description": "Returns a visible non-deleted project and linked members/coordinators.",
        "tags": [
          "Projects"
        ],
        "security": [],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Project identifier."
          }
        ],
        "responses": {
          "200": {
            "description": "Public project detail payload.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "programme": {
                      "type": "string"
                    },
                    "title": {
                      "type": "string"
                    },
                    "abstract": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "start_date": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "end_date": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "member_orcids": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "coordinator_orcids": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "data": {
                      "type": "object",
                      "additionalProperties": true
                    }
                  },
                  "required": [
                    "id",
                    "programme",
                    "title",
                    "member_orcids"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Project not found or not public.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "details": {
                      "oneOf": [
                        {
                          "type": "object",
                          "additionalProperties": true
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/v1/people": {
      "get": {
        "summary": "List installation-authenticated people",
        "description": "Returns people that have at least one visible public publication. Requires installation credentials with people.read scope.",
        "tags": [
          "People"
        ],
        "security": [
          {
            "integrationApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": true,
            "description": "1-based page number.",
            "schema": {
              "default": 1,
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "required": true,
            "description": "Items per page.",
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Search term for name or ORCID.",
            "schema": {
              "default": "",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated public person list.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "people": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    },
                    "page": {
                      "type": "integer"
                    },
                    "per_page": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "pages": {
                      "type": "integer"
                    },
                    "q": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "people",
                    "page",
                    "per_page",
                    "total",
                    "pages",
                    "q"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameters.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "details": {
                      "oneOf": [
                        {
                          "type": "object",
                          "additionalProperties": true
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/v1/people/{orcid}": {
      "get": {
        "summary": "Get installation-authenticated person",
        "description": "Returns a single person and the count of public publications linked to that ORCID. Requires installation credentials with people.read scope.",
        "tags": [
          "People"
        ],
        "security": [
          {
            "integrationApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "orcid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Person ORCID identifier."
          }
        ],
        "responses": {
          "200": {
            "description": "Public person detail payload.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "404": {
            "description": "Person not found.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "details": {
                      "oneOf": [
                        {
                          "type": "object",
                          "additionalProperties": true
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "/v1/people/{orcid}/publications": {
      "get": {
        "summary": "List installation-authenticated person publications",
        "description": "Returns visible public publications linked to a single person. Requires installation credentials with people.read scope.",
        "tags": [
          "People"
        ],
        "security": [
          {
            "integrationApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "orcid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Person ORCID identifier."
          },
          {
            "name": "page",
            "in": "query",
            "required": true,
            "description": "1-based page number.",
            "schema": {
              "default": 1,
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "required": true,
            "description": "Items per page.",
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": true,
            "description": "Sort field.",
            "schema": {
              "default": "last_fetched_at",
              "type": "string",
              "enum": [
                "last_fetched_at",
                "publication_date",
                "cited_by_count"
              ]
            }
          },
          {
            "name": "dir",
            "in": "query",
            "required": true,
            "description": "Sort direction.",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated public publication list for one person.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "publications": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "doi": {
                            "type": "string"
                          },
                          "title": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "doi_url": {
                            "type": "string"
                          },
                          "publication_date": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "publication_year": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "publication_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "cited_by_count": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "last_fetched_at": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "doi",
                          "doi_url",
                          "last_fetched_at"
                        ]
                      }
                    },
                    "page": {
                      "type": "integer"
                    },
                    "per_page": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "pages": {
                      "type": "integer"
                    },
                    "sort": {
                      "type": "string"
                    },
                    "dir": {
                      "type": "string"
                    },
                    "q": {
                      "type": "string"
                    },
                    "publication_type": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "publication_year": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "min_cited_by": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "publications",
                    "page",
                    "per_page",
                    "total",
                    "pages",
                    "sort",
                    "dir",
                    "q"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameters.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "details": {
                      "oneOf": [
                        {
                          "type": "object",
                          "additionalProperties": true
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    }
  }
}
