Certify an agent
A certification plays each test case n_runs times, compares the share of runs that pass every criterion with threshold_pct, and waits for its reviewer to approve or reject the result in the web app.
Endpoints
All paths start with /api/v1/diagnostics/certifications and need X-Space-Slug.
| Method | URL | Does | Auth |
|---|---|---|---|
GET | /defaults/ | {n_runs, threshold_pct, run_options, max_n_runs, min_threshold_pct, turn_time_limit_s, min_turn_time_limit_s, max_turn_time_limit_s, max_turns_limit, criteria} | Key or bearer |
POST | / | Launch a certification; 201; billed | Key or bearer |
GET | / | The workspace's certifications, newest first, without reports: {items, counts, reviewers}. Filters: search (agent name, or #n), reviewer_id, outcome (in_progress, certified, not_certified) | Key or bearer |
GET | /{certification_id}/ | Status, members and report | Key or bearer |
GET | /{certification_id}/chats/{chat_id}/ | One of its conversations | Key or bearer |
GET | /{certification_id}/chats/{chat_id}/files/{file_id}/presigned-url/ | A short-lived link to a file in one of its conversations | Key or bearer |
POST | /{certification_id}/retry/ | Measure a failed certification again, as a new one; 201 | Key or bearer |
POST | /{certification_id}/members/ | Add a member: {"email"} | Key or bearer |
DELETE | /{certification_id}/members/{user_id}/ | Remove a member | Key or bearer |
PUT | /{certification_id}/reviewer/ | Change the reviewer: {"user_id"} | Key or bearer |
POST | /{certification_id}/decision/ | Approve or reject | Bearer only |
POST | /people/check/ | Check that an email belongs to a member of this workspace: {"email"}; 204, or 422 | Key or bearer |
- A certification belongs to the workspace that launched it: everyone there who can read agents sees it.
- Changing members or the reviewer, and retrying, need edit access to agents, and stop once the certification is approved.
Request fields
| Field | Rule |
|---|---|
agent_id | Required |
dataset | Required, 1–25 rows, each {"simulated_user": …} as in Build an environment |
file_bucket | The files the cases hold, [{file_id, description}] |
n_runs | 1–50, default 20 |
threshold_pct | 50–100, default 80 |
turn_time_limit_s | Seconds one agent turn may take, 60–3600, default 600. A turn over it ends the conversation there, and that run fails without being judged |
max_turns | Messages each simulated person sends at most, 1–20, the same for every case. Default: the highest any case asks for |
members | Optional, up to 50 {"email"}; each member is emailed |
reviewer_email | Optional: the launcher's own or a member's; default: the launcher |
- The launcher is always a member.
GET /{id}/returns theturn_time_limit_sthe certification ran with; a retry keeps it.- Every run is judged on the platform's default criteria, listed in
GET /defaults/→criteria; an environment's checks do not apply.
Launch and read a certification
-
Build the scenarios as in Build an environment, steps 1–2, or reuse the
datasetof a saved environment fromGET /api/v1/diagnostics/kits/{kit_id}/. -
Launch it:
curl -X POST "$CENTRAL_HUB_URL/api/v1/diagnostics/certifications/" \ -H "X-API-Key: $ALO_API_KEY" \ -H "X-Space-Slug: $WORKSPACE_SLUG" \ -H "Content-Type: application/json" \ -d '{ "agent_id": 42, "dataset": [{"simulated_user": {"id": "deadline", "persona": "A bid manager at a construction firm", "context": "Preparing a bid for a public tender", "goal": "Learn the exact submission deadline", "opening": "When is the deadline for this tender?"}}], "file_bucket": [], "members": [{"email": "reviewer@example.com"}], "reviewer_email": "reviewer@example.com" }' -
Poll
GET /{id}/untilstatusis no longerrunning; see Statuses. While it runs,report.partialistrueand the rate is so far, not a verdict. -
Read the result in
report; see Report fields.
Statuses
status | Means |
|---|---|
running, cancelling | In progress |
awaiting | Measured; waiting for the reviewer |
approved, rejected | The reviewer decided |
completed | Ended with nothing judged; nothing to approve |
cancelled, failed | Stopped; failed carries error_message |
Report fields
| Field | Holds |
|---|---|
runs_passed, executions, meets_threshold | The verdict: runs that passed every criterion, out of all runs |
judged, conversations_total | How far it got |
criteria[] | Each criterion with {label, passed, evaluated} |
cases[].executions[] | Each run: met, failed_criteria[] with {id, label, reason}, timed_out_turn (the turn that ran over the time limit, or null), and chat_id; read the conversation with GET /{id}/chats/{chat_id}/ |
avg_cost_usd, avg_latency_s | Per conversation |
To stop a certification, cancel its gym session: POST /api/v1/diagnostics/gym/{gym_session_id}/cancel/, with gym_session_id from GET /{id}/.
Troubleshooting
| Response | Cause | Fix |
|---|---|---|
422 No one in this workspace signs in as … | An address in members or reviewer_email is not a member of this workspace; nothing ran | Use the address the person signs in with, or invite them to the workspace first |
422 The reviewer must be one of the members. | reviewer_email is not the launcher or in members | Add the reviewer to members |
403 Changing who a certification is shared with needs edit access. | Members or reviewer changed without edit access to agents | Ask someone who can edit agents |
409 An approved certification can no longer change hands. | Members or reviewer changed after approval | Nothing to do |
409 Choose another reviewer before removing this one. · Whoever launched it stays a member. | Removing the reviewer or the launcher | Change the reviewer first; the launcher stays |
422 The reviewer must be a member first. | PUT /reviewer/ with someone not in the members | Add them with POST /members/ first |
409 Only a failed certification can be retried. · Its agent was deleted. | Retry on a certification that did not fail, or whose agent is gone | Launch a new one |
401 {"detail": "Not authenticated"} on /decision/ | This route takes a signed-in user only | The reviewer decides in the web app |