Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.argalabs.com/llms.txt

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

The Arga API lets you start validations, retrieve run results, and manage authentication programmatically. All endpoints are available at https://api.argalabs.com.

Authentication

Every authenticated endpoint accepts a Bearer token in the Authorization header:
Authorization: Bearer <token>
Arga supports two token types:
Token typeHow to obtainFormat
API keyCreate one from Settings → API Keys in the web app, run arga login from the CLI to create a device-scoped key, or sign up with email via POST /auth/email/signup/verify.Prefixed with arga_sk_
JWTReturned after completing the GitHub OAuth flow in the web app.Standard JWT
Both token types use the same Authorization: Bearer <token> header. Endpoints below note which token types they accept.

Auth requirements by endpoint

EndpointMethodAPI keyJWTNotes
/healthGETNo auth required
/validate/url-runPOSTYesYesUnified URL validation
/validate/pr-runPOSTYesYesUnified PR/branch validation (also used for sandbox runs via run_type: "agent_run")
/validate/url/probePOSTYesYesDetect twins for a URL
/validate/twinsGETYesYes
/validate/twins/provisionPOSTYesYes
/validate/twins/provision/{run_id}/statusGETYesYes
/validate/twins/provision/{run_id}/extendPOSTYesYes
/validate/twins/provision/{run_id}/teardownPOSTYesYes
/validate/{run_id}/feedbackPOSTYesYesDeprecated
/validate/{run_id}/cancelPOSTYesYes
/validate/{run_id}/resultsGETYesYesSSE stream
/runs/{run_id}GETYesYes
/runs/{run_id}/logsGETYesYesTwin and sandbox logs
/validate/{run_id}/artifacts/{filename}GETYesYesAlso accepts ?token= query param
/validation/github/configGETYesYesTeam plan required
/validation/github/configPOSTYesYesTeam plan required
/validation/github/configPATCHYesYesTeam plan required
/validation/prPOSTYesYesTeam plan required
/validation/runsGETYesYesTeam plan required
/scenarios/presetsGETNo auth required
/scenariosPOSTYesYes
/scenariosGETYesYes
/scenarios/{scenario_id}GETYesYes
/scenarios/{scenario_id}PUTYesYes
/scenarios/{scenario_id}DELETEYesYes
/demo-runner/runsPOSTYesYesRecord a browser flow from a prompt
/demo-runner/runsGETYesYesList recent demo runs
/demo-runner/runs/{run_id}GETYesYes
/demo-runner/runs/{run_id}/configPATCHYesYesUpdate the saved TestConfig for a run
/demo-runner/runs/{run_id}/messagesPOSTYesYesSend a user message to a run
/demo-runner/runs/{run_id}/rerunPOSTYesYesReplay a recorded flow
/demo-runner/runs/{run_id}/artifacts/{filename}GETYesYesAlso accepts ?token= query param
/demo-runner/testsGETYesYesList saved runner tests
/demo-runner/testsPOSTYesYesSave a runner test from a completed run
/demo-runner/tests/{test_id}GETYesYes
/demo-runner/tests/{test_id}PATCHYesYes
/demo-runner/tests/{test_id}DELETEYesYes
/demo-runner/tests/{test_id}/runPOSTYesYesExecute a saved runner test
/auth/device/startPOSTPublic
/auth/device/pollPOSTPublic (device code acts as credential)
/auth/meGETYesYes
/auth/api-keysPOSTYes
/auth/cli/devicesGETYes
/auth/email/signupPOSTPublic
/auth/email/signup/verifyPOSTPublic
/auth/cli/devices/{cli_api_key_id}/revokePOSTYesYes
API keys (from arga login or the dashboard) are the primary authentication method for programmatic access. All endpoints in this reference accept API keys unless noted otherwise.

Health check

GET Health

GET /health
Returns the API server status. No authentication required. Response
{"status": "ok", "version": "0.1.0"}

Unified workflows

These are the primary endpoints for starting validation runs.

POST Start a URL run

Accepts both API key and JWT authentication.
POST /validate/url-run
Start a validation run against a deployed URL. When you include a prompt, the run starts immediately. When you omit prompt, the server plans the run automatically and streams progress via server-sent events (SSE). Request body
FieldTypeRequiredDescription
urlstringYesTarget URL to validate. Must be a public HTTP or HTTPS URL.
promptstringNoNatural-language description of what to test. When provided, the run starts immediately. When omitted, the server auto-plans the run and returns an SSE stream.
credentialsobjectNoLogin credentials for the target app.
credentials.emailstringNoEmail address for authentication. Must be provided together with password.
credentials.passwordstringNoPassword for authentication. Must be provided together with email.
twinsarray of stringNoDigital twin services to include in the run (e.g. slack, stripe). When provided, only the specified twins are provisioned. When omitted and a scenario_id is provided, the twins declared in that scenario are used automatically. Only valid twin names from the twin catalog are accepted.
runner_modestringNoRunner execution mode. Use "dom" for DOM-based interaction or "visual" for screenshot-based visual interaction.
session_idstringNoUUID of an existing chat session to attach this run to. When omitted, a new session is created.
repostringNoRepository in owner/repo format. When provided together with branch, enables diff-aware test planning so the generated tests focus on the code changes in that branch.
branchstringNoBranch name. Used together with repo for diff-aware test planning.
pr_urlstringNoPull request URL. Used to resolve the branch when branch is not provided directly.
provision_idstringNoUUID of a twin provisioning session returned from Provision twins. When provided, the run reuses the already-provisioned twin environment instead of creating new instances. The provision must be in ready status.
scenario_idstringNoUUID of a saved scenario to pre-seed twins with sample data. When provided without prompt, the scenario’s own prompt is used. If you supply both, your prompt takes precedence. When twins is not specified, the scenario’s own twin list is used as the default.

Workflow with twins

If you want your URL run to exercise digital twins, follow this sequence:
  1. Provision twins via POST /validate/twins/provision and wait until the status is ready.
  2. Deploy your app to staging with its environment variables rewritten to point at the twin URLs (the same .env changes the wizard does automatically).
  3. Start the URL run against that staging URL, passing the provision_id from step 1 so the run reuses the already-provisioned twins.
You can also pass a twins array directly to /validate/url-run (which provisions twins inline), but your app still needs to be deployed against the twin URLs for the tests to actually hit the twin-backed paths.
The arga wizard init CLI handles steps 1 and 2 automatically — it provisions twins, rewrites your .env, and you just start your app.
Example request (with prompt)
curl -X POST https://api.argalabs.com/validate/url-run \
  -H "Authorization: Bearer $ARGA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://staging.example.com",
    "prompt": "test the login flow",
    "twins": ["slack", "stripe"]
  }'
Response (with prompt)
{
  "run_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "queued",
  "session_id": "f0e1d2c3-b4a5-6789-0abc-def123456789"
}
FieldTypeDescription
run_idstringUnique identifier for the validation run.
statusstringInitial run status. queued when a prompt is provided; transitions to running once the runner job is dispatched.
session_idstringChat session associated with this run.
Response (without prompt) When prompt is omitted, the endpoint returns a text/event-stream response with SSE events as the server plans the run. The X-Session-Id and X-Run-Id response headers contain the session and run identifiers. Errors
StatusDetail
400A valid public http(s) URL is required.
400Email and password must both be provided.
400Invalid provision_id
400Invalid scenario_id format
401Invalid or expired token.
403Plan limit errors (free plan restrictions, monthly limit reached).
404Provision not found
404Scenario not found
409Provision is not ready (status: {status}). Poll status first.

POST Start a PR run

Accepts both API key and JWT authentication.
POST /validate/pr-run
Start a validation run against a pull request or branch. The server deploys the branch, generates a test plan, and streams progress via server-sent events (SSE). Request body
FieldTypeRequiredDescription
repostringYesRepository in owner/repo format.
branchstringConditionalBranch name. Required unless pr_url is provided.
pr_urlstringConditionalPull request URL. Used to resolve the branch when branch is not provided.
context_notesstringNoAdditional instructions or context for the validation.
scenario_promptstringNoNatural-language prompt to customize the generated test scenarios.
scenario_idstringNoUUID of a saved scenario to pre-seed twins with sample data. When provided without scenario_prompt, the scenario’s own prompt is used.
twinsarray of stringNoDigital twin services to include in the run (e.g. slack, stripe). When provided, the specified twins are merged with any twins auto-detected from the repository’s runtime profile. Only valid twin names from the twin catalog are accepted.
frontend_urlstringNoBase URL of the frontend under test. Defaults to http://localhost:3000.
session_idstringNoUUID of an existing chat session to attach this run to. When omitted, a new session is created.
run_typestringNoControls how the run is categorized. Accepted values: "pr_run" (default) or "agent_run". When set to "agent_run", the run uses the same story-based validation pipeline but is grouped under the sandbox section in the dashboard.
Example request
curl -X POST https://api.argalabs.com/validate/pr-run \
  -H "Authorization: Bearer $ARGA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "repo": "acme/web-app",
    "branch": "feature/checkout",
    "context_notes": "focus on the checkout flow changes"
  }'
Response The endpoint returns a text/event-stream response with SSE events as the server generates the test plan and deploys the branch. The X-Session-Id and X-Run-Id response headers contain the session and run identifiers. Errors
StatusDetail
400A branch or PR URL is required.
400GitHub integration required for validation.
400Invalid repository format.
400Invalid scenario_id format
401Invalid or expired token.
403Plan limit errors.
404Session not found
404Scenario not found
Sandbox runs use the same /validate/pr-run endpoint with run_type: "agent_run". There is no separate sandbox endpoint.

