Sections

Imports and private documents

Bring papers into the library, and the member's private documents

POST/documents

Start uploading a PDF from the member's machine

API key or sign-inMCP: create_uploadwrite

An assignment brief, or a paper they were given and downloaded. Returns a presigned URL: PUT the file to it directly (see `curl` in the result), then call extract_brief (kind "brief") or ingest_pdf (kind "paper") with the returned document_id. The URL is single-purpose and expires in minutes. Uploaded files are private to the member's account and never shown to anyone else.

Request body (JSON)
FieldTypeDescription
filename *stringThe PDF's filename, ending in .pdf
kind *"brief" | "paper""brief" (assignment brief) or "paper" (a PDF they were given)
project_idinteger | nullOptional project to attach the document to (can be set later)
Response: UploadResponse
FieldTypeDescription
content_type *string
curl *stringA ready-made upload command
document_id *integer
expires_in_seconds *integer
kind *string
max_bytes *integer
method *string
next_step *stringextract_brief for a brief, ingest_pdf for a paper
upload_url *stringPresigned URL: PUT the PDF here
curl
curl -X POST 'https://api.papervantage.com/documents' \
  -H "Authorization: Bearer $PV_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"kind":"brief","filename":"<filename>"}'
pv
pv documents create-upload --filename <filename> --kind <kind>

DELETE/documents/{document_id}

Permanently delete one private document: its stored text, chunks and files

API key or sign-inMCP: delete_documentdestructive

Public papers are never affected.

Parameters
NameInTypeDescription
document_id *pathinteger
Response: DeletedResponse
FieldTypeDescription
document_id *integer
status *string
curl
curl -X DELETE 'https://api.papervantage.com/documents/1' \
  -H "Authorization: Bearer $PV_API_KEY"
pv
pv documents delete <document_id>

GET/documents/{document_id}

Status and content of one private document

API key or sign-inMCP: get_document

Use it to re-check a document still "processing" or "queued", or to read its text.

Parameters
NameInTypeDescription
document_id *pathinteger
include_transcriptquerybooleanInclude the converted markdown Default: false
max_charsqueryintegerCap on the markdown returned (1000-200000) Default: 60000
Response: DocumentResponse
FieldTypeDescription
abstractstring | null
authorsstring | null
created_at *string | null
document_id *integer
error *string | null
filename *string
kind *string
markdownstring | null
markdown_errorstring | null
matched_paperobject | null
matched_paper_id *integer | nullSet when the PDF is a paper the library already holds
notestring | null
page_count *integer | null
private *boolean
project_id *integer | null
queue_notestring | null
status *stringqueued, processing, succeeded or failed
structuredobject | nullA brief's parsed requirements
summarystring | null
title *string | null
curl
curl 'https://api.papervantage.com/documents/1' \
  -H "Authorization: Bearer $PV_API_KEY"
pv
pv documents get <document_id>

POST/documents/{document_id}/brief

Convert an uploaded assignment-brief PDF to markdown and parse its requirements

API key or sign-inMCP: extract_briefcostly

Call after the upload. Waits up to wait_seconds for the conversion; if it is not finished the status is "processing" (or "queued" while it waits for a processing worker): check again with GET /documents/{id}.

On success returns `markdown` (the brief as text) and `structured`: title, module, deadline (YYYY-MM-DD), word_count {min,max}, citation_style, questions, rubric [{criterion, weight, descriptors}], required_sections, constraints. Fields not stated in the brief are null or empty, never guessed: check `structured` against `markdown` before relying on it.

