Finalize session audio upload
US Region: https://public-api.sessionboard.com · EU Region: https://public-api-eu.sessionboard.com
Marks the recording as completed and normalizes common audio formats for playback.
Already-completed recordings return 200 without re-processing. Requires write:transcriptions.
Request example
curl --request POST \ --url 'https://public-api.sessionboard.com/v1/event/{eventId}/sessions/{sessionId}/recordings/{recordingId}/complete' \ --header 'x-access-token: <api-token>' \ --header 'Content-Type: application/json' \ --data '{ "duration_seconds": 123.45, "file_size_bytes": 123}'const response = await fetch('https://public-api.sessionboard.com/v1/event/{eventId}/sessions/{sessionId}/recordings/{recordingId}/complete', { method: 'POST', headers: { "x-access-token": "<api-token>", "Content-Type": "application/json" }, body: JSON.stringify({ "duration_seconds": 123.45, "file_size_bytes": 123 }),});
const data = await response.json();console.log(data);import requests
response = requests.request( "POST", "https://public-api.sessionboard.com/v1/event/{eventId}/sessions/{sessionId}/recordings/{recordingId}/complete", headers={ "x-access-token": "<api-token>", "Content-Type": "application/json" }, json={ "duration_seconds": 123.45, "file_size_bytes": 123 },)
print(response.json())<?php
$curl = curl_init();
curl_setopt_array($curl, [ CURLOPT_URL => "https://public-api.sessionboard.com/v1/event/{eventId}/sessions/{sessionId}/recordings/{recordingId}/complete", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => '{ "duration_seconds": 123.45, "file_size_bytes": 123}', CURLOPT_HTTPHEADER => [ "x-access-token: <api-token>", "Content-Type: application/json", ],]);
$response = curl_exec($curl);curl_close($curl);
echo $response;package main
import ( "fmt" "io" "net/http" "strings")
func main() { req, _ := http.NewRequest("POST", "https://public-api.sessionboard.com/v1/event/{eventId}/sessions/{sessionId}/recordings/{recordingId}/complete", strings.NewReader(`{ "duration_seconds": 123.45, "file_size_bytes": 123}`)) req.Header.Add("x-access-token", "<api-token>") req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))}HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://public-api.sessionboard.com/v1/event/{eventId}/sessions/{sessionId}/recordings/{recordingId}/complete")) .header("x-access-token", "<api-token>") .header("Content-Type", "application/json") .method("POST", HttpRequest.BodyPublishers.ofString("{\n \"duration_seconds\": 123.45,\n \"file_size_bytes\": 123\n}")) .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
recordingIdstring<uuid>pathrequired
Request body
duration_secondsnumberfile_size_bytesinteger
{ "duration_seconds": 123.45, "file_size_bytes": 123}Responses
200application/json
OK
dataRecordingShow child attributes
idstring<uuid>typestring- Example
"recording"
session_idstring<uuid>s3_bucketstrings3_keystringAfter complete, non-PCM uploads are stored as
.pcmkeys.encodingstring- Example
"linear16"
sample_rateinteger- Example
16000
channelsinteger- Example
1
statusstring- Allowed values
"recording", "completed"
duration_secondsnumberfile_size_bytesintegerstarted_atstring<date-time>completed_atstring<date-time>created_atstring<date-time>updated_atstring<date-time>mp3_urlstring<uri> | null6-hour presigned HTTPS URL for an MP3 sibling of the original PCM take. Null while the recording is in progress or if transcode has not succeeded yet. Download and store this file — do not hotlink it as a permanent CDN URL. Session PDFs and user-uploaded files stay on
/contentand/files.mp3_expires_atstring<date-time> | nullWhen
mp3_urlstops working. Request the recording again to refresh the URL.
403
Missing write:transcriptions scope
422
PCM transcode failed (TRANSCODE_ERROR)
Response examples
{ "data": { "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a", "type": "recording", "session_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a", "s3_bucket": "<string>", "s3_key": "<string>", "encoding": "linear16", "sample_rate": 16000, "channels": 1, "status": "recording", "duration_seconds": 123.45, "file_size_bytes": 123, "started_at": "2026-01-15T09:30:00Z", "completed_at": "2026-01-15T09:30:00Z", "created_at": "2026-01-15T09:30:00Z", "updated_at": "2026-01-15T09:30:00Z", "mp3_url": "https://example.com", "mp3_expires_at": "2026-01-15T09:30:00Z" }}