Skip to Content
Attempts

Attempts

An attempt is the parent container for a single learner’s run through a simulation. It owns the chats, the grading, the artifacts, and the lifecycle state. If a learner is doing something in Glow, they’re inside an attempt.

What is an attempt?

An attempt is created when a learner starts a simulation. It holds:

  • One chat per scenario in the simulation — each scenario becomes a sibling conversation under the same attempt
  • Grading state — when the attempt completes, rubric scoring rolls up across the chats
  • Lifecycle metadata — start time, completion time, archive flag, practice vs. graded mode
  • Group membership — attempts can be bound to an attempt group for batch coordination

The conversation surface itself — messages, audio, hints, grading — lives in the chat sub-namespace. The analytics view on top of an attempt lives in dashboard. This page covers the root attempt artifact: the lifecycle and management ops that act on an attempt as a whole.


The lifecycle

Every attempt moves through a small state machine:

StepEndpointWhat happens
1. StartPOST /attempt/startCreate the attempt, fan out one chat per scenario
2. RunPOST /chat/*Learner converses with each persona — see chat
3. Stop (optional)POST /attempt/stopHalt an in-flight AI generation mid-stream
4. CompletePOST /attempt/completeFinalize the attempt and trigger rubric grading
5. Archive (optional)POST /attempt/archiveHide from default lists without deleting

Steps 1, 3, 4, and 5 are the focus of this page. Step 2 is the chat surface — covered in full on /chat.


Starting an attempt

POST /attempt/start takes either a home_id or a practice_id (the entry the learner clicked from the home or practice page) and resolves it into the underlying simulation. One chat is created per scenario in that simulation, all parented under the new attempt_id.

# Start from a home entry glow attempts start --body '{"home_id": "00000000-0000-0000-0000-000000000001"}' # Start from a practice entry glow attempts start --body '{"practice_id": "00000000-0000-0000-0000-000000000002"}'

The response carries the new attempt_id plus the list of chat_ids that were spawned. From there the client typically calls POST /chat/message (or the audio variants) to drive the first conversation.


Stopping in-flight generation

POST /attempt/stop halts a running AI response. It targets the attempt’s group_id (the streaming hub key — see Streaming Foundations) and cancels the in-flight generation without tearing down the attempt itself.

glow attempts stop --body '{"group_id": "00000000-0000-0000-0000-000000000003"}'

This is the safe way to interrupt a long-running response (e.g. the learner wants to retry, or the persona is going off the rails). The attempt and chat rows are unaffected — only the generation is cancelled.


Completing and archiving

Two different operations, two different intents.

Complete

POST /attempt/complete finalizes the attempt. It freezes the chats, runs the rubric grader across them, and produces the completion_id that downstream views (dashboard, reports) hang off of.

glow attempts complete --body '{ "attempt_id": "00000000-0000-0000-0000-000000000010", "message": "Completed by learner" }'

Completion is irreversible in the sense that the grading rollup happens at this point — subsequent chat edits won’t retroactively re-grade. To re-grade, regenerate via the chat-level grade endpoint (see /chat).

Archive

POST /attempt/archive hides attempts from default list views without deleting them. Use it when a learner’s run was a mistake, a test, or otherwise shouldn’t show up in dashboards.

Archive uses the canonical bulk-write shape — pass either explicit IDs, or all: true with flat filter fields plus excluded_ids. See Patterns: bulk operations for the full pattern.

# Archive specific attempts glow attempts archive --body '{ "attempt_ids": ["00000000-0000-0000-0000-000000000010"], "archived": true }' # Bulk-archive everything matching a filter, except a few keepers glow attempts archive --body '{ "all": true, "filter_cohort_ids": ["00000000-0000-0000-0000-000000000020"], "excluded_ids": ["00000000-0000-0000-0000-000000000011"], "archived": true }'

To unarchive, pass archived: false with the same selector. Default search hides archived attempts; pass show_archived: true to include them.


Listing and searching

POST /attempt/search is the canonical paginated history endpoint. The previous per-view /attempt/{home,practice,dashboard}/search routes were collapsed into this one — view intent is now expressed through filter parameters (practice, target_profile_id, profile_ids, …).

glow attempts search --body '{ "cohort_ids": ["00000000-0000-0000-0000-000000000020"], "simulation_search": "tutoring", "practice": false, "page": 0, "page_size": 25 }'

The response is a HistoryResponse with hydrated display aggregates (score %, persona, time, etc.) plus filter facets so the UI can render dropdowns without a second round-trip. For the full facet recipe and filter-field conventions, see Patterns: search facets and the Attempt API reference for the complete filter schema.


Exporting

POST /attempt/export returns a {file_id, file_name, row_count} descriptor. The client then downloads the actual ZIP via the canonical media path (/attempt/file/download) — see Media Foundations for the universal download flow.

glow attempts export --body '{ "view": "dashboard", "attempt_id": "00000000-0000-0000-0000-000000000010" }'

The export bundles chat transcripts, audio, rubric scoring, and any generated artifacts. View-aware: view: "record" exports a single learner’s history, view: "dashboard" exports the cohort-level slice, etc.


Groups

POST /attempt/group resolves (or mints) the group_id that ties an attempt to the streaming hub. Most clients don’t call this directly — attempt/start mints the group for you — but it’s exposed for advanced flows that need to coordinate cross-attempt batches or re-attach to an existing group.


Universal ops

The attempt artifact also exposes the universal cross-cutting operations every artifact in Glow gets for free. These are documented once in Foundations rather than re-explained here:

  • POST /attempt/context, POST /attempt/problem, POST /attempt/refresh, POST /attempt/title — generic artifact helpers (context loading, error surfacing, cache-bust, retitle).
  • POST /attempt/generate and POST /attempt/generations — the generation request / history pair. See Generation.
  • POST /attempt/watch — the SSE subscription for live updates. See Streaming Foundations.
  • POST /attempt/audio_upload, POST /attempt/audio_download, POST /attempt/file_download, POST /attempt/file_preview, POST /attempt/image_download, POST /attempt/text_download, POST /attempt/video_download — universal media operations. See Media.
  • POST /attempt/get, POST /attempt/draft, POST /attempt/drafts — single-row fetch and the draft cycle. The draft cycle follows the same optimistic-concurrency pattern as personas.

Common operations reference

TaskCLIAPI
Start an attemptglow attempts start --body '{...}'POST /attempt/start
Stop in-flight generationglow attempts stop --body '{...}'POST /attempt/stop
Complete an attemptglow attempts complete --body '{...}'POST /attempt/complete
Archive attemptsglow attempts archive --body '{...}'POST /attempt/archive
Search attemptsglow attempts search --body '{...}'POST /attempt/search
Export an attemptglow attempts export --body '{...}'POST /attempt/export
Resolve attempt groupglow attempts group --body '{...}'POST /attempt/group
Get one attemptglow attempts get --body '{...}'POST /attempt/get
Save a draftglow attempts draft --body '{...}'POST /attempt/draft
List draftsglow attempts draftsPOST /attempt/drafts
Last updated on