Parameters
NameInTypeDescription
document_id *pathinteger
Request body (JSON)
FieldTypeDescription
project_idinteger | nullOptional project to attach the brief to
wait_secondsintegerHow long to wait for the result (0-25, default 20)
Response: DocumentResponse
FieldTypeDescription
abstractstring | null
authorsstring | null
created_at *string | null
document_id *integer
error *string | null
filename *string
kind *string
markdownstring | null
markdown_errorstring | null
matched_paperobject | null
matched_paper_id *integer | nullSet when the PDF is a paper the library already holds
notestring | null
page_count *integer | null
private *boolean
project_id *integer | null
queue_notestring | null
status *stringqueued, processing, succeeded or failed
structuredobject | nullA brief's parsed requirements
summarystring | null
title *string | null
curl
curl -X POST 'https://api.papervantage.com/documents/1/brief' \
  -H "Authorization: Bearer $PV_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"project_id":1}'
pv
pv documents extract-brief <document_id>

POST/documents/{document_id}/ingest

Add a PDF the member already has to a project

API key or sign-inMCP: ingest_pdfcostly

Call after the upload (kind "paper"). The PDF is converted and indexed PRIVATELY: searchable by the member only, never displayed to anyone else, and not added to the shared library. If it is a paper the library already holds (same arXiv id, DOI or title), the public record is attached to the project instead (`matched_paper_id` / `matched_paper`) and no private copy is stored. Waits up to wait_seconds; if unfinished the status is "processing" or "queued".

Parameters
NameInTypeDescription
document_id *pathinteger
Request body (JSON)
FieldTypeDescription
project_id *integerThe project to add it to
wait_secondsintegerHow long to wait for the result (0-25, default 20)
Response: DocumentResponse
FieldTypeDescription
abstractstring | null
authorsstring | null
created_at *string | null
document_id *integer
error *string | null
filename *string
kind *string
markdownstring | null
markdown_errorstring | null
matched_paperobject | null
matched_paper_id *integer | nullSet when the PDF is a paper the library already holds
notestring | null
page_count *integer | null
private *boolean
project_id *integer | null
queue_notestring | null
status *stringqueued, processing, succeeded or failed
structuredobject | nullA brief's parsed requirements
summarystring | null
title *string | null
curl
curl -X POST 'https://api.papervantage.com/documents/1/ingest' \
  -H "Authorization: Bearer $PV_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"project_id":1}'
pv
pv documents ingest <document_id> --project-id <project_id>

GET/papers/imports

Where your imports are

API key or sign-inMCP: get_import_status

