---
title: Files and documents
sidebar_label: Files and documents
description: "Store, list, download, replace, update and delete files with the document routes, and choose between the private and public download."
---

# Files and documents

The document routes store files in your project. Each file has a document record, a FHIR [`DocumentReference`](/api/fhir/r4/document-reference), that holds its name, type and author. You list, change and delete files through that record.

Ovok never receives the file bytes. You create the document, Ovok returns a short-lived signed form, and you upload the file straight to file storage with it.

Use `https://api.sandbox.ovok.com` for the examples. These routes are not versioned: the paths start with `/document`, with no `/v1`. Send a bearer token on every route except the public download. Each route runs with your token, so the project and the AccessPolicy in the token decide what you can reach. See [Authentication](/authentication) and [Access policies](/access-policies).

## How a file moves

1. **Create the document.** `POST /document` with the file name and type. The answer holds the document `id` and `uploadOptions`: an upload `url` and the form `fields`.
2. **Upload the file.** Send a `multipart/form-data` `POST` to `uploadOptions.url` with every entry of `uploadOptions.fields` as a form field, then the file as the last part, named `file`. The form is valid for 10 minutes and accepts files up to 5 GB.
3. **Use the document.** List documents with `GET /document`. Download one with `GET /document/:id`, which answers with a redirect to a signed file URL. For a public document, anyone with its `publicToken` can download it with `GET /document/public/:token`.
4. **Change it.** `PATCH /document/:id` renames it, changes its type, or makes it public or private. `POST /document/:id` replaces the file and returns a new upload form. `DELETE /document/:id` removes the file and the document.

The document exists as soon as step 1 returns, even if you never complete step 2.

## Which route to use

| I want to… | Route | Page |
| --- | --- | --- |
| Add a new file | `POST /document`, then upload to `uploadOptions.url` | [Create document](/files-and-documents/create-document) |
| Put a new file in an existing document | `POST /document/:id`, then upload | [Replace document file](/files-and-documents/replace-document) |
| List the documents I can read | `GET /document` | [Search documents](/files-and-documents/search-documents) |
| Download a file as a signed-in user | `GET /document/:id` | [Download document](/files-and-documents/get-document) |
| Embed or share a file without a token | `GET /document/public/:token` | [Download public document](/files-and-documents/get-public-document) |
| Rename a file, change its type, or make it public or private | `PATCH /document/:id` | [Update document metadata](/files-and-documents/update-document) |
| Remove a file | `DELETE /document/:id` | [Delete document](/files-and-documents/delete-document) |

## Routes

- [`POST /document` — Create document](/files-and-documents/create-document)
- [`POST /document/:id` — Replace document file](/files-and-documents/replace-document)
- [`GET /document` — Search documents](/files-and-documents/search-documents)
- [`GET /document/:id` — Download document](/files-and-documents/get-document)
- [`GET /document/public/:token` — Download public document](/files-and-documents/get-public-document)
- [`PATCH /document/:id` — Update document metadata](/files-and-documents/update-document)
- [`DELETE /document/:id` — Delete document](/files-and-documents/delete-document)

## What the AccessPolicy must allow

| Route | Needs |
| --- | --- |
| `POST /document` | `Binary:create` and `DocumentReference:create` |
| `POST /document/:id` | `DocumentReference:read` and `DocumentReference:update` |
| `GET /document` | `DocumentReference:search` and `DocumentReference:read` |
| `GET /document/:id` | `DocumentReference:read` |
| `GET /document/public/:token` | Nothing. No bearer token is needed. |
| `PATCH /document/:id` | `DocumentReference:read` and `DocumentReference:update` |
| `DELETE /document/:id` | `DocumentReference:read` and `DocumentReference:delete` |

A document belongs to the project of the token that created it. A document you cannot see answers `404` or `403`, depending on the policy.

## Allowed file types

`contentType` must be one of these values, matched exactly:

- Images: `image/jpeg`, `image/jpg`, `image/png`, `image/gif`, `image/webp`
- Documents: `application/pdf`, `application/json`, `application/xml`, `text/plain`, `text/csv`
- Video: `video/mp4`, `video/webm`
- Audio: `audio/mpeg`, `audio/wav`

Any other value is rejected with `400`. The upload form limits the size of the file only. It does not check that the bytes match `contentType`.

## Errors

Validation failures on these routes answer `400`, not `422`. `message` is then a list of strings of the form `path: message`, for example `fileName: Required`. Every error body has `statusCode`, `error`, `timestamp`, `path`, `message` and `requestId`.

## Deprecated file routes

The older `/binary` routes are deprecated and still answer. The document routes replace them: they cover uploads through the signed form, and downloads by document id or public token. Use the document routes for new work.

- [`POST /binary/single` — Upload binary file (deprecated)](/files-and-documents/upload-binary)
- [`GET /binary/:documentReferenceId` — Download binary file (deprecated)](/files-and-documents/download-binary)