Twins

GET List available twins

Accepts both API key and JWT authentication.
GET /validate/twins
List the digital twin services available for sandbox deployments. Returns an array sorted by kind (backend twins first, then frontend twins), then alphabetically by label within each group. Response
[
  {
    "name": "slack",
    "label": "Slack",
    "kind": "backend",
    "show_in_ui": true
  },
  {
    "name": "discord",
    "label": "Discord",
    "kind": "backend",
    "show_in_ui": true
  },
  {
    "name": "jira",
    "label": "Jira",
    "kind": "backend",
    "show_in_ui": true
  },
  {
    "name": "notion",
    "label": "Notion",
    "kind": "backend",
    "show_in_ui": true
  },
  {
    "name": "unified",
    "label": "Unified",
    "kind": "backend",
    "show_in_ui": true
  },
  {
    "name": "stripe",
    "label": "Stripe",
    "kind": "backend",
    "show_in_ui": true
  },
  {
    "name": "unstructured",
    "label": "Unstructured",
    "kind": "backend",
    "show_in_ui": true
  },
  {
    "name": "google_drive",
    "label": "Google Drive",
    "kind": "frontend",
    "show_in_ui": true
  },
  {
    "name": "google_calendar",
    "label": "Google Calendar",
    "kind": "frontend",
    "show_in_ui": true
  },
  {
    "name": "dropbox",
    "label": "Dropbox",
    "kind": "frontend",
    "show_in_ui": true
  },
  {
    "name": "box",
    "label": "Box",
    "kind": "frontend",
    "show_in_ui": true
  }
]
FieldTypeDescription
namestringTwin identifier used in the twins array when deploying a sandbox.
labelstringHuman-readable display name.
kindstringTwin category: backend for server-side API mocks (e.g. messaging, billing, integration proxies) or frontend for client-side file storage and productivity tool mocks.
show_in_uibooleanWhether this twin is shown in the web UI by default.
Errors
StatusDetail
401Invalid or expired token.

POST Probe a URL for twin suggestions

Accepts both API key and JWT authentication.
POST /validate/url/probe
Probe a URL for integration SDK and API fingerprints and return suggested digital twins. Use this before starting a validation to discover which twins would be useful for the target application. Request body
FieldTypeRequiredDescription
urlstringYesTarget URL to probe. Must be a publicly reachable HTTP or HTTPS URL. The server fetches the page to detect integration fingerprints, so the URL must be accessible from Arga’s infrastructure.
Example request
curl -X POST https://api.argalabs.com/validate/url/probe \
  -H "Authorization: Bearer $ARGA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://staging.example.com"}'
Response
{
  "suggested_twins": ["slack", "stripe"],
  "reasoning": ["Detected Slack SDK references in page resources", "Found Stripe.js integration"],
  "detected_signals": ["slack-sdk", "stripe-js"]
}
FieldTypeDescription
suggested_twinsarray of stringTwin names recommended for this URL based on detected signals.
reasoningarray of stringHuman-readable explanations for each suggestion.
detected_signalsarray of stringRaw integration fingerprints found during probing.
Errors
StatusDetail
400A valid public http(s) URL is required.
401Invalid or expired token.

POST Provision twins

Accepts both API key and JWT authentication.
POST /validate/twins/provision
Provision one or more ephemeral twin instances. Returns a run_id you can use to poll for status and retrieve connection details. Request body
FieldTypeRequiredDefaultDescription
twinsarray of stringYesTwin names to provision (e.g. slack, stripe). At least one valid twin name is required. Use the twin catalog to discover available names.
ttl_minutesintegerNo60Time-to-live in minutes before the twins are automatically torn down. Range: 1480.
scenario_idstringNoUUID of a scenario to pre-seed the twins with sample data. Takes precedence over scenario_prompt when both are provided.
scenario_promptstringNoNatural-language prompt describing the desired twin state (e.g. “A Slack workspace with two channels and five messages”). When provided without a scenario_id, the twins are seeded by generating a configuration from this prompt. Ignored when scenario_id is also set.
Example request
curl -X POST https://api.argalabs.com/validate/twins/provision \
  -H "Authorization: Bearer $ARGA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "twins": ["slack", "stripe"],
    "ttl_minutes": 120,
    "scenario_prompt": "A Slack workspace with two channels and a Stripe account with one active subscription"
  }'
