Consumer API
API-key authenticated Legaciti API for publication discovery and person browsing. The ingestion entrypoint is documented separately because it is intended for controlled clients.
API-key authenticated Legaciti API for publication discovery and person browsing. The ingestion entrypoint is documented separately because it is intended for controlled clients.
Version: 1.0.0
Raw OpenAPI JSON: /openapi/consumer-api.json
Servers
Section titled “Servers”- https://api.legaciti.org - Consumer API domain
Endpoints
Section titled “Endpoints”Health
Section titled “Health”| Method | Path | Summary |
|---|---|---|
| GET | /health | Health check |
GET /health
Section titled “GET /health”Health check Simple worker health endpoint. Authentication: Public Tags: Health
Parameters
Section titled “Parameters”No parameters.
Request Body
Section titled “Request Body”No request body.
Responses
Section titled “Responses”200 - Worker health response.
Section titled “200 - Worker health response.”Content type: application/json
{ "type": "object", "properties": { "status": { "type": "string", "enum": [ "ok" ] } }, "required": [ "status" ]}Ingestion
Section titled “Ingestion”| Method | Path | Summary |
|---|---|---|
| POST | /api/ingest | Queue public ingestion |
POST /api/ingest
Section titled “POST /api/ingest”Queue public ingestion Queues one or more ORCID ingestion jobs from the public API surface. Requires a super-admin full-access key. Authentication: API key (X-API-Key) Tags: Ingestion
Parameters
Section titled “Parameters”No parameters.
Request Body
Section titled “Request Body”Content type: application/json
{ "type": "object", "properties": { "orcid_ids": { "minItems": 1, "maxItems": 100, "type": "array", "items": { "type": "string", "minLength": 1 } } }, "required": [ "orcid_ids" ], "additionalProperties": false}Responses
Section titled “Responses”202 - Queued public ingestion requests.
Section titled “202 - Queued public ingestion requests.”Content type: application/json
{ "type": "object", "properties": { "queued": { "type": "integer" }, "requested": { "type": "integer" } }, "required": [ "queued", "requested" ]}401 - Missing or invalid API key.
Section titled “401 - Missing or invalid API key.”Content type: application/json
{ "type": "object", "properties": { "error": { "type": "string" }, "details": { "oneOf": [ { "type": "object", "additionalProperties": true }, { "type": "null" } ] } }, "required": [ "error" ], "additionalProperties": true}403 - API key is inactive or missing required scope.
Section titled “403 - API key is inactive or missing required scope.”Content type: application/json
{ "type": "object", "properties": { "error": { "type": "string" }, "details": { "oneOf": [ { "type": "object", "additionalProperties": true }, { "type": "null" } ] } }, "required": [ "error" ], "additionalProperties": true}429 - API key rate limit exceeded.
Section titled “429 - API key rate limit exceeded.”Content type: application/json
{ "type": "object", "properties": { "error": { "type": "string" }, "details": { "oneOf": [ { "type": "object", "additionalProperties": true }, { "type": "null" } ] } }, "required": [ "error" ], "additionalProperties": true}500 - API key logging or migration setup is incomplete.
Section titled “500 - API key logging or migration setup is incomplete.”Content type: application/json
{ "type": "object", "properties": { "error": { "type": "string" }, "details": { "oneOf": [ { "type": "object", "additionalProperties": true }, { "type": "null" } ] } }, "required": [ "error" ], "additionalProperties": true}Partners
Section titled “Partners”| Method | Path | Summary |
|---|---|---|
| POST | /api/partners/people/{orcid}/membership | Update person CESAM membership |
POST /api/partners/people/{orcid}/membership
Section titled “POST /api/partners/people/{orcid}/membership”Update person CESAM membership Updates membership status for an existing person. Restricted to CESAM entity transitions and requires a super-admin full-access key. Authentication: API key (X-API-Key) Tags: Partners
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
| orcid | path | string | yes | Person ORCID identifier. |
Request Body
Section titled “Request Body”Content type: application/json
{ "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
Section titled “Responses”200 - Membership transition applied.
Section titled “200 - Membership transition applied.”Content type: application/json
{ "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 - Invalid ORCID or request body.
Section titled “400 - Invalid ORCID or request body.”Content type: application/json
{ "type": "object", "properties": { "error": { "type": "string" }, "details": { "oneOf": [ { "type": "object", "additionalProperties": true }, { "type": "null" } ] } }, "required": [ "error" ], "additionalProperties": true}401 - Missing or invalid API key.
Section titled “401 - Missing or invalid API key.”Content type: application/json
{ "type": "object", "properties": { "error": { "type": "string" }, "details": { "oneOf": [ { "type": "object", "additionalProperties": true }, { "type": "null" } ] } }, "required": [ "error" ], "additionalProperties": true}403 - API key is inactive or missing required scope.
Section titled “403 - API key is inactive or missing required scope.”Content type: application/json
{ "type": "object", "properties": { "error": { "type": "string" }, "details": { "oneOf": [ { "type": "object", "additionalProperties": true }, { "type": "null" } ] } }, "required": [ "error" ], "additionalProperties": true}404 - Person or entity not found.
Section titled “404 - Person or entity not found.”Content type: application/json
{ "type": "object", "properties": { "error": { "type": "string" }, "details": { "oneOf": [ { "type": "object", "additionalProperties": true }, { "type": "null" } ] } }, "required": [ "error" ], "additionalProperties": true}429 - API key rate limit exceeded.
Section titled “429 - API key rate limit exceeded.”Content type: application/json
{ "type": "object", "properties": { "error": { "type": "string" }, "details": { "oneOf": [ { "type": "object", "additionalProperties": true }, { "type": "null" } ] } }, "required": [ "error" ], "additionalProperties": true}500 - API key logging or migration setup is incomplete.
Section titled “500 - API key logging or migration setup is incomplete.”Content type: application/json
{ "type": "object", "properties": { "error": { "type": "string" }, "details": { "oneOf": [ { "type": "object", "additionalProperties": true }, { "type": "null" } ] } }, "required": [ "error" ], "additionalProperties": true}People
Section titled “People”| Method | Path | Summary |
|---|---|---|
| GET | /v1/people | List installation-authenticated people |
| GET | /v1/people/{orcid} | Get installation-authenticated person |
| GET | /v1/people/{orcid}/publications | List installation-authenticated person publications |
GET /v1/people
Section titled “GET /v1/people”List installation-authenticated people Returns people that have at least one visible public publication. Requires installation credentials with people.read scope. Authentication: API key (X-API-Key) Tags: People
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
| page | query | integer | yes | 1-based page number. |
| per_page | query | integer | yes | Items per page. |
| q | query | string | yes | Search term for name or ORCID. |
Request Body
Section titled “Request Body”No request body.
Responses
Section titled “Responses”200 - Paginated public person list.
Section titled “200 - Paginated public person list.”Content type: application/json
{ "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 - Invalid query parameters.
Section titled “400 - Invalid query parameters.”Content type: application/json
{ "type": "object", "properties": { "error": { "type": "string" }, "details": { "oneOf": [ { "type": "object", "additionalProperties": true }, { "type": "null" } ] } }, "required": [ "error" ], "additionalProperties": true}GET /v1/people/{orcid}
Section titled “GET /v1/people/{orcid}”Get installation-authenticated person Returns a single person and the count of public publications linked to that ORCID. Requires installation credentials with people.read scope. Authentication: API key (X-API-Key) Tags: People
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
| orcid | path | string | yes | Person ORCID identifier. |
Request Body
Section titled “Request Body”No request body.
Responses
Section titled “Responses”200 - Public person detail payload.
Section titled “200 - Public person detail payload.”Content type: application/json
{ "type": "object", "additionalProperties": true}404 - Person not found.
Section titled “404 - Person not found.”Content type: application/json
{ "type": "object", "properties": { "error": { "type": "string" }, "details": { "oneOf": [ { "type": "object", "additionalProperties": true }, { "type": "null" } ] } }, "required": [ "error" ], "additionalProperties": true}GET /v1/people/{orcid}/publications
Section titled “GET /v1/people/{orcid}/publications”List installation-authenticated person publications Returns visible public publications linked to a single person. Requires installation credentials with people.read scope. Authentication: API key (X-API-Key) Tags: People
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
| orcid | path | string | yes | Person ORCID identifier. |
| page | query | integer | yes | 1-based page number. |
| per_page | query | integer | yes | Items per page. |
| sort | query | string | yes | Sort field. |
| dir | query | string | yes | Sort direction. |
Request Body
Section titled “Request Body”No request body.
Responses
Section titled “Responses”200 - Paginated public publication list for one person.
Section titled “200 - Paginated public publication list for one person.”Content type: application/json
{ "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 - Invalid query parameters.
Section titled “400 - Invalid query parameters.”Content type: application/json
{ "type": "object", "properties": { "error": { "type": "string" }, "details": { "oneOf": [ { "type": "object", "additionalProperties": true }, { "type": "null" } ] } }, "required": [ "error" ], "additionalProperties": true}Projects
Section titled “Projects”| Method | Path | Summary |
|---|---|---|
| GET | /v1/projects | List public projects |
| GET | /v1/projects/{id} | Get public project by ID |
GET /v1/projects
Section titled “GET /v1/projects”List public projects Returns visible, non-deleted projects with pagination, search, and sorting. Authentication: Public Tags: Projects
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
| page | query | integer | yes | 1-based page number. |
| per_page | query | integer | yes | Items per page. |
| q | query | string | yes | Search term for programme, title, or abstract. |
| sort | query | string | yes | Sort field. |
| dir | query | string | yes | Sort direction. |
| funding_currency | query | string | no | Funding currency filter. |
Request Body
Section titled “Request Body”No request body.
Responses
Section titled “Responses”200 - Paginated public project list.
Section titled “200 - Paginated public project list.”Content type: application/json
{ "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 - Invalid query parameters.
Section titled “400 - Invalid query parameters.”Content type: application/json
{ "type": "object", "properties": { "error": { "type": "string" }, "details": { "oneOf": [ { "type": "object", "additionalProperties": true }, { "type": "null" } ] } }, "required": [ "error" ], "additionalProperties": true}GET /v1/projects/{id}
Section titled “GET /v1/projects/{id}”Get public project by ID Returns a visible non-deleted project and linked members/coordinators. Authentication: Public Tags: Projects
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
| id | path | string | yes | Project identifier. |
Request Body
Section titled “Request Body”No request body.
Responses
Section titled “Responses”200 - Public project detail payload.
Section titled “200 - Public project detail payload.”Content type: application/json
{ "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 - Project not found or not public.
Section titled “404 - Project not found or not public.”Content type: application/json
{ "type": "object", "properties": { "error": { "type": "string" }, "details": { "oneOf": [ { "type": "object", "additionalProperties": true }, { "type": "null" } ] } }, "required": [ "error" ], "additionalProperties": true}Publications
Section titled “Publications”| Method | Path | Summary |
|---|---|---|
| GET | /v1/publications | List visible publications |
| GET | /v1/doi/{doi} | Get visible publication by DOI |
GET /v1/publications
Section titled “GET /v1/publications”List visible publications Returns public publications with search, sort, and metadata filters. Authentication: Public Tags: Publications
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
| page | query | integer | yes | 1-based page number. |
| per_page | query | integer | yes | Items per page. |
| q | query | string | yes | Title search term. |
| sort | query | string | yes | Sort field. |
| dir | query | string | yes | Sort direction. |
| publication_type | query | string | no | Publication type filter. |
| publication_year | query | integer | no | Publication year filter. |
| min_cited_by | query | integer | no | Minimum citation count filter. |
Request Body
Section titled “Request Body”No request body.
Responses
Section titled “Responses”200 - Paginated public publication list.
Section titled “200 - Paginated public publication list.”Content type: application/json
{ "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 - Invalid query parameters.
Section titled “400 - Invalid query parameters.”Content type: application/json
{ "type": "object", "properties": { "error": { "type": "string" }, "details": { "oneOf": [ { "type": "object", "additionalProperties": true }, { "type": "null" } ] } }, "required": [ "error" ], "additionalProperties": true}GET /v1/doi/{doi}
Section titled “GET /v1/doi/{doi}”Get visible publication by DOI Returns the merged visible publication payload for a DOI when the record is public. Authentication: Public Tags: Publications
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
| doi | path | string | yes | DOI path parameter, URL-encoded if necessary. |
Request Body
Section titled “Request Body”No request body.
Responses
Section titled “Responses”200 - Public publication detail payload.
Section titled “200 - Public publication detail payload.”Content type: application/json
{ "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 - Publication not found or not public.
Section titled “404 - Publication not found or not public.”Content type: application/json
{ "type": "object", "properties": { "error": { "type": "string" }, "details": { "oneOf": [ { "type": "object", "additionalProperties": true }, { "type": "null" } ] } }, "required": [ "error" ], "additionalProperties": true}