Skip to content

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.

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; its tenant_id is 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.
MethodPathAuthReturns
GET/v1/healthnone{ status, service, version }
GET/v1/activity-resultstenant key{ data: ActivityResult[], next_cursor }
GET/v1/activity-results/:idtenant keyActivityResult (404 if not your tenant)
GET/v1/progresstenant key{ data: Progress[], next_cursor }
GET/v1/artifactstenant key{ data: Artifact[], next_cursor }
GET/v1/artifacts/:idtenant keyArtifact

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.

list activity results
curl https://api.iterahq.dev/v1/activity-results?limit=50 \
-H "Authorization: Bearer itera_<prefix>_<secret>"

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 }.

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:

MethodPathAuthPurpose
POST/v1/embed/sessionDFL JWTTrade 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/judgeDFL JWTGrade 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.