Response
{
  "run_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
FieldTypeDescription
run_idstringUnique identifier for the provisioning session. Use this to poll for status.
Errors
StatusDetail
400At least one valid twin name is required.
401Invalid or expired token.
403Quickstart API key has no provisions remaining. Run arga login for full access. — Returned when a quickstart-scoped key (issued via email signup) has exhausted its 5-provision limit.
403Free plan allows 1 twin per run. Upgrade to Team for unlimited twins per run.
403Monthly free plan limit reached. Upgrade to Team for unlimited test runner runs per month.

GET Get twin provision status

Accepts both API key and JWT authentication.
GET /validate/twins/provision/{run_id}/status
Poll the provisioning status of a twin quickstart session. Once the status is ready, the response includes connection details for each twin. When the provision request includes a scenario_id or scenario_prompt, the status remains provisioning until twin seeding is complete and seed_results are available. This means clients can safely treat ready as fully initialized — there is no window where twins are reachable but not yet seeded. Path parameters
ParameterTypeDescription
run_idstringUUID of the provisioning session returned from Provision twins.
Example request
curl "https://api.argalabs.com/validate/twins/provision/a1b2c3d4-e5f6-7890-abcd-ef1234567890/status" \
  -H "Authorization: Bearer $ARGA_API_KEY"
Response (provisioning)
{
  "run_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "provisioning",
  "twins": {},
  "dashboard_url": null,
  "expires_at": null,
  "proxy_token": null,
  "error": null,
  "seed_results": null
}
Response (ready)
{
  "run_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "ready",
  "twins": {
    "slack": {
      "name": "slack",
      "label": "Slack",
      "base_url": "https://r123--slack.sandbox.argalabs.com",
      "admin_url": "https://r123--slack.sandbox.argalabs.com",
      "env_vars": {"SLACK_API_URL": "https://r123--slack.sandbox.argalabs.com", "SLACK_BOT_TOKEN": "xoxb-twin-..."},
      "show_in_ui": true
    }
  },
  "dashboard_url": "https://app.argalabs.com/runs/a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "expires_at": null,
  "proxy_token": null,
  "error": null,
  "seed_results": {
    "slack": {"channels_created": 2, "messages_posted": 5, "users_created": 3}
  }
}
Response (failed)
{
  "run_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "failed",
  "twins": {},
  "dashboard_url": null,
  "expires_at": null,
  "proxy_token": null,
  "error": "Provisioning timed out waiting for twin services to start.",
  "seed_results": null
}
FieldTypeDescription
run_idstringProvisioning session identifier.
statusstringCurrent status: provisioning, ready, failed, or cancelled. When a scenario_id or scenario_prompt is attached, the status stays provisioning until twin seeding finishes and seed_results are populated.
twinsobjectMap of twin name to connection details. Empty while provisioning.
twins[name].namestringTwin identifier.
twins[name].labelstringHuman-readable display name.
twins[name].base_urlstringBase URL for API requests to this twin.
twins[name].admin_urlstringAdmin URL for managing twin state.
twins[name].env_varsobjectEnvironment variables to configure your application to use this twin. When the provision includes a scenario_id or scenario_prompt and the seeding process produces twin-specific credentials (for example a Slack bot token), those values are merged into this object so you always get the most up-to-date configuration without inspecting seed_results separately.
twins[name].show_in_uibooleanWhether this twin is shown in the web UI by default.
dashboard_urlstring | nullURL to view the session in the Arga dashboard. Available when status is ready.
expires_atstring | nullISO 8601 timestamp when the twins will be automatically torn down.
proxy_tokenstring | nullAuthentication token for the proxy, if applicable.
errorstring | nullError message describing why provisioning failed. Only present when status is failed.
seed_resultsobject | nullPer-twin seeding outcome when the provision included a scenario_id or scenario_prompt. Each key is a twin name and its value contains provider-specific details about what was seeded. null while seeding is in progress or when no seeding was requested. The overall status remains provisioning until this field is populated.
seed_results[twin_name]objectProvider-specific details about what was seeded into this twin (for example {"channels_created": 2, "messages_posted": 5, "users_created": 3} for Slack, or {"guilds_created": 1, "channels_created": 2, "messages_posted": 4, "guild_id": "...", "channel_ids": ["...", "..."]} for Discord). When the seed result includes an env_vars key, those values are automatically merged into the corresponding twin’s env_vars field so your application configuration stays up to date.
Errors
StatusDetail
400Invalid run_id
401Invalid or expired token.
404Run not found

POST Extend twin provision TTL

Accepts both API key and JWT authentication.
POST /validate/twins/provision/{run_id}/extend
Extend the time-to-live of an active twin provisioning session. The run must be in ready, provisioning, or queued status. Path parameters
ParameterTypeDescription
run_idstringUUID of the provisioning session.
Request body
FieldTypeRequiredDefaultDescription
ttl_minutesintegerNo60New time-to-live in minutes from now. Range: 1480.
Example request
curl -X POST https://api.argalabs.com/validate/twins/provision/a1b2c3d4-e5f6-7890-abcd-ef1234567890/extend \
  -H "Authorization: Bearer $ARGA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"ttl_minutes": 120}'
Response
{"status": "extended", "ttl_minutes": 120}
FieldTypeDescription
statusstringAlways extended.
ttl_minutesintegerThe new TTL that was applied.
Errors
StatusDetail
400Invalid run_id
400Cannot extend run in status: {status} (includes the current run status)
401Invalid or expired token.
404Run not found

POST Tear down twin provision

Accepts both API key and JWT authentication.
POST /validate/twins/provision/{run_id}/teardown
Immediately tear down a twin provisioning session and clean up its environment. The run must be in ready, provisioning, or queued status. Path parameters
ParameterTypeDescription
run_idstringUUID of the provisioning session.
Example request
curl -X POST https://api.argalabs.com/validate/twins/provision/a1b2c3d4-e5f6-7890-abcd-ef1234567890/teardown \
  -H "Authorization: Bearer $ARGA_API_KEY"
Response
{"status": "cleaning_up", "run_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"}
FieldTypeDescription
statusstringAlways cleaning_up. The environment is being torn down.
run_idstringThe provisioning session identifier.
Errors
StatusDetail
400Invalid run_id
400Cannot teardown run in status: {status} (includes the current run status)
401Invalid or expired token.
404Run not found

Run management

POST Cancel a validation run

Accepts both API key and JWT authentication.
POST /validate/{run_id}/cancel
Cancel a running validation. The run must not already be in a terminal state (completed, failed, or cancelled). Path parameters
ParameterTypeDescription
run_idstringUUID of the validation run.
Response
{"status": "cancelled"}
Errors
StatusDetail
401Invalid or expired token.
404Validation run not found
409Cannot cancel run in terminal state: {status} — returned when the run has already completed, failed, or been cancelled.

POST Submit run feedback

Deprecated. This endpoint is deprecated and will be removed in a future release. Existing calls will continue to work but you should stop relying on this endpoint.
Accepts both API key and JWT authentication.
POST /validate/{run_id}/feedback
Submit user feedback for a completed validation run. Feedback is stored on the run and can be viewed in the run details response. Submitting feedback again for the same run overwrites the previous value. Path parameters
ParameterTypeDescription
run_idstringUUID of the validation run.
Request body
FieldTypeRequiredDescription
feedbackstringYesFree-text feedback about the validation run. Must not be empty or exceed 10,000 characters.
Example request
curl -X POST https://api.argalabs.com/validate/a1b2c3d4-e5f6-7890-abcd-ef1234567890/feedback \
  -H "Authorization: Bearer $ARGA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"feedback": "The login step timed out before the page fully loaded."}'
Response
{
  "run_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "user_feedback": "The login step timed out before the page fully loaded."
}
FieldTypeDescription
run_idstringThe validation run identifier.
user_feedbackstring | nullThe feedback that was saved.
Errors
StatusDetail
400Invalid run_id
400Feedback cannot be empty
400Feedback is too long (max 10000 characters)
401Invalid or expired token.
404Validation run not found

GET Stream validation results

Accepts both API key and JWT authentication.
GET /validate/{run_id}/results
Server-sent event (SSE) stream of live validation step results. Each event is a JSON object sent as data: {JSON}\n\n. When the run is already in a terminal state (completed, failed, or cancelled), the endpoint returns a single SSE event with the terminal status instead of keeping the connection open. The event has the shape {"type": "run_{status}", "status": "{status}"}. Path parameters
ParameterTypeDescription
run_idstringUUID of the validation run.
Errors
StatusDetail
401Invalid or expired token.
404Validation run not found

GET Get run details

Accepts both API key and JWT authentication.
GET /runs/{run_id}
Get full details of a validation or scan run. Path parameters
ParameterTypeDescription
run_idstringUUID of the validation run.
Example request
curl "https://api.argalabs.com/runs/a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
  -H "Authorization: Bearer $ARGA_API_KEY"
Response The response includes the full run state. Key fields:
FieldTypeDescription
idstringRun identifier.
session_idstring | nullChat session associated with this run.
statusstringCurrent status (e.g. queued, running, complete, failed, cancelled).
pr_urlstringPull request URL, if applicable.
frontend_urlstringBase URL of the frontend under test.
run_typestringType of run. Canonical values: url_run, pr_run, agent_run. Legacy values such as url, staging, pr, branch, and redteam may appear on older runs.
modestring | nullValidation mode for the run (e.g. validation, auto_visual, redteam).
promptstring | nullThe prompt that initiated the run.
environment_urlstring | nullURL of the sandbox environment, if applicable.
twinsarray | nullList of digital twin services used in the run.
surface_urlsobject | nullMap of twin name to its proxied URL.
raw_surface_urlsobject | nullMap of twin name to its direct (non-proxied) URL.
runtime_profileobject | nullRuntime profile configuration used for the run.
context_notesstring | nullAdditional context or instructions provided when the run was started.
user_feedbackstring | nullDeprecated. User-submitted feedback for this run. This field is deprecated and will be removed in a future release.
repo_full_namestring | nullRepository in owner/repo format.
git_branchstring | nullBranch name.
commit_shastring | nullCommit SHA.
github_pr_numberinteger | nullPull request number, if the run is associated with a PR.
github_check_run_idstring | nullGitHub check run identifier.
github_check_run_urlstring | nullURL of the GitHub check run.
event_log_jsonarray | nullChronological log of events during the run.
story_jsonobject | nullGenerated user story with steps and coverage matrix.
auto_story_bundle_jsonobject | nullAuto-generated story bundle for multi-story runs.
auto_visual_reportsarray | nullReports from auto-visual story runs. Each object includes worker_key, title, status, issues, and optional story_json and results_json.
attack_plan_jsonobject | nullAttack plan for red-team or security scan runs.
results_jsonarray | nullStep-by-step results with status (pass, fail, error) and descriptions.
step_summariesarray | nullSummarized step results. Each object includes title, status, details, step_number, and step_numbers.
redteam_report_jsonobject | nullRed-team report with anomalies and coverage, if this is a scan run.
worker_progressarray | nullProgress information for each worker in a multi-worker run.
login_identifierstring | nullLogin identifier used during validation, if applicable.
coverage_manifestobject | nullCoverage manifest describing tested routes and features.
failure_categorystring | nullCategory of failure when the run ends in failed status. Possible values: test_failure, system_error, twin_limitation, timeout, deploy_error. Always populated on failed runs.
failure_detailobject | nullStructured details about the failure. Always populated on failed runs. See sub-fields below.
failure_detail.phasestringPipeline phase where the failure occurred: build, deploy, runtime, cleanup, or fidelity.
failure_detail.kindstringFailure kind: build_failure, deploy_failure, proxy_failure, twin_failure, unsupported_endpoint, auth_failure, timeout, or connect_error.
failure_detail.codestringMachine-readable error code (e.g. worker_exception, scan_anomalies_found, runner_timeout).
failure_detail.public_messagestringHuman-readable description of the failure.
failure_detail.retryablebooleanWhether the failure is considered retryable.
readiness_resultsobject | nullPre-run readiness check results.
retry_countinteger | nullNumber of times this run has been retried.
created_atstring | nullISO 8601 timestamp.
Errors
StatusDetail
401Invalid or expired token.
404Validation run not found

GET Get run logs

Accepts both API key and JWT authentication.
GET /runs/{run_id}/logs
Retrieve worker and runtime logs for a validation run. Returns logs from the twin and sandbox infrastructure associated with the run. Only logs belonging to the authenticated user’s runs are returned. Path parameters
ParameterTypeDescription
run_idstringUUID of the validation run.
Example request
curl "https://api.argalabs.com/runs/a1b2c3d4-e5f6-7890-abcd-ef1234567890/logs" \
  -H "Authorization: Bearer $ARGA_API_KEY"
Response
{
  "run": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "status": "complete"
  },
  "worker_logs": [
    {
      "job_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "job_type": "deploy",
      "target_role": "builder",
      "status": "completed",
      "content": "Building image...\nDeploy successful.",
      "truncated": false,
      "error": null
    }
  ],
  "runtime_logs": [
    {
      "timestamp": "2026-03-21T12:05:00Z",
      "service_name": "arga-api",
      "severity": "INFO",
      "event": "run.started",
      "code": null,
      "request_id": "req-abc123",
      "job_id": null,
      "surface_name": "slack",
      "message": "Validation run started"
    }
  ],
  "warnings": []
}
FieldTypeDescription
runobjectRun summary with current status and metadata. Same shape as the Get run details response.
worker_logsarrayLogs from cluster worker jobs (build, deploy, warm-up).
worker_logs[].job_idstringIdentifier of the worker job.
worker_logs[].job_typestring | nullType of worker job (e.g. deploy, build).
worker_logs[].target_rolestring | nullRole of the target instance (e.g. builder, warm).
worker_logs[].statusstring | nullJob status (e.g. completed, failed).
worker_logs[].contentstring | nullLog text content. May be null if the log could not be retrieved.
worker_logs[].truncatedbooleanWhether the log content was truncated due to size limits.
worker_logs[].errorstring | nullError message if the log could not be loaded.
runtime_logsarrayStructured runtime logs from API and proxy services scoped to this run.
runtime_logs[].timestampstring | nullISO 8601 timestamp of the log entry.
runtime_logs[].service_namestring | nullService that produced the log (e.g. arga-api, preview-proxy).
runtime_logs[].severitystring | nullLog severity level (e.g. INFO, ERROR).
runtime_logs[].eventstring | nullStructured event name.
runtime_logs[].codestring | nullEvent code, if applicable.
runtime_logs[].request_idstring | nullRequest identifier for correlation.
runtime_logs[].job_idstring | nullAssociated worker job identifier, if applicable.
runtime_logs[].surface_namestring | nullTwin or surface name associated with the log entry.
runtime_logs[].messagestring | nullHuman-readable log message.
warningsarray of stringWarnings encountered while fetching logs (e.g. if a log source was unavailable).
Errors
StatusDetail
400run_id must be a valid UUID
401Invalid or expired token.
404Validation run not found

