Upload a session file (simple)
US Region: https://public-api.sessionboard.com · EU Region: https://public-api-eu.sessionboard.com
Upload a file in one multipart request. Sessionboard detects size and
MIME type from the bytes, runs security scanning, and returns the
finalized file. Max 50 MB. Requires write:sessions.
For files larger than 50 MB (up to 500 MB), use the direct-to-storage
flow: POST .../files → PUT to signed URL → POST .../complete.
See Uploading session files.
Request example
curl --request POST \ --url 'https://public-api.sessionboard.com/v1/event/{eventId}/sessions/{sessionId}/files/upload' \ --header 'x-access-token: <api-token>' \ --form 'file=@/path/to/slides.pdf' \ --form 'title=<string>' \ --form 'assigned_participant_id=3c90c3cc-0d44-4b50-8888-8dd25736052a' \ --form 'content_slot_id=3c90c3cc-0d44-4b50-8888-8dd25736052a'const form = new FormData();form.append('file', fileInput.files[0]); // a File or Blobform.append('title', "<string>");form.append('assigned_participant_id', "3c90c3cc-0d44-4b50-8888-8dd25736052a");form.append('content_slot_id', "3c90c3cc-0d44-4b50-8888-8dd25736052a");
const response = await fetch('https://public-api.sessionboard.com/v1/event/{eventId}/sessions/{sessionId}/files/upload', { method: 'POST', headers: { "x-access-token": "<api-token>" }, // no Content-Type: fetch sets the multipart boundary body: form,});
const data = await response.json();console.log(data);import requests
response = requests.request( "POST", "https://public-api.sessionboard.com/v1/event/{eventId}/sessions/{sessionId}/files/upload", headers={ "x-access-token": "<api-token>" }, files={"file": open("/path/to/slides.pdf", "rb")}, data={"title": "<string>", "assigned_participant_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a", "content_slot_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"},)
print(response.json())<?php
$curl = curl_init();
curl_setopt_array($curl, [ CURLOPT_URL => "https://public-api.sessionboard.com/v1/event/{eventId}/sessions/{sessionId}/files/upload", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => [ "file" => new CURLFile("/path/to/slides.pdf"), "title" => "<string>", "assigned_participant_id" => "3c90c3cc-0d44-4b50-8888-8dd25736052a", "content_slot_id" => "3c90c3cc-0d44-4b50-8888-8dd25736052a", ], CURLOPT_HTTPHEADER => [ "x-access-token: <api-token>", ],]);
$response = curl_exec($curl);curl_close($curl);
echo $response;package main
import ( "bytes" "fmt" "io" "mime/multipart" "net/http" "os")
func main() { var body bytes.Buffer w := multipart.NewWriter(&body) f, _ := os.Open("/path/to/slides.pdf") defer f.Close() part, _ := w.CreateFormFile("file", f.Name()) io.Copy(part, f) w.WriteField("title", "<string>") w.WriteField("assigned_participant_id", "3c90c3cc-0d44-4b50-8888-8dd25736052a") w.WriteField("content_slot_id", "3c90c3cc-0d44-4b50-8888-8dd25736052a") w.Close()
req, _ := http.NewRequest("POST", "https://public-api.sessionboard.com/v1/event/{eventId}/sessions/{sessionId}/files/upload", &body) req.Header.Set("Content-Type", w.FormDataContentType()) req.Header.Add("x-access-token", "<api-token>")
res, _ := http.DefaultClient.Do(req) defer res.Body.Close() out, _ := io.ReadAll(res.Body) fmt.Println(string(out))}// Java 11+ HttpClient has no multipart helper: build the body with a boundary.String boundary = "----sessionboard" + System.currentTimeMillis();var bytes = new java.io.ByteArrayOutputStream();bytes.write(("--" + boundary + "\r\nContent-Disposition: form-data; name=\"file\"; filename=\"slides.pdf\"\r\nContent-Type: application/octet-stream\r\n\r\n").getBytes());bytes.write(java.nio.file.Files.readAllBytes(java.nio.file.Path.of("/path/to/slides.pdf")));bytes.write("\r\n".getBytes());bytes.write(("--" + boundary + "\r\nContent-Disposition: form-data; name=\"title\"\r\n\r\n" + "<string>" + "\r\n").getBytes());bytes.write(("--" + boundary + "\r\nContent-Disposition: form-data; name=\"assigned_participant_id\"\r\n\r\n" + "3c90c3cc-0d44-4b50-8888-8dd25736052a" + "\r\n").getBytes());bytes.write(("--" + boundary + "\r\nContent-Disposition: form-data; name=\"content_slot_id\"\r\n\r\n" + "3c90c3cc-0d44-4b50-8888-8dd25736052a" + "\r\n").getBytes());bytes.write(("--" + boundary + "--\r\n").getBytes());
HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://public-api.sessionboard.com/v1/event/{eventId}/sessions/{sessionId}/files/upload")) .header("Content-Type", "multipart/form-data; boundary=" + boundary) .header("x-access-token", "<api-token>") .method("POST", HttpRequest.BodyPublishers.ofByteArray(bytes.toByteArray())) .build();
HttpResponse<String> response = HttpClient.newHttpClient() .send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());Try it
Response headers
Authorizations
x-access-tokenstringheaderOrganization API token. Generate from Organization Settings → API Tokens.
AuthorizationBearer <token>headerorOAuth 2.1 access token. Obtained via the OAuth PKCE flow at
/oauth/token.
Send one of these. See Authentication.
Path parameters
eventIdintegerpathrequiredEvent ID
sessionIdstring<uuid>pathrequiredSession UUID
Request body
filestring<binary>requiredThe file to attach (field name must be
file).titlestringDisplay title. Defaults to the uploaded filename.
assigned_participant_idstring<uuid>Contact UUID of a session participant.
content_slot_idstring<uuid>Optional upload slot this file answers. Same rules as
content_slot_idonPOST .../files: the slot must be active, apply to the session, accept the file's type and have room;400names the slot otherwise. Sets the file'stype.
{ "file": "<string>", "title": "<string>", "assigned_participant_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a", "content_slot_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"}Responses
201application/json
Created — file attached and scanned
dataContentA content attachment (file, document, or media) associated with a session.
Approvals. On events using Approvals (Early Access), a file can be held back until it is approved and its release time has passed. The Session Files endpoints still list a held file, so an integration knows it exists, but return
url: nulluntil it is released. Publish only files whoseapproval_statusisapprovedornot_required. When a file you already published moves to any other status, remove it from your destination.Show child attributes
idstring<uuid>urlstring<uri> | nullDownload URL.
nullwhile Approvals holds the file back (seeapproval_status), so nothing built on the API can publish it early.titlestringfilenamestringsizeintegermimetypestringtypestring | nullOrganizer-facing file type, e.g.
presentation,handout,poster, orholding_slidefor slides generated by Sessionboard. Filterable with?type=on the list endpoint.- Example
"holding_slide"
labelstring | nullDisplay label shown on the session's Files tab, e.g.
Holding Slide.- Example
"Holding Slide"
created_atstring<date-time>updated_atstring<date-time>assigned_participant_idstring<uuid> | nullContact UUID of the session participant this file is assigned to.
assigned_participant_emailstring<email> | nullassigned_participant_namestring | nullcontent_slot_idstring<uuid> | nullThe upload slot this file answers — see
GET /v1/event/{eventId}/content-slots. Present only while the event uses upload slots;nullfor events on a single file request, and for files uploaded before slots existed or outside any slot.approval_statusstringApproval state, returned by the Session Files endpoints.
not_required: not under an approval workflow (no workflow, workflow off, or uploaded before it was turned on).pending: waiting on a reviewer.approved: approved and released.denied: sent back to the uploader for changes.superseded: a newer version replaced it before it was decided.embargoed: approved (or not required) but held until a release time; seeembargo_until.
Only
approvedandnot_requiredfiles have aurl.- Allowed values
"not_required", "pending", "approved", "denied", "superseded", "embargoed"- Example
"approved"
embargo_untilstring<date-time> | nullWhen an
embargoedfile is released (UTC).nullwhen it is not embargoed, or when it waits for its session to be scheduled (release "when each file's session starts").
400
Validation error (missing file, oversize, denied type)
403
Missing write:sessions scope
Response examples
{ "data": { "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a", "url": "https://example.com", "title": "<string>", "filename": "<string>", "size": 123, "mimetype": "<string>", "type": "holding_slide", "label": "Holding Slide", "created_at": "2026-01-15T09:30:00Z", "updated_at": "2026-01-15T09:30:00Z", "assigned_participant_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a", "assigned_participant_email": "jane@example.com", "assigned_participant_name": "<string>", "content_slot_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a", "approval_status": "approved", "embargo_until": "2026-01-15T09:30:00Z" }}