Reading results (itera-api)
itera-api (https://api.iterahq.dev) is the pull-only REST surface for
reading learners’ activity results, progress, and artifacts back out of
Itera. It is how DFL (or any tenant) consumes Itera — dashboards, LMS admin,
Gantt, etc.
Auth — per-tenant API key
Section titled “Auth — per-tenant API key”Authorization: Bearer itera_<prefix>_<secret>(or X-Itera-Api-Key: itera_<prefix>_<secret>).
- The key is sha256’d and looked up in
itera.api_keys; itstenant_idis the only authorization. Every query is scoped to that tenant. - Unknown / revoked →
401. A cross-tenant id fetch →404(no enumeration). - To obtain a key: ask your Itera admin — see Authentication → reading results.
/v1 endpoints
Section titled “/v1 endpoints”| Method | Path | Auth | Returns |
|---|---|---|---|
| GET | /v1/health | none | { status, service, version } |
| GET | /v1/activity-results | tenant key | { data: ActivityResult[], next_cursor } |
| GET | /v1/activity-results/:id | tenant key | ActivityResult (404 if not your tenant) |
| GET | /v1/progress | tenant key | { data: Progress[], next_cursor } |
| GET | /v1/artifacts | tenant key | { data: Artifact[], next_cursor } |
| GET | /v1/artifacts/:id | tenant key | Artifact |
Query params: ?limit=N (default 50, max 200), ?cursor=<opaque>,
?activity_id=<uuid> (results/artifacts), ?user_id=<uuid> (artifacts).
Pagination is keyset over (created_at, id); next_cursor is an opaque
base64url cursor, stable under inserts.
curl https://api.iterahq.dev/v1/activity-results?limit=50 \ -H "Authorization: Bearer itera_<prefix>_<secret>"Schemas
Section titled “Schemas”ActivityResult
{ "id": "…", "activity_id": "…", "lesson_id": "…", "itera_user_id": "…", "status": "completed | in_progress | failed", "score": 90, "completed_at": "…", "created_at": "…", "artifact_ids": ["…"]}Progress
{ "itera_user_id": "…", "program_id": "…", "completed_count": 7, "total_count": 12, "percent": 58, "last_activity_at": "…"}Artifact
{ "id": "…", "result_id": "…", "kind": "diagram | document | site | repo", "ref_url": "…", "repo_url": "…", "verification": {…}, "created_at": "…"}Error — { "error": { "code", "message" } }, code ∈ { unauthorized, not_found, invalid_request, rate_limited, internal_error }.
Embed SSO & the AI judge (learner-facing)
Section titled “Embed SSO & the AI judge (learner-facing)”Two endpoints on itera-api are not tenant-key auth — they take a DFL
JWT (the embed boundary) and serve the learner/player flow. A teacher rarely
calls them directly, but they explain the DFL↔Itera handoff:
| Method | Path | Auth | Purpose |
|---|---|---|---|
| POST | /v1/embed/session | DFL JWT | Trade a verified DFL access token for a fresh Itera session ({ access_token, refresh_token, expires_in, itera_user_id }). This is how an internal DFL teacher gets an Itera token — see Authentication. |
| POST | /v1/embed/judge | DFL JWT | Grade a learner’s artifact against an activity’s spec + rubric (a free OpenRouter model), persist the verdict, and gate progress on a pass. Degrades to status: "pending" (still 200) if unconfigured. |