Autonomy Docs
HTTP API v1

Operations

Routes, scopes, idempotency requirements, and purposes for all 18 HTTP API operations.

Call every operation with POST /api/v1/<operation> and a JSON object body. The operation name in the tables is the exact suffix after /api/v1/.

Test Cases

OperationScopeIdempotencyPurpose
test_case.listautonomy:readNoneList Test Cases in the organization, newest first. Filter by platform or a name query. Use before creating a case so existing coverage is reused.
test_case.getautonomy:readNoneFetch one Test Case with its full step list.
test_case.createautonomy:test_cases:writeRequiredCreate a Test Case from explicit steps. Fill values are literal, agent (Agent-chosen at run time), or environment (named Environment runtime value); credential-shaped literals are rejected unless explicitly relocated to an Environment secret.
test_case.update_stepsautonomy:test_cases:writeRequiredReplace a Test Case's whole step list. Requires confirm: true; without it the response describes what would change and nothing is written.

Test Plans

OperationScopeIdempotencyPurpose
test_plan.listautonomy:readNoneList Test Plans (named selections of Test Cases) in the organization.
test_plan.getautonomy:readNoneFetch one Test Plan with its ordered member Test Cases.
test_plan.createautonomy:test_plans:writeRequiredCreate a Test Plan and optionally its initial ordered member Test Cases.
test_plan.set_membersautonomy:test_plans:writeRequiredReplace a Test Plan's ordered membership. Removing cases requires confirm: true; without it the response lists the cases that would be dropped and nothing is written.

Runs

OperationScopeIdempotencyPurpose
run.triggerautonomy:runs:writeRequiredQueue Runs. Give exactly one of testCaseId or testPlanId (a plan queues one Run per member case). Target a saved Environment by slug, or pass explicit targets for a fresh deployment or artifact. Returns immediately; follow with run.get.
run.listautonomy:readNoneList recent Runs, newest first. Filter by status, Test Case, Environment, or branch. Check here before triggering duplicate work.
run.getautonomy:readNoneFetch a Run's state. Pass the previous cursor and waitMs (≤ 25000) to block until something changes; timedOut: true means nothing changed and is not an error. next is advice, never authority.
run.evidenceautonomy:readNoneGet External Evidence for a Run: what the product showed and expected per step, the verdict and diagnosis, neutral actions, and short-lived media links. Model, prompt, token, and runner internals are never included. Filter with step.

Environments

OperationScopeIdempotencyPurpose
environment.listautonomy:readNoneList Environments (named deployment targets) with their per-platform targets. Runtime value names are shown; values never are.
environment.getautonomy:readNoneFetch one Environment by slug.
environment.upsertautonomy:environments:writeRequiredCreate an Environment, or update one by slug. Updating an existing slug overwrites the given targets and requires confirm: true; without it the response describes the change and nothing is written.

Notes

Notes are HTTP-only and do not appear in the MCP tool catalog.

OperationScopeIdempotencyPurpose
note.listautonomy:readNoneList Notes on an Environment, newest first. Filter by status.
note.createautonomy:notes:writeRequiredFile a Note on an Environment. The body is plain text, where each newline starts a paragraph. Cite Runs with runIds.
note.commentautonomy:notes:writeRequiredAdd a plain-text comment to a Note's activity.

Idempotent mutations

Every mutation marked Required must include an idempotencyKey string in its JSON body. Reuse the same key when retrying the same intended mutation; use a new key for a different intended mutation. Read operations do not use an idempotency key.

Create a Test Case

This request uses only fields accepted by test_case.create. The valueSpec objects distinguish an ordinary literal from an Environment value resolved at Run time.

test_case.createbash
curl --request POST "$AUTONOMY_API_BASE/api/v1/test_case.create" \
--header "Authorization: Bearer $AUTONOMY_API_KEY" \
--header "Content-Type: application/json" \
--data '{
  "idempotencyKey": "ci-test-case-checkout-smoke-v1",
  "name": "Checkout smoke",
  "description": "A customer can complete checkout.",
  "platforms": ["web"],
  "tags": ["checkout", "smoke"],
  "steps": [
    {
      "action": "navigate",
      "target": "/checkout"
    },
    {
      "action": "fill",
      "target": "Email",
      "valueSpec": { "kind": "literal", "text": "qa@example.com" }
    },
    {
      "action": "fill",
      "target": "Password",
      "valueSpec": { "kind": "environment", "variable": "LOGIN_PASSWORD" }
    },
    {
      "action": "click",
      "target": "Place order"
    }
  ]
}'

Set AUTONOMY_API_BASE to NEXT_PUBLIC_CONVEX_SITE_URL and store the aut_ key in AUTONOMY_API_KEY.

Trigger a Run

Give exactly one of testCaseId or testPlanId. This example targets a fresh web preview; use environmentSlug instead when the target is saved.

run.triggerbash
curl --request POST "$AUTONOMY_API_BASE/api/v1/run.trigger" \
--header "Authorization: Bearer $AUTONOMY_API_KEY" \
--header "Content-Type: application/json" \
--data '{
  "idempotencyKey": "ci-run-pr-128-checkout-smoke-9f3a2c1",
  "testCaseId": "jh7exampletestcaseid",
  "platforms": ["web"],
  "targets": {
    "web": { "baseUrl": "https://preview-128.example.com" }
  },
  "branch": "feature/checkout-copy",
  "pr": "128",
  "deployment": { "commitSha": "9f3a2c1d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b" },
  "scope": "changed",
  "changedFiles": ["src/checkout/page.tsx"]
}'

The response contains runIds and, for a Test Plan, may contain planGroupRunId. Triggering returns immediately; follow each id with run.get.

Confirmation before replacement

confirm: true is never required for a create or for run.trigger. It is required only when an operation would replace existing configuration:

  • test_case.update_steps always requires it because the whole step list is replaced.
  • test_plan.set_members requires it only when cases would be removed.
  • environment.upsert requires it when an existing slug would be updated with supplied fields or targets.

Without confirmation, the API returns INVALID_ARGUMENT with details.confirmRequired: true and a details.wouldChange preview. Inspect that preview before retrying; do not add confirm: true automatically.

Cursor pagination

Every *.list request accepts an optional limit and opaque cursor:

Codejson
1{2  "limit": 20,3  "cursor": "<nextCursor from the previous response>"4}

limit defaults to 20 and must be an integer from 1 through 100. Each response has { items, nextCursor }. Pass nextCursor unchanged to fetch the next page; null means there are no more pages. Filter arguments belong in the same body and should remain unchanged across pages.

On this page