GET Get a run artifact

Accepts API key, JWT authentication, or a token query parameter.
GET /validate/{run_id}/artifacts/{filename}
Retrieve an artifact (such as a screenshot) from a validation or scan run. Returns a redirect to a signed download URL that expires after 60 minutes. Path parameters
ParameterTypeDescription
run_idstringUUID of the validation run.
filenamestringPath of the artifact within the run (e.g. screenshot.png).
Example request
curl -L "https://api.argalabs.com/validate/a1b2c3d4-e5f6-7890-abcd-ef1234567890/artifacts/screenshot.png" \
  -H "Authorization: Bearer $ARGA_API_KEY" \
  -o screenshot.png
Response 302 redirect to a signed URL for the artifact. Errors
StatusDetail
401Authentication required
404Validation run not found
404Artifact not found
500Failed to retrieve artifact

PR validation

GET Get GitHub repo validation config

Accepts both API key and JWT authentication. Requires a Team or Paid plan.
GET /validation/github/config
Retrieve the current automatic validation configuration for a GitHub repository. Returns the configuration for the specified trigger mode, or defaults if no configuration has been saved yet. Query parameters
ParameterTypeRequiredDefaultDescription
repostringYesRepository in owner/repo format.
trigger_modestringNo"pr"Which trigger mode to retrieve configuration for. Use "pr" for pull request events or "branch" for commits to a specific branch.
Example request
curl "https://api.argalabs.com/validation/github/config?repo=acme/web-app&trigger_mode=branch" \
  -H "Authorization: Bearer $ARGA_API_KEY"
Response
{
  "repo": "acme/web-app",
  "installed": true,
  "installation_id": "12345678",
  "enabled": true,
  "trigger_mode": "branch",
  "branch": "main",
  "default_branch": "main",
  "custom_instructions": "focus on the checkout flow",
  "comment_on_pr": true
}
FieldTypeDescription
repostringRepository in owner/repo format.
installedbooleanWhether the Arga GitHub App is installed on this repository.
installation_idstring | nullGitHub App installation identifier.
enabledbooleanWhether automatic validation is active for this trigger mode.
trigger_modestringTrigger mode: "pr" or "branch".
branchstring | nullBranch name for branch-triggered validation. When trigger mode is "pr", returns the repository’s default branch.
default_branchstring | nullThe repository’s default branch (e.g. main).
custom_instructionsstring | nullCustom instructions for validation runs.
comment_on_prbooleanWhether Arga posts PR comment summaries.
Errors
StatusDetail
401Invalid or expired token.
403Requires a Team or Paid plan.

POST Save GitHub repo validation config

Accepts both API key and JWT authentication. Requires a Team or Paid plan.
POST /validation/github/config
Create or update the automatic validation configuration for a GitHub repository. The repository must have the Arga GitHub App installed before you can save a configuration. Request body
FieldTypeRequiredDefaultDescription
repostringYesRepository in owner/repo format.
trigger_modestringYesHow Arga triggers validation runs. Use "pr" for pull request events or "branch" for commits to a specific branch.
branchstringNoBranch name for branch-triggered validation. Required when trigger_mode is "branch". When trigger_mode is "pr", this field is ignored. Defaults to the repository’s default branch when omitted for branch mode.
custom_instructionsstringNoAdditional context that applies to every validation run for this repository (e.g. “focus on the checkout flow” or “ignore visual regressions”). Leading and trailing whitespace is trimmed.
comment_on_prbooleanNotrueWhether Arga posts a comment summary on pull requests.
enabledbooleanNotrueWhether automatic validation is active for this repository. Set to false to pause validation without removing the configuration.
Example request
curl -X POST https://api.argalabs.com/validation/github/config \
  -H "Authorization: Bearer $ARGA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "repo": "acme/web-app",
    "trigger_mode": "pr",
    "comment_on_pr": true,
    "custom_instructions": "focus on the checkout flow"
  }'
Response
{
  "repo": "acme/web-app",
  "installed": true,
  "installation_id": "12345678",
  "enabled": true,
  "trigger_mode": "pr",
  "branch": null,
  "default_branch": "main",
  "custom_instructions": "focus on the checkout flow",
  "comment_on_pr": true
}
FieldTypeDescription
repostringRepository in owner/repo format.
installedbooleanWhether the Arga GitHub App is installed on this repository.
installation_idstring | nullGitHub App installation identifier.
enabledbooleanWhether automatic validation is active.
trigger_modestringTrigger mode: "pr" or "branch".
branchstring | nullBranch name for branch-triggered validation. null when trigger mode is "pr".
default_branchstring | nullThe repository’s default branch (e.g. main).
custom_instructionsstring | nullCustom instructions for validation runs.
comment_on_prbooleanWhether Arga posts PR comment summaries.
Errors
StatusDetail
400Choose a branch for branch-triggered validation.
401Invalid or expired token.
403Requires a Team or Paid plan.
409Install the Arga GitHub App on this repository before saving validation settings.

PATCH Toggle GitHub repo validation

Accepts both API key and JWT authentication. Requires a Team or Paid plan.
PATCH /validation/github/config
Enable or disable automatic validation for a specific trigger mode on a repository without changing any other configuration. The repository must already have a saved validation configuration for the specified trigger mode. Request body
FieldTypeRequiredDescription
repostringYesRepository in owner/repo format.
trigger_modestringYesWhich trigger mode to toggle. Use "pr" for pull request events or "branch" for commits to a specific branch.
enabledbooleanYesSet to true to enable or false to disable automatic validation.
Example request
curl -X PATCH https://api.argalabs.com/validation/github/config \
  -H "Authorization: Bearer $ARGA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "repo": "acme/web-app",
    "trigger_mode": "pr",
    "enabled": false
  }'
Response Returns the same response shape as POST /validation/github/config.
{
  "repo": "acme/web-app",
  "installed": true,
  "installation_id": "12345678",
  "enabled": false,
  "trigger_mode": "pr",
  "branch": null,
  "default_branch": "main",
  "custom_instructions": "focus on the checkout flow",
  "comment_on_pr": true
}
Errors
StatusDetail
401Invalid or expired token.
403Requires a Team or Paid plan.
404No {trigger_mode} validation configuration found for this repository. — where {trigger_mode} is the value you passed (e.g. pr or branch).

POST Start a PR validation

Accepts both API key and JWT authentication. Requires a Team or Paid plan.
POST /validation/pr
Start an automatic validation run for a pull request. Request body
FieldTypeRequiredDescription
repostringYesRepository in owner/repo format.
pr_numberintegerYesPull request number.
frontend_urlstringNoBase URL of the frontend under test. Defaults to http://localhost:3000.
context_notesstringNoAdditional instructions or context for the validation.
Example request
curl -X POST https://api.argalabs.com/validation/pr \
  -H "Authorization: Bearer $ARGA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "repo": "acme/web-app",
    "pr_number": 42,
    "context_notes": "focus on the checkout flow changes"
  }'
Response
{
  "run_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "queued"
}
FieldTypeDescription
run_idstringUnique identifier for the validation run.
statusstringInitial run status.
Errors
StatusDetail
400Repository must be provided as owner/repo.
401Invalid or expired token.
403Automatic PR validation requires a Team or Paid plan.

GET List validation runs

Accepts both API key and JWT authentication. Requires a Team or Paid plan.
GET /validation/runs
List validation runs with pagination and optional filtering. Returns URL, PR, branch, and agent runs. Query parameters
ParameterTypeRequiredDefaultDescription
repostringNoFilter by repository in owner/repo format.
querystringNoSearch by branch name or PR number.
limitintegerNo10Number of results per page. Range: 1100.
offsetintegerNo0Pagination offset.
Example request
curl "https://api.argalabs.com/validation/runs?repo=acme/web-app&limit=5" \
  -H "Authorization: Bearer $ARGA_API_KEY"
Response
{
  "items": [
    {
      "run_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "status": "complete",
      "repo": "acme/web-app",
      "pr_number": 42,
      "branch": "feature/checkout",
      "commit_sha": "abc1234",
      "trigger_type": "pr",
      "created_at": "2026-03-21T12:00:00Z"
    }
  ],
  "total": 1,
  "limit": 5,
  "offset": 0,
  "has_more": false
}
FieldTypeDescription
itemsarrayList of validation run summaries.
items[].run_idstringUnique identifier for the run.
items[].statusstringCurrent run status.
items[].repostringRepository in owner/repo format.
items[].pr_numberinteger | nullPull request number, if applicable.
items[].branchstring | nullBranch name.
items[].commit_shastring | nullCommit SHA that triggered the run.
items[].trigger_typestring | nullHow the run was triggered (e.g. pr_run, url_run, agent_run, branch, manual). Legacy values such as pr and url may appear on older runs.
items[].created_atstringISO 8601 timestamp.
totalintegerTotal number of matching runs.
limitintegerPage size used.
offsetintegerCurrent offset.
has_morebooleanWhether more results are available.
Errors
StatusDetail
400Repository must be provided as owner/repo.
401Invalid or expired token.
403Automatic PR validation requires a Team or Paid plan.

