Quickstart
Esta página aún no está disponible en tu idioma.
This is the whole loop, end to end. Copy it, change the key, and you have a working integration.
Throughout, replace aik_yourPartnerTokenHere with your key.
1. Create the athlete
Section titled “1. Create the athlete”Optional, and worth doing anyway. Height, weight and gender make the metrics body-aware — green zones, ground reaction forces and anything mass-dependent are scaled to this person. Without an athlete, the analysers fall back to population defaults and the report is measurably vaguer.
curl -X POST https://api.ai.aikynetix.app/api/clients/ \ -H 'Authorization: Bearer aik_yourPartnerTokenHere' \ -H 'Content-Type: application/json' \ -d '{"display_name":"Anna Petrova","gender":"female","height_cm":171,"weight_kg":63.5}'Keep the returned id. Reuse it for every session for that athlete — that is
what makes progress over time readable.
2. Reserve an upload
Section titled “2. Reserve an upload”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"}'{ "session_id": "5c836d7d-3301-49df-bfa0-9cff0550fd0e", "url": "https://s3.ai.aikynetix.app/…?X-Amz-Signature=…", "method": "PUT", "headers": { "Content-Type": "video/mp4" }, "public_url": "https://s3.ai.aikynetix.app/…/5c836d7d….source.mp4"}You get back a session id reserved for you, and a URL to PUT the bytes to. The URL is write-only to that one object and valid for two hours.
3. Upload the video
Section titled “3. Upload the video”curl -X PUT --upload-file clip.mp4 \ -H 'Content-Type: video/mp4' \ "<the url from step 2>"4. Create the session
Section titled “4. Create the session”This is the call that starts the analysis and debits one session of quota.
curl -X POST https://api.ai.aikynetix.app/api/sessions/ \ -H 'Authorization: Bearer aik_yourPartnerTokenHere' \ -H 'Content-Type: application/json' \ -d '{ "id": "5c836d7d-3301-49df-bfa0-9cff0550fd0e", "activity": "running", "exercise": "Treadmill", "video_url": "<the public_url from step 2>", "client": "<the client id from step 1>", "camera_view": "side" }'Pass the session_id back as id and the public_url as video_url. That is
what keeps the database row and the stored object pointing at each other.
You get a 201 with status: "pending".
5. Poll until it is done
Section titled “5. Poll until it is done”import timeimport requests
HEADERS = {"Authorization": "Bearer aik_yourPartnerTokenHere"}url = "https://api.ai.aikynetix.app/api/sessions/5c836d7d-3301-49df-bfa0-9cff0550fd0e/"
DEADLINE = time.monotonic() + 600 # give up after 10 minutesdelay = 2.5 # then back off
while True: r = requests.get(url, headers=HEADERS, timeout=30) r.raise_for_status() session = r.json() if session["status"] in ("completed", "failed"): break if time.monotonic() > DEADLINE: raise TimeoutError(f"still {session['status']} after 10 minutes") time.sleep(delay) delay = min(delay * 1.5, 30) # a stuck session must not be hammered
if session["status"] == "failed": raise RuntimeError(session["failure_reason"])
for metric in session["metrics"]: print(metric["key"], metric["value_num"])const HEADERS = { Authorization: "Bearer aik_yourPartnerTokenHere" };const url = "https://api.ai.aikynetix.app/api/sessions/5c836d7d-3301-49df-bfa0-9cff0550fd0e/";
const deadline = Date.now() + 600_000; // give up after 10 minuteslet delay = 2500; // then back offlet session;for (;;) { const r = await fetch(url, { headers: HEADERS }); if (!r.ok) throw new Error(`HTTP ${r.status}`); session = await r.json(); if (session.status === "completed" || session.status === "failed") break; if (Date.now() > deadline) throw new Error(`still ${session.status} after 10 minutes`); await new Promise((resolve) => setTimeout(resolve, delay)); delay = Math.min(delay * 1.5, 30_000); // a stuck session must not be hammered}
if (session.status === "failed") throw new Error(session.failure_reason);for (const metric of session.metrics) console.log(metric.key, metric.value_num);A typical clip finishes in tens of seconds. See The analysis lifecycle for what the intermediate states mean and how to show progress.
What you get back
Section titled “What you get back”metrics is a list of { key, value_num, value_json }. value_num is always
SI — centimetres, metres per second, milliseconds, degrees. metric_targets
carries the good range for this athlete, already adjusted for their profile.
analyzed_url is the annotated video.
Reading results explains how to interpret all of it.
- Core concepts — the objects and how they relate.
- Activities and exercises — the exact strings you may pass.
- Errors — what to branch on when a call fails.