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 type | How to obtain | Format |
|---|
| API key | Create 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_ |
| JWT | Returned 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
| Endpoint | Method | API key | JWT | Notes |
|---|
/health | GET | — | — | No auth required |
/validate/url-run | POST | Yes | Yes | Unified URL validation |
/validate/pr-run | POST | Yes | Yes | Unified PR/branch validation (also used for sandbox runs via run_type: "agent_run") |
/validate/url/probe | POST | Yes | Yes | Detect twins for a URL |
/validate/twins | GET | Yes | Yes | |
/validate/twins/provision | POST | Yes | Yes | |
/validate/twins/provision/{run_id}/status | GET | Yes | Yes | |
/validate/twins/provision/{run_id}/extend | POST | Yes | Yes | |
/validate/twins/provision/{run_id}/teardown | POST | Yes | Yes | |
/validate/{run_id}/feedback | POST | Yes | Yes | Deprecated |
/validate/{run_id}/cancel | POST | Yes | Yes | |
/validate/{run_id}/results | GET | Yes | Yes | SSE stream |
/runs/{run_id} | GET | Yes | Yes | |
/runs/{run_id}/logs | GET | Yes | Yes | Twin and sandbox logs |
/validate/{run_id}/artifacts/{filename} | GET | Yes | Yes | Also accepts ?token= query param |
/validation/github/config | GET | Yes | Yes | Team plan required |
/validation/github/config | POST | Yes | Yes | Team plan required |
/validation/github/config | PATCH | Yes | Yes | Team plan required |
/validation/pr | POST | Yes | Yes | Team plan required |
/validation/runs | GET | Yes | Yes | Team plan required |
/scenarios/presets | GET | — | — | No auth required |
/scenarios | POST | Yes | Yes | |
/scenarios | GET | Yes | Yes | |
/scenarios/{scenario_id} | GET | Yes | Yes | |
/scenarios/{scenario_id} | PUT | Yes | Yes | |
/scenarios/{scenario_id} | DELETE | Yes | Yes | |
/demo-runner/runs | POST | Yes | Yes | Record a browser flow from a prompt |
/demo-runner/runs | GET | Yes | Yes | List recent demo runs |
/demo-runner/runs/{run_id} | GET | Yes | Yes | |
/demo-runner/runs/{run_id}/config | PATCH | Yes | Yes | Update the saved TestConfig for a run |
/demo-runner/runs/{run_id}/messages | POST | Yes | Yes | Send a user message to a run |
/demo-runner/runs/{run_id}/rerun | POST | Yes | Yes | Replay a recorded flow |
/demo-runner/runs/{run_id}/artifacts/{filename} | GET | Yes | Yes | Also accepts ?token= query param |
/demo-runner/tests | GET | Yes | Yes | List saved runner tests |
/demo-runner/tests | POST | Yes | Yes | Save a runner test from a completed run |
/demo-runner/tests/{test_id} | GET | Yes | Yes | |
/demo-runner/tests/{test_id} | PATCH | Yes | Yes | |
/demo-runner/tests/{test_id} | DELETE | Yes | Yes | |
/demo-runner/tests/{test_id}/run | POST | Yes | Yes | Execute a saved runner test |
/auth/device/start | POST | — | — | Public |
/auth/device/poll | POST | — | — | Public (device code acts as credential) |
/auth/me | GET | Yes | Yes | |
/auth/api-keys | POST | — | Yes | |
/auth/cli/devices | GET | — | Yes | |
/auth/email/signup | POST | — | — | Public |
/auth/email/signup/verify | POST | — | — | Public |
/auth/cli/devices/{cli_api_key_id}/revoke | POST | Yes | Yes | |
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
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.
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
| Field | Type | Required | Description |
|---|
url | string | Yes | Target URL to validate. Must be a public HTTP or HTTPS URL. |
prompt | string | No | Natural-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. |
credentials | object | No | Login credentials for the target app. |
credentials.email | string | No | Email address for authentication. Must be provided together with password. |
credentials.password | string | No | Password for authentication. Must be provided together with email. |
twins | array of string | No | Digital 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_mode | string | No | Runner execution mode. Use "dom" for DOM-based interaction or "visual" for screenshot-based visual interaction. |
session_id | string | No | UUID of an existing chat session to attach this run to. When omitted, a new session is created. |
repo | string | No | Repository 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. |
branch | string | No | Branch name. Used together with repo for diff-aware test planning. |
pr_url | string | No | Pull request URL. Used to resolve the branch when branch is not provided directly. |
provision_id | string | No | UUID 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_id | string | No | UUID 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:
- Provision twins via
POST /validate/twins/provision and wait until the status is ready.
- Deploy your app to staging with its environment variables rewritten to point at the twin URLs (the same
.env changes the wizard does automatically).
- 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"
}
| Field | Type | Description |
|---|
run_id | string | Unique identifier for the validation run. |
status | string | Initial run status. queued when a prompt is provided; transitions to running once the runner job is dispatched. |
session_id | string | Chat 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
| Status | Detail |
|---|
400 | A valid public http(s) URL is required. |
400 | Email and password must both be provided. |
400 | Invalid provision_id |
400 | Invalid scenario_id format |
401 | Invalid or expired token. |
403 | Plan limit errors (free plan restrictions, monthly limit reached). |
404 | Provision not found |
404 | Scenario not found |
409 | Provision is not ready (status: {status}). Poll status first. |
POST Start a PR run
Accepts both API key and JWT authentication.
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
| Field | Type | Required | Description |
|---|
repo | string | Yes | Repository in owner/repo format. |
branch | string | Conditional | Branch name. Required unless pr_url is provided. |
pr_url | string | Conditional | Pull request URL. Used to resolve the branch when branch is not provided. |
context_notes | string | No | Additional instructions or context for the validation. |
scenario_prompt | string | No | Natural-language prompt to customize the generated test scenarios. |
scenario_id | string | No | UUID of a saved scenario to pre-seed twins with sample data. When provided without scenario_prompt, the scenario’s own prompt is used. |
twins | array of string | No | Digital 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_url | string | No | Base URL of the frontend under test. Defaults to http://localhost:3000. |
session_id | string | No | UUID of an existing chat session to attach this run to. When omitted, a new session is created. |
run_type | string | No | Controls 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
| Status | Detail |
|---|
400 | A branch or PR URL is required. |
400 | GitHub integration required for validation. |
400 | Invalid repository format. |
400 | Invalid scenario_id format |
401 | Invalid or expired token. |
403 | Plan limit errors. |
404 | Session not found |
404 | Scenario 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.
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
}
]
| Field | Type | Description |
|---|
name | string | Twin identifier used in the twins array when deploying a sandbox. |
label | string | Human-readable display name. |
kind | string | Twin 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_ui | boolean | Whether this twin is shown in the web UI by default. |
Errors
| Status | Detail |
|---|
401 | Invalid or expired token. |
POST Probe a URL for twin suggestions
Accepts both API key and JWT authentication.
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
| Field | Type | Required | Description |
|---|
url | string | Yes | Target 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"]
}
| Field | Type | Description |
|---|
suggested_twins | array of string | Twin names recommended for this URL based on detected signals. |
reasoning | array of string | Human-readable explanations for each suggestion. |
detected_signals | array of string | Raw integration fingerprints found during probing. |
Errors
| Status | Detail |
|---|
400 | A valid public http(s) URL is required. |
401 | Invalid 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
| Field | Type | Required | Default | Description |
|---|
twins | array of string | Yes | — | Twin names to provision (e.g. slack, stripe). At least one valid twin name is required. Use the twin catalog to discover available names. |
ttl_minutes | integer | No | 60 | Time-to-live in minutes before the twins are automatically torn down. Range: 1–480. |
scenario_id | string | No | — | UUID of a scenario to pre-seed the twins with sample data. Takes precedence over scenario_prompt when both are provided. |
scenario_prompt | string | No | — | Natural-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"
}
| Field | Type | Description |
|---|
run_id | string | Unique identifier for the provisioning session. Use this to poll for status. |
Errors
| Status | Detail |
|---|
400 | At least one valid twin name is required. |
401 | Invalid or expired token. |
403 | Quickstart 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. |
403 | Free plan allows 1 twin per run. Upgrade to Team for unlimited twins per run. |
403 | Monthly 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
| Parameter | Type | Description |
|---|
run_id | string | UUID 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
}
| Field | Type | Description |
|---|
run_id | string | Provisioning session identifier. |
status | string | Current 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. |
twins | object | Map of twin name to connection details. Empty while provisioning. |
twins[name].name | string | Twin identifier. |
twins[name].label | string | Human-readable display name. |
twins[name].base_url | string | Base URL for API requests to this twin. |
twins[name].admin_url | string | Admin URL for managing twin state. |
twins[name].env_vars | object | Environment 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_ui | boolean | Whether this twin is shown in the web UI by default. |
dashboard_url | string | null | URL to view the session in the Arga dashboard. Available when status is ready. |
expires_at | string | null | ISO 8601 timestamp when the twins will be automatically torn down. |
proxy_token | string | null | Authentication token for the proxy, if applicable. |
error | string | null | Error message describing why provisioning failed. Only present when status is failed. |
seed_results | object | null | Per-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] | object | Provider-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
| Status | Detail |
|---|
400 | Invalid run_id |
401 | Invalid or expired token. |
404 | Run 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
| Parameter | Type | Description |
|---|
run_id | string | UUID of the provisioning session. |
Request body
| Field | Type | Required | Default | Description |
|---|
ttl_minutes | integer | No | 60 | New time-to-live in minutes from now. Range: 1–480. |
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}
| Field | Type | Description |
|---|
status | string | Always extended. |
ttl_minutes | integer | The new TTL that was applied. |
Errors
| Status | Detail |
|---|
400 | Invalid run_id |
400 | Cannot extend run in status: {status} (includes the current run status) |
401 | Invalid or expired token. |
404 | Run 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
| Parameter | Type | Description |
|---|
run_id | string | UUID 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"}
| Field | Type | Description |
|---|
status | string | Always cleaning_up. The environment is being torn down. |
run_id | string | The provisioning session identifier. |
Errors
| Status | Detail |
|---|
400 | Invalid run_id |
400 | Cannot teardown run in status: {status} (includes the current run status) |
401 | Invalid or expired token. |
404 | Run 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
| Parameter | Type | Description |
|---|
run_id | string | UUID of the validation run. |
Response
Errors
| Status | Detail |
|---|
401 | Invalid or expired token. |
404 | Validation run not found |
409 | Cannot 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
| Parameter | Type | Description |
|---|
run_id | string | UUID of the validation run. |
Request body
| Field | Type | Required | Description |
|---|
feedback | string | Yes | Free-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."
}
| Field | Type | Description |
|---|
run_id | string | The validation run identifier. |
user_feedback | string | null | The feedback that was saved. |
Errors
| Status | Detail |
|---|
400 | Invalid run_id |
400 | Feedback cannot be empty |
400 | Feedback is too long (max 10000 characters) |
401 | Invalid or expired token. |
404 | Validation 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
| Parameter | Type | Description |
|---|
run_id | string | UUID of the validation run. |
Errors
| Status | Detail |
|---|
401 | Invalid or expired token. |
404 | Validation run not found |
GET Get run details
Accepts both API key and JWT authentication.
Get full details of a validation or scan run.
Path parameters
| Parameter | Type | Description |
|---|
run_id | string | UUID 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:
| Field | Type | Description |
|---|
id | string | Run identifier. |
session_id | string | null | Chat session associated with this run. |
status | string | Current status (e.g. queued, running, complete, failed, cancelled). |
pr_url | string | Pull request URL, if applicable. |
frontend_url | string | Base URL of the frontend under test. |
run_type | string | Type 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. |
mode | string | null | Validation mode for the run (e.g. validation, auto_visual, redteam). |
prompt | string | null | The prompt that initiated the run. |
environment_url | string | null | URL of the sandbox environment, if applicable. |
twins | array | null | List of digital twin services used in the run. |
surface_urls | object | null | Map of twin name to its proxied URL. |
raw_surface_urls | object | null | Map of twin name to its direct (non-proxied) URL. |
runtime_profile | object | null | Runtime profile configuration used for the run. |
context_notes | string | null | Additional context or instructions provided when the run was started. |
user_feedback | string | null | Deprecated. User-submitted feedback for this run. This field is deprecated and will be removed in a future release. |
repo_full_name | string | null | Repository in owner/repo format. |
git_branch | string | null | Branch name. |
commit_sha | string | null | Commit SHA. |
github_pr_number | integer | null | Pull request number, if the run is associated with a PR. |
github_check_run_id | string | null | GitHub check run identifier. |
github_check_run_url | string | null | URL of the GitHub check run. |
event_log_json | array | null | Chronological log of events during the run. |
story_json | object | null | Generated user story with steps and coverage matrix. |
auto_story_bundle_json | object | null | Auto-generated story bundle for multi-story runs. |
auto_visual_reports | array | null | Reports from auto-visual story runs. Each object includes worker_key, title, status, issues, and optional story_json and results_json. |
attack_plan_json | object | null | Attack plan for red-team or security scan runs. |
results_json | array | null | Step-by-step results with status (pass, fail, error) and descriptions. |
step_summaries | array | null | Summarized step results. Each object includes title, status, details, step_number, and step_numbers. |
redteam_report_json | object | null | Red-team report with anomalies and coverage, if this is a scan run. |
worker_progress | array | null | Progress information for each worker in a multi-worker run. |
login_identifier | string | null | Login identifier used during validation, if applicable. |
coverage_manifest | object | null | Coverage manifest describing tested routes and features. |
failure_category | string | null | Category 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_detail | object | null | Structured details about the failure. Always populated on failed runs. See sub-fields below. |
failure_detail.phase | string | Pipeline phase where the failure occurred: build, deploy, runtime, cleanup, or fidelity. |
failure_detail.kind | string | Failure kind: build_failure, deploy_failure, proxy_failure, twin_failure, unsupported_endpoint, auth_failure, timeout, or connect_error. |
failure_detail.code | string | Machine-readable error code (e.g. worker_exception, scan_anomalies_found, runner_timeout). |
failure_detail.public_message | string | Human-readable description of the failure. |
failure_detail.retryable | boolean | Whether the failure is considered retryable. |
readiness_results | object | null | Pre-run readiness check results. |
retry_count | integer | null | Number of times this run has been retried. |
created_at | string | null | ISO 8601 timestamp. |
Errors
| Status | Detail |
|---|
401 | Invalid or expired token. |
404 | Validation run not found |
GET Get run logs
Accepts both API key and JWT authentication.
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
| Parameter | Type | Description |
|---|
run_id | string | UUID 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": []
}
| Field | Type | Description |
|---|
run | object | Run summary with current status and metadata. Same shape as the Get run details response. |
worker_logs | array | Logs from cluster worker jobs (build, deploy, warm-up). |
worker_logs[].job_id | string | Identifier of the worker job. |
worker_logs[].job_type | string | null | Type of worker job (e.g. deploy, build). |
worker_logs[].target_role | string | null | Role of the target instance (e.g. builder, warm). |
worker_logs[].status | string | null | Job status (e.g. completed, failed). |
worker_logs[].content | string | null | Log text content. May be null if the log could not be retrieved. |
worker_logs[].truncated | boolean | Whether the log content was truncated due to size limits. |
worker_logs[].error | string | null | Error message if the log could not be loaded. |
runtime_logs | array | Structured runtime logs from API and proxy services scoped to this run. |
runtime_logs[].timestamp | string | null | ISO 8601 timestamp of the log entry. |
runtime_logs[].service_name | string | null | Service that produced the log (e.g. arga-api, preview-proxy). |
runtime_logs[].severity | string | null | Log severity level (e.g. INFO, ERROR). |
runtime_logs[].event | string | null | Structured event name. |
runtime_logs[].code | string | null | Event code, if applicable. |
runtime_logs[].request_id | string | null | Request identifier for correlation. |
runtime_logs[].job_id | string | null | Associated worker job identifier, if applicable. |
runtime_logs[].surface_name | string | null | Twin or surface name associated with the log entry. |
runtime_logs[].message | string | null | Human-readable log message. |
warnings | array of string | Warnings encountered while fetching logs (e.g. if a log source was unavailable). |
Errors
| Status | Detail |
|---|
400 | run_id must be a valid UUID |
401 | Invalid or expired token. |
404 | Validation 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
| Parameter | Type | Description |
|---|
run_id | string | UUID of the validation run. |
filename | string | Path 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
| Status | Detail |
|---|
401 | Authentication required |
404 | Validation run not found |
404 | Artifact not found |
500 | Failed 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
| Parameter | Type | Required | Default | Description |
|---|
repo | string | Yes | — | Repository in owner/repo format. |
trigger_mode | string | No | "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
}
| Field | Type | Description |
|---|
repo | string | Repository in owner/repo format. |
installed | boolean | Whether the Arga GitHub App is installed on this repository. |
installation_id | string | null | GitHub App installation identifier. |
enabled | boolean | Whether automatic validation is active for this trigger mode. |
trigger_mode | string | Trigger mode: "pr" or "branch". |
branch | string | null | Branch name for branch-triggered validation. When trigger mode is "pr", returns the repository’s default branch. |
default_branch | string | null | The repository’s default branch (e.g. main). |
custom_instructions | string | null | Custom instructions for validation runs. |
comment_on_pr | boolean | Whether Arga posts PR comment summaries. |
Errors
| Status | Detail |
|---|
401 | Invalid or expired token. |
403 | Requires 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
| Field | Type | Required | Default | Description |
|---|
repo | string | Yes | — | Repository in owner/repo format. |
trigger_mode | string | Yes | — | How Arga triggers validation runs. Use "pr" for pull request events or "branch" for commits to a specific branch. |
branch | string | No | — | Branch 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_instructions | string | No | — | Additional 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_pr | boolean | No | true | Whether Arga posts a comment summary on pull requests. |
enabled | boolean | No | true | Whether 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
}
| Field | Type | Description |
|---|
repo | string | Repository in owner/repo format. |
installed | boolean | Whether the Arga GitHub App is installed on this repository. |
installation_id | string | null | GitHub App installation identifier. |
enabled | boolean | Whether automatic validation is active. |
trigger_mode | string | Trigger mode: "pr" or "branch". |
branch | string | null | Branch name for branch-triggered validation. null when trigger mode is "pr". |
default_branch | string | null | The repository’s default branch (e.g. main). |
custom_instructions | string | null | Custom instructions for validation runs. |
comment_on_pr | boolean | Whether Arga posts PR comment summaries. |
Errors
| Status | Detail |
|---|
400 | Choose a branch for branch-triggered validation. |
401 | Invalid or expired token. |
403 | Requires a Team or Paid plan. |
409 | Install 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
| Field | Type | Required | Description |
|---|
repo | string | Yes | Repository in owner/repo format. |
trigger_mode | string | Yes | Which trigger mode to toggle. Use "pr" for pull request events or "branch" for commits to a specific branch. |
enabled | boolean | Yes | Set 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
| Status | Detail |
|---|
401 | Invalid or expired token. |
403 | Requires a Team or Paid plan. |
404 | No {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.
Start an automatic validation run for a pull request.
Request body
| Field | Type | Required | Description |
|---|
repo | string | Yes | Repository in owner/repo format. |
pr_number | integer | Yes | Pull request number. |
frontend_url | string | No | Base URL of the frontend under test. Defaults to http://localhost:3000. |
context_notes | string | No | Additional 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"
}
| Field | Type | Description |
|---|
run_id | string | Unique identifier for the validation run. |
status | string | Initial run status. |
Errors
| Status | Detail |
|---|
400 | Repository must be provided as owner/repo. |
401 | Invalid or expired token. |
403 | Automatic 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.
List validation runs with pagination and optional filtering. Returns URL, PR, branch, and agent runs.
Query parameters
| Parameter | Type | Required | Default | Description |
|---|
repo | string | No | — | Filter by repository in owner/repo format. |
query | string | No | — | Search by branch name or PR number. |
limit | integer | No | 10 | Number of results per page. Range: 1–100. |
offset | integer | No | 0 | Pagination 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
}
| Field | Type | Description |
|---|
items | array | List of validation run summaries. |
items[].run_id | string | Unique identifier for the run. |
items[].status | string | Current run status. |
items[].repo | string | Repository in owner/repo format. |
items[].pr_number | integer | null | Pull request number, if applicable. |
items[].branch | string | null | Branch name. |
items[].commit_sha | string | null | Commit SHA that triggered the run. |
items[].trigger_type | string | null | How 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_at | string | ISO 8601 timestamp. |
total | integer | Total number of matching runs. |
limit | integer | Page size used. |
offset | integer | Current offset. |
has_more | boolean | Whether more results are available. |
Errors
| Status | Detail |
|---|
400 | Repository must be provided as owner/repo. |
401 | Invalid or expired token. |
403 | Automatic 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
Return built-in preset scenario templates. No authentication required.
Query parameters
| Parameter | Type | Required | Description |
|---|
twin | string | No | Filter presets that include this twin name. |
tag | string | No | Filter 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
| Tag | Description |
|---|
preset | Automatically added to all preset scenarios as the first tag |
ecommerce | E-commerce and checkout flows |
payments | Payment processing scenarios |
saas | SaaS billing and subscription management |
billing | Billing-related scenarios |
devops | DevOps and CI/CD pipelines |
ci-cd | Continuous integration and deployment |
support | Customer support workflows |
customer-service | Customer service scenarios |
collaboration | Document and team collaboration |
documents | Document management flows |
security | Security and access control |
fraud | Fraud detection and prevention |
auth | Authentication and authorization |
access-control | Access control boundaries |
functional | General functional testing |
POST Create a scenario
Accepts both API key and JWT authentication.
Create a new scenario for pre-seeding twins.
Request body
| Field | Type | Required | Description |
|---|
name | string | Yes | Display name for the scenario. |
description | string | No | Human-readable description of the scenario. |
prompt | string | Conditional | Natural-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. |
twins | array of string | Conditional | Twin 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_config | object | Conditional | Explicit 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. |
tags | array of string | No | Tags 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"
}
| Field | Type | Description |
|---|
id | string | Unique identifier for the scenario. Use this as the scenario_id when provisioning twins. |
name | string | Display name. |
description | string | null | Human-readable description. |
prompt | string | null | The natural-language prompt used to generate the configuration, if provided. |
twins | array of string | Twin names included in this scenario. |
seed_config | object | The resolved seed configuration. |
tags | array of string | Tags for organizing scenarios. |
is_preset | boolean | Whether this is a built-in preset scenario. Defaults to false for user-created scenarios. |
created_at | string | ISO 8601 timestamp. Empty string for preset scenarios. |
updated_at | string | ISO 8601 timestamp. Empty string for preset scenarios. |
Errors
| Status | Detail |
|---|
401 | Invalid or expired token. |
422 | Either 'prompt' or 'seed_config' must be provided |
422 | 'twins' is required when 'seed_config' is provided without 'prompt' |
422 | Seed config generation failed. Returned when the prompt cannot be resolved into a valid twin configuration. |
422 | Scenario 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.
List all scenarios for the authenticated user. You can optionally include built-in preset scenarios in the response.
Query parameters
| Parameter | Type | Required | Description |
|---|
twin | string | No | Filter scenarios that include this twin name. |
tag | string | No | Filter scenarios that include this tag. |
include_presets | boolean | No | When 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
| Status | Detail |
|---|
401 | Invalid 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
| Parameter | Type | Description |
|---|
scenario_id | string | UUID of the scenario. |
Response
A scenario object (same shape as the create response).
Errors
| Status | Detail |
|---|
401 | Invalid or expired token. |
404 | Scenario 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
| Parameter | Type | Description |
|---|
scenario_id | string | UUID of the scenario. |
Request body
| Field | Type | Required | Description |
|---|
name | string | No | Updated display name. |
description | string | null | No | Updated description. Set to null to clear the description. |
prompt | string | No | Updated natural-language prompt. When provided without seed_config, the seed configuration is regenerated. |
twins | array of string | No | Updated twin names. |
seed_config | object | No | Updated seed configuration. |
tags | array of string | No | Updated tags. |
Response
The updated scenario object (same shape as the create response).
Errors
| Status | Detail |
|---|
401 | Invalid or expired token. |
404 | Scenario not found |
422 | Seed config generation failed. |
DELETE Delete a scenario
Accepts both API key and JWT authentication.
DELETE /scenarios/{scenario_id}
Delete a scenario.
Path parameters
| Parameter | Type | Description |
|---|
scenario_id | string | UUID of the scenario. |
Response
Errors
| Status | Detail |
|---|
401 | Invalid or expired token. |
404 | Scenario 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.
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
| Field | Type | Required | Description |
|---|
prompt | string | Yes | Natural-language description of the flow to record. Length: 1–20,000 characters. |
start_url | string | Conditional | Absolute 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_config | object | No | Optional 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
}
| Field | Type | Description |
|---|
id | string | Unique identifier for the demo run. |
source_run_id | string | null | The run this run was forked from. null for new recordings; populated when the run was created via POST /demo-runner/runs/{run_id}/rerun. |
mode | string | Execution mode: record_from_prompt for new recordings or rerun_from_config for replays. |
status | string | Current status: queued, running, completed, or failed. |
prompt | string | The prompt the run was created with. |
start_url | string | The resolved start URL. |
test_config_json | object | null | The 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_json | array of object | Patches applied during a replay to recover from selector or step drift. Empty for new recordings. |
summary_text | string | null | Plain-text summary of the run produced after completion. null until the run completes (and may remain null if no summary was generated). |
summary_json | object | null | Structured 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_json | array of object | Chronological event log. Each event includes id, type, message, details, and timestamp. |
artifacts_json | object | Map 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_id | string | null | Identifier of the underlying flow runner job. null until the job has been queued or when the runner job failed to launch. |
error_message | string | null | Error message when status is failed. |
created_at | string | null | ISO 8601 timestamp. |
updated_at | string | null | ISO 8601 timestamp of the last status or event update. |
started_at | string | null | ISO 8601 timestamp when the runner job started executing. |
completed_at | string | null | ISO 8601 timestamp when the run reached a terminal state. |
Errors
| Status | Detail |
|---|
400 | Provide a start URL or include one in the prompt. |
400 | Start URL must be an absolute http(s) URL. |
401 | Invalid or expired token. |
503 | FLOW_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
| Parameter | Type | Description |
|---|
run_id | string | UUID 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.
| Field | Type | Required | Description |
|---|
prompt | string | No | Override the prompt for this rerun. When omitted or empty, the source run’s prompt is reused. Max length: 20,000 characters. |
start_url | string | No | Override 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
| Status | Detail |
|---|
401 | Invalid or expired token. |
404 | Test run not found |
409 | Source run does not have a TestConfig yet — returned when the source run has not finished recording. |
503 | FLOW_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.
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"
}
]
}
| Field | Type | Description |
|---|
runs | array of object | Demo run objects with the same shape as POST /demo-runner/runs. |
Errors
| Status | Detail |
|---|
401 | Invalid 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
| Parameter | Type | Description |
|---|
run_id | string | UUID of the demo run. |
Response
A demo run object with the same shape as POST /demo-runner/runs.
Errors
| Status | Detail |
|---|
401 | Invalid or expired token. |
404 | Test 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:
| Format | Example | Notes |
|---|
[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 selectors | button.primary | Stable 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
| Parameter | Type | Description |
|---|
run_id | string | UUID of the demo run. |
Request body
| Field | Type | Required | Description |
|---|
test_config | object | Yes | The 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
| Status | Detail |
|---|
401 | Invalid or expired token. |
404 | Test 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
| Parameter | Type | Description |
|---|
run_id | string | UUID of the demo run. |
Request body
| Field | Type | Required | Description |
|---|
message | string | Yes | User 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
| Status | Detail |
|---|
401 | Invalid or expired token. |
404 | Test 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
| Parameter | Type | Description |
|---|
run_id | string | UUID of the demo run. |
filename | string | Path 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
| Status | Detail |
|---|
401 | Authentication required |
404 | Test run not found |
404 | Artifact 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.
List saved runner tests for the authenticated user, ordered by updated_at (most recently updated first). Optionally filter by repository.
Query parameters
| Parameter | Type | Required | Description |
|---|
repo_full_name | string | No | Filter 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"
}
]
}
| Field | Type | Description |
|---|
tests | array of object | Saved test objects with the same shape as the create response. |
Errors
| Status | Detail |
|---|
401 | Invalid or expired token. |
POST Save a runner test
Accepts both API key and JWT authentication.
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
| Field | Type | Required | Default | Description |
|---|
name | string | Yes | — | Display name for the saved test. Length: 1–255 characters. |
description | string | null | No | null | Free-text description. Max length: 10,000 characters. |
run_id | string | Conditional | — | UUID 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. |
prompt | string | Conditional | — | Override the prompt to save on the test. Required when run_id is omitted. Max length: 20,000 characters. |
start_url | string | Conditional | — | Override the start URL to save on the test. Required when run_id is omitted. Max length: 1,024 characters. |
test_config | object | Conditional | — | The 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_name | string | null | No | null | Repository 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_enabled | boolean | No | false | Whether to attach this saved test to the repository’s CI checks. Requires repo_full_name. |
credentials | object | No | null | Map 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. |
tags | array of string | No | [] | 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"
}
| Field | Type | Description |
|---|
id | string | Unique identifier for the saved test. |
source_run_id | string | null | UUID of the demo run this test was created from, if any. |
name | string | Display name. |
description | string | null | Free-text description. |
repo_full_name | string | null | Repository in owner/repo format. |
prompt | string | Saved prompt. |
start_url | string | Saved start URL. |
test_config_json | object | Saved TestConfig. |
ci_enabled | boolean | Whether the saved test is attached to the repository’s CI checks. |
has_credentials | boolean | Whether encrypted credentials are stored on this test. |
credential_keys | array of string | Sorted list of credential keys stored on the test. Plaintext values are never returned. |
tags | array of string | Tags for organizing saved tests. |
created_at | string | null | ISO 8601 timestamp. |
updated_at | string | null | ISO 8601 timestamp of the most recent update. |
Errors
| Status | Detail |
|---|
400 | Provide a test_config or run_id with saved blocks |
400 | Saved tests require prompt and start_url |
401 | Invalid or expired token. |
404 | Runner run not found — returned when run_id does not match a run owned by the authenticated user. |
409 | Runner 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
| Parameter | Type | Description |
|---|
test_id | string | UUID of the saved test. |
Response
A saved test object with the same shape as the create response.
Errors
| Status | Detail |
|---|
401 | Invalid or expired token. |
404 | Runner 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
| Parameter | Type | Description |
|---|
test_id | string | UUID of the saved test. |
Request body
| Field | Type | Required | Description |
|---|
name | string | No | Updated display name. Length: 1–255 characters. |
description | string | null | No | Updated description. Include this field with a null value to clear it. |
prompt | string | No | Updated prompt. Max length: 20,000 characters. |
start_url | string | No | Updated start URL. Max length: 1,024 characters. |
test_config | object | No | Replace test_config_json in full. |
repo_full_name | string | null | No | Updated repository in owner/repo format. Include with a null value to detach the test from any repository. |
ci_enabled | boolean | No | Whether the test is attached to the repository’s CI checks. |
credentials | object | No | Replace the stored credentials. Pass an empty object to clear them. Plaintext values are never returned in responses. |
tags | array of string | No | Updated tags. |
Response
The updated saved test object with the same shape as the create response.
Errors
| Status | Detail |
|---|
401 | Invalid or expired token. |
404 | Runner 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
| Parameter | Type | Description |
|---|
test_id | string | UUID of the saved test. |
Response
Errors
| Status | Detail |
|---|
401 | Invalid or expired token. |
404 | Runner 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
| Parameter | Type | Description |
|---|
test_id | string | UUID 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.
| Field | Type | Required | Description |
|---|
prompt | string | No | Override the prompt for this run. When omitted or empty, the saved test’s prompt is reused. Max length: 20,000 characters. |
start_url | string | No | Override 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. |
twins | array of string | No | Optional list of twin identifiers to associate with this run. Recorded on the created event. |
ttl_minutes | integer | No | Optional run TTL in minutes. Range: 1–480. Recorded on the created event. |
session_id | string | No | Optional 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
| Status | Detail |
|---|
401 | Invalid or expired token. |
404 | Runner test not found |
503 | FLOW_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
| Parameter | Type | Description |
|---|
run_id | string | UUID of the demo run. |
Query parameters
| Parameter | Type | Required | Description |
|---|
token | string | Yes | API 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
Begin the CLI device authorization flow. Returns a device code for the user to approve in the browser.
Request body (optional)
| Field | Type | Required | Description |
|---|
device_name | string | No | Label 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
Poll the status of a pending device authorization.
Request body
| Field | Type | Required | Description |
|---|
device_code | string | Yes | The device code returned from the start endpoint. |
Response (pending)
Response (approved)
{
"api_key": "arga_sk_...",
"cli_api_key_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"device_name": "CLI device"
}
Errors
| Status | Detail |
|---|
404 | Device session not found |
409 | Device code already used. Run `arga login` again. |
410 | Device code expired. Run `arga login` again. |
GET Get current user
Accepts both API key and JWT authentication.
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
}
| Field | Type | Description |
|---|
id | string | User identifier. |
github_login | string | null | GitHub username. null for accounts created via email-only signup. |
email | string | null | Email address on the account. |
email_verified | boolean | Whether the email address has been verified. |
avatar_url | string | null | URL of the user’s GitHub avatar. |
workspace | string | null | Workspace name. null when the user does not belong to a workspace. |
workspace_id | string | null | Workspace identifier. null when the user does not belong to a workspace. |
workspace_role | string | null | The user’s role in the workspace: owner or member. null when the user does not belong to a workspace. |
workspace_github_org | string | null | GitHub organization login linked to the workspace. null when the user does not belong to a workspace. |
api_key | string | null | Masked 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_plan | string | Current billing plan: free, team, or paid. |
plan_limits | object | Plan-specific limits and usage for the current billing period. |
plan_limits.url_runs_limit | integer | null | Monthly 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_limit | integer | null | Monthly PR run limit. 500 for team plans, null for paid (unlimited) and free (not available). |
plan_limits.pr_runs_used | integer | PR runs consumed in the current monthly billing period. |
plan_limits.pr_runs_remaining | integer | null | PR runs remaining this month. null for paid plans (unlimited) and free plans (not available). |
plan_limits.sandbox_runs_limit | integer | null | Monthly sandbox (agent) run limit. 100 for team plans, null for paid (unlimited) and free (not available). |
plan_limits.sandbox_runs_used | integer | Sandbox runs consumed in the current monthly billing period. |
plan_limits.sandbox_runs_remaining | integer | null | Sandbox runs remaining this month. null for paid plans (unlimited) and free plans (not available). |
plan_limits.max_twins_per_run | integer | null | Maximum twins allowed per run. 1 for free plan, null for team/paid (unlimited). |
plan_limits.max_ttl_minutes | integer | null | Maximum TTL in minutes for validation runs. 10 for free plan, 480 for team and paid plans. |
plan_limits.ci_checks_limit | integer | null | Monthly CI check limit. Only applies to team plans. |
plan_limits.ci_checks_used | integer | CI checks consumed in the current monthly billing period. |
plan_limits.ci_checks_remaining | integer | null | CI checks remaining this month. null when no limit applies. |
plan_limits.prompt_required | boolean | Whether the user’s plan requires a test prompt. true for free plan, false for team/paid. |
twin_bootups_used | integer | Kept for backward compatibility. |
twin_bootups_limit | integer | null | Kept for backward compatibility. |
twin_bootups_remaining | integer | null | Kept 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
| Status | Detail |
|---|
401 | Invalid or expired token. |
POST Create an API key
Requires JWT authentication.
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
| Field | Type | Required | Default | Description |
|---|
name | string | No | "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"
}
| Field | Type | Description |
|---|
id | string | UUID of the newly created key. |
name | string | The label assigned to the key. |
key | string | The full API key. Shown only once in this response. |
key_preview | string | Masked preview of the key for display purposes. |
created_at | string | null | ISO 8601 timestamp of when the key was created. |
Errors
| Status | Detail |
|---|
401 | Invalid or expired token. |
500 | Failed to create API key |
GET List CLI devices
Requires JWT authentication.
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
| Parameter | Type | Description |
|---|
cli_api_key_id | string | UUID of the CLI API key to revoke. |
Response
Errors
| Status | Detail |
|---|
401 | Invalid or expired token. |
404 | CLI device not found |
POST 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
| Field | Type | Required | Description |
|---|
email | string | Yes | The email address to sign up with. |
Response
{
"status": "sent",
"email": "user@example.com"
}
| Field | Type | Description |
|---|
status | string | Always "sent" on success. |
email | string | The normalized email address the code was sent to. |
Errors
| Status | Detail |
|---|
400 | Enter a valid email address |
429 | Wait 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
| Field | Type | Required | Description |
|---|
email | string | Yes | The email address used in the signup request. |
code | string | Yes | The six-digit verification code received via email. |
Response
{
"status": "verified",
"api_key": "arga_sk_..."
}
| Field | Type | Description |
|---|
status | string | Always "verified" on success. |
api_key | string | A 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
| Status | Detail |
|---|
400 | Enter a valid email address |
400 | Invalid verification code |
404 | No signup found for that email. Request a code first. |
404 | No active verification code found for that email |
429 | Too many verification attempts. Request a new code |