Scenarios

Scenarios define pre-seeded twin configurations that you can reuse across validation runs. You can create a scenario by providing an explicit seed configuration, a natural-language prompt (which generates the configuration automatically), or both. Arga also ships with built-in preset scenarios — ready-to-use templates covering common use cases like e-commerce checkout, SaaS billing, DevOps CI/CD, and more. Presets are available without authentication and can be mixed into your own scenario list.

GET List preset scenarios

GET /scenarios/presets
Return built-in preset scenario templates. No authentication required. Query parameters
ParameterTypeRequiredDescription
twinstringNoFilter presets that include this twin name.
tagstringNoFilter presets that include this tag.
Example request
curl "https://api.argalabs.com/scenarios/presets?twin=stripe"
Response An array of scenario objects. Preset scenarios have is_preset set to true and empty created_at / updated_at timestamps. The tags array for preset scenarios always includes "preset" as the first element.
[
  {
    "id": "d4f5a6b7-...",
    "name": "E-commerce Checkout",
    "description": "End-to-end checkout flow with three customer tiers...",
    "prompt": "Simulate an e-commerce checkout experience...",
    "twins": ["stripe", "slack"],
    "seed_config": {"stripe": {...}, "slack": {...}},
    "tags": ["preset", "ecommerce", "payments", "functional"],
    "created_at": "",
    "updated_at": "",
    "is_preset": true
  }
]
Available preset tags
TagDescription
presetAutomatically added to all preset scenarios as the first tag
ecommerceE-commerce and checkout flows
paymentsPayment processing scenarios
saasSaaS billing and subscription management
billingBilling-related scenarios
devopsDevOps and CI/CD pipelines
ci-cdContinuous integration and deployment
supportCustomer support workflows
customer-serviceCustomer service scenarios
collaborationDocument and team collaboration
documentsDocument management flows
securitySecurity and access control
fraudFraud detection and prevention
authAuthentication and authorization
access-controlAccess control boundaries
functionalGeneral functional testing

POST Create a scenario

Accepts both API key and JWT authentication.
POST /scenarios
Create a new scenario for pre-seeding twins. Request body
FieldTypeRequiredDescription
namestringYesDisplay name for the scenario.
descriptionstringNoHuman-readable description of the scenario.
promptstringConditionalNatural-language description of the desired twin state (e.g. “3 GitHub repos, each with 3 files and 2 PRs on one of them”). Either prompt or seed_config is required.
twinsarray of stringConditionalTwin names to include. Required when seed_config is provided without prompt. When using prompt alone, Arga automatically selects the single most relevant provider-specific twin (e.g. github, slack, stripe) — or multiple twins only if the prompt explicitly names more than one provider. The unified twin is only selected when the prompt explicitly mentions “unified” or “unified.to”.
seed_configobjectConditionalExplicit seed configuration with the JSON structure each twin runner expects. Either prompt or seed_config is required. When both are provided, seed_config takes precedence and the prompt is stored for reference.
tagsarray of stringNoTags for organizing scenarios. Defaults to an empty array.
Example request
curl -X POST https://api.argalabs.com/scenarios \
  -H "Authorization: Bearer $ARGA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "E-commerce checkout",
    "prompt": "A Stripe account with 3 products, 2 active subscriptions, and a pending invoice"
  }'
Response
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "name": "E-commerce checkout",
  "description": null,
  "prompt": "A Stripe account with 3 products, 2 active subscriptions, and a pending invoice",
  "twins": ["stripe"],
  "seed_config": {"stripe": {"products": [...], "subscriptions": [...]}},
  "tags": [],
  "is_preset": false,
  "created_at": "2026-03-21T12:00:00",
  "updated_at": "2026-03-21T12:00:00"
}
FieldTypeDescription
idstringUnique identifier for the scenario. Use this as the scenario_id when provisioning twins.
namestringDisplay name.
descriptionstring | nullHuman-readable description.
promptstring | nullThe natural-language prompt used to generate the configuration, if provided.
twinsarray of stringTwin names included in this scenario.
seed_configobjectThe resolved seed configuration.
tagsarray of stringTags for organizing scenarios.
is_presetbooleanWhether this is a built-in preset scenario. Defaults to false for user-created scenarios.
created_atstringISO 8601 timestamp. Empty string for preset scenarios.
updated_atstringISO 8601 timestamp. Empty string for preset scenarios.
Errors
StatusDetail
401Invalid or expired token.
422Either 'prompt' or 'seed_config' must be provided
422'twins' is required when 'seed_config' is provided without 'prompt'
422Seed config generation failed. Returned when the prompt cannot be resolved into a valid twin configuration.
422Scenario generation failed: {error} — returned when an unexpected error occurs during scenario generation from a prompt.

GET List scenarios

Accepts both API key and JWT authentication.
GET /scenarios
List all scenarios for the authenticated user. You can optionally include built-in preset scenarios in the response. Query parameters
ParameterTypeRequiredDescription
twinstringNoFilter scenarios that include this twin name.
tagstringNoFilter scenarios that include this tag.
include_presetsbooleanNoWhen true, prepend built-in preset scenarios to the results. Defaults to false.
Example request
curl "https://api.argalabs.com/scenarios?twin=stripe&include_presets=true" \
  -H "Authorization: Bearer $ARGA_API_KEY"
Response An array of scenario objects (same shape as the create response), sorted by creation date (newest first). When include_presets is true, preset scenarios (with is_preset: true) appear before user-created scenarios. Errors
StatusDetail
401Invalid or expired token.

GET Get a scenario

Accepts both API key and JWT authentication.
GET /scenarios/{scenario_id}
Get a single scenario by ID. Path parameters
ParameterTypeDescription
scenario_idstringUUID of the scenario.
Response A scenario object (same shape as the create response). Errors
StatusDetail
401Invalid or expired token.
404Scenario not found

PUT Update a scenario

Accepts both API key and JWT authentication.
PUT /scenarios/{scenario_id}
Update an existing scenario. All fields are optional — only provided fields are updated. When a new prompt is provided without a new seed_config, the seed configuration is regenerated from the prompt. You can explicitly set description to null to clear it. Path parameters
ParameterTypeDescription
scenario_idstringUUID of the scenario.
Request body
FieldTypeRequiredDescription
namestringNoUpdated display name.
descriptionstring | nullNoUpdated description. Set to null to clear the description.
promptstringNoUpdated natural-language prompt. When provided without seed_config, the seed configuration is regenerated.
twinsarray of stringNoUpdated twin names.
seed_configobjectNoUpdated seed configuration.
tagsarray of stringNoUpdated tags.
Response The updated scenario object (same shape as the create response). Errors
StatusDetail
401Invalid or expired token.
404Scenario not found
422Seed config generation failed.

DELETE Delete a scenario

Accepts both API key and JWT authentication.
DELETE /scenarios/{scenario_id}
Delete a scenario. Path parameters
ParameterTypeDescription
scenario_idstringUUID of the scenario.
Response
{"status": "deleted"}
Errors
StatusDetail
401Invalid or expired token.
404Scenario not found

Demo runner

The demo runner records a browser flow from a natural-language prompt, distills it into a deterministic TestConfig, and lets you replay it later. Each run executes inside an ephemeral Playwright session and streams events back over a WebSocket while the flow is in progress.

POST Create a demo run

Accepts both API key and JWT authentication.
POST /demo-runner/runs
Start a new recording run. The runner navigates to start_url (or a URL detected in the prompt), executes the prompt against the page, and saves a deterministic TestConfig you can rerun. Progress events stream over the demo run WebSocket. Request body
FieldTypeRequiredDescription
promptstringYesNatural-language description of the flow to record. Length: 1–20,000 characters.
start_urlstringConditionalAbsolute http(s) URL to begin the recording at. Required unless the prompt already contains a URL — in that case the first URL found in the prompt is used. Max length: 1,024 characters.
test_configobjectNoOptional saved TestConfig to launch the run from. When provided, the run is created with mode set to rerun_from_config, the supplied config is applied with prompt and start_url overrides, and the runner replays it instead of recording a new flow.
Example request
curl -X POST https://api.argalabs.com/demo-runner/runs \
  -H "Authorization: Bearer $ARGA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Sign in with the demo account, create a new task, and mark it complete.",
    "start_url": "https://staging.example.com"
  }'
