Language versions: 简体中文
Related documents: Overview · Quick Start · Plugin Development Guide
- Protocol: HTTP
- Default address:
http://127.0.0.1:29467 - API prefix:
/api/v1 - Data format:
application/json; charset=utf-8 - Supported API methods:
GET,POST,PUT,OPTIONS - Write access: optional, disabled by default while
Read-Only Modeis on, and only available after the user turnsRead-Only Modeoff inSettings → Local API.PUT /api/v1/papers/{uuid}/pdfadditionally requirespdf-uploadin/status.capabilities - Plugin static hosting lives under
/plugins/{name}/...and is not under/api/v1
- Normal business endpoints return
200 OK - Successful paper creation returns
201 Created - Preflight requests return
204 No Content
Most error responses include at least:
{
"error": "Error message"
}Some error payloads include extra fields:
{
"error": "Duplicate paper found",
"existingPaperID": "550E8400-E29B-41D4-A716-446655440000"
}{
"error": "Library limit reached",
"currentCount": 50,
"limit": 50
}| Status | Meaning | Typical reason |
|---|---|---|
200 |
Success | The request completed normally |
201 |
Created | POST /api/v1/papers created a paper, or PUT /api/v1/papers/{uuid}/pdf uploaded bytes |
204 |
No content | OPTIONS preflight |
400 |
Bad request | Invalid request format, malformed JSON, empty title, invalid paperType, invalid strategy, missing metadata lookup query, or invalid PDF request shape |
403 |
Forbidden | Non-local request, origin not allowed, or public write access is still read-only |
404 |
Not found | Unknown endpoint, missing paper, failed metadata lookup, or missing plugin asset |
405 |
Method not allowed | Unsupported method such as PATCH or DELETE, or a method/path combination the API does not implement |
409 |
Conflict | Duplicate paper was detected during create, or a PDF is already attached and upload was not forced |
422 |
Unprocessable Content | Free-tier paper limit was reached |
413 |
Payload too large | Request body exceeded the configured size limit |
503 |
Service unavailable | PDF upload was requested but no usable upload destination is configured |
500 |
Internal server error | Lattice failed to process the request |
Use GET /api/v1/status before relying on optional behavior.
In particular:
- treat
create-paperincapabilitiesas the source of truth for whetherPOST /api/v1/papersis usable - treat
create-paper-v2as the signal that duplicate strategy and rich create/replace responses are supported - treat
pdf-uploadas the source of truth for whetherPUT /api/v1/papers/{uuid}/pdfis usable - do not assume write access is enabled on every machine
This section is the quickest way to answer two questions:
- which fields exist at all
- which HTTP methods expose or accept each field
| Field | GET /status response |
Notes |
|---|---|---|
ok |
ok |
Health flag |
apiVersion |
apiVersion |
Local API version string |
appVersion |
appVersion |
Lattice app version string |
capabilities[] |
capabilities[] |
Capability list for the current instance |
readOnly |
readOnly |
Whether the public /api/v1 write surface is currently read-only |
baseURL |
baseURL |
Current localhost base address |
browserExtensionEnabled |
browserExtensionEnabled |
Mirrors the Browser Extension toggle in Settings |
| Field | GET /search query |
GET /search response |
Notes |
|---|---|---|---|
q |
q |
— | Empty query returns recent papers |
limit |
limit |
— | Clamped to 1...50; unparsable values fall back to 10 |
papers[] |
— | papers[] |
Top-level result array |
id |
— | papers[].id |
Search hit paper UUID |
title |
— | papers[].title |
Search hit display title |
authorsDisplay |
— | papers[].authorsDisplay |
Search-only author summary |
subtitle |
— | papers[].subtitle |
Search-only secondary summary |
year |
— | papers[].year |
Search hit year |
citekey |
— | papers[].citekey |
Search hit citation key |
paperType |
— | papers[].paperType |
Search hit paper type |
| Field | GET /metadata query |
GET /metadata response |
Notes |
|---|---|---|---|
doi |
doi |
doi |
At least one of doi, arxivId, isbn, or title is required |
arxivId |
arxivId |
— | Lookup input only |
isbn |
isbn |
isbn |
Can be used as both lookup input and output |
title |
title |
title |
Can be used as both lookup input and output |
authors |
— | authors |
Semicolon-separated author string |
year |
— | year |
Resolved publication year |
journal |
— | journal |
Resolved source / venue |
abstract |
— | abstract |
Resolved abstract text |
volume |
— | volume |
Resolved volume |
issue |
— | issue |
Resolved issue |
pages |
— | pages |
Resolved pages |
paperType |
— | paperType |
Resolved paper type when available |
| Field | GET /collections response |
Notes |
|---|---|---|
id |
[].id |
Collection UUID |
name |
[].name |
Leaf collection name |
path |
[].path |
Full slash-delimited collection path |
depth |
[].depth |
Nesting depth for UI indentation |
| Field | GET /tags response |
Notes |
|---|---|---|
id |
[].id |
Tag UUID |
name |
[].name |
Tag display name |
colorHex |
[].colorHex |
Optional stored color |
| Field | GET /papers/{uuid} response |
GET /metadata response |
POST /papers request |
POST /papers response |
Notes |
|---|---|---|---|---|---|
id |
id |
— | — | id |
Stable paper UUID; can be used to synthesize lattice://paper/{id} |
citekey |
citekey |
— | — | — | Read-only citation key |
title |
title |
title |
title |
title |
Present in read and write flows |
authors |
authors[] |
authors |
authors |
authors |
Detail uses string[]; metadata lookup and write request/response use a semicolon-separated string |
year |
year |
year |
year |
year |
Shared core field |
journal |
journal |
journal |
journal |
— | Accepted on create, returned on detail and metadata lookup, not echoed by create response |
abstract |
— | abstract |
abstract |
— | Stored on create and returned by metadata lookup, not currently exposed by paper-detail payloads |
doi |
doi |
doi |
doi |
doi |
Shared core identifier |
volume |
volume |
volume |
volume |
— | Accepted on create, returned on detail and metadata lookup |
issue |
issue |
issue |
issue |
— | Accepted on create, returned on detail and metadata lookup |
pages |
pages |
pages |
pages |
— | Accepted on create, returned on detail and metadata lookup |
isbn |
isbn |
isbn |
isbn |
— | Accepted on create, returned on detail and metadata lookup |
paperType |
paperType |
paperType |
paperType |
— | Accepted on create, returned on detail, metadata lookup, and search |
pdfPath |
— | — | pdfPath |
— | Input-only field for path-based PDF attachment attempts during create |
collections |
— | — | collections[] |
— | Input-only case-insensitive collection-path list |
tags |
— | — | tags[] |
— | Input-only tag-name list |
enrich |
— | — | enrich |
— | Input-only background enrichment flag |
strategy |
— | — | strategy |
— | Duplicate strategy for create: "skip" or "replace" |
pdfAttached |
— | — | — | pdfAttached |
Whether the paper has an attached PDF after the operation |
enrichmentStatus |
— | — | — | enrichmentStatus |
Output-only write result field: pending or none |
warnings |
— | — | — | warnings[] |
Output-only non-fatal write warnings |
alreadyExists |
— | — | — | alreadyExists |
false for new creates, true when strategy: "replace" updated an existing paper |
conflict |
— | — | — | conflict |
Conflict summary object returned on successful replace responses |
cslItem |
cslItem |
— | — | — | Read-only CSL payload object |
| Field | PUT /papers/{uuid}/pdf request |
PUT /papers/{uuid}/pdf response |
Notes |
|---|---|---|---|
uuid |
path segment | — | Existing paper UUID |
Content-Type |
application/pdf |
— | Required |
| request body | raw PDF bytes | — | Must start with %PDF- |
force |
force=true query |
— | Optional; bypasses the existing-PDF conflict check |
reason |
— | reason |
Success payload currently returns { "reason": "uploaded" } |
| Field | GET /papers/{uuid} response |
Notes |
|---|---|---|
cslItem.id |
cslItem.id |
Same UUID as top-level id |
cslItem.type |
cslItem.type |
CSL item type |
cslItem.title |
cslItem.title |
CSL title |
cslItem.author[] |
cslItem.author[] |
CSL author array |
cslItem.author[].family |
cslItem.author[].family |
Present when the name can be split |
cslItem.author[].given |
cslItem.author[].given |
Present when the name can be split |
cslItem.author[].literal |
cslItem.author[].literal |
Used for mononyms, institutional names, or unsplittable names |
cslItem.container-title |
cslItem.container-title |
Used for non-book container titles |
cslItem.publisher |
cslItem.publisher |
Used for book-like items |
cslItem.issued.date-parts |
cslItem.issued.date-parts |
Currently [[YYYY]] when a year exists |
cslItem.DOI |
cslItem.DOI |
CSL DOI |
cslItem.volume |
cslItem.volume |
CSL volume |
cslItem.issue |
cslItem.issue |
CSL issue |
cslItem.page |
cslItem.page |
CSL pages |
cslItem.ISBN |
cslItem.ISBN |
CSL ISBN |
These fields are not available in GET /search or GET /papers/{uuid} today:
abstractcollectionstagsnotespdfPathpdfURLlatticeURL
Checks whether the service is online and reports which capabilities the current instance supports.
GET /api/v1/status| Field | Type | Description |
|---|---|---|
ok |
boolean |
Health flag. Normally true when the service is available |
apiVersion |
string |
Current Local API version |
appVersion |
string |
Current Lattice app version |
capabilities |
string[] |
Supported capability list |
readOnly |
boolean |
Whether the public /api/v1 write surface is currently read-only |
baseURL |
string |
Current localhost base URL |
browserExtensionEnabled |
boolean |
Mirrors the Browser Extension toggle in Settings |
| Capability | Description |
|---|---|
search |
Paper search is available |
paper-detail |
Per-paper detail fetch by paper ID is available |
csl-item |
Detail payloads include CSL-JSON usable by citation engines |
create-paper-v2 |
The create route supports duplicate strategy and rich create/replace responses |
create-paper |
POST /api/v1/papers is enabled for this Lattice instance |
pdf-upload |
PUT /api/v1/papers/{uuid}/pdf is currently available |
plugin-hosting |
Local plugin static hosting is available |
{
"ok": true,
"apiVersion": "1",
"appVersion": "1.2.3 (456)",
"readOnly": false,
"baseURL": "http://127.0.0.1:29467",
"browserExtensionEnabled": true,
"capabilities": [
"search",
"paper-detail",
"csl-item",
"plugin-hosting",
"create-paper",
"create-paper-v2",
"pdf-upload"
]
}Searches the Lattice library and returns lightweight result cards suitable for suggestion UIs, pickers, and search result lists.
GET /api/v1/search?q=<query>&limit=<n>| Parameter | Required | Type | Default | Description |
|---|---|---|---|---|
q |
No | string |
empty string | Search query. If empty, the endpoint returns recently added papers |
limit |
No | integer |
10 |
Requested result count. Valid integers are clamped to 1...50; unparsable values fall back to 10 |
From an external integration point of view, search matches the following kinds of fields:
- title
- author
- journal / venue / source
citekey- year
{
"papers": [
{
"id": "550E8400-E29B-41D4-A716-446655440000",
"title": "Attention Is All You Need",
"authorsDisplay": "Ashish Vaswani, Noam Shazeer, Niki Parmar, ...",
"subtitle": "Ashish Vaswani, Noam Shazeer, Niki Parmar, ... • 2017 • NeurIPS",
"year": 2017,
"citekey": "vaswani2017attention",
"paperType": "inproceedings"
}
]
}| Field | Type | Description |
|---|---|---|
id |
string |
Paper UUID |
title |
string |
Display title. Empty titles are returned as Untitled |
authorsDisplay |
string |
Author text formatted for direct UI display |
subtitle |
string |
Secondary summary text, typically combining author, year, and source |
year |
integer | null |
Publication year |
citekey |
string |
Preferred citation key. If no persisted key exists, a usable generated key is returned |
paperType |
string |
Paper type |
articlebookinproceedingsthesisreportmisc
curl "http://127.0.0.1:29467/api/v1/search?q=transformer&limit=5"Fetches detailed citation metadata for a single paper.
GET /api/v1/papers/{uuid}| Parameter | Type | Description |
|---|---|---|
uuid |
string |
Paper UUID. If the path segment is not a valid UUID, the request falls through to 404 Not Found |
{
"id": "550E8400-E29B-41D4-A716-446655440000",
"citekey": "vaswani2017attention",
"title": "Attention Is All You Need",
"authors": [
"Ashish Vaswani",
"Noam Shazeer"
],
"year": 2017,
"journal": "NeurIPS",
"doi": "10.5555/example-doi",
"volume": "30",
"issue": null,
"pages": "5998-6008",
"isbn": null,
"paperType": "inproceedings",
"cslItem": {
"id": "550E8400-E29B-41D4-A716-446655440000",
"type": "paper-conference",
"title": "Attention Is All You Need",
"author": [
{
"family": "Vaswani",
"given": "Ashish"
},
{
"family": "Shazeer",
"given": "Noam"
}
],
"container-title": "NeurIPS",
"publisher": null,
"issued": {
"date-parts": [[2017]]
},
"DOI": "10.5555/example-doi",
"volume": "30",
"issue": null,
"page": "5998-6008",
"ISBN": null
}
}| Field | Type | Description |
|---|---|---|
id |
string |
Paper UUID |
citekey |
string |
Preferred citation key |
title |
string |
Title |
authors |
string[] |
Array of author strings |
year |
integer | null |
Year |
journal |
string | null |
Journal, conference, publisher, or other source text |
doi |
string | null |
DOI |
volume |
string | null |
Volume |
issue |
string | null |
Issue |
pages |
string | null |
Page range |
isbn |
string | null |
ISBN |
paperType |
string |
Paper type |
cslItem |
object |
Object ready to be passed to a CSL citation processor |
| Field | Type | Description |
|---|---|---|
id |
string |
Same as the paper ID |
type |
string |
CSL item type |
title |
string |
Title |
author |
object[] |
Author array with family / given / literal fields |
container-title |
string | null |
Journal, proceedings, or other container title |
publisher |
string | null |
Publisher. Common for book-like items |
issued |
object | null |
Date object in the form {"date-parts": [[YYYY]]} |
DOI |
string | null |
DOI |
volume |
string | null |
Volume |
issue |
string | null |
Issue |
page |
string | null |
Pages |
ISBN |
string | null |
ISBN |
| Field | Type | Description |
|---|---|---|
family |
string | null |
Family name when Lattice can split the author name |
given |
string | null |
Given name when Lattice can split the author name |
literal |
string | null |
Literal name used for one-part, institutional, or otherwise unsplittable names |
| Field | Type | Description |
|---|---|---|
date-parts |
integer[][] |
Currently [[YYYY]] when a year exists |
paperType |
cslItem.type |
|---|---|
article |
article-journal |
book |
book |
inproceedings |
paper-conference |
thesis |
thesis |
report |
report |
misc |
article |
GET /api/v1/papers/{uuid} is citation-oriented. It currently does not expose:
abstractcollectionstagsnotespdfPathpdfURLlatticeURL
If your integration only needs to open the paper in Lattice, you can synthesize:
lattice://paper/{id}
The current Local API does not return a dedicated latticeURL field, and it does not expose the local PDF file path.
- Fetch a full paper snapshot before inserting a citation
- Build input for citeproc / CSL engines
- Show a detailed citation card in an external tool
- Maintain a local metadata cache inside a plugin
Returns assignable collections for write-oriented clients.
GET /api/v1/collections[
{
"id": "550E8400-E29B-41D4-A716-446655440000",
"name": "Transformers",
"path": "Deep Learning/Transformers",
"depth": 1
}
]- the response is a top-level JSON array, not an object wrapper
- collections are sorted by
pathusing localized case-insensitive comparison - use
pathas the write-side identifier forPOST /api/v1/papers
Returns assignable tags for write-oriented clients.
GET /api/v1/tags[
{
"id": "550E8400-E29B-41D4-A716-446655440000",
"name": "foundational",
"colorHex": "#FF9500"
}
]- the response is a top-level JSON array, not an object wrapper
- tags are sorted by stored
sortOrderfirst and by name second - use
nameas the write-side identifier forPOST /api/v1/papers
Looks up citation metadata from a lightweight identifier.
GET /api/v1/metadata?doi=<doi>
GET /api/v1/metadata?arxivId=<id>
GET /api/v1/metadata?isbn=<isbn>
GET /api/v1/metadata?title=<title>| Parameter | Required | Type | Description |
|---|---|---|---|
doi |
Conditionally | string |
DOI lookup input |
arxivId |
Conditionally | string |
arXiv ID lookup input |
isbn |
Conditionally | string |
ISBN lookup input |
title |
Conditionally | string |
Title lookup input |
At least one of these parameters must be present and non-empty.
{
"title": "Attention Is All You Need",
"authors": "Ashish Vaswani; Noam Shazeer; Niki Parmar",
"year": 2017,
"journal": "NeurIPS",
"abstract": "The dominant sequence transduction models are based on...",
"doi": "10.48550/arXiv.1706.03762",
"volume": "30",
"issue": null,
"pages": "5998-6008",
"isbn": null,
"paperType": "inproceedings"
}| Status | Typical payload | Meaning |
|---|---|---|
400 |
{"error":"Provide at least one of doi, arxivId, isbn, or title."} |
No lookup key was provided |
404 |
{"error":"Not found"} |
No metadata was resolved |
500 |
{"error":"Internal server error"} |
Encoding or server-side processing failed unexpectedly |
- Prefill a create form from a DOI, arXiv ID, ISBN, or title
- Enrich a host application's lightweight search result before the user commits a write
- Resolve a better title / author list before deciding whether a duplicate should be skipped or replaced
Creates one paper in the library.
- The endpoint path is
POST /api/v1/papers - It is intended for localhost callers only
- It only works when
/status.capabilitiescontainscreate-paper - If write access is disabled, the endpoint returns
403
{
"title": "Attention Is All You Need",
"authors": "Vaswani, Ashish; Shazeer, Noam; Parmar, Niki",
"year": 2017,
"journal": "NeurIPS",
"abstract": "The dominant sequence transduction models are based on...",
"doi": "10.48550/arXiv.1706.03762",
"volume": "30",
"issue": null,
"pages": "5998-6008",
"isbn": "9780306406157",
"paperType": "inproceedings",
"pdfPath": "/Users/me/Papers/attention.pdf",
"collections": ["Deep Learning/Transformers"],
"tags": ["foundational", "NLP"],
"strategy": "skip",
"enrich": true
}| Field | Required | Type | Default | Description |
|---|---|---|---|---|
title |
Yes | string |
none | Paper title. Leading/trailing whitespace is trimmed. Empty or whitespace-only titles are rejected |
authors |
No | string | null |
null |
Author list as a single semicolon-separated string. Example: "Einstein, Albert; Bohr, Niels" |
year |
No | integer | null |
null |
Publication year |
journal |
No | string | null |
null |
Journal, venue, publisher, or other source text |
abstract |
No | string | null |
null |
Abstract text. Stored on the paper, but not returned by the current read endpoints |
doi |
No | string | null |
null |
DOI. Lattice cleans DOI URLs to the canonical DOI form before saving |
volume |
No | string | null |
null |
Volume |
issue |
No | string | null |
null |
Issue |
pages |
No | string | null |
null |
Page range |
isbn |
No | string | null |
null |
ISBN. Cleaned and validated before saving; invalid values are dropped |
paperType |
No | string | null |
"misc" |
Paper type. Matching is case-insensitive. Invalid non-empty values return 400 |
pdfPath |
No | string | null |
null |
Local filesystem path to a PDF to attach. The file must exist, be a PDF, and live inside a Trusted Folder or one of its subfolders. This is an input-only field; it is not returned by GET /papers/{uuid} |
collections |
No | string[] | null |
[] |
Collection paths to assign, using existing collection paths such as "AI/Transformers". Matching is case-insensitive |
tags |
No | string[] | null |
[] |
Tag names to attach. Existing tags are reused; missing tags are created automatically |
strategy |
No | string | null |
"skip" |
Duplicate handling strategy. "skip" returns 409 on duplicate; "replace" updates the existing paper and returns a success response |
enrich |
No | boolean | null |
false |
When true, Lattice queues background enrichment if the created paper has a DOI or an attached PDF |
title: at most1024UTF-8 bytesabstract: at most65536UTF-8 bytesauthors: at most16384UTF-8 bytescollections: at most100itemstags: at most100items- each
collections[i]andtags[i]: at most256UTF-8 bytes
articlebookinproceedingsthesisreportmisc
Status: 201 Created
{
"id": "550E8400-E29B-41D4-A716-446655440000",
"title": "Attention Is All You Need",
"authors": "Vaswani, Ashish; Shazeer, Noam; Parmar, Niki",
"year": 2017,
"doi": "10.48550/arXiv.1706.03762",
"pdfAttached": true,
"enrichmentStatus": "pending",
"warnings": ["Collection not found: Deep Learning/Missing"],
"alreadyExists": false,
"conflict": null
}When strategy: "replace" updates an existing paper, the status is 200 OK and alreadyExists becomes true.
| Field | Type | Description |
|---|---|---|
id |
string |
Newly created paper UUID |
title |
string |
Saved display title |
authors |
string | null |
Saved authors joined with "; " |
year |
integer | null |
Saved year |
doi |
string | null |
Cleaned DOI |
pdfAttached |
boolean |
Whether the paper has an attached PDF after the operation |
enrichmentStatus |
string |
"pending" when enrichment was queued, otherwise "none" |
warnings |
string[] |
Non-fatal issues such as unknown collections or PDF attachment failures |
alreadyExists |
boolean |
false for new creates, true when strategy: "replace" updated an existing paper |
conflict |
object | null |
Conflict summary describing the matched existing paper when replace succeeded |
| Status | Typical payload | Meaning |
|---|---|---|
400 |
{"error":"Malformed JSON"} |
Invalid JSON request body |
400 |
{"error":"Title is required and must not be empty"} |
Missing or blank title |
400 |
{"error":"Invalid paperType"} |
Unsupported paperType value |
400 |
{"error":"Invalid strategy"} |
Unsupported strategy value |
403 |
{"error":"API is in read-only mode"} |
Read-Only Mode is still on |
404 |
{"error":"Not found"} |
Path other than /api/v1/papers |
409 |
{"error":"Duplicate paper found","existingPaperID":"uuid","existingTitle":"...","conflictField":"doi","latticeURL":"lattice://paper/..."} |
Duplicate DOI or normalized title match was found while strategy resolved to "skip" |
422 |
{"error":"Library limit reached","currentCount":50,"limit":50} |
Free-tier paper limit was reached |
500 |
{"error":"Failed to save"} |
Save failed unexpectedly |
- Duplicate detection checks DOI first and normalized title second
strategydefaults to"skip""replace"overwrites fields the incoming request actually supplies, but preserves existing values for omitted optional fieldscollectionsare matched against existing collection paths case-insensitively; missing collections become warnings and are not auto-createdtagsare matched by normalized name; missing tags are created automaticallypdfPathmust point to an existing PDF inside a Trusted Folder or one of its subfolders; failures become warnings and do not abort paper creation- If
pdfPathis outside every Trusted Folder, the warning is:PDF path is not inside a Trusted Folder. Add the enclosing folder in Settings > Local API > Trusted Folders, or attach the PDF manually in Lattice. - Lattice does not copy the PDF file into app storage; it stores a security-scoped bookmark instead
enrich: trueonly queues background enrichment when the created paper has a DOI or an attached PDF- After creation,
GET /api/v1/papers/{uuid}still returns the citation-oriented read payload, not a full echo of all write-time fields
curl -X POST http://127.0.0.1:29467/api/v1/papers \
-H "Content-Type: application/json" \
-d '{"title":"A Brief History of Time"}'Uploads raw PDF bytes to an existing paper.
- The endpoint path is
PUT /api/v1/papers/{uuid}/pdf - It is intended for localhost callers only
- Treat
pdf-uploadin/status.capabilitiesas the source of truth for whether the endpoint is usable - If write access is disabled, the endpoint returns
403
PUT /api/v1/papers/{uuid}/pdf
Content-Type: application/pdfRequest body: raw PDF bytes.
Optional query parameter:
| Parameter | Required | Type | Default | Description |
|---|---|---|---|---|
force |
No | boolean |
false |
When true, bypasses the existing-PDF conflict check |
Status: 201 Created
{
"reason": "uploaded"
}| Status | Typical payload | Meaning |
|---|---|---|
400 |
{"error":"Content-Type must be application/pdf"} |
Wrong or missing content type |
400 |
{"error":"Invalid PDF payload"} |
Body did not look like a PDF |
403 |
{"error":"API is in read-only mode"} |
Read-Only Mode is still on |
404 |
{"error":"Not found"} |
Unknown paper or unknown path |
409 |
{"error":"PDF already attached"} |
The paper already has a PDF and force=true was not supplied |
413 |
{"error":"Payload too large"} |
The PDF body exceeded the upload limit |
503 |
{"reason":"not-configured"} |
No usable PDF upload destination is currently configured |
500 |
{"error":"..."} |
Upload failed unexpectedly |
- the request body must be raw bytes and begin with
%PDF- - the current upload limit for this route is
200000000bytes - a successful upload updates the paper's stored PDF bookmark and may trigger a background refresh
Serves static files from Lattice's local plugin directory.
- Endpoint prefix:
/plugins/ - Purpose: host local front-end assets for plugins and add-ins
- Not part of
/api/v1 - Static files are served from Lattice's sandboxed Application Support plugin directory
- Path traversal attempts are rejected
.html.js.css.json.png.svg.xml.csl
The Local API also accepts OPTIONS to support browser preflight requests.
- Returns
204 No Content - Returns CORS headers for allowed origins
- Does not return business payload data
If your page is hosted by Lattice under /plugins/{name}/..., you usually do not need to handle this explicitly.
By default, the Local API is intended for local browser origins:
http://localhost:*https://localhost:*http://127.0.0.1:*https://127.0.0.1:*
This is why hosting your plugin page under /plugins/{name}/... is the simplest and most reliable option.
Advanced note:
- the server allows
GET, POST, PUT, OPTIONS - the CORS allowlist can be extended with the
citationBridgeAllowedOriginsuser-defaults override when needed for advanced integrations
For most routes, the total HTTP request size is limited to 262144 bytes (256 KiB), including headers and body.
PUT /api/v1/papers/{uuid}/pdf has a larger PDF body limit of 200000000 bytes.
curl http://127.0.0.1:29467/api/v1/papers/not-a-uuid{
"error": "Not found"
}curl http://127.0.0.1:29467/api/v1/metadata{
"error": "Provide at least one of doi, arxivId, isbn, or title."
}{
"error": "Not found"
}- If you have not yet verified that the service is reachable, start with Quick Start
- If you are building a local plugin or host extension, pair this with Plugin Development Guide