Each import is "queued" (waiting for the PDF fetch), "queued_waiting_for_workers" (waiting, and the background workers look offline: it will resume when they're back), "fetching" (being converted), "converted" (full text ready, search index pending), "chunked" (fully searchable) or "failed" (with error). No timing is promised. Also returns the import allowance. Imports into one project: GET /projects/{project_id}/imports.

Parameters
NameInTypeDescription
import_idsqueryinteger[] | nullOnly these imports
Response: ImportStatusResponse
FieldTypeDescription
allowance *object
imports *object[][{identifier, status: queued|queued_waiting_for_workers|fetching|converted|chunked|failed, ...}]
curl
curl 'https://api.papervantage.com/papers/imports' \
  -H "Authorization: Bearer $PV_API_KEY"
pv
pv imports status

POST/papers/imports

Import papers into the library by arXiv id or DOI, or from a .bib/.ris file

API key or sign-inMCP: import_paperscostly

Up to 25 identifiers, or a .bib/.ris export's text (file_text). Papers already in the library are free; only new ones count against the import allowance. New papers' PDFs are then converted in the background: check GET /papers/imports. To add them to a project too, use POST /projects/{project_id}/imports.

Returns {"imports": [{identifier, status: added|already_in_library|failed, paper_id, title, counted, error}], "allowance", "skipped" (file entries with no id)}.

Request body (JSON)
FieldTypeDescription
file_textstring | nullContents of a .bib or .ris file instead of identifiers
identifiersstring[] | nullarXiv ids (2306.03310), arXiv/doi.org URLs or DOIs (up to 25)
Response: ImportsResponse
FieldTypeDescription
allowance *objectThe import allowance: used, limit, ...
imports *object[][{identifier, status: added|already_in_library|failed, paper_id, title, counted, error}]
skippedstring[]File entries with no arXiv id or DOI
curl
curl -X POST 'https://api.papervantage.com/papers/imports' \
  -H "Authorization: Bearer $PV_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"file_text":"<file_text>"}'
pv
pv imports start <identifiers>...

POST/papers/ingest/title

Find a paper by title on Semantic Scholar and add it to the library

API key or sign-inMCP: search_and_ingest_papercostly

Searches Semantic Scholar by title (and optionally author) and ingests the best-matching paper into PaperVantage's library through the same pipeline as a direct arXiv import (summary generation, embedding, reference extraction). Only papers with an arXiv id can be ingested. Prefer POST /papers/imports (by arXiv id or DOI; find them with GET /papers/search?mode=title), which is metered and can add to a project.

Request body (JSON)
FieldTypeDescription
authorstring | nullOptional author name to disambiguate if multiple papers share the title
title *stringPaper title (required)
Response: PaperResponse
FieldTypeDescription
abstract *string
arxiv_idstring | null
authors *string
categories *string
citation_countinteger
classic_rankinteger | null
created_at *string
dislikesinteger
doistring | null
hot_score *number
id *integer
is_classicboolean
likesinteger
match_reasonstring | null
match_scorenumber
pdf_urlstring | null
published_datestring | null
relevance_scorenumber | null
source *string
summarystring | null
title *string
viewer_ratinginteger | null
viewer_readboolean | null
curl
curl -X POST 'https://api.papervantage.com/papers/ingest/title' \
  -H "Authorization: Bearer $PV_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"<title>"}'
pv
pv papers import-title <title>

GET/projects/{project_id}/imports

Where this project's imports are

API key or sign-inMCP: get_import_status

Each import is "queued" (waiting for the PDF fetch), "queued_waiting_for_workers" (waiting, and the background workers look offline: it will resume when they're back), "fetching" (being converted), "converted" (full text ready, search index pending), "chunked" (fully searchable) or "failed" (with error). No timing is promised. Also returns the import allowance.

Parameters
NameInTypeDescription
project_id *pathinteger
import_idsqueryinteger[] | nullOnly these imports
Response: ImportStatusResponse
FieldTypeDescription
allowance *object
imports *object[][{identifier, status: queued|queued_waiting_for_workers|fetching|converted|chunked|failed, ...}]
curl
curl 'https://api.papervantage.com/projects/1/imports' \
  -H "Authorization: Bearer $PV_API_KEY"
pv
pv imports project-status <project_id>

POST/projects/{project_id}/imports

Import papers into the library and this project, by arXiv id or DOI, or from a .bib/.ris file

API key or sign-inMCP: import_paperscostly

Up to 25 identifiers, or a .bib/.ris export's text (file_text). Papers already in the library are free and attach at once; only new ones count against the import allowance. New papers' PDFs are then converted in the background: check GET /projects/{project_id}/imports. In the in-paper assistant this always waits for the member's Confirm click (HTTP 202 with the pending action).

Returns {"imports": [{identifier, status: added|already_in_library|failed, paper_id, title, counted, error}], "allowance", "skipped" (file entries with no id)}.

Parameters
NameInTypeDescription
project_id *pathinteger
Request body (JSON)
FieldTypeDescription
file_textstring | nullContents of a .bib or .ris file instead of identifiers
identifiersstring[] | nullarXiv ids (2306.03310), arXiv/doi.org URLs or DOIs (up to 25)
Response: ImportsResponse
FieldTypeDescription
allowance *objectThe import allowance: used, limit, ...
imports *object[][{identifier, status: added|already_in_library|failed, paper_id, title, counted, error}]
skippedstring[]File entries with no arXiv id or DOI

In an in-paper assistant turn this write may answer 202 with a pending action for the member to confirm.

curl
curl -X POST 'https://api.papervantage.com/projects/1/imports' \
  -H "Authorization: Bearer $PV_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"file_text":"<file_text>"}'
pv
pv imports start-in-project <project_id> <identifiers>...

Next: Library