Response
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "source_run_id": null,
  "mode": "record_from_prompt",
  "status": "queued",
  "prompt": "Sign in with the demo account, create a new task, and mark it complete.",
  "start_url": "https://staging.example.com",
  "test_config_json": null,
  "repair_patches_json": [],
  "summary_text": null,
  "summary_json": null,
  "events_json": [
    {
      "id": "e1f2a3b4-...",
      "type": "created",
      "message": "Demo runner run created.",
      "details": {"mode": "record_from_prompt", "start_url": "https://staging.example.com"},
      "timestamp": "2026-04-29T12:00:00Z"
    }
  ],
  "artifacts_json": {},
  "runner_job_id": "job-abc123",
  "error_message": null,
  "created_at": "2026-04-29T12:00:00Z",
  "updated_at": "2026-04-29T12:00:00Z",
  "started_at": null,
  "completed_at": null
}
FieldTypeDescription
idstringUnique identifier for the demo run.
source_run_idstring | nullThe run this run was forked from. null for new recordings; populated when the run was created via POST /demo-runner/runs/{run_id}/rerun.
modestringExecution mode: record_from_prompt for new recordings or rerun_from_config for replays.
statusstringCurrent status: queued, running, completed, or failed.
promptstringThe prompt the run was created with.
start_urlstringThe resolved start URL.
test_config_jsonobject | nullThe distilled TestConfig produced by the recording. null until distillation completes. Use this object as the implicit input when calling POST /demo-runner/runs/{run_id}/rerun.
repair_patches_jsonarray of objectPatches applied during a replay to recover from selector or step drift. Empty for new recordings.
summary_textstring | nullPlain-text summary of the run produced after completion. null until the run completes (and may remain null if no summary was generated).
summary_jsonobject | nullStructured summary of the run produced after completion. null until the run completes (and may remain null if no structured summary was generated). When present, includes the deterministic fields total_blocks and total_steps (the number of steps in the saved test_config_json), passed (count of passing steps; equal to total_blocks when completed is true, otherwise 0), warnings (count of limitations plus issues), and assertions.total (count of steps with action: "expect"). These metric fields are computed from the saved TestConfig rather than from the model’s response. Additional model-provided fields such as answer, completed, limitations, notable_observations, and issues (concrete, user-facing issues observed during the run, including any explanations from repair_patches_json) may also be present.
events_jsonarray of objectChronological event log. Each event includes id, type, message, details, and timestamp.
artifacts_jsonobjectMap of artifact name to signed download URL or relative path within the run (e.g. recorded_trace_url, test_config_url, repaired_test_config_url).
runner_job_idstring | nullIdentifier of the underlying flow runner job. null until the job has been queued or when the runner job failed to launch.
error_messagestring | nullError message when status is failed.
created_atstring | nullISO 8601 timestamp.
updated_atstring | nullISO 8601 timestamp of the last status or event update.
started_atstring | nullISO 8601 timestamp when the runner job started executing.
completed_atstring | nullISO 8601 timestamp when the run reached a terminal state.
Errors
StatusDetail
400Provide a start URL or include one in the prompt.
400Start URL must be an absolute http(s) URL.
401Invalid or expired token.
503FLOW_RUNNER_JOB_NAME is not configured — returned when the deployment has no flow runner job configured.

POST Rerun a demo run

Accepts both API key and JWT authentication.
POST /demo-runner/runs/{run_id}/rerun
Replay a previously recorded flow using its saved TestConfig. The runner re-executes each step deterministically and may produce repair patches when selectors or steps need to drift to match the live page. The source run must already have a saved test_config_json. Path parameters
ParameterTypeDescription
run_idstringUUID of the source demo run to replay.
Request body The request body is optional. Send an empty object (or omit the body) to replay the source run as recorded. To override values for this replay, include either or both of the fields below.
FieldTypeRequiredDescription
promptstringNoOverride the prompt for this rerun. When omitted or empty, the source run’s prompt is reused. Max length: 20,000 characters.
start_urlstringNoOverride the start URL for this rerun. When provided, it replaces the saved TestConfig’s starting_url and the first goto step. When omitted, the source run’s start_url is reused. Max length: 1,024 characters.
Example request
curl -X POST https://api.argalabs.com/demo-runner/runs/a1b2c3d4-e5f6-7890-abcd-ef1234567890/rerun \
  -H "Authorization: Bearer $ARGA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Sign in with the demo account and create a new task.",
    "start_url": "https://staging.example.com"
  }'
Response Returns a new demo run object with the same shape as POST /demo-runner/runs. The new run has mode set to rerun_from_config, source_run_id set to the source run’s id, and test_config_json copied from the source run (with prompt, starting_url, and the first goto step overridden when those fields were provided in the request body). Errors
StatusDetail
401Invalid or expired token.
404Test run not found
409Source run does not have a TestConfig yet — returned when the source run has not finished recording.
503FLOW_RUNNER_JOB_NAME is not configured — returned when the deployment has no flow runner job configured.

GET List demo runs

Accepts both API key and JWT authentication.
GET /demo-runner/runs
List the 25 most recent demo runs for the authenticated user, ordered by creation time (newest first). Example request
curl "https://api.argalabs.com/demo-runner/runs" \
  -H "Authorization: Bearer $ARGA_API_KEY"
Response
{
  "runs": [
    {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "source_run_id": null,
      "mode": "record_from_prompt",
      "status": "completed",
      "prompt": "Sign in with the demo account...",
      "start_url": "https://staging.example.com",
      "test_config_json": {"steps": [{}, {}]},
      "repair_patches_json": [],
      "summary_text": "Signed in and created a new task.",
      "summary_json": {
        "answer": "Signed in and created a new task.",
        "completed": true,
        "limitations": [],
        "total_blocks": 6,
        "total_steps": 6,
        "passed": 6,
        "warnings": 0,
        "assertions": {"total": 2}
      },
      "events_json": [],
      "artifacts_json": {"recorded_trace_url": "https://...", "test_config_url": "https://..."},
      "runner_job_id": "job-abc123",
      "error_message": null,
      "created_at": "2026-04-29T12:00:00Z",
      "updated_at": "2026-04-29T12:05:00Z",
      "started_at": "2026-04-29T12:00:30Z",
      "completed_at": "2026-04-29T12:05:00Z"
    }
  ]
}
FieldTypeDescription
runsarray of objectDemo run objects with the same shape as POST /demo-runner/runs.
Errors
StatusDetail
401Invalid or expired token.

GET Get a demo run

Accepts both API key and JWT authentication.
GET /demo-runner/runs/{run_id}
Get the full state of a single demo run, including its event log, artifacts, and (when available) the distilled TestConfig. Path parameters
ParameterTypeDescription
run_idstringUUID of the demo run.
Response A demo run object with the same shape as POST /demo-runner/runs. Errors
StatusDetail
401Invalid or expired token.
404Test run not found

PATCH Update a demo run’s TestConfig

Accepts both API key and JWT authentication.
PATCH /demo-runner/runs/{run_id}/config
Replace the saved test_config_json for a demo run. Use this endpoint to edit the distilled TestConfig produced by a recording — for example, to tweak step values, selectors, or assertions — before calling POST /demo-runner/runs/{run_id}/rerun to replay the updated config. Updating the config appends a test_config_updated event to the run’s event log; it does not start a new runner job. Step selector formats Each step’s selector accepts any of the following formats. Prefer stable, semantic selectors so steps remain robust when the underlying markup changes:
FormatExampleNotes
[data-testid=...][data-testid="sign-in"]Most stable; preferred when available.
control="<label>"control="Get Started"Semantic locator for visible buttons or links. Resolves to the matching button, link, or text role using a case-insensitive match on the visible label.
field="<label>"field="(est.) in 12 months"Semantic locator for form fields. Resolves to the matching label, placeholder, spinbutton, or textbox role; falls back to any visible input, textarea, or [contenteditable=true].
:has-text("...")button:has-text("Submit")Matches by visible text, optionally constrained by a leading button, link/a, label, or text tag. Without a tag, behaves like control="...".
text="..." / role=...text="Sign in"Playwright role/text selectors.
CSS selectorsbutton.primaryStable CSS selectors as a last resort.
Bad selectors fall through quickly: each candidate selector is attempted with a short per-candidate timeout (capped at 1.5 s) before moving on, so the overall step still respects the step’s timeout_ms. Path parameters
ParameterTypeDescription
run_idstringUUID of the demo run.
Request body
FieldTypeRequiredDescription
test_configobjectYesThe new TestConfig to save on the run. Replaces test_config_json in full — fields that are omitted are dropped.
Example request
curl -X PATCH https://api.argalabs.com/demo-runner/runs/a1b2c3d4-e5f6-7890-abcd-ef1234567890/config \
  -H "Authorization: Bearer $ARGA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "test_config": {
      "prompt": "Sign in with the demo account and create a new task.",
      "starting_url": "https://staging.example.com",
      "steps": [
        {"id": "step_0_goto", "action": "goto", "value": "https://staging.example.com"},
        {"id": "step_1_click_sign_in", "action": "click", "selector": "control=\"Sign in\""}
      ]
    }
  }'
Response A demo run object with the same shape as POST /demo-runner/runs. The returned test_config_json reflects the value submitted in the request, and the event log includes a new test_config_updated event. Errors
StatusDetail
401Invalid or expired token.
404Test run not found

POST Send a message to a demo run

Accepts both API key and JWT authentication.
POST /demo-runner/runs/{run_id}/messages
Append a user message to a demo run’s event log. The message is recorded as a user_message event with details.role set to "user" and is broadcast to subscribers of the demo run WebSocket. Use this to feed mid-run instructions to the runner without restarting the run. Path parameters
ParameterTypeDescription
run_idstringUUID of the demo run.
Request body
FieldTypeRequiredDescription
messagestringYesUser message to attach to the run. Length: 1–10,000 characters. Leading and trailing whitespace is trimmed.
Example request
curl -X POST https://api.argalabs.com/demo-runner/runs/a1b2c3d4-e5f6-7890-abcd-ef1234567890/messages \
  -H "Authorization: Bearer $ARGA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"message": "Use the discount code WELCOME10 at checkout."}'
Response A demo run object with the same shape as POST /demo-runner/runs. The returned events_json includes the new user_message event. Errors
StatusDetail
401Invalid or expired token.
404Test run not found

GET Get a demo run artifact

