---
title: "Get File"
method: GET
path: "/v1/files/{file_id}"
tags: ["files"]
---

# Get File

`GET /v1/files/{file_id}`

## Request

- Base URL: `https://api.versionstory.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.versionstory.com/v1/files/{file_id}`
- Auth: HTTP bearer

Download a file in each format asked for: docx (the default), pdf, md or json (its listing) or html,
and a comparison's redline also pdf_changed_pages_only (the pages that changed); a workbook or
presentation as it is, and a presentation comparison's redline also as pdf. Use it for a version of a document (by its file_id from
GET /v1/documents/{document_id}) when the user wants that version's file: to save, send or replace their copy. An edit's
or a merge's own result comes from GET /v1/edit/{edit_id} or GET /v1/merge/{merge_id}, and a version's redline from
GET /v1/compare/{comparison_id} with its comparison_id. A format still being made is reported in pending_formats: call
again to keep waiting. Each downloads[] entry's url serves the file directly and expires after one
hour.

To send a document outside the firm without its hidden data, ask for it with clean_metadata. Each
downloads[] entry then carries metadata_report: tell the user what was removed (its items) and pass on its
warnings. To clean a document the user has as a file, upload it with POST /v1/files first, and a
redline by the file.file_id GET /v1/compare/{comparison_id} returned.

To read a long document's md listing before editing it, search for the words and phrases the request names
(search, several at once), and read it in parts (max_chars, then next_offset) only when a result was cut off.

## Path parameters

- `file_id` string, required

## Query parameters

- `format` string[], nullable: docx (default), pdf, md, json, html; repeatable or comma-separated. pdf is the document to show a person, docx the Word file. md and json are the file's content listing, which every edit copies its locators from (GET /v1/reference/listing explains it; components.schemas.StructuredDocument is json's shape): md, the listing to write every edit from, and json, the same listing as structured data. html is the document to embed in a page where the view must be interactive: frame its url in <iframe sandbox="allow-scripts">, with the embed origin and display options in its fragment. A comparison's redline is also served as pdf_changed_pages_only, the pages that changed. A workbook or presentation is served as it is (xlsx, pptx), and a presentation comparison's redline also as pdf.
- `clean_metadata` 'standard' | 'strict', nullable: standard or strict: download each format with its metadata removed. standard removes what nobody sees (properties, revision ids, hidden text, custom XML and the rest); strict also removes comments and speaker notes, accepts tracked changes and anonymizes authors. Each download then carries metadata_report.
- `clean_metadata_revisions` 'keep' | 'accept' | 'reject', nullable: With clean_metadata: keep, accept or reject tracked changes; overrides the preset.
- `clean_metadata_comments` 'keep' | 'remove', nullable: With clean_metadata: keep or remove comments; overrides the preset.
- `clean_metadata_authors` 'keep' | 'anonymize', nullable: With clean_metadata: keep or anonymize authors; overrides the preset.
- `search` string[], nullable: Words or phrases to find, ignoring case, matched as an edit's text is: returns only the paragraphs holding one, with their indexes, and how many hold each. md only, and not with offset or max_chars.
- `offset` integer, nullable: Where a part starts: 0 (default) or a next_offset. md only.
- `max_chars` integer, nullable: The most characters a part holds, ending at a paragraph; next_offset is where the next part starts. md only.

## Headers

- `X-Customer-Id` string, nullable: Id of one of your customers (created in the developer dashboard) to attribute this request's credit usage to. Billing and limits stay organization-wide.

## Response `200`

Successful Response

- FileReadResponse: GET /v1/files/{file_id}'s answer: the File, and with format=md and search, offset or max_chars, the part of the md listing that read asks for, from its stored md (markdown_listing.read_markdown).
  - `file_id` string, required
  - `file_name` string, required
  - `status` 'processing' | 'ready' | 'failed', required: The state of the formats this request asked for: processing while one is still being produced (poll again after Retry-After), ready when every one is in downloads, failed when the document cannot be used (error) or a requested format will never be produced.
  - `downloads` FormatDownload[], nullable: One per requested format that is ready.
    - `format` string, required
    - `url` string, required: Signed; it expires at expires_at.
    - `file_name` string, required
    - `expires_at` string, required: ISO 8601 in UTC, to the second: 2026-10-21T18:22:31Z.
    - `metadata_report` MetadataReport: What a clean found in one download and did to each kind of hidden data.
      - `format` string, required: docx, xlsx, pptx, pdf or zip.
      - `preset` string, required: standard or strict.
      - `items` MetadataReportItem[], required
        - `type` string, required: The kind of hidden data, such as author, tracked_changes or hidden_text.
        - `category` string, required: properties, review, hidden, automation, package or visible.
        - `count` integer, required: How many were found.
        - `action` string, required: What was done: remove, reset, accept, reject, anonymize, convert, unlink, apply, flatten or clean; keep or report when it was left in place.
        - `examples` string[]: A few of the values found, when they are names.
      - `warnings` MetadataReportWarning[], required
        - `type` string, required: The kind of hidden data the warning is about.
        - `message` string, required: What the reader should know before sending the document.
      - `files` integer, nullable: For a zip, how many documents inside it were cleaned.
    - `content_base64` string, nullable: Only in an edit's or a creation's files, with inline=true: the file's bytes, base64-encoded.
  - `pending_formats` string[], nullable: Requested formats still being produced.
  - `failed_formats` string[], nullable: Requested formats that will never be produced.
  - `error` ComparisonErrorDescriptor
    - `code` string, required
    - `upstream_code` string, nullable
  - `markdown` string, nullable: With search, offset or max_chars, once md is ready: with search, only the matching paragraphs, without the header, each after the lines naming its part, table, row and cell; with offset or max_chars, one part, opening with those lines when it starts inside a part or table.
  - `matches` SearchMatch[], nullable: With search: each phrase, in the order given, and how many paragraphs hold it.
    - `phrase` string, required: A phrase searched for, without the spaces around it.
    - `paragraphs` integer, required: How many paragraphs hold the phrase; 0 when none does.
  - `omitted_paragraphs` integer, nullable: With search: the matching paragraphs left out once markdown reached 48,000 characters.
  - `total_chars` integer, nullable: With offset or max_chars: the length of the whole listing, in characters.
  - `next_offset` integer, nullable: With offset or max_chars: where the next part starts; absent once a part ends the listing.
  - `message` string, nullable: With search: the next step when not every matching paragraph fit in markdown.

## Other responses

- `400`: The request is invalid: INVALID_REQUEST when a parameter or the body fails validation, otherwise the code of the operation's own refusal.

---

[API](https://skmtc.dev/versionstory/apis/version-story-public-api.md) - [All operations](https://skmtc.dev/versionstory/apis/version-story-public-api/llms.txt) - [OpenAPI document](https://skmtc.dev/versionstory/apis/version-story-public-api/revisions/994ce15faf32?raw)
