Skip to main content
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).
This is not the media or recording upload flow. Use Media & Transcriptions for video/audio that should be transcribed or stored as session recordings.

Pick your upload path

Best for: most integrations — one API call, no S3 steps. Sessionboard detects file size and MIME type from the bytes you send.
EndpointPOST /v1/event/{eventId}/sessions/{sessionId}/files/upload
Max size50 MB
Scopewrite:sessions
Optional form fields: title, assigned_participant_id (contact UUID on the session).
1

Upload the file

POST /v1/event/{eventId}/sessions/{sessionId}/files/upload
Content-Type: multipart/form-data
X-Access-Token: {your-token}
curl
curl -X POST "https://public-api.sessionboard.com/v1/event/{eventId}/sessions/{sessionId}/files/upload" \
  -H "X-Access-Token: $TOKEN" \
  -F "[email protected]" \
  -F "title=Session handout"
Node.js (form-data)
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:
{
  "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)

GET /v1/event/{eventId}/sessions/{sessionId}/files

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:
X-Access-Token: {your-token}

Common file types

KindExamples
DocumentsPDF, DOC, DOCX
PresentationsPPT, PPTX
SpreadsheetsXLS, XLSX
ImagesPNG, 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:
PUT /v1/event/{eventId}/sessions/{sessionId}/files/{fileId}
Content-Type: application/json
{
  "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

SituationWhat you’ll see
Simple upload over 50 MB400 — use direct-to-storage flow
Direct create over 500 MB400 — file too large
Missing multipart file field400 VALIDATION_ERROR
Missing filename / size_bytes (direct create)400 VALIDATION_ERROR
Executable / installer type400 — file type not allowed
Called complete before PUT400 — upload not found in storage
Missing write:sessions403
Unknown fileId / session404

Scopes quick reference

ActionScope
List filesread:sessions
Upload / create / complete / replace / update / deletewrite:sessions