Accepts API key, JWT authentication, or a token query parameter.
GET /demo-runner/runs/{run_id}/artifacts/{filename}
Retrieve an artifact (such as a recorded trace, distilled TestConfig, or screenshot) from a demo run. Returns a redirect to a signed download URL that expires after 60 minutes. Path parameters
ParameterTypeDescription
run_idstringUUID of the demo run.
filenamestringPath of the artifact within the run (e.g. recorded_trace.json, test_config.json, repaired_test_config.json). Path segments are supported.
Example request
curl -L "https://api.argalabs.com/demo-runner/runs/a1b2c3d4-e5f6-7890-abcd-ef1234567890/artifacts/test_config.json" \
  -H "Authorization: Bearer $ARGA_API_KEY" \
  -o test_config.json
Response 302 redirect to a signed URL for the artifact. Errors
StatusDetail
401Authentication required
404Test run not found
404Artifact not found

Saved runner tests

Saved runner tests turn a completed demo run into a reusable test you can manage, edit, and attach to repository CI checks. Each saved test snapshots the run’s prompt, start_url, and distilled TestConfig, plus optional metadata like tags, description, encrypted credentials, and a repo_full_name for CI attachment.

GET List saved runner tests

Accepts both API key and JWT authentication.
GET /demo-runner/tests
List saved runner tests for the authenticated user, ordered by updated_at (most recently updated first). Optionally filter by repository. Query parameters
ParameterTypeRequiredDescription
repo_full_namestringNoFilter tests by repository in owner/repo format. When omitted, all of the user’s saved tests are returned.
Example request
curl "https://api.argalabs.com/demo-runner/tests?repo_full_name=acme/web-app" \
  -H "Authorization: Bearer $ARGA_API_KEY"
Response
{
  "tests": [
    {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "source_run_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "name": "Checkout happy path",
      "description": "Sign in, add an item, and complete checkout.",
      "repo_full_name": "acme/web-app",
      "prompt": "Sign in with the demo account, add an item to the cart, and complete checkout.",
      "start_url": "https://staging.example.com",
      "test_config_json": {"steps": [{}, {}]},
      "ci_enabled": true,
      "has_credentials": true,
      "credential_keys": ["DEMO_PASSWORD", "DEMO_USER"],
      "tags": ["checkout", "smoke"],
      "created_at": "2026-04-30T10:00:00+00:00",
      "updated_at": "2026-04-30T10:15:00+00:00"
    }
  ]
}
FieldTypeDescription
testsarray of objectSaved test objects with the same shape as the create response.
Errors
StatusDetail
401Invalid or expired token.

POST Save a runner test

Accepts both API key and JWT authentication.
POST /demo-runner/tests
Save a reusable test. You can either reference a completed demo run via run_id (in which case its prompt, start_url, and test_config_json are copied onto the saved test) or supply those fields directly. Request body
FieldTypeRequiredDefaultDescription
namestringYesDisplay name for the saved test. Length: 1–255 characters.
descriptionstring | nullNonullFree-text description. Max length: 10,000 characters.
run_idstringConditionalUUID of a demo run to copy prompt, start_url, and test_config_json from. The source run must already have a saved test_config_json. Required unless prompt, start_url, and test_config are all provided directly.
promptstringConditionalOverride the prompt to save on the test. Required when run_id is omitted. Max length: 20,000 characters.
start_urlstringConditionalOverride the start URL to save on the test. Required when run_id is omitted. Max length: 1,024 characters.
test_configobjectConditionalThe TestConfig to save on the test. Required when run_id is omitted. When run_id is provided, this overrides the source run’s test_config_json.
repo_full_namestring | nullNonullRepository in owner/repo format. Used to surface this test in the PR validation settings for that repo when ci_enabled is true. Max length: 255 characters.
ci_enabledbooleanNofalseWhether to attach this saved test to the repository’s CI checks. Requires repo_full_name.
credentialsobjectNonullMap of credential key to value (e.g. {"DEMO_USER": "demo@example.com", "DEMO_PASSWORD": "secret"}). Stored encrypted at rest. The plaintext values are never returned in any response — only the credential keys are exposed via credential_keys.
tagsarray of stringNo[]Tags for organizing saved tests.
Example request
curl -X POST https://api.argalabs.com/demo-runner/tests \
  -H "Authorization: Bearer $ARGA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Checkout happy path",
    "description": "Sign in, add an item, and complete checkout.",
    "run_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
    "repo_full_name": "acme/web-app",
    "ci_enabled": true,
    "credentials": {"DEMO_USER": "demo@example.com", "DEMO_PASSWORD": "secret"},
    "tags": ["checkout", "smoke"]
  }'
Response
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "source_run_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
  "name": "Checkout happy path",
  "description": "Sign in, add an item, and complete checkout.",
  "repo_full_name": "acme/web-app",
  "prompt": "Sign in with the demo account, add an item to the cart, and complete checkout.",
  "start_url": "https://staging.example.com",
  "test_config_json": {"steps": [{}, {}]},
  "ci_enabled": true,
  "has_credentials": true,
  "credential_keys": ["DEMO_PASSWORD", "DEMO_USER"],
  "tags": ["checkout", "smoke"],
  "created_at": "2026-04-30T10:00:00+00:00",
  "updated_at": "2026-04-30T10:00:00+00:00"
}
FieldTypeDescription
idstringUnique identifier for the saved test.
source_run_idstring | nullUUID of the demo run this test was created from, if any.
namestringDisplay name.
descriptionstring | nullFree-text description.
repo_full_namestring | nullRepository in owner/repo format.
promptstringSaved prompt.
start_urlstringSaved start URL.
test_config_jsonobjectSaved TestConfig.
ci_enabledbooleanWhether the saved test is attached to the repository’s CI checks.
has_credentialsbooleanWhether encrypted credentials are stored on this test.
credential_keysarray of stringSorted list of credential keys stored on the test. Plaintext values are never returned.
tagsarray of stringTags for organizing saved tests.
created_atstring | nullISO 8601 timestamp.
updated_atstring | nullISO 8601 timestamp of the most recent update.
Errors
StatusDetail
400Provide a test_config or run_id with saved blocks
400Saved tests require prompt and start_url
401Invalid or expired token.
404Runner run not found — returned when run_id does not match a run owned by the authenticated user.
409Runner run does not have editable blocks yet — returned when the source run has not produced a test_config_json yet.

GET Get a saved runner test

Accepts both API key and JWT authentication.
GET /demo-runner/tests/{test_id}
Get a single saved runner test by ID. Path parameters
ParameterTypeDescription
test_idstringUUID of the saved test.
Response A saved test object with the same shape as the create response. Errors
StatusDetail
401Invalid or expired token.
404Runner test not found

PATCH Update a saved runner test

Accepts both API key and JWT authentication.
PATCH /demo-runner/tests/{test_id}
Update a saved runner test. All fields are optional — only fields included in the request body are updated. Path parameters
ParameterTypeDescription
test_idstringUUID of the saved test.
Request body
FieldTypeRequiredDescription
namestringNoUpdated display name. Length: 1–255 characters.
descriptionstring | nullNoUpdated description. Include this field with a null value to clear it.
promptstringNoUpdated prompt. Max length: 20,000 characters.
start_urlstringNoUpdated start URL. Max length: 1,024 characters.
test_configobjectNoReplace test_config_json in full.
repo_full_namestring | nullNoUpdated repository in owner/repo format. Include with a null value to detach the test from any repository.
ci_enabledbooleanNoWhether the test is attached to the repository’s CI checks.
credentialsobjectNoReplace the stored credentials. Pass an empty object to clear them. Plaintext values are never returned in responses.
tagsarray of stringNoUpdated tags.
Response The updated saved test object with the same shape as the create response. Errors
StatusDetail
401Invalid or expired token.
404Runner test not found

DELETE Delete a saved runner test

Accepts both API key and JWT authentication.
DELETE /demo-runner/tests/{test_id}
Delete a saved runner test. Path parameters
ParameterTypeDescription
test_idstringUUID of the saved test.
Response
{"status": "deleted"}
Errors
StatusDetail
401Invalid or expired token.
404Runner test not found

POST Run a saved runner test

Accepts both API key and JWT authentication.
POST /demo-runner/tests/{test_id}/run
Execute a saved runner test directly. The runner replays the test’s stored test_config_json without requiring you to first patch a run. Optional fields in the request body let you override the prompt or start URL for this execution; when omitted, the saved test’s values are used. Path parameters
ParameterTypeDescription
test_idstringUUID of the saved test to run.
Request body The request body is optional. Send an empty object (or omit the body) to replay the saved test as stored. To override values for this execution, include any of the fields below.
FieldTypeRequiredDescription
promptstringNoOverride the prompt for this run. When omitted or empty, the saved test’s prompt is reused. Max length: 20,000 characters.
start_urlstringNoOverride the start URL for this run. When provided, it replaces the saved TestConfig’s starting_url and the first goto step. When omitted, the saved test’s start_url is reused. Max length: 1,024 characters.
twinsarray of stringNoOptional list of twin identifiers to associate with this run. Recorded on the created event.
ttl_minutesintegerNoOptional run TTL in minutes. Range: 1–480. Recorded on the created event.
session_idstringNoOptional client-supplied session identifier. Recorded on the created event.
Example request
curl -X POST https://api.argalabs.com/demo-runner/tests/a1b2c3d4-e5f6-7890-abcd-ef1234567890/run \
  -H "Authorization: Bearer $ARGA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "start_url": "https://staging.example.com"
  }'
