---
title: "Upload a file"
method: POST
path: "/files"
tags: ["Uploads"]
---

# Upload a file

`POST /files`

## Request

- Base URL: `https://putit.online/api/v1`
- URL: `https://putit.online/api/v1/files`
- Auth: one of:
  - none
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://putit.online/oauth/authorize`, token URL `https://putit.online/oauth/token`, scopes: `links:read`, `links:write`, `account:read`)

Put a file online (text, or base64 for binary) and get a short link. Status "checking"/"publishing" means not live yet (poll get_link before sharing); "unpublished" means publishing needs a plan (checkout_url).

## Request body

- object
  - `filename` string, required: File name including extension, e.g. "report.pdf" or "index.html". The extension decides how the link renders.
  - `content` string, required: File content: plain text, or base64 when encoding is "base64" (use base64 for any binary file).
  - `encoding` 'text' | 'base64': How `content` is encoded.
  - `mime_type` string: Optional MIME type; used to add a missing file extension.
  - `slug` string: Custom link name (3-40 letters, digits, dashes); available on plans with custom names.
  - `password` string: Visitors must enter this password to open the link; available on plans with password protection.

## Response `201`

OK

- object
  - `slug` string, required
  - `url` string, required: The public link to share.
  - `status` 'awaiting_upload' | 'checking' | 'live' | 'in_review' | 'unpublished' | 'publishing' | 'removed' | 'expired' | 'deleted', required: checking = not live yet (poll get_link); live = shareable; unpublished = not published; publishing = will be live soon (poll get_link); in_review = not available right now; removed = removed by moderation (see removed_reason, appeal_url).
  - `status_message` string, required
  - `content_url` string: Only when live, for sites and single files: where the content itself is served (https://<slug>.putitcdn.com/…). Share `url` instead; it always works.
  - `checkout_url` string: Only with status unpublished: the page where the uploader can publish this link.
  - `removed_reason` string: Only with status removed: why, in plain words.
  - `removed_category` string, nullable: Only with status removed: the moderation category (malware, phishing, explicit, …); null when not disclosed.
  - `appeal_url` string: Only with status removed: mailto link to appeal to abuse@putit.online.
  - `kind` string, required: html | site | file | bundle | pending
  - `title` string, required
  - `size_bytes` number, required
  - `file_count` number, required
  - `views` number, nullable, required: View count; null when the link's account plan has no view counts, or the link has no account.
  - `permanent` boolean, required
  - `password_protected` boolean, required
  - `created_at` string, required
  - `expires_at` string, nullable, required: ISO time the link stops working; null for permanent links.
  - `manage_url` string: Private page to manage/delete the link. Only returned on creation; keep it secret.
  - `manage_token` string: Secret token returned on creation for every new link (keep it secret). Anonymous callers pass it to get_link/delete_link; a link in an account is managed by that account instead.

## Other responses

- `400`: Invalid request
- `401`: Authorization required or token invalid
- `402`: Subscription required (see upgrade_url)
- `403`: Blocked: VPN/proxy, banned uploader or missing scope
- `422`: Rejected by the safety check
- `429`: Rate limited (see Retry-After)

---

[API](https://skmtc.dev/putit/apis/put-it-online-api.md) · [All operations](https://skmtc.dev/putit/apis/put-it-online-api/llms.txt) · [OpenAPI document](https://skmtc.dev/putit/apis/put-it-online-api/revisions/a0c9fe8d4301?raw)
