---
title: "Prepare a resume upload"
method: POST
path: "/api/v1/uploads"
tags: ["Uploads"]
---

# Prepare a resume upload

`POST /api/v1/uploads`

## Request

- Base URL: `https://app.probbai.com`
- URL: `https://app.probbai.com/api/v1/uploads`
- Auth: HTTP bearer

Create a report and a temporary upload destination before analysing a resume. Use this to connect one candidate application to a job description. This step does not start analysis.

## Before you call

Have one PDF or DOCX (up to 10 MiB), its exact byte length, and job text or an active saved job ID. Choose a stable Idempotency-Key for this preparation.

**Required scope:** `analyses:write`.

## What happens next

Save reportId, then PUT the file bytes to upload.url using upload.mimeType. Do not send your API key to storage. The URL lasts ten minutes; the preparation lasts 24 hours. After uploading, request an analysis quote.

## Recovery

Repeat the identical body/key after a timeout. EXTERNAL_REFERENCE_CONFLICT means the application reference is already used. JD_REVISION_CHANGED requires reviewing the updated job. PENDING_UPLOAD_LIMIT requires cancelling unused preparations or waiting for expiry.

[Follow the complete workflow](/integration-api/) · [Errors and retries](/api-errors/)

## Headers

- `Idempotency-Key` string, required

## Request body

- UploadInput
  - `externalReference` object: Your application identity: source plus id, unique within the workspace. Prefer an application ID rather than personal information.
    - `source` string, required: Lowercase external-system slug, such as my-ats. Combined with id to identify one application in the workspace.
    - `id` string, required: Resource identifier. External-reference IDs are supplied by your system; resource/event IDs are returned by ProBB AI.
  - `fileName` string, required: Original PDF or DOCX filename, including extension. Paths and control characters are rejected.
  - `fileSize` integer, required: Exact file byte length, from 1 to 10,485,760. This is not the number of characters or a megabyte count.
  - `mimeType` 'application/pdf' | 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', required: File content type. The file extension, declared type, and uploaded content must agree.
  - `jobDescription` union, required: Role context: inline text or a saved job ID on input; selected role fields on a report response.
    - object
      - `kind` 'text', required: Variant selector. For job input use text or existing; for batches identifies uploads, analyses, or interviews.
      - `text` string, required: Inline job-description text, up to 50,000 characters; describe responsibilities and required evidence.
    - object
      - `kind` 'existing', required: Variant selector. For job input use text or existing; for batches identifies uploads, analyses, or interviews.
      - `id` string, required: Resource identifier. External-reference IDs are supplied by your system; resource/event IDs are returned by ProBB AI.
      - `expectedRevision` string: Optional SHA-256 job revision from discovery. Reject preparation if the saved role changed since you reviewed it.

## Response `201`

Save reportId, then PUT the file bytes to upload.url using upload.mimeType. Do not send your API key to storage. The URL lasts ten minutes; the preparation lasts 24 hours. After uploading, request an analysis quote.

- object
  - `data` Upload, required
    - `reportId` string, required: Report ID returned by upload preparation, admission, discovery, or an event. It must belong to the API key's workspace.
    - `upload` object, nullable, required: Temporary upload instructions; null after admission or when no eligible upload destination can be returned.
      - `url` string, uri, required: Short-lived signed storage URL. Treat it as a credential; never send your ProBB AI API key to it.
      - `method` 'PUT', required: HTTP method required for the signed file upload: PUT.
      - `mimeType` string, required: File content type. The file extension, declared type, and uploaded content must agree.
      - `sizeBytes` number, required: Expected upload size in bytes; send the matching file bytes to the signed URL.
      - `expiresInSeconds` 600, required: Upload URL lifetime in seconds from issuance; refresh before reuse after expiry.

## Other responses

- `400`: Invalid input or cursor
- `401`: Invalid, expired, or revoked API key
- `403`: Disabled organisation or missing scope
- `404`: The resource is absent, expired, deleted, or unavailable in this workspace. Verify the resource ID and key's workspace.
- `405`: Method not allowed; consult Allow for supported methods
- `409`: Repeat the identical body/key after a timeout. EXTERNAL_REFERENCE_CONFLICT means the application reference is already used. JD_REVISION_CHANGED requires reviewing the updated job. PENDING_UPLOAD_LIMIT requires cancelling unused preparations or waiting for expiry.
- `422`: Input cannot be processed or workspace allowance/capacity is insufficient. Inspect error.reason before retrying.
- `429`: Request limit exceeded
- `500`: Unexpected failure
- `503`: Service unavailable

---

[API](https://skmtc.dev/probbai/apis/probb-ai-customer-api.md) · [All operations](https://skmtc.dev/probbai/apis/probb-ai-customer-api/llms.txt) · [OpenAPI document](https://skmtc.dev/probbai/apis/probb-ai-customer-api/revisions/33a3294530e4?raw)
