> ## Documentation Index
> Fetch the complete documentation index at: https://docs.royaltyport.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Statement Upload

> Upload statements via multipart form data or JSON with base64-encoded files.

Upload a statement file to a project. The file is stored and queued for processing.

<Note>
  Only PDF files are supported. Maximum file size is 50 MB.
</Note>

***

## Upload Statement

Creates a new statement staging record and uploads the file. Supports two content types: `multipart/form-data` for direct file upload, and `application/json` for base64-encoded files.

### Request

```
POST /v1/statements
```

### Query Parameters

| Parameter   | Type | Required | Default | Description                            |
| ----------- | ---- | -------- | ------- | -------------------------------------- |
| `projectId` | UUID | Yes      | —       | The project to upload the statement to |

### Headers

| Header          | Required | Description                                                      |
| --------------- | -------- | ---------------------------------------------------------------- |
| `Authorization` | Yes      | `Bearer <token>` — must be scoped to the requested project       |
| `Content-Type`  | Yes      | `multipart/form-data` or `application/json`                      |
| `Accept`        | No       | Set to `text/event-stream` for real-time upload progress via SSE |

***

### Option A: Multipart Form Data

Upload a file directly using `multipart/form-data`.

| Field  | Type | Required | Description            |
| ------ | ---- | -------- | ---------------------- |
| `file` | File | Yes      | The PDF file to upload |

#### Example

```bash theme={null}
curl -X POST "https://api.royaltyport.com/v1/statements?projectId=a1b2c3d4-..." \
  -H "Authorization: Bearer rp_your_token_here" \
  -F "file=@Q1-royalties.pdf"
```

***

### Option B: JSON Body

Upload a base64-encoded file using `application/json`.

| Field      | Type   | Required | Default           | Description                          |
| ---------- | ------ | -------- | ----------------- | ------------------------------------ |
| `file`     | string | Yes      | —                 | Base64-encoded file content          |
| `fileName` | string | Yes      | —                 | The file name (e.g. `statement.pdf`) |
| `fileType` | string | No       | `application/pdf` | MIME type of the file                |

#### Example

```bash theme={null}
curl -X POST "https://api.royaltyport.com/v1/statements?projectId=a1b2c3d4-..." \
  -H "Authorization: Bearer rp_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{
    "file": "JVBERi0xLjQK...",
    "fileName": "Q1-royalties.pdf"
  }'
```

***

### Response

| Field             | Type    | Description                                                              |
| ----------------- | ------- | ------------------------------------------------------------------------ |
| `staging_id`      | integer | Unique identifier for tracking processing progress                       |
| `staging_stage`   | string  | Current processing stage (`queued`, `processing`, `completed`, `failed`) |
| `staging_done`    | boolean | Whether staging (pre-processing) has completed                           |
| `processing_done` | boolean | Whether statement processing has completed                               |
| `created_at`      | string  | Upload timestamp (ISO 8601)                                              |

```json theme={null}
{
  "data": {
    "staging_id": 456,
    "staging_stage": "queued",
    "staging_done": false,
    "processing_done": false,
    "created_at": "2025-03-01T12:00:00Z"
  }
}
```

### SSE Response

If the `Accept` header includes `text/event-stream`, the response is a server-sent event stream with upload progress:

```
event: progress
data: {"bytesUploaded":3145728,"bytesTotal":10485760,"percent":30}

event: progress
data: {"bytesUploaded":10485760,"bytesTotal":10485760,"percent":100}

event: complete
data: {"data":{"staging_id":456,"staging_stage":"queued","staging_done":false,"processing_done":false,"created_at":"2025-03-01T12:00:00Z"}}
```

### Errors

| Status | Description                                                |
| ------ | ---------------------------------------------------------- |
| `400`  | Missing file, unsupported file type, or file exceeds 50 MB |
| `403`  | Token is not scoped to the requested project               |
| `429`  | Rate limit exceeded                                        |
| `500`  | File upload or database error                              |
