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

# Uploading session files

> Attach PDFs, PowerPoint decks, and other documents to a session via the Public API.

Use this guide to upload documents to a session — the same Session Files you manage in the admin UI and speaker portal (slides, handouts, PDFs, and similar).

> [!NOTE]
>
> This is **not** the media or recording upload flow. Use [Media & Transcriptions](https://apidocs.sessionboard.com/guides/uploading-media-and-transcriptions.md) for video/audio that should be transcribed or stored as session recordings.

## Pick your upload path

**Simple upload (≤ 50 MB)**

**Best for:** most integrations — one API call, no S3 steps. Sessionboard detects file size and MIME type from the bytes you send.

| | |
| - | - |
| **Endpoint** | `POST /v1/event/{eventId}/sessions/{sessionId}/files/upload` |
| **Max size** | **50 MB** |
| **Scope** | `write:sessions` |

Optional form fields: `title`, `assigned_participant_id` (contact UUID on the session).

**1. Upload the file**

```http theme={null}
POST /v1/event/{eventId}/sessions/{sessionId}/files/upload
Content-Type: multipart/form-data
X-Access-Token: {your-token}
```

**curl**

```bash theme={null}
curl -X POST "https://public-api.sessionboard.com/v1/event/{eventId}/sessions/{sessionId}/files/upload" \
  -H "X-Access-Token: $TOKEN" \
  -F "file=@handout.pdf" \
  -F "title=Session handout"
```

**Node.js (form-data)**

```js theme={null}
import fs from 'node:fs';
import FormData from 'form-data';

const form = new FormData();
form.append('file', fs.createReadStream('./handout.pdf'));
form.append('title', 'Session handout');

const res = await fetch(uploadUrl, {
  method: 'POST',
  headers: { 'X-Access-Token': token, ...form.getHeaders() },
  body: form
});
```

The multipart field name must be **`file`**. You do **not** send `filename`, `size_bytes`, or `content_type` — Sessionboard infers them from the upload.

**2. Use the response**

On success (`201`) you get the finalized file `Content` object — same shape as after the direct-to-storage **complete** step:

```json theme={null}
{
  "data": {
    "id": "a1b2c3d4-....",
    "filename": "handout.pdf",
    "title": "Session handout",
    "size": 512000,
    "mimetype": "application/pdf",
    "url": "https://content.sessionboard.com/..."
  }
}
```

Security scanning runs before the response is returned. No follow-up call is required.

**3. Confirm (optional)**

```http theme={null}
GET /v1/event/{eventId}/sessions/{sessionId}/files
```

**Direct to storage (> 50 MB)**

**Best for:** files **larger than 50 MB** (up to **500 MB**), or when you prefer uploading bytes straight to Sessionboard storage (same pattern as [session recordings](https://apidocs.sessionboard.com/guides/uploading-media-and-transcriptions.md#playbook-3-%E2%80%94-upload-session-audio)).

| | |
| - | - |
| **Flow** | create → PUT to signed URL → complete |
| **Max size** | **500 MB** |
| **Scope** | `write:sessions` |

**1. Start the upload**

```http theme={null}
POST /v1/event/{eventId}/sessions/{sessionId}/files
Content-Type: application/json
```

```json theme={null}
{
  "filename": "large-deck.pptx",
  "size_bytes": 52428800,
  "title": "Full slide archive"
}
```

`size_bytes` must match the file on disk. `content_type` is optional — inferred from the filename when omitted.

Response includes `data.id` and `data.upload.url` for the next step.

**2. PUT the file bytes**

Upload the raw file to `data.upload.url` with the `Content-Type` from `data.upload.headers`. Do **not** send your API token to the storage URL.

**3. Mark complete**

```http theme={null}
POST /v1/event/{eventId}/sessions/{sessionId}/files/{fileId}/complete
```

Sessionboard verifies the object, scans the bytes, and attaches the file.

***

## Before you begin

* API token with **`write:sessions`** (list/read also needs **`read:sessions`** when your token uses explicit scopes)
* Your `{eventId}` and `{sessionId}`

Send your token on every API request:

```http theme={null}
X-Access-Token: {your-token}
```

### Common file types

| Kind | Examples |
| - | - |
| Documents | PDF, DOC, DOCX |
| Presentations | PPT, PPTX |
| Spreadsheets | XLS, XLSX |
| Images | PNG, JPG, GIF, WEBP, SVG |

Executable and installer files (for example `.exe`, `.msi`, `.dmg`, `.sh`) are rejected on all paths.

***

## Update metadata

Change the display title or assigned participant without re-uploading:

```http theme={null}
PUT /v1/event/{eventId}/sessions/{sessionId}/files/{fileId}
Content-Type: application/json
```

```json theme={null}
{
  "title": "Updated slide deck",
  "assigned_participant_id": "contact-uuid-or-null"
}
```

***

## Replace or delete

**Replace** (direct-to-storage flow only today): `POST .../files/{fileId}/replace` → PUT bytes → `POST .../complete`.

**Delete:** `DELETE .../files/{fileId}` → `204 No Content`.

***

## Common errors

| Situation | What you'll see |
| - | - |
| Simple upload over 50 MB | `400` — use direct-to-storage flow |
| Direct create over 500 MB | `400` — file too large |
| Missing multipart `file` field | `400` `VALIDATION_ERROR` |
| Missing `filename` / `size_bytes` (direct create) | `400` `VALIDATION_ERROR` |
| Executable / installer type | `400` — file type not allowed |
| Called **complete** before PUT | `400` — upload not found in storage |
| Missing `write:sessions` | `403` |
| Unknown `fileId` / session | `404` |

***

## Scopes quick reference

| Action | Scope |
| - | - |
| List files | `read:sessions` |
| Upload / create / complete / replace / update / delete | `write:sessions` |

## Related reference

* [Session Files API overview](https://apidocs.sessionboard.com/api-reference/session-files.md)
* [Transcriptions & Media](https://apidocs.sessionboard.com/api-reference/transcriptions-and-media.md)
* [Authentication & scopes](https://apidocs.sessionboard.com/authentication.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.