> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developers.upwardli.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developers.upwardli.com/_mcp/server.

# Uploading Onboarding Documents

## Overview

During onboarding you can send Upward supporting documents for the entity being onboarded, such as a business's EIN letter or formation documents. Each document is uploaded against an existing onboarding and is stored securely by Upward. The onboarding response lists every document on file.

Uploading documents is not a step in the onboarding flow: it does not advance `current_steps`, and you can upload at any point after the onboarding is created.

> **Note**
>
> This endpoint requires a partner token with the `ui:client-onboarding` scope.

## Upload a Document

Send one document per request, with its contents Base64-encoded in the JSON body.

> **Warning**
>
> **Accepted file sizes:** each file must be between 1 byte and 1.5 MB (1,572,864 bytes), measured before Base64 encoding. Base64 adds about a third, so the encoded `data` value can be up to about 2 MB. Larger files are rejected; compress or downscale them before uploading.

See the [upload document](/api-access/api-reference/onboarding/create-document-upload-request) API.

POST `https://api-sandbox.upwardli.com/v2/onboarding/{onboarding id}/documents/`

Body

```json
{
  "document_type": "EIN_LETTER",
  "filename": "ein-letter.pdf",
  "content_type": "application/pdf",
  "data": "JVBERi0xLjQKJ..."
}
```

| Field           | Description                                                               |
| --------------- | ------------------------------------------------------------------------- |
| `document_type` | What the document is. One of the [document types](#document-types) below. |
| `filename`      | The original file name. It is shown back to you in the response.          |
| `content_type`  | The file's format: `application/pdf`, `image/jpeg` or `image/png`.        |
| `data`          | The file's contents, Base64-encoded.                                      |

### Document Types

| Value                | Document                                                      |
| -------------------- | ------------------------------------------------------------- |
| `EIN_LETTER`         | IRS EIN confirmation letter                                   |
| `FORMATION_DOCUMENT` | Business formation document, such as articles of organization |
| `STATE_ID`           | State-issued ID                                               |
| `PROOF_OF_ADDRESS`   | Proof of address                                              |

### File Requirements

* **Formats:** PDF, JPEG or PNG. The file's contents must match `content_type`. A PNG sent as `image/jpeg`, for example, is rejected.
* **Size:** from 1 byte up to 1.5 MB (1,572,864 bytes) before Base64 encoding. Empty files are rejected.
* **Encoding:** standard Base64 with no line breaks or whitespace, and no `data:` URI prefix. Send `JVBERi0x...`, not `data:application/pdf;base64,JVBERi0x...`.

For example, to encode a file from the command line:

```bash
base64 -i ein-letter.pdf | tr -d '\n'
```

## Replacing a Document

Upward keeps one document per `document_type` for each onboarding. Uploading a type that is already on file replaces the earlier document, whatever its filename. To correct a document, upload the new file with the same `document_type`.

Different document types can be uploaded in parallel.

## Response

A successful upload returns `200 OK` with the onboarding object. The `documents` block lists every document currently on file for the onboarding:

```json
{
  "id": "bcc76111-2451-4299-a02d-3f067cf3ca5a",
  "status": "new",
  ...
  "documents": {
    "uploaded": [
      {
        "document_type": "EIN_LETTER",
        "filename": "ein-letter.pdf",
        "content_type": "application/pdf",
        "byte_size": 184213,
        "uploaded_at": "2026-10-27T16:04:11.532018+00:00"
      },
      {
        "document_type": "FORMATION_DOCUMENT",
        "filename": "articles-of-organization.pdf",
        "content_type": "application/pdf",
        "byte_size": 402551,
        "uploaded_at": "2026-10-27T16:04:12.108334+00:00"
      }
    ],
    "errors": []
  },
  ...
}
```

The same `documents` block is returned by the [get onboarding](/api-access/api-reference/onboarding/get-onboarding) API, so you can check which documents are on file at any time.

> **Info**
>
> Unsafe characters in `filename` (path separators, spaces and other special characters) are replaced with `_`, so the stored name may differ slightly from the one you sent.

## Errors

| Status                  | Cause                                                                                                                                                                                                  |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `400 Bad Request`       | A field is missing or invalid: an unknown `document_type` or `content_type`, `data` that is not valid Base64, or file contents that don't match `content_type`. The response names the field at fault. |
| `404 Not Found`         | No onboarding with that `id` exists for your partner account.                                                                                                                                          |
| `413 Payload Too Large` | The decoded file is empty or larger than 1.5 MB. A request much larger than the limit may be rejected with `400` before the file is checked.                                                           |

A failed upload leaves the documents already on file unchanged, so it is safe to fix the request and retry.