Response Returns a new demo run object with the same shape as POST /demo-runner/runs. The new run has mode set to rerun_from_config, source_run_id copied from the saved test, and test_config_json populated from the saved test (with prompt and start_url overrides applied). Errors
StatusDetail
401Invalid or expired token.
404Runner test not found
503FLOW_RUNNER_JOB_NAME is not configured — returned when the deployment has no flow runner job configured.

WEBSOCKET Stream demo run events

WSS /demo-runner/runs/{run_id}/stream?token={api_key_or_jwt}
Subscribe to a live WebSocket feed of events for a demo run. The server pushes JSON messages as the runner executes — including step events, browser stream frames, and a final done message when the run reaches a terminal state. Authentication is performed via the token query parameter because most browser WebSocket clients cannot set custom headers. Pass an API key or JWT. Path parameters
ParameterTypeDescription
run_idstringUUID of the demo run.
Query parameters
ParameterTypeRequiredDescription
tokenstringYesAPI key or JWT for authentication.
Message shapes The server sends JSON messages of the following shapes:
{"type": "event", "event": {"id": "...", "type": "running", "message": "...", "details": {}, "timestamp": "..."}}
{"type": "done", "status": "completed"}
{"type": "done", "status": "failed", "message": "Flow runner failed: ..."}
The connection closes with WebSocket code 1008 when the token is missing or invalid, or when the run does not belong to the authenticated user.

Authentication endpoints

POST Start device authorization

POST /auth/device/start
Begin the CLI device authorization flow. Returns a device code for the user to approve in the browser. Request body (optional)
FieldTypeRequiredDescription
device_namestringNoLabel for this device. Stored on the server and returned in the approval response and device list.
Response
{
  "device_code": "abc123...",
  "verification_url": "https://app.argalabs.com/cli"
}

POST Poll device authorization

POST /auth/device/poll
Poll the status of a pending device authorization. Request body
FieldTypeRequiredDescription
device_codestringYesThe device code returned from the start endpoint.
Response (pending)
{"status": "pending"}
Response (approved)
{
  "api_key": "arga_sk_...",
  "cli_api_key_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "device_name": "CLI device"
}
Errors
StatusDetail
404Device session not found
409Device code already used. Run `arga login` again.
410Device code expired. Run `arga login` again.

GET Get current user

Accepts both API key and JWT authentication.
GET /auth/me
Return the authenticated user’s profile. Response
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "github_login": "octocat",
  "email": "octocat@example.com",
  "email_verified": true,
  "avatar_url": "https://avatars.githubusercontent.com/u/1",
  "workspace": "Arga Labs",
  "workspace_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
  "workspace_role": "owner",
  "workspace_github_org": "arga-labs",
  "api_key": "••••abcd",
  "billing_plan": "team",
  "plan_limits": {
    "url_runs_limit": null,
    "pr_runs_limit": 500,
    "pr_runs_used": 12,
    "pr_runs_remaining": 488,
    "sandbox_runs_limit": 100,
    "sandbox_runs_used": 3,
    "sandbox_runs_remaining": 97,
    "max_twins_per_run": null,
    "max_ttl_minutes": 480,
    "ci_checks_limit": 500,
    "ci_checks_used": 0,
    "ci_checks_remaining": 500,
    "prompt_required": false
  },
  "twin_bootups_used": 0,
  "twin_bootups_limit": null,
  "twin_bootups_remaining": null
}
FieldTypeDescription
idstringUser identifier.
github_loginstring | nullGitHub username. null for accounts created via email-only signup.
emailstring | nullEmail address on the account.
email_verifiedbooleanWhether the email address has been verified.
avatar_urlstring | nullURL of the user’s GitHub avatar.
workspacestring | nullWorkspace name. null when the user does not belong to a workspace.
workspace_idstring | nullWorkspace identifier. null when the user does not belong to a workspace.
workspace_rolestring | nullThe user’s role in the workspace: owner or member. null when the user does not belong to a workspace.
workspace_github_orgstring | nullGitHub organization login linked to the workspace. null when the user does not belong to a workspace.
api_keystring | nullMasked preview of the user’s API key (e.g. ••••abcd). The full key is only returned when the key is first created. null when no key exists.
billing_planstringCurrent billing plan: free, team, or paid.
plan_limitsobjectPlan-specific limits and usage for the current billing period.
plan_limits.url_runs_limitinteger | nullMonthly URL run limit. null for team and paid plans (unlimited). On the free plan, this equals the overall run limit (e.g. 10).
plan_limits.pr_runs_limitinteger | nullMonthly PR run limit. 500 for team plans, null for paid (unlimited) and free (not available).
plan_limits.pr_runs_usedintegerPR runs consumed in the current monthly billing period.
plan_limits.pr_runs_remaininginteger | nullPR runs remaining this month. null for paid plans (unlimited) and free plans (not available).
plan_limits.sandbox_runs_limitinteger | nullMonthly sandbox (agent) run limit. 100 for team plans, null for paid (unlimited) and free (not available).
plan_limits.sandbox_runs_usedintegerSandbox runs consumed in the current monthly billing period.
plan_limits.sandbox_runs_remaininginteger | nullSandbox runs remaining this month. null for paid plans (unlimited) and free plans (not available).
plan_limits.max_twins_per_runinteger | nullMaximum twins allowed per run. 1 for free plan, null for team/paid (unlimited).
plan_limits.max_ttl_minutesinteger | nullMaximum TTL in minutes for validation runs. 10 for free plan, 480 for team and paid plans.
plan_limits.ci_checks_limitinteger | nullMonthly CI check limit. Only applies to team plans.
plan_limits.ci_checks_usedintegerCI checks consumed in the current monthly billing period.
plan_limits.ci_checks_remaininginteger | nullCI checks remaining this month. null when no limit applies.
plan_limits.prompt_requiredbooleanWhether the user’s plan requires a test prompt. true for free plan, false for team/paid.
twin_bootups_usedintegerKept for backward compatibility.
twin_bootups_limitinteger | nullKept for backward compatibility.
twin_bootups_remaininginteger | nullKept for backward compatibility.
Free plan responses also include validation_runs_limit, validation_runs_used, and validation_runs_remaining fields for backward compatibility. New integrations should use the per-type fields (url_runs_*, pr_runs_*, sandbox_runs_*) instead.
Errors
StatusDetail
401Invalid or expired token.

POST Create an API key

Requires JWT authentication.
POST /auth/api-keys
Create a new API key. The full key is returned only in this response — store it immediately, as it cannot be retrieved later. Request body
FieldTypeRequiredDefaultDescription
namestringNo"API Key"A label for the key (max 255 characters).
Response
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "name": "Cursor MCP",
  "key": "arga_sk_live_abc123...",
  "key_preview": "arga_sk_abc1...xyz9",
  "created_at": "2026-04-09T22:00:00Z"
}
FieldTypeDescription
idstringUUID of the newly created key.
namestringThe label assigned to the key.
keystringThe full API key. Shown only once in this response.
key_previewstringMasked preview of the key for display purposes.
created_atstring | nullISO 8601 timestamp of when the key was created.
Errors
StatusDetail
401Invalid or expired token.
500Failed to create API key

GET List CLI devices

Requires JWT authentication.
GET /auth/cli/devices
List all API keys for the current user, including keys created from the dashboard and device-scoped keys from arga login. Response
[
  {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "device_name": "Work laptop",
    "key_preview": "arga_sk_abc1...xyz9",
    "created_at": "2026-03-21T12:00:00Z",
    "last_used_at": "2026-03-21T14:30:00Z",
    "revoked_at": null
  }
]

POST Revoke a CLI device

Accepts both API key and JWT authentication.
POST /auth/cli/devices/{cli_api_key_id}/revoke
Revoke a CLI API key. Path parameters
ParameterTypeDescription
cli_api_key_idstringUUID of the CLI API key to revoke.
Response
{"status": "revoked"}
Errors
StatusDetail
401Invalid or expired token.
404CLI device not found

POST Email signup

POST /auth/email/signup
Begin the email-only signup flow. Sends a six-digit verification code to the provided email address. If an account with this email already exists and is verified, the code is sent to the existing account. Otherwise, a new account is created. Codes expire after 10 minutes. You can request a new code once per minute. Request body
FieldTypeRequiredDescription
emailstringYesThe email address to sign up with.
Response
{
  "status": "sent",
  "email": "user@example.com"
}
FieldTypeDescription
statusstringAlways "sent" on success.
emailstringThe normalized email address the code was sent to.
Errors
StatusDetail
400Enter a valid email address
429Wait before requesting another verification code

POST Verify email signup

POST /auth/email/signup/verify
Complete the email-only signup flow by submitting the verification code. On success, returns a quickstart API key scoped to 5 twin provisions. Run arga login for full access after trying the quickstart flow. You have up to 5 attempts per code. After 5 failed attempts, request a new code. Request body
FieldTypeRequiredDescription
emailstringYesThe email address used in the signup request.
codestringYesThe six-digit verification code received via email.
Response
{
  "status": "verified",
  "api_key": "arga_sk_..."
}
FieldTypeDescription
statusstringAlways "verified" on success.
api_keystringA quickstart-scoped API key limited to 5 twin provisions. Store it immediately — it is not shown again. Run arga login after the quickstart flow for a full-access key.
Errors
StatusDetail
400Enter a valid email address
400Invalid verification code
404No signup found for that email. Request a code first.
404No active verification code found for that email
429Too many verification attempts. Request a new code