Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.awaithumans.dev/llms.txt

Use this file to discover all available pages before exploring further.

POST /api/tasks/{id}/complete
Authorization: Bearer <ADMIN_API_TOKEN>   (or session cookie)
Content-Type: application/json
Records the human’s response and transitions the task toward a terminal status. If a verifier is configured, this endpoint runs the LLM call inline before deciding the final status. The dashboard’s “Submit” button hits this endpoint. So do the Slack modal view_submission handler and the email magic-link confirmation page (each with their own auth shape — Slack signature, magic-link token).

Authorization

CallerAllowed?
Admin bearer token
Operator session
Assignee session
Other logged-in user403
The assignee check is the security-critical bit — a non-operator can complete only their own assigned tasks.

Request

{
  "response": { "approved": true, "notes": "Duplicate charge confirmed." },
  "completed_by_email": null,
  "completed_via_channel": null
}
FieldTypeRequiredDescription
responseobjectyesMust validate against the task’s response_schema.
completed_by_emailstring | nullnoOverride stamped attribution. Browser-driven calls leave null and the server reads the session.
completed_via_channelstring | nullnoFree-form channel identifier (dashboard, slack, email). Used by the audit log.

Response

HTTP/1.1 200 OK
Content-Type: application/json
The full task record (same shape as POST /api/tasks response). The status field reflects what happened:
  • completed — verifier passed (or no verifier). Final.
  • rejected — verifier rejected this attempt; the task is non-terminal, the human can resubmit.
  • verification_exhausted — verifier rejected, attempts exhausted. Final.
Inspect verifier_result.reason for the verifier’s explanation when rejected / verification_exhausted.

With verifier

If task.verifier_config is set:
  1. Server runs the LLM call inline (5–30s typical).
  2. Pass → status=completed, response saved, audit log records action=verified.
  3. Fail with attempts left → status=rejected, verification_attempt bumped, audit log records action=rejected + verifier_reason. The task stays open for resubmission.
  4. Fail with attempts exhausted → status=verification_exhausted (terminal), audit log records action=verification_exhausted.
Provider-level failures (vendor outage, missing API key, missing SDK extra) propagate as 5xx with typed error_code and DO NOT consume an attempt.

With redact_payload=True

The verifier is skipped entirely. The operator marked the payload sensitive; we don’t ship it to a third-party LLM. Status goes straight to completed.

Errors

Statuserror_codeCause
400(validation)Body shape mismatch.
401Missing / invalid auth.
403Caller isn’t operator / admin / assignee.
404TASK_NOT_FOUNDTask ID doesn’t exist.
409TASK_ALREADY_TERMINALTask is already in a terminal status (race with timeout / cancel).
422VERIFIER_CONFIG_INVALIDStored verifier config doesn’t match the current schema.
422VERIFIER_PROVIDER_UNKNOWNOperator typo’d the provider name.
500VERIFIER_API_KEY_MISSINGServer can’t read the LLM API key.
500VERIFIER_PROVIDER_UNAVAILABLESDK extra not installed.
502VERIFIER_PROVIDER_ERRORVendor returned an error.
Each error body has the typed error_code + docs URL.

Outbound webhook

If task.callback_url is set AND the task transitions to a terminal status, an HMAC-signed POST fires to the callback URL after the response is sent (FastAPI BackgroundTask — the human’s submit doesn’t wait on it). See Self-hosting → Security for the signature scheme.

SDK equivalent

The dashboard calls this directly from the form submission. From your own code:
curl -X POST http://localhost:3001/api/tasks/tsk_abc/complete \
  -H "Authorization: Bearer $AWAITHUMANS_ADMIN_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"response": {"approved": true}}'
For the typical agent loop (create + poll), use the SDK’s await_human().