---
title: "Create an upload"
method: POST
path: "/uploads"
tags: ["Files"]
---

# Create an upload

`POST /uploads`

## Request

- Base URL: `https://api.parley.so/v1`
- URL: `https://api.parley.so/v1/uploads`
- Auth: HTTP bearer

Start uploading a file. PUT the file's bytes to the returned url in one request before it expires (for example, curl -X PUT --upload-file ./letter.pdf "$URL"). Then pass the upload's id as uploadId to POST /files to add the file to a location, or to POST /skills or PATCH /skills/{slug} for a skill.

## Request body

- object
  - `fileName` string, required: The file name, including its extension, such as engagement-letter.pdf. The file keeps this name in Parley.

## Response `201`

Created.

- object
  - `id` string, required: Pass as uploadId when adding a file or when creating or updating a skill, once the upload finishes.
  - `url` string, uri, required: PUT the file's bytes to this URL in a single request. Send no Authorization header.
  - `expiresAt` string, date-time, required: When the url stops accepting uploads.

## Other responses

- `400`: The request was invalid. VALIDATION_FAILED.
- `401`: Missing or invalid credentials. UNAUTHORIZED.
- `403`: You don't have permission. FORBIDDEN.
- `429`: Too many requests, or a usage limit was reached. TOO_MANY_REQUESTS.

## Changes

- **2026-11-02** `6b78aeee07bc`: 1 breaking, 1 warning
  - added `subschema #1` to the `fileName` request property `allOf` list
  - changed the pattern of the request property `fileName` from `^(?!\.+$)[^/\\]+$` to `^[^\p{Cc}\p{Bidi_Control}]*$`

[Operation history](https://skmtc.dev/parley/apis/parley-api/changes/uploads/post.md)

---

[API](https://skmtc.dev/parley/apis/parley-api.md) - [All operations](https://skmtc.dev/parley/apis/parley-api/llms.txt) - [OpenAPI document](https://skmtc.dev/parley/apis/parley-api/revisions/6b78aeee07bc?raw)
