Skip to content

Upload Audio

The wearable or mobile app streams audio to the server in 30-second windowed chunks during an active session; the Lambda stores each chunk in S3 and triggers downstream ingest when both audio and frames are ready for a window.

Flow

Per-window chunk upload (primary path)

  1. Client sends audio chunk — A POST request is sent to /sessions/{sessionId}/audio?windowIndex=<n> with the audio bytes as the request body (audio/wav, possibly base64-encoded by API Gateway).

  2. Session lookupsessionId is extracted from path parameters; missing session ID returns HTTP 400.

  3. Body decoding — If isBase64Encoded is set in the API Gateway event, the body is base64-decoded; otherwise it is used as-is.

  4. S3 write — Audio is stored at sessions/{sessionId}/window_{windowIndex:03d}/audio.wav.

  5. DynamoDB atomic updatecompletedAudioWindows set is extended with windowIndex using an ADD operation; the updated session record is returned.

  6. Ingest trigger decision — Ingest is triggered if:

  7. captureMode == "audio_only", OR
  8. the same windowIndex already appears in completedFrameWindows

  9. Deduplication claim — A conditional ADD to ingestTriggeredWindows ensures only one invocation triggers ingest per window (idempotent across retries and concurrent calls).

  10. Ingest Lambda invocation — The ingest function is called asynchronously (InvocationType=Event) with { sessionId, userId, windowIndex, frameCount }.

  11. Response — Returns { "ok": true, "s3Key": "...", "windowIndex": n, "ingestTriggered": true/false }.

Legacy full-session upload (backward compat)

If windowIndex is absent from the query string, the entire audio body is stored at sessions/{sessionId}/audio/full.{ext} and returns { "ok": true, "s3Key": "...", "legacy": true }. No ingest is triggered.

Entry Point

  • Lambda: main/server/api/sessions/audio/app.pylambda_handler
  • HTTP method: POST /sessions/{sessionId}/audio (API Gateway)

Dependencies

  • S3 bucket: BUCKET_NAME (default encache-raw-memory)
  • DynamoDB: SESSIONS_TABLE_NAME
  • Lambda: INGEST_FUNCTION_NAME

Error Cases

Condition Response
Missing sessionId path param 400
Non-integer windowIndex 400
Negative windowIndex 400