---
title: "Start a file upload"
description: "Starts publishing a file of any size: send its name, size and SHA-256, and get back presigned URLs to PUT each part to."
canonical_url: https://docs.markdrop.in/api/files/start-a-file-upload
last_updated: 2026-10-30
site: "Markdrop Docs"
index: https://docs.markdrop.in/llms.txt
---

# Start a file upload

`POST https://api.markdrop.in/api/v1/files/uploads`

Starts publishing a file of any size: send its name, size and SHA-256, and get back presigned URLs to `PUT` each part to. Then [finish the upload](https://docs.markdrop.in/api/files/finish-a-file-upload). With `target_slug`, the file replaces the one behind an existing link instead, keeping the link, its access and its views.

The CLI does all of this, with resume, in one command.

- **Authentication:** API token required: `Authorization: Bearer mdk_…`.
- **Rate limit:** 30 per minute per IP address.
- **CLI:** `markdrop upload deck.pdf --title "Q3 deck"`
- **MCP tool:** `create_upload` ([tools](https://docs.markdrop.in/ai/tools))
- **Guide:** [Large uploads](https://docs.markdrop.in/files/large-uploads)

## Request body

`application/json`, required.

- `file_name` (string, required): The file's name, with its extension. 1–255 characters.
- `size_bytes` (integer, required): The file's exact size in bytes. At least 1.
- `content_type` (string): Up to 255 characters. Default `""`.
- `sha256` (string, required): The SHA-256 of the whole file, in hex. The server checks it before the file goes live. Matches `^[0-9a-fA-F]{64}$`.
- `target_slug` (string): Replace the file behind this existing address instead of publishing a new one. The link, access and views stay. Matches `^[A-Za-z0-9_-]{1,64}$`.
- `title` (string): Shown on the page and in link previews. Up to 200 characters.
- `access` ("link" | "private" | "password" | "workspace"): Who can open it: `link`, `private`, `password` (needs `password`) or `workspace` (needs `workspace`).
- `password` (string): 1–100 characters.
- `workspace` (string): File it in this workspace: the workspace's id. 1–64 characters.
- `folder` (string): An existing folder of `workspace`: its id or its path, like `guides/setup`. 1–400 characters.
- `slug` (string): Your own address: `markdrop.in/<slug>`. 3–50 characters. Matches `^[a-zA-Z0-9_-]+$`.

## Responses

- `200`: OK.
  - `upload_id` (string)
  - `part_size` (integer)
  - `parts` (array of object)
    - `part_number` (integer)
    - `url` (string)
  - `expires_at` (string (date-time)): ISO 8601, for example `2026-11-30T12:00:00Z`.
- `401`: No token, or the token is revoked or mistyped.
- `409`: The address you asked for is taken, or reserved.
- `413`: The file is over the size limit for its type.
- `422`: The request didn't validate. `detail` lists each problem, with where it is (`loc`) and why (`msg`).
- `429`: Too many requests from your IP address. Wait the seconds in `Retry-After`.
- `507`: Your storage is full.

## Examples

**curl**

```bash
curl -X POST https://api.markdrop.in/api/v1/files/uploads \
  -H "Authorization: Bearer $MARKDROP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
       "file_name": "deck.pdf",
       "size_bytes": 1048576,
       "sha256": "SHA256_OF_THE_FILE",
       "title": "Q3 deck"
     }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.markdrop.in/api/v1/files/uploads", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.MARKDROP_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "file_name": "deck.pdf",
    "size_bytes": 1048576,
    "sha256": "SHA256_OF_THE_FILE",
    "title": "Q3 deck"
  }),
});
const data = await res.json();
```

**Python**

```python
import os

import requests

r = requests.post(
    "https://api.markdrop.in/api/v1/files/uploads",
    headers={"Authorization": f"Bearer {os.environ['MARKDROP_TOKEN']}"},
    json={
        "file_name": "deck.pdf",
        "size_bytes": 1048576,
        "sha256": "SHA256_OF_THE_FILE",
        "title": "Q3 deck",
    },
)
r.raise_for_status()
print(r.json())
```

**CLI**

```bash
markdrop upload deck.pdf --title "Q3 deck"
```
