---
title: "Create a single-use signed upload slot"
method: POST
path: "/uploads"
tags: ["data-transfer"]
---

# Create a single-use signed upload slot

`POST /uploads`

## Request

- Base URL: `https://api.pscrpt.com/v1`
- URL: `https://api.pscrpt.com/v1/uploads`
- Auth: one of:
  - HTTP bearer
  - OAuth 2
    - Authorization code: `https://api.pscrpt.com/oauth/authorize`
    - Token URL: `https://api.pscrpt.com/oauth/token`

See [Bulk imports](/docs/bulk-imports#upload-a-file).

## Headers

- `Idempotency-Key` string
- `Postscript-Version` string, date

## Request body

- UploadRequest
  - `byte_count` integer, required: At most 1 GiB.
  - `content_type` string, required
  - `filename` string, required

## Response `201`

Upload slot created (201). PUT the raw bytes to `upload_url` within 1 h.

- UploadEnvelope
  - `data` Upload, required: A single-use slot for one import file.
    - `byte_count` integer, required
    - `checksum` string, nullable, required: Set once an import has read the file.
    - `content_type` string, required
    - `created_at` string, date-time, required
    - `expires_at` string, date-time, required
    - `filename` string, required
    - `id` string, required
    - `object` 'upload', required
    - `status` 'pending' | 'uploaded' | 'consumed' | 'expired', required
    - `upload_url` string, uri, nullable, required: Signed `PUT` URL for the file's bytes, valid for one hour. Present only while `status` is `pending`.
    - `upload_url_expires_at` string, date-time, nullable, required
  - `meta` Meta, required
    - `as_of` string, date-time
    - `livemode` boolean, required
    - `page` PageMeta
      - `limit` integer, required
      - `next_cursor` string, nullable, required: Pass as `page[after]`. Null on the last page.
    - `request_id` string, required
    - `resolved_from` string: The merged-away profile ID the request addressed; `data` holds the survivor.
    - `revision` string, date, required

## Other responses

- `400`: Malformed input, an unknown parameter, an unsupported filter, sort, or expand, or a mistyped ID.
- `401`: Missing or invalid API key.
- `403`: The key lacks the required scope.
- `409`: State conflict: an identifier collision (`identity_conflict`), an idempotency key reused with a different body, or a duplicate request still in flight (`Retry-After` present).
- `429`: Rate limit exceeded.
- `500`: Internal error.
- `502`: Upstream provider failure.
- `503`: Temporarily unavailable.

## Changes

- **2026-10-28** `3aede004c7f6`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/pscrpt/apis/postscript-native-api-beta/changes/uploads/post.md)

---

[API](https://skmtc.dev/pscrpt/apis/postscript-native-api-beta.md) - [All operations](https://skmtc.dev/pscrpt/apis/postscript-native-api-beta/llms.txt) - [OpenAPI document](https://skmtc.dev/pscrpt/apis/postscript-native-api-beta/revisions/882458ee1f36?raw)
