A file is one immutable document held by Version Story, named by a file_id. Uploads, a
comparison's redline, an edit's results and created documents are all files, and every endpoint
that reads a document takes its file_id. Every response that carries a document carries it as the
same File object, the one GET /v1/files/{file_id} answers with.
| Base URL | https://api.versionstory.com |
| Auth | Authorization: Bearer vs_.... See Authentication |
POST /v1/files
multipart/form-data with one file field, document: a .docx, .doc or .pdf to read, edit or
show, or a .xlsx or .pptx to compare with another of its kind.
curl -sS https://api.versionstory.com/v1/files \
-H "Authorization: Bearer vs_live_..." \
-F "document=@nda.docx"{ "file_id": "3f2a9c1e-...", "status": "processing" }- A
.docxanswers at once while it is prepared in the background.processingneeds no polling of its own: every request that reads the file waits for it. - A
.docor.pdfis converted to Word first. The request waits up to 20 seconds and answersready,failedwith anerror, orprocessingif conversion is still running. A redline PDF's insertions and deletions become tracked changes; send the optional fieldtrack_redline_changes=falseto keep them as formatting. See Redline PDFs. - A workbook or presentation is stored as it is and answers
ready. It can be compared, never read or edited.
GET /v1/files/{file_id}
Signed downloads for one file. The pdf shows the file's own tracked changes and comments as a
redline: it is what to show a person.
| Parameter | In | Required | Default | Meaning |
|---|---|---|---|---|
file_id | path | Yes | — | The file's id |
format | query | No | docx | One or more of pdf, html, docx, md, json. Repeatable or comma-separated. A workbook or presentation is served as it is (xlsx, pptx) |
clean_metadata | query | No | — | standard or strict: serve every format with its metadata removed. See Clean metadata |
clean_metadata_revisions | query | No | the preset's | With clean_metadata: keep, accept or reject tracked changes |
clean_metadata_comments | query | No | the preset's | With clean_metadata: keep or remove comments |
clean_metadata_authors | query | No | the preset's | With clean_metadata: keep or anonymize the names on changes and comments |
search | query | No | — | md only: return only the paragraphs holding a phrase. See Reading the listing |
offset, max_chars | query | No | — | md only: read the listing in parts. See Reading the listing |
format | Is |
|---|---|
pdf | The document as a PDF, with its tracked changes and comments shown. The view to show a person |
html | The document as one self-contained HTML file, to frame where the view must be interactive. See Embed redlines |
docx | The Word file |
md | The document's listing as Markdown: its text, each paragraph's locator, and its tracked changes. What edits are written from, and what a model reads. See Edit |
json | The same listing as structured data, for code. See Document JSON |
curl -sS "https://api.versionstory.com/v1/files/3f2a9c1e-...?format=pdf,docx" \
-H "Authorization: Bearer vs_live_..."{
"file_id": "3f2a9c1e-...",
"file_name": "nda.docx",
"status": "processing",
"downloads": [
{
"format": "docx",
"url": "https://documents.versionstory.com/...",
"file_name": "nda.docx",
"expires_at": "2026-10-22T18:00:00Z"
}
],
"pending_formats": ["pdf"]
}status is the state of the formats this request asked for: processing while one is still being
made (the response carries Retry-After; poll again), ready when every one is in downloads, and
failed when the document cannot be used or a requested format will never be made. The first request
for a PDF or HTML starts making it. A format that failed is named in failed_formats, and a file whose
source could not be read at all answers "status": "failed" with an error.
Signed links are valid for one hour, and polling again mints fresh ones. A workbook or presentation
has no pdf, html, md or json, and asking for one is 400 UNSUPPORTED_FORMAT.
Reading the listing
The md listing of a long document can be large. Two ways to read only part of it, both for md
alone:
search, repeated for several phrases (?format=md&search=Closing&search=36%20months). Once the listing is ready, the response addsmarkdown, holding only the paragraphs that contain a phrase, each after the lines that say where it is (its header, footer, note, table, row and cell).matchesgives each phrase with the number of paragraphs holding it. A phrase matches as an edit's text selector does, ignoring case. The paragraphs stop at 48,000 characters, andomitted_paragraphsthen counts those left out.offsetandmax_charsread the listing in parts.markdownholds the part starting atoffset(0, or the last response'snext_offset) and ending at the last whole line that fits inmax_chars. The response addstotal_charsand, until the part reaches the end,next_offset.
search takes neither offset nor max_chars; sending them together, or with any format but md,
is 400 INVALID_REQUEST.
Clean metadata
A document carries more than its text: who wrote and edited it, when, on which template and from
which network folder, its comments and tracked changes, hidden text, and the earlier revisions a PDF
keeps. Add clean_metadata to download a copy without it, to send outside the firm.
curl -sS "https://api.versionstory.com/v1/files/3f2a9c1e-...?format=pdf,docx&clean_metadata=standard" \
-H "Authorization: Bearer vs_live_..."| Preset | What it removes |
|---|---|
standard | What nobody sees on the page: document properties, people and account ids, revision ids, hidden text, document variables, mail merge sources, custom XML, printer settings, image metadata, and a PDF's XMP, earlier revisions and JavaScript. Tracked changes, comments and authors' names stay |
strict | Everything standard removes, and the review: tracked changes accepted, comments, PDF notes and speaker notes removed, authors anonymized, white or tiny text, hidden sheets and slides, and macros removed, and PDF form fields and stamps flattened into the page |
The three choices override the preset: clean_metadata=standard&clean_metadata_comments=remove keeps
tracked changes but removes comments. Each choice needs clean_metadata; one sent without it is
400 INVALID_REQUEST, so a request never gets the uncleaned document by mistake. clean_metadata
cleans documents, not listings, so it does not apply to md, json or html.
Each download in the response is the cleaned copy, with a metadata_report:
{
"format": "docx",
"url": "https://documents.versionstory.com/...",
"file_name": "nda.docx",
"expires_at": "2026-10-22T18:00:00Z",
"metadata_report": {
"format": "docx",
"preset": "standard",
"items": [
{ "type": "author", "category": "properties", "count": 1, "action": "remove", "examples": [] },
{ "type": "comments", "category": "review", "count": 4, "action": "keep", "examples": [] }
],
"warnings": [
{ "type": "document_numbers", "message": "A header or footer shows a document number or file path. It is visible text, so it was left in place." }
]
}
}items lists every kind of hidden data found and the action taken: what was removed, reset or
converted, and with keep or report, what was left in place. Show the warnings to whoever sends
the document; they name what the cleaner cannot decide for you, such as visible document numbers or
text under a dark box that only looks redacted. Every type and what each preset does to it is in
Metadata types.
A PDF that Version Story made from a Word file (a redline's, or an uploaded document's) draws its
comments, their authors and its tracked changes onto the page, where no clean of the PDF can reach
them. So its clean cleans the Word file with the same options and renders the PDF again: what the
options remove from the Word file is gone from the PDF too. A comparison's redline is cleaned through
this endpoint by its file.file_id.
A format whose clean is still running is in pending_formats, as a PDF still converting is; poll
until it is ready. One that cannot be cleaned is in failed_formats, and its uncleaned original is
never served in its place. Word, Excel, PowerPoint and PDF files are cleaned, and each copy is kept for
the options that made it, so asking again is immediate.
POST /v1/files/{file_id}/acknowledge
For an organization with zero-day retention, deletes an uploaded file, a created document or a selective comparison's PDF as soon as you have saved what you need, instead of an hour after it was created. No body.
curl -sS -X POST https://api.versionstory.com/v1/files/3f2a9c1e-.../acknowledge \
-H "Authorization: Bearer vs_live_..."{ "file_id": "3f2a9c1e-...", "status": "deletion_queued" }An edit's files are deleted with the edit: acknowledge those with
POST /v1/edit/{edit_id}/acknowledge.
Errors
| Status | Code | Cause |
|---|---|---|
| 400 | INVALID_REQUEST | A missing or empty document; an unknown clean_metadata value, a choice sent without it, or clean_metadata with md, json or html; or search, offset or max_chars sent together or with a format other than md |
| 400 | UNSUPPORTED_FILE_TYPE | The upload is not a .docx, .doc, .pdf, .xlsx or .pptx |
| 400 | DOCUMENT_UNREADABLE | The upload is not a readable Word file: corrupt, or encrypted |
| 400 | UNSUPPORTED_FORMAT | A format is unknown, or not offered for this file |
| 401 | INVALID_API_KEY | Missing, malformed, unknown, revoked, or expired key |
| 402 | USAGE_LIMIT_REACHED | The organization's monthly upload allowance is exhausted |
| 404 | FILE_NOT_FOUND | No such file, or it belongs to another organization |
| 409 | CONFLICT | An acknowledgment of a file without zero-day retention, or of an edit's own file |
| 410 | CONTENT_DELETED | The file's content was deleted under zero-day retention |
| 413 | FILE_TOO_LARGE | The upload exceeds the 100 MB limit |
Kept for existing integrations
GET /v1/files/{file_id}/content answers the listing in the response body rather than as a download:
markdown with format=md, document with format=json. It is deprecated, and marked so in the
OpenAPI specification; read the md and json downloads above instead. Its document gives level
the meaning the download calls list_level.
Related
- Edit: change a document with tracked changes
- Embed redlines: frame a document's HTML
- Metadata types: every kind of hidden data a clean reports
- Data handling: what is kept, and for how long