Data API · stable v1

Data API

Build private, read-only tools around the same Quko account permissions you already have. Read sessions, health data and analytics, and download the exact files produced by the web application. Only the owner of an application can authorize it.

Base URLhttps://cloud.quko.es/api/v1
AuthenticationOAuth 2.1 + PKCE S256
Envelope{ data, meta }
SpecificationOpenAPI 3.1 · 1.0.0
No live credentials. Every example and animation uses bundled synthetic fixtures. Quko Dev never asks for, transmits, or stores customer access tokens.
01

Quick start

One authorization code flow, one consistent response shape.

1

Register

Create a Data application in the dashboard. Redirect URIs match exactly.

2

Authorize

Use Authorization Code with PKCE S256, state, and—when using OIDC—a nonce.

3

Call

Send a Bearer access token. Follow opaque cursors and retry idempotent jobs safely.

curl --request GET \
  --url 'https://cloud.quko.es/api/v1/sessions?limit=25&important=true' \
  --header 'Authorization: Bearer <access_token>' \
  --header 'Accept: application/json'
02

OAuth 2.1 and OpenID Connect

Authorization Code is the only interactive grant; PKCE S256 is mandatory.

GET/.well-known/openid-configuration/apiDiscovery
GET/api/oauth/authorizeAuthorization
POST/api/oauth/tokenCode + refresh exchange
GET/api/oauth/userinfoOIDC claims
POST/api/oauth/revokeToken revocation
POST/api/oauth/introspectApproved confidential clients
GET/api/oauth/jwks.jsonJWT verification keys

Interactive PKCE builder

Generate a local verifier, S256 challenge, state, nonce, and authorization URL. Nothing leaves this browser.

Select “Generate synthetic request”.

Security checks

  • Exact registered redirect URI and intended audience
  • State checked before exchange; nonce checked in the ID token
  • Confidential clients authenticate with HTTP Basic
  • Refresh tokens rotate; replay revokes the token family
  • Grant revocation rejects access tokens immediately
  • Only the application owner can authorize it
03

Requests, pagination, jobs, and errors

These rules apply to every resource card below.

Opaque cursors

Lists accept limit up to 100 and the unmodified meta.next_cursor. Cursors expire and are resource- and subject-bound.

Inaccessible is 404

Ownership failures do not disclose whether another user’s identifier exists.

Idempotency

Send Idempotency-Key on creation and processing. Reuse it only for the identical operation.

Asynchronous work

Uploads, exports, and device operations return 202. Poll the status URL with bounded backoff.

Success

{
  "data": [{ "id": 482, "distance_m": 1000 }],
  "meta": { "next_cursor": "eyJraW5kIjoic2Vzc2lvbiJ9…", "limit": 25 }
}

Error

{
  "error": "invalid_request",
  "error_description": "limit must be from 1 to 100",
  "request_id": "req_synthetic_01"
}
04

Privacy projection

Allowlisted serializers are the boundary—not database models.

Available when authorized

  • Processed, bounded metrics and summaries
  • Downsampled route coordinates under sessions:read
  • Derived strokes, splits, comparisons, and analyses
  • Owned metadata permitted by the requested scope

Never crosses the API

  • data, datapal, IMU matrices, or full-rate channels
  • Credentials, tokens, serials, UUIDs, network data, telemetry, or logs
  • Unauthorized crew identities or private crew data
  • Unknown-provenance sensitive fields

The original encrypted .qk file is the sole device portability exception. It is delivered once, unchanged and still encrypted; no Data endpoint decodes it or exposes its sensor arrays. Garmin-origin and other external-provider data never cross this API either.

05

Session analytics · Chart.js example

Real session data (distance on the X axis) plotted with Chart.js. Scroll to zoom, drag to pan.

Cursor pagination and filtering

Comparison request

06

Workout tree and export jobs

Edit a version-1 template and simulate the asynchronous web-equivalent export workflow.

Workout builder

Export lifecycle

JSON, PDF, full PDF, XLSX, FIT, and TCX are generated by the same builders as the Quko web app. Partner exports use those builders in privacy-safe mode.

Not queued
07

Own-account data

Existing web permissions, no administrative side door.

Roster & teams

Read-only under athlete:read. There is no route to grant access, change memberships, staff roles, or licences.

Tracks

Read-only under sessions:read. The API cannot create, edit, merge, or delete a track.

Devices

Sanitized status under devices:read; manifests and one-time encrypted file portability under devices:files.

06

Independent health consent

health:read is read-only, approved separately, and begins unchecked.

OriginReadRule
Quko / Kosoku heart rateYesThe authorizing person only
Manual Quko weight / lactateYesIndependent health consent
Garmin or other providerNeverPermanent provenance exclusion
Another crew memberNeverSubject isolation
07

QukoSim · Three.js example

The Quko Cloud replay scene (same K1 model, water, sky and lane buoys) driven by a synthetic privacy-reduced artifact—no metric, GPS, identity, stroke, health, equipment, device, timestamp, or source-index arrays.

30 Hz artifact · interpolated

Drag to orbit; wheel to zoom; the camera follows the lead boat. Playback, interpolation, seeking, camera motion, and comparison remain in this browser.

Artifact header

{
  "schema": 1,
  "frame_count": 900,
  "model_class": "K1",
  "quantization": { "position_m": 0.25, "orientation_deg": 2.0 },
  "frames": [[x, 0, 0, roll, pitch, yaw, paddle_phase], …]
}
// delivered at 30 Hz; clients interpolate between frames

Embed lifecycle

  1. Create for 1–9 authorized sessions and an approved exact HTTPS origin.
  2. Consume the two-minute single-use launch without OAuth in the iframe URL.
  3. Fetch immutable private artifacts once and keep them in memory.
  4. Renew a revocable ten-minute authorization lease.

A viewer can inspect or retain quantized visible transforms already received, much like analysing a screen recording. They cannot reconstruct sensor, GPS, health, stroke, or analytics arrays. Revocation blocks new access; it cannot recall information already displayed.

08

Complete endpoint reference

Loading the bundled OpenAPI 3.1 contract…