Skip to content

Reserve a session_id and create a presigned upload URL

POST
/api/sessions/upload-intent/
curl -X POST https://api.ai.aikynetix.app/api/sessions/upload-intent/ \
-H 'Authorization: Bearer aik_yourPartnerTokenHere' \
-H 'Content-Type: application/json' \
-d '{"filename":"clip.mp4","content_type":"video/mp4","activity":"running"}'

Step 1 of the upload-and-analyse workflow. Reserves a session UUID and mints a presigned PUT URL into teams/<team_id>/sessions/<yyyy>/<mm>/<session_id>.source.mp4. PUT the raw video bytes (MP4 / MOV / WebM, ≤500 MB, ≤180 s; ≤30 s for a session that renders with original_quality — on create, and on a re-run that turns the flag on or keeps it) directly to that URL with the returned headers — no auth, expires in 2 hours — then call POST /api/sessions/ passing the same session_id plus the returned public_url as video_url. Bypasses the API for the heavy upload so a flaky mobile network can retry the PUT without re-traversing your backend.

Auth: team-scoped — reachable with a partner aik_… API key.

Request body for POST /api/sessions/upload-intent/.

object
filename
required

Original filename. Recorded for reference; never used as the storage key.

string
>= 1 characters <= 200 characters
content_type
required

MIME type of the video (e.g. video/mp4). Replayed as the PUT Content-Type.

string
>= 1 characters <= 120 characters
activity
One of:
  • running - Running
  • walking - Walking
  • jump - Vertical Jump
  • weightlifting - Weightlifting
  • mobility - Mobility Assessment
  • workspace_wellness - Workspace Wellness
  • agility - Agility
  • fencing - Fencing
  • cycling - Cycling
  • tennis - Tennis
  • padel - Padel Tennis
  • bowling - Bowling
  • baseball - Baseball
  • football - Football
  • badminton - Badminton
  • cricket - Cricket
  • basketball - Basketball
  • scuba_diving - Scuba Diving
  • ice_hockey - Ice Hockey
  • american_football - American Football
  • fri - Falls Risk Indicator
  • pickleball - Pickleball
string
Allowed values: running walking jump weightlifting mobility workspace_wellness agility fencing cycling tennis padel bowling baseball football badminton cricket basketball scuba_diving ice_hockey american_football fri pickleball
posture_media_content_type

MIME type of the optional posture-media upload — image or short (1-3 s) video showing the subject at their workstation. Only honoured when activity is workspace_wellness (gate is activity-level today; the WW activity carries a single exercise, Ergonomics Assessment, so the pair is equivalent — the first additional WW exercise will need this gate refined or it inherits a mandatory survey). Ignored for every other activity. When present and the activity matches, the response carries a second posture_media intent block alongside the primary video presign. Must be one of video/mp4, video/quicktime, image/jpeg, image/png, image/webp — anything else 400s. Damian’s Q11 from #303.

string
nullable <= 120 characters

Examples

ExampleRunning,TreadmillClip

Running, treadmill clip

{
"filename": "treadmill_2026-04-29.mp4",
"content_type": "video/mp4",
"activity": "running"
}
Media typeapplication/json
object
session_id
required

Reserved session UUID. Pass this back to POST /api/sessions/ as id.

string format: uuid
url
required

Presigned PUT URL for the raw video bytes (expires in 2 hours).

string
method
required

Always PUT.

string
headers
required

Headers to replay verbatim on the PUT (e.g. Content-Type).

object
key
additional properties
string
object_key
required

Storage key the upload lands at (team-scoped prefix).

string
public_url
required

URL of the uploaded object, presigned so it can be read back once the PUT lands. Pass it as video_url when creating the session — it is stored without the signature.

string
posture_media

Only present when activity is workspace_wellness AND the request supplied posture_media_content_type. Carries the second presign for the image-or-short-video upload that pairs with the ergonomics survey (Damian Q11 from #303). Independent of the primary video presign — uploadable in parallel.

object
url
required

Presigned PUT URL for the posture media bytes (expires in 2 hours).

string
method
required

Always PUT.

string
headers
required

Headers to replay verbatim on the PUT (e.g. Content-Type).

object
key
additional properties
string
object_key
required

Storage key the upload lands at (team-scoped prefix).

string
public_url
required

URL of the uploaded posture media (presigned; stored without the signature). Pass as workstation_assessment.posture_media.url when creating the workspace_wellness session.

string

Examples

ExampleSuccessfulIntent

Successful intent

{
"session_id": "5c836d7d-3301-49df-bfa0-9cff0550fd0e",
"url": "https://s3.ai.aikynetix.app/aikynetix-media/teams/2648a781-8751-47c0-836d-2c0189792d71/sessions/2026/04/5c836d7d-3301-49df-bfa0-9cff0550fd0e.source.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=7200&...",
"method": "PUT",
"headers": {
"Content-Type": "video/mp4"
},
"object_key": "teams/2648a781-8751-47c0-836d-2c0189792d71/sessions/2026/04/5c836d7d-3301-49df-bfa0-9cff0550fd0e.source.mp4",
"public_url": "https://s3.ai.aikynetix.app/aikynetix-media/teams/2648a781-8751-47c0-836d-2c0189792d71/sessions/2026/04/5c836d7d-3301-49df-bfa0-9cff0550fd0e.source.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=…&X-Amz-Date=20260421T000000Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&X-Amz-Signature=…"
}
Media typeapplication/json
object
detail
required

Human-readable message, or a stable machine code for the cases a client branches on. The standard envelope for 400 (validation — a field-keyed object may appear instead), 401 (missing / invalid credentials), 403 (authenticated but not permitted), and 404 (absent — cross-team records are collapsed to 404 so the API never leaks the existence of another team’s data).

string

Example generated

{
"detail": "example"
}
Media typeapplication/json
object
detail
required

Human-readable message, or a stable machine code for the cases a client branches on. The standard envelope for 400 (validation — a field-keyed object may appear instead), 401 (missing / invalid credentials), 403 (authenticated but not permitted), and 404 (absent — cross-team records are collapsed to 404 so the API never leaks the existence of another team’s data).

string

Example generated

{
"detail": "example"
}
Media typeapplication/json
object
detail
required

429 — rate limit exceeded. Honour the Retry-After response header (seconds to wait) before retrying; it is sent on every 429.

string

Example generated

{
"detail": "example"
}