# AGENTS
Source: https://docs.argalabs.com/AGENTS
# Documentation project instructions
## About this project
* This is a documentation site built on [Mintlify](https://mintlify.com)
* Pages are MDX files with YAML frontmatter
* Configuration lives in `docs.json`
* Run `mint dev` to preview locally
* Run `mint broken-links` to check links
## Terminology
## Style preferences
* Use active voice and second person ("you")
* Keep sentences concise — one idea per sentence
* Use sentence case for headings
* Bold for UI elements: Click **Settings**
* Code formatting for file names, commands, paths, and code references
## Content boundaries
# API reference
Source: https://docs.argalabs.com/api-reference
Public API endpoints for twins, scenarios, browser tests, and PR Test Runs
The Arga API is organized around service environments, reusable state, browser tests, and GitHub-triggered test runs.
List services, provision Twin Runs, inspect status, reset, extend, lock, and tear down.
Create reusable seed state and manage persistent Scenario twin environments.
Start browser runs against reachable application URLs and inspect their events and artifacts.
Save, edit, and execute reusable browser TestConfigs.
Install the GitHub App and configure pull-request or branch triggers.
Inspect run details, logs, result streams, and generated files.
See [Availability notes](/api-reference/availability-notes) for compatibility routes and distinctions between the current APIs.
# Authentication
Source: https://docs.argalabs.com/api-reference/auth
Authenticate requests to the Arga API
All public API requests use a bearer token:
```bash theme={null}
Authorization: Bearer
```
Use an Arga API key for server-to-server calls. You can create one from **Settings -> API Keys** in the web app or by running `arga login` from the CLI.
| Token type | Typical use | Notes |
| ---------- | ---------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| API key | SDKs, CI jobs, scripts, local tools | Starts with `arga_sk_`. Accepted by the public endpoints in this reference unless a page says otherwise. |
| JWT | Web app sessions and user-scoped browser flows | Returned by the app auth flow. Some GitHub configuration endpoints require a user session. |
The API base URL is:
```text theme={null}
https://api.argalabs.com
```
## One account per email
Each email address can only be linked to a single Arga account. Emails are normalized (trimmed and lowercased) before comparison.
Endpoints that touch identity return a `409` when this rule is violated:
| Endpoint | Trigger | Response |
| ----------------------------------------------- | ------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `POST /auth/email-verification/request` | The submitted email is already linked to another account. | `409` with detail `Only one account can use an email address. This email is already linked to another account.` |
| `POST /auth/email-verification/verify` | The submitted email is already linked to another account. | `409` with the same detail as above. |
| `POST /auth/email/signup` | An account already exists with the submitted email (verified or not). | `409` |
| `GET /auth/github/callback` (purpose `login`) | The GitHub account or the email returned by GitHub is already linked to a different Arga account. | Redirect to the web app login page with `error=github_identity_already_linked` and a `detail` query parameter describing the conflict. |
| `GET /auth/github/callback` (purpose `connect`) | The GitHub account or its email is already linked to a different Arga account. | Redirect to `/integrations` with `error=github_identity_already_linked` and a `detail` query parameter. |
When the GitHub-returned email matches an existing email-only Arga account that has not yet linked a GitHub identity, the GitHub callback links GitHub to that existing account instead of creating a duplicate.
# Availability notes
Source: https://docs.argalabs.com/api-reference/availability-notes
Current public API shape and compatibility routes
## Current public surfaces
| Product area | API surface |
| ------------------------------------------ | ------------------------------------------------- |
| Twin catalog and short-lived Twin Runs | `/validate/twins/*` and `/twin-runs/*` |
| Scenarios and persistent twin environments | `/scenarios/*` and `/scenario-twin-environments` |
| Browser Test Runs | `/runner/runs/*` and `/test-runs/*` |
| Saved Tests | `/runner/tests/*` and `/tests/*` |
| PR Test Run configuration | `/validation/github/*` |
| Run details, logs, and artifacts | `/runs/*`, result streams, and artifact endpoints |
## Compatibility notes
| Note | Current state |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| Runner alias | `/demo-runner/*` remains a deprecated alias for `/runner/*`. New clients should use `/runner/*`. |
| URL validation | `POST /validate/url-run` remains available for older clients. New browser-test integrations should use `/runner/runs` or `/test-runs`. |
| Manual PR validation | `POST /validation/pr` remains available but is deprecated. Configure automatic PR Test Runs through `/validation/github/*`. |
| Run-model aliases | `/twin-runs`, `/test-runs`, and `/tests` map to the same current implementations as their longer route families. |
Arga does not expose a public API that creates a new application deployment for every pull request. Browser Test Runs require a reachable `start_url`; PR Test Runs use the application target configured for the repository.
# POST Create a runner run
Source: https://docs.argalabs.com/api-reference/browser-agent-create-run
Run the browser agent against a reachable application URL
```bash theme={null}
POST /runner/runs
```
Starts a browser Test Run from a natural-language prompt. Pass `start_url`, or include an absolute HTTP or HTTPS URL in the prompt.
**Request body**
| Field | Type | Required | Description |
| ------------- | -------- | ----------- | ---------------------------------------------------------------- |
| `prompt` | `string` | Yes | Flow to execute, 1-20,000 characters. |
| `start_url` | `string` | Conditional | Absolute HTTP(S) URL. Required unless the prompt contains a URL. |
| `test_config` | `object` | No | Existing TestConfig to replay instead of recording a new flow. |
# GET Get runner artifact
Source: https://docs.argalabs.com/api-reference/browser-agent-get-artifact
Download an artifact from a runner run
```bash theme={null}
GET /runner/runs/{run_id}/artifacts/{filename}
```
Redirects to a signed artifact URL. Accepts bearer authentication or a `?token=` query token.
# GET Get a runner run
Source: https://docs.argalabs.com/api-reference/browser-agent-get-run
Retrieve a runner run
```bash theme={null}
GET /runner/runs/{run_id}
```
Returns run status, prompt, start URL, TestConfig, event log, artifacts, and summary fields.
# GET List runner runs
Source: https://docs.argalabs.com/api-reference/browser-agent-list-runs
List recent runner runs
```bash theme={null}
GET /runner/runs
```
Returns the 25 most recent runner runs for the authenticated user.
# POST Rerun a runner run
Source: https://docs.argalabs.com/api-reference/browser-agent-rerun
Rerun a browser test from its saved TestConfig
```bash theme={null}
POST /runner/runs/{run_id}/rerun
```
Creates a new Test Run from a previous run's `test_config_json`. The rerun uses the original URL unless you override `start_url`.
**Request body**
| Field | Type | Required | Description |
| ----------- | -------- | -------- | -------------------------- |
| `prompt` | `string` | No | Override the prompt. |
| `start_url` | `string` | No | Override the starting URL. |
# POST Send runner message
Source: https://docs.argalabs.com/api-reference/browser-agent-send-message
Append instructions to a running runner run
```bash theme={null}
POST /runner/runs/{run_id}/messages
```
**Request body**
| Field | Type | Required | Description |
| --------- | -------- | -------- | --------------------------------------- |
| `message` | `string` | Yes | Message to append, 1-10,000 characters. |
# WEBSOCKET Stream runner events
Source: https://docs.argalabs.com/api-reference/browser-agent-stream
Subscribe to run progress events
```bash theme={null}
WEBSOCKET /runner/runs/{run_id}/stream
```
Streams run events for the authenticated user. The server sends JSON event payloads as the runner run progresses.
# PATCH Update runner config
Source: https://docs.argalabs.com/api-reference/browser-agent-update-config
Edit a run's TestConfig
```bash theme={null}
PATCH /runner/runs/{run_id}/config
```
**Request body**
| Field | Type | Required | Description |
| ------------- | -------- | -------- | ----------------------- |
| `test_config` | `object` | Yes | Replacement TestConfig. |
# GET Get PR Test Run config
Source: https://docs.argalabs.com/api-reference/ci-github-config
Read repository test-run settings
```bash theme={null}
GET /validation/github/config
```
**Query parameters**
| Parameter | Type | Required | Description |
| -------------- | -------- | -------- | ----------------------------------- |
| `repo` | `string` | Yes | Repository in `owner/repo` format. |
| `trigger_mode` | `string` | No | `pr` or `branch`. Defaults to `pr`. |
# GET List enabled GitHub CI repos
Source: https://docs.argalabs.com/api-reference/ci-github-enabled
List repositories with CI validation enabled
```bash theme={null}
GET /validation/github/enabled
```
Returns enabled GitHub validation configurations for the authenticated user.
# POST Install PR Test Runs
Source: https://docs.argalabs.com/api-reference/ci-github-install
Register a repository for GitHub-triggered tests
```bash theme={null}
POST /validation/github/install
```
Registers PR Test Runs for a repository. Requires a Team or Paid plan.
**Request body**
| Field | Type | Required | Description |
| ------ | -------- | -------- | ---------------------------------- |
| `repo` | `string` | Yes | Repository in `owner/repo` format. |
# POST Save PR Test Run config
Source: https://docs.argalabs.com/api-reference/ci-github-save-config
Create or update repository test-run settings
```bash theme={null}
POST /validation/github/config
```
**Request body**
| Field | Type | Required | Description |
| --------------------- | --------- | -------- | -------------------------------------------------- |
| `repo` | `string` | Yes | Repository in `owner/repo` format. |
| `trigger_mode` | `string` | Yes | `pr` or `branch`. |
| `branch` | `string` | No | Branch for branch-triggered validation. |
| `custom_instructions` | `string` | No | Extra validation instructions. |
| `comment_on_pr` | `boolean` | No | Whether Arga comments on PRs. Defaults to `true`. |
| `enabled` | `boolean` | No | Whether validation is enabled. Defaults to `true`. |
# GET List CI validation runs
Source: https://docs.argalabs.com/api-reference/ci-list-validation-runs
List GitHub validation runs
```bash theme={null}
GET /validation/runs
```
**Query parameters**
| Parameter | Type | Description |
| --------- | --------- | --------------------------------- |
| `repo` | `string` | Filter by repository. |
| `query` | `string` | Search branch or PR number. |
| `limit` | `integer` | Page size, 1-100. Defaults to 10. |
| `offset` | `integer` | Offset. Defaults to 0. |
# POST Start a PR Test Run
Source: https://docs.argalabs.com/api-reference/ci-start-pr-validation
Legacy endpoint for manually starting a repository run
```bash theme={null}
POST /validation/pr
```
Starts a PR Test Run manually. This endpoint is deprecated; configure GitHub-triggered runs through `/validation/github/*` for new integrations. Requires a Team or Paid plan.
**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 | Frontend URL. Defaults to the server default. |
| `context_notes` | `string` | No | Additional instructions. |
# DELETE Delete a test
Source: https://docs.argalabs.com/api-reference/delete-delete-a-saved-runner-test
Delete a saved browser-agent test
```bash theme={null}
DELETE /runner/tests/{test_id}
```
Deletes a saved test owned by the authenticated user.
**Response**
```json theme={null}
{"status": "deleted"}
```
# DELETE Delete a scenario
Source: https://docs.argalabs.com/api-reference/delete-delete-a-scenario
Delete a saved scenario
```bash theme={null}
DELETE /scenarios/{scenario_id}
```
Deletes a saved scenario owned by the authenticated user.
**Response**
```json theme={null}
{"status": "deleted"}
```
# GET Get validation run artifact
Source: https://docs.argalabs.com/api-reference/get-get-a-run-artifact
Download an artifact from a validation run
```bash theme={null}
GET /validate/{run_id}/artifacts/{filename}
```
Redirects to an artifact URL. Accepts bearer authentication or a `?token=` query token.
# GET Get a test
Source: https://docs.argalabs.com/api-reference/get-get-a-saved-runner-test
Retrieve a saved test
```bash theme={null}
GET /runner/tests/{test_id}
```
Returns the saved test metadata and TestConfig.
# GET Get a scenario
Source: https://docs.argalabs.com/api-reference/get-get-a-scenario
Retrieve one scenario
```bash theme={null}
GET /scenarios/{scenario_id}
```
Returns a saved scenario owned by the authenticated user.
# GET Get validation run details
Source: https://docs.argalabs.com/api-reference/get-get-run-details
Fetch a validation run summary
```bash theme={null}
GET /runs/{run_id}
```
Returns a validation run summary owned by the authenticated user.
# GET Get validation run logs
Source: https://docs.argalabs.com/api-reference/get-get-run-logs
Fetch logs for a validation run
```bash theme={null}
GET /runs/{run_id}/logs
```
Returns worker and runtime logs for a validation run.
**Query parameters**
| Parameter | Type | Description |
| ------------- | --------- | -------------------------------------------------------------- |
| `errors_only` | `boolean` | Return only warning/error runtime logs and failed worker logs. |
# GET Get twin provision status
Source: https://docs.argalabs.com/api-reference/get-get-twin-provision-status
Poll a twin provisioning run
```bash theme={null}
GET /validate/twins/provision/{run_id}/status
```
Returns provisioning status, expiration, twin URLs, env vars, proxy token, and seed results when available.
**Response fields**
| Field | Type | Description |
| ----------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `run_id` | `string` | Provisioning run id. |
| `status` | `string` | `provisioning`, `ready`, `expired`, `cancelled`, `failed`, or another run status. |
| `expires_at` | `string \| null` | UTC cleanup deadline in ISO 8601 format. It is `null` until cleanup is scheduled. Stop calling twin URLs at this time. |
| `twins` | `object` | Map of twin name to connection details. Populated when ready. |
| `twins[name].base_url` | `string` | URL your app should call for that provider. |
| `twins[name].admin_url` | `string` | Private admin URL for state/reset operations. |
| `twins[name].env_vars` | `object` | Suggested env vars and credentials for your app. |
| `proxy_token` | `string \| null` | Token for private proxy access. |
| `seed_results` | `object \| null` | Per-twin seeding results. |
| `is_public` | `boolean` | Whether `base_url` is public. |
After `expires_at`, twin URLs return `410 environment_destroyed`. They do not remain available while cleanup runs.
# GET List available twins
Source: https://docs.argalabs.com/api-reference/get-list-available-twins
List digital twins that can be provisioned
```bash theme={null}
GET /validate/twins
```
Returns the catalog of twin services that can be provisioned.
**Response fields**
| Field | Type | Description |
| ------------ | --------- | -------------------------------------------------- |
| `name` | `string` | Twin identifier to pass to provision requests. |
| `label` | `string` | Human-readable twin name. |
| `kind` | `string` | Twin type from the runtime catalog. |
| `show_in_ui` | `boolean` | Whether the twin has a visible UI surface in Arga. |
**Example**
```bash theme={null}
curl https://api.argalabs.com/validate/twins \
-H "Authorization: Bearer $ARGA_API_KEY"
```
Current catalog entries include `attio`, `box`, `checkhq`, `datadog`, `discord`, `documenso`, `dropbox`, `github`, `gitlab`, `gmail`, `google_calendar`, `google_docs`, `google_drive`, `google_sheets`, `google_workspace`, `hubspot`, `jira`, `linear`, `linkedin`, `notion`, `postgres`, `quickbooks`, `resend`, `salesforce`, `slack`, `stripe`, `trolley`, `unified`, `unstructured`, and `waterfall`.
# GET List preset scenarios
Source: https://docs.argalabs.com/api-reference/get-list-preset-scenarios
List built-in seed scenarios
```bash theme={null}
GET /scenarios/presets
```
Returns built-in scenario presets. This endpoint does not require authentication.
**Query parameters**
| Parameter | Type | Description |
| --------- | -------- | ----------------------------------- |
| `twin` | `string` | Filter presets that include a twin. |
| `tag` | `string` | Filter presets by tag. |
# GET List tests
Source: https://docs.argalabs.com/api-reference/get-list-saved-runner-tests
List saved browser-agent tests
```bash theme={null}
GET /runner/tests
```
**Query parameters**
| Parameter | Type | Description |
| ---------------- | -------- | -------------------------------------- |
| `repo_full_name` | `string` | Filter tests attached to a repository. |
# GET List scenario long runs
Source: https://docs.argalabs.com/api-reference/get-list-scenario-long-runs
List the latest active twin quickstart run for each saved scenario
```bash theme={null}
GET /scenarios/long-runs
```
Returns the most recent non-terminal twin quickstart run associated with each of your saved scenarios. Use this to rehydrate scenario cards with their active twin provisioning state after a reload or relogin, since the response includes the same URLs, lock state, seed results, and error information as [GET Get twin provision status](/api-reference/get-get-twin-provision-status).
Runs whose status is `completed`, `failed`, `cancelled`, or `expired` are excluded. Only one entry is returned per scenario (the most recently created active run).
**Response**
Array of objects with the following fields:
| Field | Type | Description |
| ------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `scenario_id` | `string` | Saved scenario id this run belongs to. |
| `run` | `object` | Twin provision status payload for the active run. Same shape as [GET Get twin provision status](/api-reference/get-get-twin-provision-status), including `run_id`, `status`, `expires_at`, `twins`, `dashboard_url`, `proxy_token`, `error`, `seed_results`, and `is_public`. |
| `updated_at` | `string \| null` | ISO 8601 timestamp of the last run update. |
# GET List scenarios
Source: https://docs.argalabs.com/api-reference/get-list-scenarios
List your saved scenarios
```bash theme={null}
GET /scenarios
```
**Query parameters**
| Parameter | Type | Description |
| ----------------- | --------- | ------------------------------------------------------- |
| `twin` | `string` | Filter scenarios that include a twin. |
| `tag` | `string` | Filter scenarios by tag. |
| `include_presets` | `boolean` | Include preset scenarios before user-created scenarios. |
# GET Stream validation results
Source: https://docs.argalabs.com/api-reference/get-stream-validation-results
Stream validation run events with SSE
```bash theme={null}
GET /validate/{run_id}/results
```
Streams validation results over server-sent events for a run owned by the authenticated user.
# PATCH Toggle GitHub CI config
Source: https://docs.argalabs.com/api-reference/patch-toggle-github-repo-validation
Enable or disable GitHub validation
```bash theme={null}
PATCH /validation/github/config
```
**Request body**
| Field | Type | Required | Description |
| -------------- | --------- | -------- | ---------------------------------- |
| `repo` | `string` | Yes | Repository in `owner/repo` format. |
| `trigger_mode` | `string` | Yes | `pr` or `branch`. |
| `enabled` | `boolean` | Yes | Desired enabled state. |
# PATCH Update a test
Source: https://docs.argalabs.com/api-reference/patch-update-a-saved-runner-test
Update a saved browser-agent test
```bash theme={null}
PATCH /runner/tests/{test_id}
```
Updates any saved-test fields, including `test_config`, `ci_enabled`, credentials, repository, and tags.
# POST Cancel a validation run
Source: https://docs.argalabs.com/api-reference/post-cancel-a-validation-run
Cancel a running validation
```bash theme={null}
POST /validate/{run_id}/cancel
```
Cancels a run owned by the authenticated user.
# POST Create a scenario
Source: https://docs.argalabs.com/api-reference/post-create-a-scenario
Create reusable twin seed data
```bash theme={null}
POST /scenarios
```
Create a scenario from explicit seed JSON or a natural-language prompt.
**Request body**
| Field | Type | Required | Description |
| ------------- | --------------- | ----------- | -------------------------------------------------------------------------------------------- |
| `name` | `string` | Yes | Scenario name. |
| `description` | `string` | No | Optional description. |
| `prompt` | `string` | Conditional | Natural-language description of the desired seed. Required unless `seed_config` is provided. |
| `twins` | `array` | Conditional | Required when providing `seed_config` without `prompt`. |
| `seed_config` | `object` | Conditional | Explicit provider seed config. Required unless `prompt` is provided. |
| `tags` | `array` | No | Scenario tags. |
# POST Extend twin provision TTL
Source: https://docs.argalabs.com/api-reference/post-extend-twin-provision-ttl
Extend an active twin session
```bash theme={null}
POST /validate/twins/provision/{run_id}/extend
```
Reschedules the environment cleanup for an active twin provision so the session stays alive longer. The run must be in `ready`, `provisioning`, or `queued` status.
**Path parameters**
| Field | Type | Description |
| -------- | -------- | ------------------------------------------------------------------- |
| `run_id` | `string` | Provisioning run id returned from `POST /validate/twins/provision`. |
**Request body**
| Field | Type | Required | Description |
| ------------- | --------- | -------- | ---------------------------------------------------- |
| `ttl_minutes` | `integer` | No | New cleanup delay in minutes, 1-480. Defaults to 60. |
**Response**
```json theme={null}
{
"status": "extended",
"ttl_minutes": 60,
"expires_at": "2026-07-30T18:45:00+00:00"
}
```
Use the returned `expires_at` value as the new cleanup deadline.
**Errors**
| Status | Description |
| ------ | -------------------------------------------------------------------------------- |
| `400` | `run_id` is not a valid UUID, or the run is not in a state that can be extended. |
| `404` | No run with that id exists for the authenticated user. |
| `503` | Cleanup could not be rescheduled. The previous expiration still applies. |
# POST Lock twin provision public access
Source: https://docs.argalabs.com/api-reference/post-lock-twin-provision-public-access
Disable public access without teardown
```bash theme={null}
POST /validate/twins/provision/{run_id}/lock
```
Revokes public `pub-` host access for a provisioned twin environment. Private proxy-token access remains available until TTL or teardown. The deployment keeps running until its TTL expires or you call teardown.
**Path parameters**
| Field | Type | Description |
| -------- | -------- | ------------------------------------------------------------------- |
| `run_id` | `string` | Provisioning run id returned from `POST /validate/twins/provision`. |
**Response**
When public access is revoked by this call:
```json theme={null}
{"status": "locked", "run_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "is_public": false}
```
When the provision was already private, the endpoint is a no-op and returns:
```json theme={null}
{"status": "already_locked", "run_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "is_public": false}
```
**Response fields**
| Field | Type | Description |
| ----------- | --------- | ----------------------------------------------------------------------------------------------------------- |
| `status` | `string` | `locked` when this call revoked public access, or `already_locked` when public access was already disabled. |
| `run_id` | `string` | Provisioning run id. |
| `is_public` | `boolean` | Always `false` after a successful response. |
**Errors**
| Status | Description |
| ------ | ------------------------------------------------------ |
| `400` | `run_id` is not a valid UUID. |
| `404` | No run with that id exists for the authenticated user. |
# POST Provision twins
Source: https://docs.argalabs.com/api-reference/post-provision-twins
Spin up ephemeral digital twins
```bash theme={null}
POST /validate/twins/provision
```
Provision ephemeral twin instances without deploying user code. This is the core "twins only" API.
**Request body**
| Field | Type | Required | Description |
| ----------------- | --------------- | -------- | ------------------------------------------------------------------------ |
| `twins` | `array` | Yes | Twin names from the catalog. |
| `ttl_minutes` | `integer` | No | Session TTL, 1-480 minutes. Defaults to 60. |
| `scenario_id` | `string` | No | Scenario UUID or preset id used to seed the twins. |
| `scenario_prompt` | `string` | No | Natural-language seed prompt. Ignored when `scenario_id` is provided. |
| `public` | `boolean` | No | Whether returned base URLs are public drop-in hosts. Defaults to `true`. |
**Response**
```json theme={null}
{
"run_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
```
Poll [Get twin provision status](/api-reference/get-get-twin-provision-status) until `status` is `ready`. Save the returned `expires_at` deadline and stop calling twin URLs when the session expires.
# POST Run a test
Source: https://docs.argalabs.com/api-reference/post-run-a-saved-runner-test
Execute a saved browser-agent test
```bash theme={null}
POST /runner/tests/{test_id}/run
```
**Request body**
| Field | Type | Required | Description |
| ------------- | --------------- | -------- | ------------------------------------------------------------------------------------------- |
| `start_url` | `string` | No | Override the saved start URL. |
| `prompt` | `string` | No | Override the saved prompt. |
| `twins` | `array` | No | Twins recorded in the run event metadata. This route does not provision twins by itself. |
| `ttl_minutes` | `integer` | No | TTL recorded in the run event metadata. This route does not manage twin lifetime by itself. |
| `session_id` | `string` | No | Session id metadata for the run event. |
# POST Save a test
Source: https://docs.argalabs.com/api-reference/post-save-a-runner-test
Create a reusable browser-agent test
```bash theme={null}
POST /runner/tests
```
Create a saved test from a completed run or an explicit TestConfig.
**Request body**
| Field | Type | Required | Description |
| ---------------- | --------------- | ----------- | --------------------------------------------- |
| `name` | `string` | Yes | Test name. |
| `description` | `string` | No | Optional description. |
| `run_id` | `string` | Conditional | Completed run to copy TestConfig from. |
| `prompt` | `string` | Conditional | Required when not deriving from `run_id`. |
| `start_url` | `string` | Conditional | Required when not deriving from `run_id`. |
| `test_config` | `object` | Conditional | Required unless `run_id` has saved blocks. |
| `repo_full_name` | `string` | No | Repository in `owner/repo` format. |
| `ci_enabled` | `boolean` | No | Whether the test is enabled for CI workflows. |
| `credentials` | `object` | No | Encrypted credentials for the test. |
| `tags` | `array` | No | Test tags. |
# POST Tear down twin provision
Source: https://docs.argalabs.com/api-reference/post-tear-down-twin-provision
Destroy a twin session immediately
```bash theme={null}
POST /validate/twins/provision/{run_id}/teardown
```
Cancels the run and queues environment cleanup immediately. The run must be in `ready`, `provisioning`, or `queued` status.
**Path parameters**
| Field | Type | Description |
| -------- | -------- | ------------------------------------------------------------------- |
| `run_id` | `string` | Provisioning run id returned from `POST /validate/twins/provision`. |
**Response**
```json theme={null}
{"status": "cleaning_up", "run_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"}
```
**Errors**
| Status | Description |
| ------ | --------------------------------------------------------------------------------- |
| `400` | `run_id` is not a valid UUID, or the run is not in a state that can be torn down. |
| `404` | No run with that id exists for the authenticated user. |
# PUT Update a scenario
Source: https://docs.argalabs.com/api-reference/put-update-a-scenario
Update reusable twin seed data
```bash theme={null}
PUT /scenarios/{scenario_id}
```
Updates scenario metadata, prompt, twin list, seed config, or tags. If you update `prompt` without `seed_config`, the server regenerates the seed config.
# CLI
Source: https://docs.argalabs.com/cli-and-mcp
Manage Twin Runs, Scenarios, Test Runs, Saved Tests, and PR Test Runs
The `arga` CLI authenticates your machine and gives scripts or coding agents access to the same core workflows as the web app.
## Install
```bash theme={null}
uv tool install arga-cli
arga --help
```
You can also use `pipx install arga-cli` or `pip install arga-cli`.
## Authenticate
```bash theme={null}
arga login
arga whoami
```
`arga login` starts the device authorization flow and stores a device-scoped credential in `~/.config/arga/config.json`. Run `arga logout` to remove and revoke the current device credential.
## Twin Runs
List the available services:
```bash theme={null}
arga previews twins list
```
Provision a short-lived Twin Run and wait until it is ready:
```bash theme={null}
arga twin-runs create \
--twins datadog \
--ttl 60 \
--wait
```
Google Drive, Docs, Sheets, and the grouped Workspace service APIs are separate
twins. Provision only what the app uses, or combine them:
```bash theme={null}
arga twin-runs create --twins google_drive --ttl 60 --wait
arga twin-runs create --twins google_docs --ttl 60 --wait
arga twin-runs create --twins google_sheets --ttl 60 --wait
arga twin-runs create --twins google_workspace --ttl 60 --wait
arga twin-runs create --twins google_drive,google_docs,google_sheets --ttl 60 --wait
```
`google_docs` and `google_sheets` are full twins: each provision exposes its provider-compatible API and an interactive editor UI. When you provision any two or more of `google_drive`, `google_docs`, and `google_sheets` under the same Twin Run ID, they share one run-scoped file state. Creates, edits, renames, permissions, revisions, trash, and deletes stay synchronized across the selected twins. Different Twin Run IDs remain isolated.
`google_workspace` contains People, Workspace Events, Apps Script, Pub/Sub, and
helper task/push-notification APIs. It does not contain Drive, Docs, Sheets,
Gmail, or Calendar.
When you use `gws`, cache each provisioned service's Discovery document. See
[Use the Google Workspace CLI with Arga twins](/features/google-workspace-cli)
for the complete setup.
Seed the twins from a saved Scenario:
```bash theme={null}
arga previews twins provision \
--twins slack,stripe \
--scenario-id \
--ttl 60 \
--wait
```
Manage a running environment:
```bash theme={null}
arga previews twins status
arga previews twins reset
arga previews twins extend --ttl 90
arga previews twins lock
arga previews twins teardown
```
* `reset` restores the baseline captured when the twins were provisioned.
* `extend` changes the requested TTL within your plan limit.
* `lock` revokes public access while preserving authenticated access.
* `teardown` ends the run immediately.
### Configure a local project
Run the wizard from your project directory:
```bash theme={null}
arga wizard
```
The wizard detects supported provider configuration, backs up `.env` to `.env.arga-backup`, provisions selected twins, and replaces provider endpoints or credentials with twin values. Restore the original file with:
```bash theme={null}
cp .env.arga-backup .env
```
## Scenarios
```bash theme={null}
arga test-runner scenarios list --include-presets
arga test-runner scenarios get
arga test-runner scenarios create \
--name "Billing customer" \
--prompt "A Stripe customer with an active annual subscription" \
--twin stripe
arga test-runner scenarios import --file scenario.json
arga test-runner scenarios export --output scenario.json
arga test-runner scenarios update --file scenario.json
arga test-runner scenarios delete
```
Use explicit JSON when an agent or fixture needs exact provider state. Use a prompt for faster exploratory setup.
## Test Runs
Start a browser run against a reachable URL:
```bash theme={null}
arga test-runner runs url \
--url https://staging.example.com \
--prompt "Sign in and verify checkout"
```
For an authenticated application flow, pass `--email` and `--password` together.
Inspect and manage run history:
```bash theme={null}
arga test-runner runs list
arga test-runner runs get
arga test-runner runs logs
arga test-runner runs rerun
arga test-runner runs message "Use test@example.com"
```
## Saved Tests
Create a Saved Test from a Test Run:
```bash theme={null}
arga test-runner tests create \
--name "Checkout" \
--run-id \
--repo owner/repo
```
List, edit, and run saved tests:
```bash theme={null}
arga test-runner tests list --repo owner/repo
arga test-runner tests get
arga test-runner tests edit
arga test-runner tests run --url https://staging.example.com
arga test-runner tests export --output checkout-test.json
arga test-runner tests delete
```
Add `--ci` when creating a test to make it eligible for that repository's PR Test Runs.
### TestConfig JSON
Saved Tests use agent-editable TestConfig JSON. Validate or normalize a file before importing it:
```bash theme={null}
arga test-runner tests config validate --file test-config.json
arga test-runner tests config summarize --file test-config.json
arga test-runner tests config normalize \
--file test-config.json \
--output test-config.json
```
TestConfig assertions are deliberately small and deterministic:
```json theme={null}
{"type":"text","contains":"Order confirmed"}
```
```json theme={null}
{"type":"url","contains":"/checkout/success"}
```
```json theme={null}
{"type":"visible"}
```
## PR Test Runs
Install and configure repository automation:
```bash theme={null}
arga previews pr-checks install owner/repo
arga previews pr-checks config owner/repo --trigger pr
arga previews pr-checks config-set owner/repo \
--trigger pr \
--comments on
arga previews pr-checks enabled
```
For a branch trigger:
```bash theme={null}
arga previews pr-checks config-set owner/repo \
--trigger branch \
--branch main
```
Pause or resume a configuration:
```bash theme={null}
arga previews pr-checks disable owner/repo --trigger pr
arga previews pr-checks enable owner/repo --trigger pr
```
Start a run manually:
```bash theme={null}
arga previews pr-checks run --repo owner/repo --pr 42
```
PR Test Runs use the repository's configured application target. They do not create a per-PR Arga deployment.
## JSON output
Commands that return structured data accept `--json`:
```bash theme={null}
arga previews twins provision --twins slack --wait --json
arga test-runner runs list --json
arga test-runner tests list --json
```
## Git helpers
Create a commit that skips Arga validation for that head commit:
```bash theme={null}
arga commit -m "docs: update examples" --skip
arga push --skip
```
The commit wrapper appends `[skip arga]`. The push wrapper verifies that the current commit already contains it.
## Install MCP
```bash theme={null}
arga mcp install
```
The installer adds the Arga MCP server to supported local coding agents without removing existing MCP entries. See [MCP](/mcp) for the installed files and tool reference.
## Custom API URL
Pass `--api-url` where supported or set `ARGA_API_URL`:
```bash theme={null}
export ARGA_API_URL=http://localhost:8000
arga whoami
```
# Digital twins
Source: https://docs.argalabs.com/concepts/digital-twins
Stateful replicas of external services for safe, repeatable testing
A digital twin is a stateful replica of an external service such as Stripe, Slack, GitHub, Datadog, Dropbox, or Google Workspace. It implements provider-compatible endpoints, state transitions, webhooks, edge cases, and error modes so your software can act without changing production data.
## Why digital twins?
Real integrations evolve. Static mocks don't, so tests drift from production. And when staging hits real Stripe, Slack, or Notion, state leaks across runs and you can't simulate failures, rate limits, or webhook errors. Digital twins solve both problems.
| Approach | Stateful | Behavioural | Edge cases | Safe |
| ------------- | -------- | ----------- | ---------- | ---- |
| Real service | Yes | Yes | Yes | No |
| Static mocks | No | No | No | Yes |
| Digital twins | Yes | Yes | Yes | Yes |
## Properties
The twin remembers state before an API call and updates state after the call completes. If you create a Stripe customer, subsequent calls reflect that customer's existence — just like the real Stripe API.
The twin reacts the same way the real service would to an API call, including error responses, rate limits, and side effects. A payment to a non-existent customer returns the same error code Stripe would.
## Supported services
Arga splits the current twin catalog into two categories:
* **UI twins** expose a browsable surface so you can interact with state directly during a Twin Run. They are useful for services with chats, files, dashboards, checkout pages, or other meaningful interfaces.
* **Backend twins** intercept outbound API traffic only. They have no UI surface because the underlying service is consumed purely programmatically.
For per-twin support details, known limitations, and MCP tool coverage, see the [twin reference](/concepts/twin-reference). The lists below match the twins currently exposed by the app's provisioning catalog.
### UI twins
| Twin | What it stands in for | Notes |
| ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [`datadog`](/concepts/twin-reference#datadog) | Datadog REST APIs, Pup CLI, and monitoring overview | Stateful monitors, dashboards, metrics, logs, events, SLOs, downtime, incidents, Synthetic tests, and notebooks with Datadog auth, errors, and rate limits. |
| [`discord`](/concepts/twin-reference#discord) | Discord API v10 (`discord.com`, `api.discord.com`, `discordapp.com`) | Intercepts Discord API v10 operations including guilds, channels, messages, reactions, threads, members, roles, bans, invites, webhooks, emojis, stickers, scheduled events, stage instances, auto-moderation rules, soundboard sounds, guild templates, and user endpoints. The Create Message endpoint (`POST /channels/{channel_id}/messages`) accepts `multipart/form-data` requests with file attachments — uploaded files are recorded as attachment objects on the message with `id`, `filename`, `size`, `url`, `proxy_url`, and `content_type` fields, matching the real Discord API response shape. You can send message content via a `payload_json` field or a plain `content` form field alongside one or more `files[n]` (or `file`) parts. Supports deterministic seeding, bot-token authentication, configurable [server boost levels](/concepts/digital-twins#discord-twin-boost-levels) (controlling file upload size and emoji slot limits), and event delivery with webhook subscriptions. |
| [`dropbox`](/concepts/twin-reference#dropbox) | Dropbox API v2 (`api.dropboxapi.com`, `content.dropboxapi.com`, `notify.dropboxapi.com`) | Intercepts Dropbox API v2 operations including files (list, upload, download, copy, move, delete, search, revisions, tags), sharing (shared links, shared folders, file members), file requests, file properties, team management (members, groups, team folders, legal holds, namespaces, devices, linked apps, sharing allowlist, audit log), and admin controls. Supports upload sessions, batch operations, webhook deliveries, and event replay. Seeded with a starter folder tree and team members for deterministic testing. Enforces [account tier-based storage quotas](/concepts/digital-twins#dropbox-twin-account-tiers) — uploads that exceed the quota return an `insufficient_space` error. |
| [`github`](/concepts/twin-reference#github) | GitHub API (`api.github.com`, `github.com`, `raw.githubusercontent.com`), GitHub CLI (`gh`), and [GitHub MCP server](https://github.com/github/github-mcp-server) | Intercepts GitHub REST API operations including repositories, file contents (branch-aware), raw file downloads from `raw.githubusercontent.com/{owner}/{repo}/{ref}/{path}` and `github.com/{owner}/{repo}/raw/{ref}/{path}` (served as public content without a bearer token and resolving slash-containing branch names), pull requests (with merge and reviewer requests), issues, branches (with protection rules), commits, check runs, check suites, git references, labels (repo-level and issue-level), pull request reviews and review comments, commit statuses, search (repositories, users, issues, code), organizations, users, GitHub App endpoints (installations, access tokens, repository listings, app metadata, and the manifest registration flow for creating multiple GitHub Apps at runtime), and webhooks. Adds GitHub CLI (`gh`) and GitHub MCP server compatibility: the GitHub Enterprise-style `/api/v3/...` REST prefix and the `/api/graphql` endpoint are accepted alongside the standard paths, with extended REST coverage for `/meta`, `/rate_limit`, `/zen`, repository archives, releases, gists, notifications, projects v2, Actions workflows, runs, jobs, artifacts, cache, variables, and secrets, codespaces, user SSH/signing/GPG keys, starred repositories, sub-issues and issue types, security advisories, Dependabot alerts, and code- and secret-scanning alerts. Exposes a GraphQL surface at `POST /graphql` (also reachable through `POST /api/graphql`) covering the queries and mutations used by `gh` and the GitHub MCP server, backed by the same store as the REST handlers. Supports deterministic seeding (repos, files, issues, PRs, and GitHub App configuration), multi-app installations scoped to their owning GitHub App, token authentication with OAuth scope enforcement (parent scopes automatically grant children), configurable default token scopes, OAuth flows, and webhook delivery with signed payloads for push, pull request, check run, and check suite events. |
| [`google_calendar`](/concepts/twin-reference#google-calendar) | Google Calendar API (`www.googleapis.com`, `calendar.googleapis.com`) | Intercepts Google Calendar v3 operations including calendars, calendar list, events, ACL rules, settings, free/busy queries, colors, and webhook deliveries (with watch support for events, ACL, calendar list, and settings resources). |
| [`google_docs`](/concepts/twin-reference#google-docs) | Google Docs v1 (`docs.googleapis.com`) and document editor UI | Documents, UTF-16 indexed content, named ranges, text and paragraph styling, atomic batch updates, document creation, rich-text editing, sharing, and export. |
| [`google_drive`](/concepts/twin-reference#google-drive) | Google Drive v3 (`www.googleapis.com`, `content.googleapis.com`) | Drive files, permissions, revisions, comments, changes, uploads, and preset metadata for matching Docs and Sheets resources. The full Docs and Sheets twins are provisioned separately; when selected under the same Twin Run ID, they share synchronized, run-scoped file state with Drive. |
| [`google_sheets`](/concepts/twin-reference#google-sheets) | Google Sheets v4 (`sheets.googleapis.com`) and spreadsheet editor UI | Spreadsheets, A1 values, batch updates, formulas, formatting, developer metadata, grid editing, sharing, and export. |
| [`notion`](/concepts/twin-reference#notion) | Notion API (`api.notion.com`, `notion.so`) | Intercepts Notion API operations for pages, databases, blocks, users, and search. Enforces [workspace plan-based limits](/concepts/digital-twins#notion-twin-workspace-plans) on file uploads and guest counts. Supports capability-based access control on user endpoints with granular email visibility (`read_user_information_with_email`, `read_user_information_no_email`, `no_user_information`). |
| [`slack`](/concepts/twin-reference#slack) | Slack Web API, Slack CLI, Slack MCP, and OAuth | Intercepts Slack Web API operations including channels, messages (including `chat.scheduleMessage`, `chat.scheduledMessages.list`, and `chat.deleteScheduledMessage`), users (including `users.lookupByEmail`), conversations, reactions (including `reactions.get`), pins (`pins.list`), bookmarks (`bookmarks.list`), do-not-disturb (`dnd.info`), modal views (`views.open`, `views.update`), and files (upload, external upload, info, list, delete). `chat.postMessage` accepts Block Kit `blocks` payloads even when fallback `text` is blank or whitespace, matching real Slack — `no_text` is only returned when both `text` and `blocks` are empty. Submitted `blocks` are stored and echoed back from `conversations.history` and `conversations.replies`. Auth methods include `api.test`, `auth.test`, `auth.revoke`, and `auth.teams.list`. Supports `conversations.open` for opening or creating direct-message channels. Completing an external file upload via `files.completeUploadExternal` automatically creates a channel message with the uploaded files attached (including a `file_share` subtype event), matching real Slack behavior. File uploads enforce tier-based size limits (see [tier limits](#slack-twin-tier-limits) below) — all tiers default to a 1 GB cap, and you can switch tiers via the admin API to test tier-specific behavior. The twin also supports [workspace-level constraints](#slack-twin-workspace-constraints) for disabling file uploads entirely, enforcing storage quotas, and simulating rate limits. Uploaded files are downloadable from `/files/{file_id}`. Preserves the `Authorization` header so you can test token-scoped behavior, including `xoxe.`-prefixed enterprise tokens. Enforces OAuth scope requirements on every authenticated API call — tokens missing the required scope for a method receive a `missing_scope` error (see [configurable token scopes](#slack-twin-configurable-token-scopes)). Supports the OAuth 2.0 authorization code grant flow (`/oauth/v2/authorize` and `/api/oauth.v2.access`), allowing you to test Slack "Add to Slack" install flows end-to-end without touching the real Slack OAuth servers. Bot and user token scopes are [configurable](#slack-twin-configurable-token-scopes) via scenario seeding. Also exposes the Slack CLI app-management surface (manifest validate/create/update/export, app status, developer install/uninstall, app delete, connections, hosted package upload placeholders, and hosted environment variables) plus secondary CLI families (activities, auth tickets and token rotation, app approvals, external auth, datastores, workflow triggers, function permissions, collaborators, icons, certified installs, and developer sandboxes) — point the Slack CLI at the twin by setting `SLACK_API_URL` to the twin's `/api/` base. A Slack MCP Streamable HTTP endpoint is available at `/mcp` (JSON-RPC 2.0 `initialize`, `tools/list`, `tools/call`) with OAuth protected resource metadata at `/.well-known/oauth-protected-resource/mcp` and authorization server metadata at `/.well-known/oauth-authorization-server`; the MCP tool surface (`slack_search_messages`, `slack_search_messages_and_files`, `slack_send_message`, `slack_read_channel`, `slack_list_channels`, `slack_list_users`, `slack_create_canvas`, and related Slack-shaped tools) shares state with the Web API surface. |
| [`stripe`](/concepts/twin-reference#stripe) | Stripe API (`api.stripe.com`, `files.stripe.com`, `connect.stripe.com`) | Intercepts Stripe API v1 operations including customers, payment methods, payment intents, setup intents, charges, refunds, disputes, subscriptions, invoices, invoice items, credit notes, products, prices, plans, coupons, promotion codes, tax rates, shipping rates, tokens, sources, payouts, balance, balance transactions, billing meters, meter events, meter event summaries, events, files, file links, checkout sessions, payment links, quotes, billing portal sessions, subscription items, subscription schedules, usage records, customer balance transactions, tax IDs, webhook endpoints, mandates, and test clocks. Supports idempotency keys, Stripe-compatible webhook delivery with signed payloads, test card numbers for simulating declines and 3D Secure flows, and browser-facing pages for checkout, a multi-page dashboard (home, payments, subscriptions, invoices, balances), product catalog, and customer management. |
### Backend twins
| Twin | What it stands in for | Notes |
| --------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`box`](/concepts/twin-reference#box) | Box API (`api.box.com`, `upload.box.com`, `app.box.com`) | Intercepts Box v2.0 operations including files, folders, users, search, events, and webhooks. Supports deterministic seeding and OAuth flows. |
| [`google_workspace`](/concepts/twin-reference#google-workspace) | Google Workspace service APIs | People, Workspace Events, Apps Script, Pub/Sub, and helper task/push-notification routes. Does not include Drive, Sheets, Gmail, or Calendar. |
| [`linear`](/concepts/twin-reference#linear) | Linear GraphQL API (`api.linear.app`, `linear.app`) | Intercepts the Linear GraphQL endpoint (`POST /graphql`) covering queries and mutations for teams, projects, cycles, issues, labels, comments, workflow states, users, organization, and webhooks. Authenticates personal API keys (raw value in `Authorization`, no `Bearer` prefix) and OAuth 2.0 tokens (`Authorization: Bearer `) issued by `/oauth/authorize`, `/oauth/token`, and `/oauth/revoke`. Maintains `@linear/sdk` wire compatibility: returns `__typename` on every entity, emits relations as `{ id }` in default selections, and surfaces error envelopes whose `extensions.type` matches the lowercase strings the SDK dispatches on (`"authentication error"`, `"invalid input"`, `"ratelimited"`, `"feature not accessible"`). Webhook deliveries include `Linear-Signature` (lowercase-hex HMAC-SHA256), `Linear-Delivery`, `Linear-Event`, and `Linear-Timestamp` headers, with manual flush and replay through `/admin/webhook-events`. |
| [`salesforce`](/concepts/twin-reference#salesforce) | Salesforce Platform REST API (`*.salesforce.com`, `*.force.com`, `*.my.salesforce.com`, `login.salesforce.com`, `test.salesforce.com`) | Intercepts Salesforce REST API operations under `/services/data/v{version}/` including REST discovery (`/services/data`, `/limits`, `/limits/recordCount`), sObject CRUD for Accounts, Contacts, Cases, EmailTemplates, EmailMessages, Users, and related standard objects (`GET`, `POST`, `PATCH`, `DELETE` by ID, plus `describe`, `describe/layouts`, `describe/compactLayouts`, `listviews`, relationship traversal, and updated/deleted feeds), SOQL (`/query`, `/queryAll`, `/query/{locator}`), SOSL (`/search`, `/parameterizedSearch`, `/search/scopeOrder`, `/search/layout`), composite requests (`/composite`, `/composite/batch`, `/composite/graph`, `/composite/tree/{sobject}`), Bulk API v2 job shells (`/jobs/query`, `/jobs/ingest`), invocable actions (`/actions`, `/actions/standard`, `/actions/custom`) for support-style case creation and sending email from templates, and a Tooling API surface for sobjects, queries, and basic discovery. Supports OAuth 2.0 token exchange (`/services/oauth2/token`, `/oauth2/token`), `userinfo`, identity URLs (`/id/{org_id}/{user_id}`), and bearer-token authentication. Admin endpoints (`POST /admin/reset`, `GET /admin/state`, `POST /admin/clock`) provide deterministic seeding and clock control. State starts empty by default — seed accounts, contacts, cases, and templates through scenario seeding or API calls. |
| [`jira`](/concepts/twin-reference#jira) | Jira Cloud REST API v3 (`*.atlassian.net`) | Intercepts Jira Cloud REST API v3 operations including issues (create, get, update, delete, bulk create, transitions, changelog, edit metadata), projects, comments, worklogs, attachments, issue links, issue properties, votes, watchers, search and JQL search (`/rest/api/3/search`, `/rest/api/3/search/jql`, `/rest/api/3/search/count`), users (`myself`, search, bulk, assignable, view-issue), components, versions, remote links, filters, dashboards, groups (and group members), fields, priorities, resolutions, statuses, status categories, issue types, server info, attachments metadata, and webhooks (`/rest/api/3/webhook`). Includes Agile (Jira Software) endpoints under `/rest/agile/1.0/` for boards, sprints, board sprints, and backlog issue moves. Routes are also reachable via the `/rest/api/2/` and `/rest/api/latest/` aliases. Comments and descriptions are stored as [Atlassian Document Format (ADF)](https://developer.atlassian.com/cloud/jira/platform/apis/document/structure/) — plain strings sent on input are auto-wrapped in a minimal ADF document. Supports the OAuth 2.0 authorization code grant flow with token issuance, [scope enforcement](#authentication-handling), JQL search, deterministic seeding, and webhook delivery with HMAC-signed payloads. |
| [`waterfall`](/concepts/twin-reference#waterfall) | Waterfall API (`api.waterfall.io`) | Intercepts Waterfall API operations for company search, people search, enrichment, verification, and account endpoints. Starts empty by default and uses a UUID-shaped API key for local and twin-backed testing. |
| [`unified`](/concepts/twin-reference#unified) | Unified API (`api.unified.to`) | Use this only when your app talks to Unified.to rather than directly to an upstream provider. Seeds integration connections that proxy to Slack, Google Mail, Google Drive, Google Calendar, Box, Notion, and Dropbox. For actual provider data (channels, files, pages, repos, etc.), use the provider-specific twin instead. |
| [`unstructured`](/concepts/twin-reference#unstructured) | Unstructured API (`api.unstructuredapp.io`, `platform.unstructuredapp.io`) | Intercepts Unstructured API operations including document partitioning, workflow management, source and destination CRUD, and job execution. Supports deterministic seeding and API key authentication. |
Twins and integrations serve different roles:
* Use [integrations](/integrations) to copy selected production data into a Scenario.
* Use digital twins as the provider endpoints your app or agent acts on during a test.
If you rely on a service not yet supported, [book a demo](https://cal.com/akiratong/30min?overlayCalendar=true) and we'll discuss building a twin for your stack.
## Stub alerting
Not every endpoint in a digital twin has a full stateful implementation. Endpoints that are not yet statefully implemented return **stub responses** — schema-valid mock data generated from the service's API specification. Stub responses are clearly marked so you can distinguish them from real stateful behavior:
* **`X-Twin-Stub` header** — set to `"true"` on every stub response.
* **`_twin_stub` field** — a boolean (`true`) injected into the JSON response body.
* **`_twin_warning` field** — a human-readable string explaining which endpoint is stubbed.
When the response would normally be a JSON array, it is wrapped in an object with `_twin_stub`, `_twin_warning`, and a `data` key containing the original array.
```json theme={null}
{
"_twin_stub": true,
"_twin_warning": "This endpoint (GET /repos/{owner}/{repo}/topics) is stubbed and returns mock data. Do not rely on this response in production tests.",
"data": []
}
```
You can use the `X-Twin-Stub` header to programmatically detect stub responses in your test suite and fail tests that rely on stubbed data.
### Tracking stub hits
The GitHub twin exposes an admin endpoint to audit which stubbed endpoints were called during a session:
```bash theme={null}
GET /admin/stub-hits
```
**Response**
```json theme={null}
{
"total_hits": 5,
"unique_endpoints": 2,
"summary": [
{"endpoint": "GET /repos/{owner}/{repo}/topics", "hits": 3},
{"endpoint": "GET /repos/{owner}/{repo}/languages", "hits": 2}
],
"recent": [
{
"method": "GET",
"path_template": "/repos/{owner}/{repo}/topics",
"actual_path": "/repos/acme/web-app/topics",
"timestamp": "2026-03-21T12:00:00Z"
}
]
}
```
| Field | Type | Description |
| -------------------- | --------- | ---------------------------------------------------------------------------- |
| `total_hits` | `integer` | Total number of stub endpoint calls since the last clear. |
| `unique_endpoints` | `integer` | Number of distinct stubbed endpoints called. |
| `summary` | `array` | Deduplicated list of endpoints with hit counts, sorted by most-called first. |
| `summary[].endpoint` | `string` | HTTP method and path template of the stubbed endpoint. |
| `summary[].hits` | `integer` | Number of times this endpoint was called. |
| `recent` | `array` | The 20 most recent stub hits with full details. |
To clear the stub hit log:
```bash theme={null}
POST /admin/stub-hits/clear
```
Returns `{"ok": true}` on success.
## How Arga uses digital twins
Start a Twin Run, copy its provider URLs or environment variables into your app, and run the software from your own local, staging, or preview environment. This gives you:
1. **No real side effects** — Sending a Slack notification or creating a Stripe charge changes only twin state.
2. **Repeatable starting state** — Seed or reset the twins from the same Scenario before each attempt.
3. **Edge-case coverage** — Twins can simulate failures, rate limits, permissions, quotas, and webhook behavior that are hard to trigger against real services.
## Authentication handling
When requests are routed through a digital twin, Arga controls which headers are forwarded to the twin.
For most twins, the `Authorization` header is stripped from proxied requests because the twin doesn't need real credentials — it simulates the service regardless of auth tokens.
The **Slack twin** is an exception. Slack API calls include the `Authorization` header when forwarded to the twin, allowing the twin to validate token-scoped behaviour such as bot-token versus user-token permission differences. This lets tests exercise the same authentication paths your code uses in production without touching the real Slack API.
The Slack twin enforces **OAuth scope requirements** on every authenticated API call. Each Slack Web API method requires a specific scope (for example, `chat.postMessage` requires `chat:write`, `conversations.list` requires `channels:read`). If a token does not include the required scope, the twin returns a `missing_scope` error — matching real Slack behaviour:
```json theme={null}
{
"ok": false,
"error": "missing_scope",
"needed": "chat:write",
"provided": "channels:read,channels:history"
}
```
Tokens with the wildcard scope `*` bypass scope checks and are accepted for any method. You can selectively disable scopes using the `disabled_scopes` config field — any scope in the disabled list is removed from the effective scope set before enforcement, even if the token originally had it.
The Slack twin also supports the full **OAuth 2.0 authorization code grant** flow. When `SLACK_TWIN_BASE_URL` is set, Arga routes OAuth requests (`/oauth/v2/authorize` and `/api/oauth.v2.access`) through the twin so you can test "Add to Slack" install flows, token exchange, and scope negotiation without the real Slack OAuth servers. Issued tokens (`xoxb-` for bots, `xoxp-` for users, and `xoxe.`-prefixed enterprise tokens) are fully functional within the twin and can be used for subsequent API calls like `auth.test` and `search.messages`. The scopes granted to tokens issued via the OAuth flow are determined by the twin's configurable `oauth_bot_scopes` and `oauth_user_scopes` settings (see [configurable token scopes](#slack-twin-configurable-token-scopes) below).
The **GitHub twin** preserves the `Authorization` header and enforces **OAuth scope requirements** on API calls. Each API route requires a specific scope (for example, `POST /repos/{owner}/{repo}/issues` requires `repo`, `GET /user` requires `read:user`). Parent scopes automatically grant their children — `repo` implies `repo:status`, `repo_deployment`, `repo:invite`, `public_repo`, and `security_events`; `admin:repo_hook` implies `write:repo_hook` and `read:repo_hook`; and so on. If a token does not include a required scope, the twin returns a 403 matching GitHub's real API response shape:
```json theme={null}
{
"message": "Resource not accessible by personal access token",
"documentation_url": "https://docs.github.com/rest"
}
```
You can configure the default token scopes via the `default_token_scopes` config field. Scopes can also be selectively disabled using the `disabled_scopes` config field — any scope in the disabled list is removed from the effective scope set, even if the token originally had it.
The **Google Drive twin** also enforces **OAuth scope requirements** on every API call. Each Drive API operation requires at least one of a set of accepted scopes (for example, `files.create` requires `drive` or `drive.file` or `drive.appdata`). Parent scopes automatically grant their children — `drive` implies `drive.readonly`, `drive.file`, `drive.appdata`, `drive.metadata`, and `drive.scripts`. If a token lacks any accepted scope for an operation, the twin returns a `403 insufficientPermissions` error matching the real Google Drive API. You can selectively disable scopes using the `disabled_scopes` config field.
The **Notion twin** enforces **capability-based access** on user info endpoints. The twin recognizes three user-information capability levels: `read_user_information_with_email` (full access including email), `read_user_information_no_email` (user info without email), and `no_user_information` (no access). The legacy `read_user_information` capability is treated as equivalent to `read_user_information_with_email`. If a token has no user info capability, user endpoints (`/v1/users`, `/v1/users/me`, `/v1/users/{user_id}`) return a `403 restricted_resource` error. You can selectively disable capabilities using the `disabled_capabilities` config field.
The **Stripe twin** also preserves the `Authorization` header. The twin validates that API keys use a recognized prefix (`sk_test_`, `sk_live_`, `rk_test_`, or `rk_live_`) and returns Stripe-compatible authentication errors for missing or invalid keys. This lets your code exercise its normal Stripe authentication logic against the twin.
The **Jira twin** preserves the `Authorization` header and requires every non-public request to use a `Bearer` token. Requests missing or with a malformed `Authorization` header receive a `401` matching Jira's real API response shape:
```json theme={null}
{
"errorMessages": ["Client must be authenticated to access this resource."],
"errors": {}
}
```
The twin enforces **OAuth 2.0 scope requirements** on every API call. Each route requires a specific scope — for example, `POST /rest/api/3/issue` requires `write:jira-work`, `GET /rest/api/3/myself` requires `read:jira-user`, and `POST /rest/api/3/component` requires `manage:jira-project`. Parent scopes automatically grant their children: `write:jira-work` implies `read:jira-work`, `manage:jira-project` implies `read:jira-work`, and `manage:jira-configuration` implies `read:jira-work` and `manage:jira-project`. Tokens that lack a required scope receive a `403` with a missing-scope message:
```json theme={null}
{
"errorMessages": ["The user does not have permission. Missing scope: write:jira-work"],
"errors": {}
}
```
The default token scopes are `read:jira-work`, `write:jira-work`, `read:jira-user`, `manage:jira-project`, `manage:jira-webhook`, and `manage:jira-configuration`. Configure these via the `default_token_scopes` config field, or selectively remove scopes via `disabled_scopes` — any scope in the disabled list is removed from the effective scope set even if a token would otherwise grant it. Tokens issued through the OAuth 2.0 flow (`/authorize` and `/oauth/token`) carry the scopes negotiated during authorization.
## Slack twin tier limits
The Slack twin enforces tier-based file upload size limits, letting you test how your application handles free-tier restrictions and paid-tier upgrades. The twin also supports tier-dependent workspace constraints: message history limits, app install limits, and workflow availability.
| Tier | Default max file size | Message history | Workflows |
| --------------- | --------------------- | --------------- | --------- |
| `free` | 1 GB | 90 days | Disabled |
| `pro` | 1 GB | Unlimited | Enabled |
| `business_plus` | 1 GB | Unlimited | Enabled |
| `enterprise` | 1 GB | Unlimited | Enabled |
| `paid` | 1 GB | Unlimited | Enabled |
When a file upload exceeds the current tier's limit, the twin returns a `file_too_large` error with details about the active tier and cap:
```json theme={null}
{
"ok": false,
"error": "file_too_large",
"tier": "free",
"max_file_bytes": 1073741824,
"attempted_bytes": 2048
}
```
This error is returned both when calling `files.getUploadURLExternal` with a `length` that exceeds the cap, and when uploading file content that exceeds the cap during the external upload step.
### Switching tiers
Use the admin API to switch between tiers:
```bash theme={null}
# Get current tier
GET /admin/tier
```
**Response**
```json theme={null}
{
"tier": "free",
"max_file_bytes": 1073741824,
"free_max_file_bytes": 1073741824,
"paid_max_file_bytes": 1073741824
}
```
```bash theme={null}
# Switch tier
POST /admin/tier
Content-Type: application/json
{"tier": "paid"}
```
**Response**
```json theme={null}
{
"ok": true,
"tier": "paid",
"max_file_bytes": 1073741824
}
```
| Field | Type | Description |
| --------------------- | --------- | ----------------------------------------------------------------------------------------------------------- |
| `tier` | `string` | Current tier: `"free"`, `"pro"`, `"business_plus"`, `"enterprise"`, or `"paid"`. |
| `max_file_bytes` | `integer` | Maximum file size in bytes for the active tier. |
| `free_max_file_bytes` | `integer` | Maximum file size in bytes for the free tier. |
| `paid_max_file_bytes` | `integer` | Maximum file size in bytes for the paid tier (applies to `pro`, `business_plus`, `enterprise`, and `paid`). |
## Slack twin workspace constraints
The Slack twin supports workspace-level settings that let you simulate how your application handles disabled file uploads, storage quota limits, and rate limiting. Configure these via [scenario seeding](/features/custom-scenarios#slack-workspace-constraints) or the [admin API](#patch-config-preserve-state).
### File upload toggle
Set `file_uploads_enabled` to `false` to simulate a workspace where an admin has disabled file uploads. Any call to `files.getUploadURLExternal` returns a `file_uploads_disabled` error:
```json theme={null}
{
"ok": false,
"error": "file_uploads_disabled"
}
```
File uploads are enabled by default.
### Storage quotas
Set `max_storage_bytes` to enforce a workspace-level storage quota. The twin tracks total storage usage (the sum of `storage_used_bytes` and all uploaded file content) and rejects new uploads when the quota would be exceeded. A call to `files.getUploadURLExternal` with a `length` that would push usage over the quota returns a `storage_limit_reached` error:
```json theme={null}
{
"ok": false,
"error": "storage_limit_reached"
}
```
| Field | Type | Default | Description |
| -------------------- | ----------------- | ----------------- | ----------------------------------------------------------------------------------------------------------------- |
| `max_storage_bytes` | `integer \| null` | `null` (no limit) | Maximum total storage in bytes for the workspace. Set to `null` to disable the quota. |
| `storage_used_bytes` | `integer` | `0` | Pre-existing storage usage in bytes. Use this to simulate a nearly-full workspace without uploading actual files. |
For example, setting `max_storage_bytes` to `500` and `storage_used_bytes` to `400` means only 100 bytes of new uploads are allowed before the quota is reached.
### Rate limiting
Set `rate_limiting_enabled` to `true` and provide a `rate_limits` map to simulate per-method rate limiting. When a method exceeds its configured request limit within the time window, the twin returns a `ratelimited` error:
```json theme={null}
{
"ok": false,
"error": "ratelimited"
}
```
| Field | Type | Default | Description |
| ------------------------------------------ | --------- | ------- | ------------------------------------------------------------- |
| `rate_limiting_enabled` | `boolean` | `false` | Whether rate limiting is active. |
| `rate_limits` | `object` | `{}` | Map of method names to rate limit rules. |
| `rate_limits..window_seconds` | `integer` | — | Time window in seconds for the rate limit. |
| `rate_limits..max_requests` | `integer` | — | Maximum number of requests allowed within the window. |
| `rate_limits..retry_after_seconds` | `integer` | — | Value returned in the `Retry-After` header when rate limited. |
## Slack twin configurable token scopes
You can customize the OAuth scopes granted to bot and user tokens in the Slack twin. This lets you test how your application handles missing permissions — for example, verifying that your app gracefully handles a `missing_scope` error when a required scope is not granted.
Bot tokens always receive `chat:write` and `files:write` as minimum scopes, even if your seed configuration specifies a narrower set. The twin automatically adds these scopes to any bot token that lacks them. This ensures that bots can always send messages and upload files. To test `missing_scope` errors for `chat:write` or `files:write`, use a **user** token instead.
### Default scopes
The twin ships with these default scopes:
| Token type | Default scopes |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Bot (`oauth_bot_scopes`) | `channels:history`, `channels:manage`, `channels:read`, `chat:write`, `bookmarks:read`, `commands`, `dnd:read`, `files:read`, `files:write`, `pins:read`, `reactions:read`, `reactions:write`, `search:read`, `team:read`, `users:read`, `users:read.email` |
| User (`oauth_user_scopes`) | `search:read`, `channels:read`, `channels:history`, `groups:history`, `im:history` |
### Configuring scopes via scenario seeding
Pass `oauth_bot_scopes`, `oauth_user_scopes`, or `tokens` in the Slack twin's seed configuration to override the defaults:
```json theme={null}
{
"slack": {
"channels": [{"name": "general"}],
"oauth_bot_scopes": ["chat:write", "channels:read"],
"oauth_user_scopes": ["search:read", "channels:read", "channels:history"],
"tokens": [
{
"token": "xoxb-custom-token",
"user_id": "UTWINBOT",
"scopes": ["chat:write", "channels:read", "files:write"],
"is_bot": true
}
]
}
}
```
| Field | Type | Description |
| ------------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `oauth_bot_scopes` | `array of string` | Scopes granted to bot tokens issued via the OAuth flow. Overrides the default bot scope list. |
| `oauth_user_scopes` | `array of string` | Scopes granted to user tokens issued via the OAuth flow. Overrides the default user scope list. |
| `tokens` | `array of object` | Explicit token records to register in the twin. Each token has a `token` string, `user_id`, `scopes` array, and `is_bot` boolean. Use this to create tokens with specific scope combinations for testing permission edge cases. Bot tokens always receive `chat:write` and `files:write` as minimum scopes regardless of the scopes you specify. |
When you configure a narrower set of scopes, any API call requiring a scope not in the list returns the `missing_scope` error described in [authentication handling](#authentication-handling). Note that bot tokens always retain `chat:write` and `files:write` even when you specify a narrower scope list — see the note above.
### Scope requirements by API method
The Slack twin enforces the following scope requirements:
| API method | Required scope |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------- |
| `chat.postMessage`, `chat.postEphemeral`, `chat.update`, `chat.delete`, `chat.meMessage`, `chat.scheduleMessage`, `chat.scheduledMessages.list`, `chat.deleteScheduledMessage` | `chat:write` |
| `conversations.create`, `conversations.invite`, `conversations.kick`, `conversations.archive`, `conversations.unarchive`, `conversations.rename`, `conversations.setPurpose`, `conversations.setTopic`, `conversations.leave`, `conversations.open`, `conversations.close`, `conversations.mark` | `channels:manage` |
| `conversations.join` | `channels:join` |
| `conversations.list`, `conversations.info`, `conversations.members` | `channels:read` |
| `conversations.history`, `conversations.replies` | `channels:history` |
| `files.upload`, `files.getUploadURLExternal`, `files.completeUploadExternal`, `files.delete`, `files.sharedPublicURL`, `files.revokePublicURL` | `files:write` |
| `files.info`, `files.list` | `files:read` |
| `reactions.add`, `reactions.remove` | `reactions:write` |
| `reactions.get`, `reactions.list` | `reactions:read` |
| `search.messages`, `search.files`, `search.all` | `search:read` |
| `users.info`, `users.list`, `users.identity`, `users.getPresence` | `users:read` |
| `users.setPresence`, `users.profile.set` | `users:write` |
| `users.profile.get` | `users.profile:read` |
| `users.lookupByEmail` | `users:read.email` |
| `team.info` | `team:read` |
| `team.accessLogs` | `admin` |
| `pins.add`, `pins.remove` | `pins:write` |
| `pins.list` | `pins:read` |
| `bookmarks.add`, `bookmarks.edit`, `bookmarks.remove` | `bookmarks:write` |
| `bookmarks.list` | `bookmarks:read` |
| `reminders.add`, `reminders.complete`, `reminders.delete` | `reminders:write` |
| `reminders.info`, `reminders.list` | `reminders:read` |
| `usergroups.create`, `usergroups.disable`, `usergroups.enable`, `usergroups.update`, `usergroups.users.update` | `usergroups:write` |
| `usergroups.list`, `usergroups.users.list` | `usergroups:read` |
| `dnd.setSnooze`, `dnd.endSnooze`, `dnd.endDnd` | `dnd:write` |
| `dnd.info`, `dnd.teamInfo` | `dnd:read` |
| `emoji.list` | `emoji:read` |
| `canvases.create`, `canvases.edit`, `conversations.canvases.create` | `canvases:write` |
| `views.open`, `views.publish`, `views.push`, `views.update` | `commands` |
| `groups.create`, `groups.invite` | `groups:write` / `groups:write.invites` |
| `groups.history`, `groups.replies` | `groups:history` |
| `groups.list`, `groups.info` | `groups:read` |
| `im.open`, `im.close`, `im.mark` | `im:write` |
| `im.history`, `im.replies` | `im:history` |
| `im.list` | `im:read` |
| `mpim.open`, `mpim.close`, `mpim.mark` | `mpim:write` |
| `mpim.history`, `mpim.replies` | `mpim:history` |
| `mpim.list` | `mpim:read` |
Methods not listed (such as `api.test` and `auth.test`) do not require a specific scope.
## Slack twin admin endpoints
The Slack twin exposes admin endpoints for inspecting and managing twin state during a session.
### Get config
```bash theme={null}
GET /admin/config
```
Returns the current twin configuration, including token registrations, scope settings, tier, and seed data.
**Response**
```json theme={null}
{
"seed": 1,
"team_id": "TTWIN0001",
"team_name": "Default Workspace",
"team_domain": "slack-twin",
"tier": "free",
"tokens": [
{
"token": "xoxb-F9SXMECOSFOGYR3XKXWN",
"user_id": "UTWINBOT",
"scopes": ["channels:history", "channels:manage", "channels:read", "chat:write", "files:read", "files:write", "reactions:write", "search:read", "team:read", "users:read"],
"is_bot": true
}
],
"channels": [],
"users": [
{"id": "UTWINBOT", "name": "slack-twin-bot", "real_name": "Slack Twin Bot", "is_bot": true},
{"id": "UTWINUSR", "name": "slack-twin-user", "real_name": "Slack Twin User", "is_bot": false}
]
}
```
### Replace config (full reset)
```bash theme={null}
PUT /admin/config
Content-Type: application/json
```
Replace the entire twin configuration and **reset all store state** (channels, messages, files, etc.). Use this when you need a clean slate.
**Request body**
A full `SlackTwinConfig` object. Any fields you omit revert to their defaults.
**Response**
```json theme={null}
{
"ok": true,
"config": { "...full config..." }
}
```
This endpoint resets the store. Any channels, messages, or files created during the session are lost. If you only need to update specific config fields (such as token scopes) without losing seeded data, use `PATCH /admin/config` instead.
### Patch config (preserve state)
```bash theme={null}
PATCH /admin/config
Content-Type: application/json
```
Update individual config fields **without resetting the store**. Seeded channels, messages, and files remain intact. This is useful when you need to change token scopes or other settings mid-session after data has already been seeded.
**Request body**
A partial JSON object containing only the fields you want to update. Fields you omit keep their current values.
```json theme={null}
{
"tokens": [
{
"token": "xoxb-F9SXMECOSFOGYR3XKXWN",
"user_id": "UTWINBOT",
"scopes": ["chat:write", "channels:read"],
"is_bot": true
}
]
}
```
**Response**
```json theme={null}
{
"ok": true,
"config": { "...updated config..." }
}
```
Use `PATCH` when you want to restrict token scopes after seeding sample data. For example, seed a workspace with channels and messages, then patch the config to narrow the bot token's scopes and verify your app handles `missing_scope` errors gracefully.
### List users
```bash theme={null}
GET /admin/users
```
Returns all users in the twin workspace along with their associated tokens.
**Response**
```json theme={null}
{
"users": [
{
"id": "UTWINBOT",
"name": "slack-twin-bot",
"real_name": "Slack Twin Bot",
"is_bot": true,
"deleted": false,
"team_id": "TTWIN",
"tokens": [
{
"token": "xoxb-F9SXMECOSFOGYR3XKXWN",
"is_bot": true,
"scopes": ["channels:history", "channels:manage", "channels:read", "chat:write", "files:read", "files:write", "reactions:write", "search:read", "team:read", "users:read"]
}
]
},
{
"id": "UTWINUSR",
"name": "slack-twin-user",
"real_name": "Slack Twin User",
"is_bot": false,
"deleted": false,
"team_id": "TTWIN",
"tokens": [
{
"token": "xoxp-slack-twin-user-token",
"is_bot": false,
"scopes": ["channels:history", "channels:manage", "channels:read", "chat:write", "files:read", "files:write", "reactions:write", "search:read", "team:read", "users:read"]
}
]
}
]
}
```
| Field | Type | Description |
| ------------------------- | ----------------- | -------------------------------------- |
| `users` | `array` | List of user objects in the workspace. |
| `users[].id` | `string` | User identifier. |
| `users[].name` | `string` | Username. |
| `users[].real_name` | `string \| null` | Display name. |
| `users[].is_bot` | `boolean` | Whether the user is a bot. |
| `users[].deleted` | `boolean` | Whether the user has been deactivated. |
| `users[].team_id` | `string` | Workspace team identifier. |
| `users[].tokens` | `array` | Tokens associated with this user. |
| `users[].tokens[].token` | `string` | The token string. |
| `users[].tokens[].is_bot` | `boolean` | Whether this is a bot token. |
| `users[].tokens[].scopes` | `array of string` | OAuth scopes granted to this token. |
### File downloads
Uploaded files are accessible via direct download endpoints:
```bash theme={null}
GET /files/{file_id}
GET /files/{file_id}/download
```
Both endpoints return the file content with the appropriate MIME type and a `Content-Disposition` header for download. Returns `404` if the file does not exist.
## Google Drive twin storage tiers
The Google Drive twin enforces storage quota limits based on a configurable storage tier, letting you test how your application handles quota-exceeded errors.
| Tier | Storage quota |
| --------- | ------------- |
| `free` | 15 GB |
| `basic` | 100 GB |
| `premium` | 2 TB |
| `ai_pro` | 5 TB |
When a file upload would exceed the tier's storage quota, the twin returns a `403 storageQuotaExceeded` error matching the real Google Drive API:
```json theme={null}
{
"error": {
"code": 403,
"message": "The user's Drive storage quota has been exceeded.",
"errors": [
{
"domain": "global",
"reason": "storageQuotaExceeded",
"message": "The user's Drive storage quota has been exceeded."
}
]
}
}
```
The `about.get` endpoint reflects the effective storage quota limit in its `storageQuota.limit` field.
### Switching storage tiers
Use the admin API to get or set the storage tier:
```bash theme={null}
# Get current tier
GET /admin/storage-tier
```
**Response**
```json theme={null}
{
"storage_tier": "free",
"storage_quota_limit": 15000000000,
"storage_used_bytes": 1024
}
```
```bash theme={null}
# Switch tier
POST /admin/storage-tier
Content-Type: application/json
{"storage_tier": "premium"}
```
**Response**
```json theme={null}
{
"storage_tier": "premium",
"storage_quota_limit": 2000000000000,
"storage_used_bytes": 1024
}
```
You can also override the quota limit directly via the `storage_quota_limit` config field, which takes precedence over the tier-based default.
## Dropbox twin account tiers
The Dropbox twin enforces storage quota limits based on a configurable account tier.
| Tier | Storage quota |
| -------------- | ------------- |
| `basic` | 2 GB |
| `plus` | 2 TB |
| `professional` | 3 TB |
| `business` | 5 TB |
When a file upload would exceed the tier's quota, the twin returns an `insufficient_space` error matching the real Dropbox API:
```json theme={null}
{
"error_summary": "path/insufficient_space/..",
"error": {".tag": "path", "reason": {".tag": "insufficient_space"}}
}
```
The `get_space_usage` endpoint reflects the allocated quota based on the active tier.
### Switching account tiers
Use the admin API to get or set the account tier:
```bash theme={null}
# Get current tier
GET /admin/account-tier
```
**Response**
```json theme={null}
{
"connection_id": "...",
"account_tier": "basic",
"used_bytes": 0,
"allocated_bytes": 2000000000,
"available_bytes": 2000000000
}
```
```bash theme={null}
# Switch tier
POST /admin/account-tier
Content-Type: application/json
{"tier": "plus"}
```
**Response**
```json theme={null}
{
"connection_id": "...",
"account_tier": "plus",
"used_bytes": 0,
"allocated_bytes": 2000000000000,
"available_bytes": 2000000000000
}
```
## Notion twin workspace plans
The Notion twin enforces workspace plan-based limits, letting you test how your application handles different plan tiers.
| Plan | Max file upload | Max guests |
| ------------ | --------------- | ---------- |
| `free` | 5 MB | 10 |
| `plus` | 5 GB | 100 |
| `business` | 5 GB | 250 |
| `enterprise` | 5 GB | Unlimited |
When a file upload exceeds the plan's size limit, the twin returns a validation error. The twin also supports the `disabled_capabilities` config field for selectively disabling API capabilities.
### Switching workspace plans
Use the admin API to get or set the workspace plan:
```bash theme={null}
# Get current plan
GET /admin/workspace-plan
```
**Response**
```json theme={null}
{
"workspace_plan": "free",
"limits": {"max_file_upload_bytes": 5242880, "max_guests": 10}
}
```
```bash theme={null}
# Switch plan
POST /admin/workspace-plan
Content-Type: application/json
{"workspace_plan": "business"}
```
**Response**
```json theme={null}
{
"ok": true,
"workspace_plan": "business",
"limits": {"max_file_upload_bytes": 5368709120, "max_guests": 250}
}
```
## Discord twin boost levels
The Discord twin supports configurable server boost levels that control resource limits.
| Boost level | Max file upload | Max emoji slots |
| ----------- | --------------- | --------------- |
| `0` | 25 MB | 50 |
| `1` | 25 MB | 100 |
| `2` | 50 MB | 150 |
| `3` | 100 MB | 250 |
Configure the boost level via the `guild_boost_level` config field. The `max_file_upload_bytes` and `max_emoji_slots` fields can also be set independently to override the boost-level defaults.
## Slack twin conversations.open
The Slack twin supports the `conversations.open` API method for opening or creating direct-message channels.
```bash theme={null}
POST /api/conversations.open
```
**Request body**
| Field | Type | Required | Description |
| --------- | -------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `users` | `string` | Conditional | Comma-separated list of user IDs to include in the DM. Required when `channel` is not provided. The authenticated user is automatically added if not already in the list. |
| `channel` | `string` | Conditional | Channel ID of an existing DM to reopen. When provided, `users` is ignored. |
**Response (new DM)**
```json theme={null}
{
"ok": true,
"channel": {
"id": "G0000000001",
"name": "dm-UTWINBOT_UTWINUSR",
"is_private": true,
"members": ["UTWINBOT", "UTWINUSR"]
},
"already_open": false,
"no_op": false
}
```
**Response (existing DM)**
```json theme={null}
{
"ok": true,
"channel": {
"id": "G0000000001",
"name": "dm-UTWINBOT_UTWINUSR",
"is_private": true,
"members": ["UTWINBOT", "UTWINUSR"]
},
"already_open": true,
"no_op": true
}
```
| Field | Type | Description |
| -------------- | --------- | ------------------------------------- |
| `channel` | `object` | The opened or created channel object. |
| `already_open` | `boolean` | `true` if the DM already existed. |
| `no_op` | `boolean` | `true` if no new channel was created. |
# How Arga works
Source: https://docs.argalabs.com/concepts/how-it-works
Combine controlled service state with repeatable browser tests
Arga separates the system you are testing from the external services it acts on. You keep running your app or agent in your own local, staging, or preview environment. Arga supplies realistic service twins and a browser runner that can exercise a reachable URL.
## The workflow
Start a Twin Run with the services you need. Seed it from a saved Scenario, a natural-language description, or an empty baseline.
Replace provider base URLs and credentials with the values returned by the Twin Run. Calls now change twin state instead of production state.
Give a Test Run a reachable application URL and a task. The browser runner executes the flow and records events, screenshots, and assertions.
Save a completed flow as a test. You can edit its blocks and parameters, rerun it against a URL, or associate it with a repository for PR Test Runs.
Reset the twins to their seeded baseline and run the same test again. This keeps provider state controlled across attempts.
## Core building blocks
Short-lived or persistent service environments with provider-compatible APIs and interfaces.
Saved seed configurations for one or more twins.
Browser execution against a URL with live events, evidence, and editable blocks.
GitHub-triggered execution of relevant generated tests or selected saved tests.
## What repeatability means
Arga controls the external-service starting state and the browser steps. It does not capture every function call in your application or reconstruct the application's process state. To reproduce a case, use the same Scenario, reset the twins, and rerun the same Saved Test against the same application build.
## Evidence and iteration
A Test Run keeps the browser events, generated blocks, screenshots, and final summary together. If a flow needs adjustment, edit its blocks or parameters and rerun it. Saving the result turns the flow into a reusable test definition instead of a one-off prompt.
# Twin reference
Source: https://docs.argalabs.com/concepts/twin-reference
Per-twin support, known limitations, and MCP tools
Use this page to pick the right twin name for CLI, API, and MCP workflows. This catalog reflects the twins the current Arga app exposes for provisioning and URL validation.
## MCP tools
All twins on this page can be discovered and used through the Arga MCP server:
| Tool | Use it for |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `get_twin_catalog` | List provisionable twin names and their kinds. |
| `provision_twins` | Start an ephemeral twin environment. Pass the twin name in the comma-separated `twins` parameter. |
| `start_url_validation` | Start a validation run with twins attached. Pass the twin name in the comma-separated `twins` parameter. |
| `get_validation_results` | Poll validation and provisioning run status. Validation runs return structured terminal results; twin provisions report status text such as `queued`, `provisioning`, `ready`, or `failed`. |
For full parameters, see [MCP](/mcp#available-mcp-tools).
## Twin links
| Twin | Kind | Reference |
| ------------------ | ------- | ------------------------------------- |
| `box` | Backend | [Box](#box) |
| `datadog` | UI | [Datadog](#datadog) |
| `discord` | UI | [Discord](#discord) |
| `dropbox` | UI | [Dropbox](#dropbox) |
| `github` | UI | [GitHub](#github) |
| `gitlab` | UI | [GitLab](#gitlab) |
| `gmail` | UI | [Gmail](#gmail) |
| `google_calendar` | UI | [Google Calendar](#google-calendar) |
| `google_docs` | UI | [Google Docs](#google-docs) |
| `google_drive` | UI | [Google Drive](#google-drive) |
| `google_sheets` | UI | [Google Sheets](#google-sheets) |
| `google_workspace` | Backend | [Google Workspace](#google-workspace) |
| `jira` | Backend | [Jira](#jira) |
| `notion` | UI | [Notion](#notion) |
| `salesforce` | Backend | [Salesforce](#salesforce) |
| `slack` | UI | [Slack](#slack) |
| `stripe` | UI | [Stripe](#stripe) |
| `waterfall` | Backend | [Waterfall](#waterfall) |
| `unified` | Backend | [Unified](#unified) |
| `unstructured` | Backend | [Unstructured](#unstructured) |
## Box
**Twin name:** `box`
**Supports**
* Box v2.0 file and folder APIs, including list, upload, download, update, delete, search, and event streams.
* OAuth token exchange, refresh tokens, developer tokens, and downscoped token restrictions.
* Webhook registration, signed webhook delivery attempts, retries, replay, and admin inspection.
* Unified storage and HRIS bridge behavior for apps that reach Box through Unified.
**Known limitations**
* Preview, thumbnail, transform/export, and advanced enterprise permissions are approximated rather than fully implemented.
* Unsupported webhook triggers, folder sort keys, search sort keys, event stream types, or downscope scopes return structured `400` or `403` responses.
* Arbitrary MIME uploads are stored as opaque content when the twin does not model preview or conversion behavior.
**MCP tools:** `get_twin_catalog`, `provision_twins`, `start_url_validation`, `get_validation_results`.
## Datadog
**Twin name:** `datadog`
**Supports**
* Datadog v1/v2 APIs for monitors, dashboards, events, log intake/search/aggregation, metrics, SLOs, downtime, incidents and attachments, Synthetic API tests and results, and notebooks.
* Datadog Pup CLI 1.12.1 request and response contracts across common monitoring and investigation workflows.
* API/application-key or bearer-token authentication, Datadog-shaped errors, rate-limit headers, fault injection, deterministic account state, and admin reset/state routes.
* A small browsable Datadog-style overview for inspecting twin state.
**Known limitations**
* Cloud integrations, IAM and key management, security, RUM, APM, traces, DBM, workflows, usage/cost, service catalog, on-call, and other unlisted product configuration APIs are not implemented.
* Unknown API paths return `404`; they do not return synthetic success.
**Provision**
```bash theme={null}
arga twin-runs create --twins datadog --ttl 60 --wait
```
**MCP tools:** `get_twin_catalog`, `provision_twins`, `start_url_validation`, `get_validation_results`.
## Discord
**Twin name:** `discord`
**Supports**
* Discord API v10 routes for guilds, channels, messages, reactions, threads, members, roles, bans, invites, webhooks, emojis, stickers, scheduled events, stage instances, auto-moderation rules, soundboard sounds, guild templates, and user endpoints.
* Bot-token authentication, deterministic seeding, admin state inspection, event delivery, replay, and webhook subscriptions.
* Message creation with `multipart/form-data` file uploads using `files[n]` or `file` parts plus `payload_json` or `content`.
* Configurable server boost levels for upload-size and emoji-slot limits.
**Known limitations**
* Channels, roles, members, and messages start empty unless seeded or created through API calls.
* Behavior focuses on REST API compatibility and event delivery; real Discord gateway/websocket behavior is not the primary fidelity target.
* Unsupported or malformed request shapes return Discord-style validation errors rather than silently succeeding.
**MCP tools:** `get_twin_catalog`, `provision_twins`, `start_url_validation`, `get_validation_results`.
## Dropbox
**Twin name:** `dropbox`
**Supports**
* Dropbox API v2 file operations including list, upload, download, copy, move, delete, search, revisions, tags, upload sessions, and batch operations.
* Sharing APIs for shared links, shared folders, file members, file requests, file properties, and team/admin management.
* Webhook delivery, event replay, seeded team members, a starter folder tree, and account tier-based storage quotas.
**Known limitations**
* Some advanced Dropbox surfaces are represented through deterministic in-memory behavior rather than full production infrastructure.
* Uploads that exceed configured account-tier quotas return an `insufficient_space` error.
* Routes outside the modeled Dropbox API v2 surface may return structured non-support rather than a stateful response.
**MCP tools:** `get_twin_catalog`, `provision_twins`, `start_url_validation`, `get_validation_results`.
## GitHub
**Twin name:** `github`
**Supports**
* GitHub REST API operations for repositories, branch-aware file contents, pull requests, issues, branches, commits, check runs, check suites, git references, labels, pull request reviews, review comments, commit statuses, search, organizations, users, and webhooks.
* Raw file downloads served as public content (no bearer token required) for both `https://raw.githubusercontent.com/{owner}/{repo}/{ref}/{path}` and `https://github.com/{owner}/{repo}/raw/{ref}/{path}`. The twin gateway intercepts `raw.githubusercontent.com` and the resolver matches the longest known branch prefix so slash-containing branch names (for example, `feature/deep`) and `refs/heads/...` / `HEAD/...` refs are handled correctly. Responses use the file's guessed MIME type (defaulting to `application/octet-stream`).
* GitHub App endpoints for installations, access tokens, repository listings, app metadata (`GET /app`, `GET /apps/{app_slug}`), and the [GitHub App manifest registration flow](https://docs.github.com/apps/creating-github-apps/setting-up-a-github-app/creating-a-github-app-from-a-manifest) for creating multiple GitHub Apps at runtime (`GET/POST /settings/apps/new`, `GET/POST /organizations/{org}/settings/apps/new`, `POST /app-manifests/{code}/conversions`).
* Multi-app support: each installation is scoped to its owning GitHub App, JWT and installation tokens resolve the correct app, and per-app bot users, webhook secrets, and RSA key pairs are tracked independently.
* Deterministic seeding for repos, files, issues, PRs, checks, and GitHub App configuration.
* Token authentication, OAuth flows, scope enforcement, signed webhook delivery, admin state export, and stub-hit tracking.
* GitHub CLI (`gh`) and [GitHub MCP server](https://github.com/github/github-mcp-server) compatibility. The twin accepts requests at the standard `api.github.com` paths as well as the GitHub Enterprise-style `/api/v3/...` REST prefix and the `/api/graphql` endpoint, so `gh` and MCP clients can be pointed at the twin's base URL without code changes.
* Extended REST coverage used by `gh` and the MCP server: `GET /meta`, `GET /rate_limit`, `GET /zen`, `GET /api/v3`, repository archives (`/zipball/{ref}`, `/tarball/{ref}`), releases, search for repositories, users, issues, and code, gists (list, get, create, update, delete), notifications and thread subscriptions, projects v2 (org and user fields and items), org and repo Actions workflows, workflow runs, jobs, and artifacts, Actions cache, variables, and secrets, codespaces (list, get, update, stop, delete, ports), user SSH and signing keys, GPG keys, starred repositories, sub-issues and issue types, repository security advisories, global security advisories, Dependabot alerts, code scanning alerts, and secret scanning alerts.
* GraphQL surface at `POST /graphql` (also reachable through `POST /api/graphql`) covering the queries and mutations used by `gh` and the GitHub MCP server, including `viewer`, repository, issue, and pull request lookups, search, and the corresponding mutations backed by the same store as the REST handlers.
**Install apps against the twin**
Use the GitHub twin when your app normally registers or installs a GitHub App and then authenticates with installation tokens.
1. Provision the `github` twin and seed at least one user or organization plus the repositories your app should see.
2. Point your app's GitHub API and web URLs at the provisioned twin. The wizard handles the standard `api.github.com`, `github.com`, and `raw.githubusercontent.com` rewrites automatically.
3. Register a GitHub App with the manifest flow at `GET` or `POST /settings/apps/new`, or use `GET` or `POST /organizations/{org}/settings/apps/new` for an org-owned app. Exchange the returned code with `POST /app-manifests/{code}/conversions` to receive the app id, client id, client secret, webhook secret, and PEM private key.
4. Install the app through the browser flow at `/apps/{app_slug}/installations/new`. Choose the account, repository access, optional webhook URL, and optional webhook secret.
5. For a programmatic setup, create the installation with `POST /admin/installations` using `account`, `app_slug` or `app_id`, `repository_selection`, optional `repositories`, optional `webhook_url`, and optional `webhook_secret`.
6. From your app, sign a GitHub App JWT with the returned private key, call `POST /app/installations/{installation_id}/access_tokens`, and use the returned installation token for repository, issue, PR, check, and webhook workflows.
**Known limitations**
* Endpoints without a full stateful implementation return explicit stub responses with `X-Twin-Stub`, `_twin_stub`, and `_twin_warning`.
* Stub hits can be audited through `GET /admin/stub-hits` and cleared with `POST /admin/stub-hits/clear`.
* The GraphQL surface targets the operations used by `gh` and the official GitHub MCP server. Queries and mutations outside that set may return structured stub responses.
* Strict 100% live `gh` and MCP coverage is gated by external GitHub fixtures and explicit mutation consent flags. The `scripts/validate_github_cli_mcp_compat.py` verifier reports any remaining blockers directly.
**MCP tools:** `get_twin_catalog`, `provision_twins`, `start_url_validation`, `get_validation_results`.
## GitLab
**Twin name:** `gitlab`
**Supports**
* GitLab REST API v4 routes for users, groups, namespaces, projects (by numeric ID or full path), repository branches, files, and commits, issues, merge requests, notes, discussions, pipelines, pipeline schedules, jobs, job artifacts, and project hooks.
* `glab api` style REST and GraphQL workflows, including a minimal GraphQL surface for `glab api graphql` calls.
* GitBeaker SDK-style calls, including package routes served outside `/api/v4` (`/projects/...`, `/groups/...`, `/packages/...`) and GitLab-shaped fallback responses for unmodeled endpoints on resolved projects.
* GitLab MCP-compatible JSON-RPC over `/api/v4/mcp` and `/mcp`, with tools for projects, issues, merge requests, files, and pipelines.
* Token authentication via `Authorization: Bearer ...`, `PRIVATE-TOKEN`, `JOB-TOKEN`, or `private_token` query parameters. Tokens match GitLab client expectations; no external authentication is performed.
* Admin endpoints to inspect and reseed state (`/admin/reset`, `/admin/state`, `/admin/clock`, `/admin/fidelity`) and a liveness check at `GET /healthz`.
**Known limitations**
* Users, groups, projects, branches, files, commits, issues, merge requests, pipelines, jobs, and hooks start empty unless seeded through config or scenario seeding, or created through API calls.
* The REST `/api/v4` surface, `glab` CLI compatibility, GitBeaker SDK compatibility, and the MCP JSON-RPC tools listed above are the fidelity target; other GitLab surfaces may be approximated or absent.
* Delete operations on seeded resources are non-destructive by design so SDK and CLI probes remain repeatable. To remove state, use the admin reset endpoint rather than relying on a `DELETE` to drop seeded entities.
* State is process-local and is discarded when the Twin Run ends.
**MCP tools:** `get_twin_catalog`, `provision_twins`, `start_url_validation`, `get_validation_results`.
## Gmail
**Twin name:** `gmail`
**CLI quickstart:** [Use the Google Workspace CLI with Arga twins](/features/google-workspace-cli)
**Supports**
* Gmail API workflows for inboxes, threads, messages, drafts, labels, attachments, search, send behavior, and watch events.
* OAuth-style token handling, seeded mailbox state, deterministic message/thread IDs, and resettable state for repeatable email-agent tests.
* File attachment metadata and download flows for agents that inspect or transform message attachments.
**Known limitations**
* Mailboxes start empty unless seeded or populated by the app under test.
* Delivery, spam classification, and provider reputation behavior are deterministic approximations rather than live Gmail infrastructure.
* The twin focuses on Gmail API-compatible agent workflows; broad Google Workspace admin behavior is outside the primary fidelity target.
**MCP tools:** `get_twin_catalog`, `provision_twins`, `start_url_validation`, `get_validation_results`.
## Google Calendar
**Twin name:** `google_calendar`
**CLI quickstart:** [Use the Google Workspace CLI with Arga twins](/features/google-workspace-cli)
**Supports**
* Google Calendar API v3 calendars, calendar list, events, ACL rules, settings, colors, and free/busy queries.
* Watch channels and webhook delivery for events, ACL, calendar list, and settings resources.
* Calendar CRUD, event import, quick-add, instances, move operations, and delete flows.
**Known limitations**
* Calendar and event state starts empty unless seeded or created by the app under test.
* Advanced Google Calendar edge cases outside the modeled v3 resources may be approximated or return structured errors.
* Watch delivery is deterministic and inspectable, which is useful for tests but not identical to every production timing detail.
**MCP tools:** `get_twin_catalog`, `provision_twins`, `start_url_validation`, `get_validation_results`.
Google Drive, Docs, and Sheets remain separate provisioning and API surfaces. When you provision any two or more under the same Twin Run ID, the selected twins share one run-scoped Google file state. Metadata, content, permissions, revisions, creates, edits, renames, trash, and deletes stay synchronized. Different Twin Run IDs never share this state.
## Google Docs
**Twin name:** `google_docs`
**CLI quickstart:** [Use the Google Workspace CLI with Arga twins](/features/google-workspace-cli)
**Supports**
* Google Docs v1 document create, get, and atomic `batchUpdate` operations.
* UTF-16 document indexes, text insertion and deletion, replace-all, text and paragraph styling, and named ranges.
* A Docs v1 Discovery document rewritten to the provisioned twin URL.
* A browsable Docs-style home and document editor with blank-document creation, autosave, bold, italic, underline, sharing, and document export.
* The preset document ID `google-docs-launch-notes`, which matches the corresponding file metadata in the default Drive twin.
**Known limitations**
* This provision contains the Docs API and editor UI only. Provision `google_drive` for Drive metadata and file operations, and `google_sheets` for spreadsheet editing.
* The editor focuses on common document workflows. It does not model real-time multi-user cursors, full version history, or every consumer Docs command.
**Provision**
```bash theme={null}
arga twin-runs create --twins google_docs --ttl 60 --wait
```
**MCP tools:** `get_twin_catalog`, `provision_twins`, `start_url_validation`, `get_validation_results`.
## Google Drive
**Twin name:** `google_drive`
**CLI quickstart:** [Use the Google Workspace CLI with Arga twins](/features/google-workspace-cli)
**Supports**
* Google Drive API v3 files, permissions, revisions, comments, replies, shared drives, changes, watch channels, and simple, multipart, and resumable uploads.
* File operations such as list, get, create, update, copy, delete, export, download, labels, permissions, and generated IDs.
* Preset metadata for `google-docs-launch-notes` and `google-sheets-launch-plan`, matching the default resource IDs in the separately provisioned editor twins.
* Google API client compatibility through a Drive discovery document.
* OAuth scope enforcement, change polling, watch notifications, deterministic retries, replay, and storage tier-based quotas.
**Known limitations**
* The Drive `q` query language and `orderBy` support are intentionally a subset; unsupported clauses or keys return `400 invalidQuery`.
* Unsupported export formats return `400 cannotExportFile`; Google-native exports focus on common document, sheet, slide, form, script, site, and drawing formats.
* HMAC notification signatures are a twin-only optional approximation and are disabled by default.
* Upload MIME types are accepted broadly, but preview, thumbnail, edit, export, and search capabilities depend on the modeled MIME class.
* The Google Docs and Google Sheets editor twins are not part of this provision. Request `google_docs` and `google_sheets` separately for their APIs and UIs. People, Workspace Events, Apps Script, and Pub/Sub are under `google_workspace`.
**MCP tools:** `get_twin_catalog`, `provision_twins`, `start_url_validation`, `get_validation_results`.
## Google Sheets
**Twin name:** `google_sheets`
**CLI quickstart:** [Use the Google Workspace CLI with Arga twins](/features/google-workspace-cli)
**Supports**
* Google Sheets v4 spreadsheet creation and reads, A1 values get/update/append/clear and batch methods, sheet mutation batches, formulas, formatting, and developer metadata.
* A Sheets v4 Discovery document rewritten to the provisioned twin URL.
* Deterministic spreadsheet content with auth, ACL, failure, rate-limit, and reset behavior.
* A browsable Sheets-style home and spreadsheet editor with blank-spreadsheet creation, editable cells, a formula bar, sheet tabs, autosave, sharing, and CSV, XLSX, and PDF export.
* The preset spreadsheet ID `google-sheets-launch-plan`, which matches the corresponding file metadata in the default Drive twin.
**Known limitations**
* This provision contains the Sheets API and editor UI only. Provision `google_drive` for Drive metadata, `google_docs` for document editing, and `google_workspace` for People, Workspace Events, Apps Script, and Pub/Sub.
* The editor focuses on common grid workflows. It does not model charts, pivot-table editors, macros, or real-time multi-user cursors.
**Provision**
```bash theme={null}
arga twin-runs create --twins google_sheets --ttl 60 --wait
```
**MCP tools:** `get_twin_catalog`, `provision_twins`, `start_url_validation`, `get_validation_results`.
## Google Workspace
**Twin name:** `google_workspace`
**CLI quickstart:** [Use the Google Workspace CLI with Arga twins](/features/google-workspace-cli)
**Supports**
* Google People v1 contacts, contact groups, other contacts, profile reads, and search.
* Google Workspace Events v1 subscriptions, operations, reactivation, event-type filters, task streams, and push-notification helpers.
* Google Apps Script v1 projects, content, versions, deployments, processes, and script execution.
* Cloud Pub/Sub topic, subscription, pull, acknowledge, and IAM helpers used by Workspace event workflows.
* People, Workspace Events, and Apps Script Discovery documents.
**Known limitations**
* This grouped API-only twin does not publish Drive, Docs, Sheets, Gmail, or Calendar routes. Provision those service twins separately.
* State and event delivery are deterministic approximations intended for repeatable tests, not a live Google Cloud project.
**Provision**
```bash theme={null}
arga twin-runs create --twins google_workspace --ttl 60 --wait
arga twin-runs create --twins google_workspace,google_sheets --ttl 60 --wait
```
**MCP tools:** `get_twin_catalog`, `provision_twins`, `start_url_validation`, `get_validation_results`.
## Jira
**Twin name:** `jira`
**Supports**
* Jira Cloud REST API v3 issue flows: create, read, update, delete, bulk create, transitions, changelog, edit metadata, comments, worklogs, attachments, issue links, properties, votes, watchers, and search/JQL.
* Projects, users, components, versions, remote links, filters, dashboards, groups, fields, priorities, resolutions, statuses, status categories, issue types, server info, attachment metadata, and webhooks.
* Jira Software Agile endpoints for boards, sprints, board sprints, and backlog issue moves.
* OAuth 2.0 authorization code grant, scope enforcement, deterministic seeding, ADF storage for descriptions/comments, and HMAC-signed webhook delivery.
**Known limitations**
* The v2 and `latest` REST aliases route to the v3-compatible implementation; exact historical differences between Jira API versions are not the fidelity target.
* Plain-string descriptions and comments are auto-wrapped in a minimal Atlassian Document Format document.
* Complex JQL behavior is modeled for deterministic testing, but edge cases outside the supported parser may return structured validation errors.
**MCP tools:** `get_twin_catalog`, `provision_twins`, `start_url_validation`, `get_validation_results`.
## Notion
**Twin name:** `notion`
**Supports**
* Notion API routes for users, search, pages, databases, data sources, blocks, comments, file uploads, views, OAuth token exchange, introspection, and revocation.
* Deterministic workspace state, bot identity, pagination, markdown projection, nested page content, database/data-source querying, event outbox, webhook delivery, replay, and admin inspection.
* Workspace plan limits for file uploads and guests, plus capability-based user information visibility.
**Known limitations**
* Pages, databases, and users start empty unless seeded or created through API calls.
* Unsupported property template types and unsupported database property filters return validation errors.
* Requests outside supported `/v1` routes return Notion-style invalid request errors rather than generated mock success responses.
**MCP tools:** `get_twin_catalog`, `provision_twins`, `start_url_validation`, `get_validation_results`.
## Salesforce
**Twin name:** `salesforce`
**Supports**
* Salesforce Platform REST API discovery (`GET /services/data`, `GET /services/data/v{version}`, and `GET /services/data/v{version}/limits`).
* sObject CRUD for standard objects (Account, Contact, Case, EmailTemplate, EmailMessage, User, and related types) under `/services/data/v{version}/sobjects/{sobject}`, including `GET`, `POST`, `PATCH`, and `DELETE` by record ID, `describe`, `describe/layouts`, `describe/compactLayouts`, `listviews`, relationship traversal, updated/deleted feeds, and the `relevantItems` endpoint.
* SOQL (`/services/data/v{version}/query`, `queryAll`, and `query/{locator}`), SOSL (`/services/data/v{version}/search`, `parameterizedSearch`, `search/scopeOrder`, `search/layout`), composite endpoints (`composite`, `composite/batch`, `composite/graph`, `composite/tree/{sobject}`), and Bulk API v2 job shells (`jobs/query`, `jobs/ingest`).
* Invocable actions (`actions`, `actions/standard`, `actions/custom`) including the standard email and case-creation actions used by support workflows, plus Tooling API surface for sobjects, queries, and basic discovery.
* OAuth 2.0 token exchange at `/services/oauth2/token` (and `/oauth2/token`), userinfo at `/services/oauth2/userinfo`, identity URLs at `/id/{org_id}/{user_id}`, and bearer-token authentication.
* Scenario seeding for imported custom objects, fields, record types, layouts, compact layouts, tabs, Salesforce apps, relationships, and optional sample records.
* Admin endpoints for deterministic seeding (`POST /admin/reset`, `GET /admin/state`, `POST /admin/clock`) and a liveness check at `GET /healthz` (also `GET /health`).
**Install Salesforce apps and custom metadata into the twin**
Salesforce apps are installed into the twin by seeding the Salesforce twin configuration. Use this when your app depends on custom Salesforce objects, fields, layouts, tabs, or app definitions.
Connected org import reads from a real Salesforce org and saves the selected metadata as a reusable Arga scenario:
1. Connect Salesforce with OAuth or a bearer token. OAuth requires a Salesforce Connected App callback of `https://api.argalabs.com/auth/salesforce/callback` and the scopes `api refresh_token offline_access openid`; bearer-token setup uses `POST /integrations/salesforce/connect` with the Salesforce access token plus `metadata.instance_url` and optional `metadata.api_version`.
2. List importable metadata with `GET /integrations/salesforce/catalog`.
3. Preview the generated `seed_config.salesforce` with `POST /integrations/salesforce/import-preview`, passing `object_names`, optional `app_names`, and optional sample-record settings.
4. Save the import as a scenario with `POST /integrations/salesforce/import-scenario`. The saved scenario provisions the `salesforce` twin with the imported objects, fields, layouts, record types, tabs, apps, relationships, and optional records.
Salesforce DX import is for metadata already checked into source control. Send a JSON map of file path to file contents to `POST /integrations/salesforce/sfdx/catalog`, `POST /integrations/salesforce/sfdx/import-preview`, or `POST /integrations/salesforce/sfdx/import-scenario`. The parser recognizes `sfdx-project.json`, `manifest/package.xml`, `objects/*/*.object-meta.xml`, `objects/*/fields/*.field-meta.xml`, `objects/*/recordTypes/*.recordType-meta.xml`, `objects/*/compactLayouts/*.compactLayout-meta.xml`, `layouts/*.layout-meta.xml`, `applications/*.app-meta.xml`, and `tabs/*.tab-meta.xml`.
After saving either import path as a scenario, provision `salesforce` with that `scenario_id` and point your app at the returned `SALESFORCE_INSTANCE_URL`, `SALESFORCE_API_BASE_URL`, and `SALESFORCE_ACCESS_TOKEN` values.
**Known limitations**
* Accounts, contacts, cases, email templates, email messages, users, custom objects, apps, tabs, and layouts start empty unless seeded through config or scenario seeding, imported from Salesforce, imported from Salesforce DX metadata, or created through API calls.
* The fidelity target is the Salesforce REST API surface needed for CRUD, query/search, composite requests, limits/recent/actions discovery, custom schema replay, and support-style case and email-template flows; products and endpoints outside that set (for example, Apex REST, Streaming API, Metadata API, and Einstein APIs) may be approximated or absent.
* Salesforce real-service fidelity checks are opt-in and only run when `SALESFORCE_REAL_FIDELITY=1` is set with valid `SALESFORCE_INSTANCE_URL` and `SALESFORCE_ACCESS_TOKEN` credentials.
* The Salesforce twin is backend-only — there is no browsable UI surface in the Arga app.
**MCP tools:** `get_twin_catalog`, `provision_twins`, `start_url_validation`, `get_validation_results`.
## Linear
**Twin name:** `linear`
**Supports**
* The Linear GraphQL endpoint at `POST /graphql` for teams, projects, cycles, issues, labels, comments, workflow states, users, organization, and webhooks.
* Personal API keys sent directly in the `Authorization` header, plus OAuth 2.0 tokens issued via `/oauth/authorize`, `/oauth/token`, and `/oauth/revoke`.
* `@linear/sdk` wire compatibility including `__typename` on entities, `{ id }` relation payloads in default selections, and SDK-shaped GraphQL error envelopes.
* Webhook registration and replay flows, with `Linear-Signature`, `Linear-Delivery`, `Linear-Event`, and `Linear-Timestamp` headers on deliveries.
* Admin endpoints for state inspection, config updates, reset/clock control, webhook replay, and fidelity checks.
**Known limitations**
* Teams, projects, cycles, issues, labels, comments, tokens, and webhook subscriptions start empty unless seeded or created through API calls.
* The fidelity target is the GraphQL surface used by Arga workflows and the `@linear/sdk`, not every Linear feature or internal UI behavior.
* The Linear twin is backend-only — there is no browsable UI surface in the Arga app.
**MCP tools:** `get_twin_catalog`, `provision_twins`, `start_url_validation`, `get_validation_results`.
## Slack
**Twin name:** `slack`
**Supports**
* Slack Web API methods for conversations, channels, messages, scheduled messages, users, reactions, pins, bookmarks, do-not-disturb, modal views, direct messages, and files.
* Block Kit messages on `chat.postMessage`: requests with a non-empty `blocks` array are accepted even when fallback `text` is blank or whitespace, and the submitted `blocks` are returned in the response and persisted in conversation history. Posts with both empty `text` and empty `blocks` still return `no_text`.
* Auth methods including `api.test`, `auth.test`, `auth.revoke`, and `auth.teams.list`.
* OAuth 2.0 authorization code grant through `/oauth/v2/authorize` and `/api/oauth.v2.access`, plus MCP OAuth aliases at `/oauth/v2_user/authorize` and `/api/oauth.v2.user.access`.
* Bot, user, and enterprise-style tokens, method-level OAuth scope enforcement, configurable token scopes, and missing-scope errors.
* File uploads, external upload completion, downloadable files, file-share events, workspace tier constraints, storage quotas, rate-limit simulation, event delivery, replay, and admin inspection.
* Slack CLI app management surface including manifest validate/create/update/export, app status, developer install/uninstall, app delete, connections open, hosted package upload placeholders, hosted environment variables (add/list/remove), and Slack CLI secondary API families covering activities, auth tickets and token rotation, app approvals, external auth, datastores, workflow triggers, function permissions, collaborators, icons, certified installs, and developer sandboxes. Point the Slack CLI at the twin by setting `SLACK_API_URL` to the twin's `/api/` base.
* Slack MCP Streamable HTTP endpoint at `/mcp` with JSON-RPC 2.0 `initialize`, `tools/list`, and `tools/call`, OAuth protected resource metadata at `/.well-known/oauth-protected-resource/mcp`, authorization server metadata at `/.well-known/oauth-authorization-server`, and Slack-shaped MCP tools (`slack_search_messages`, `slack_search_messages_and_files`, `slack_search_public_and_private`, `slack_search_public`, `slack_search_files`, `slack_search_users`, `slack_search_channels`, `slack_list_channels`, `slack_read_channel`, `slack_send_message`, `slack_schedule_message`, `slack_send_message_draft`, `slack_read_thread`, `slack_list_users`, `slack_get_user`, `slack_read_user_profile`, `slack_create_canvas`, `slack_update_canvas`, `slack_read_canvas`) that share state with the Web API surface.
**Known limitations**
* Channels start empty unless seeded or created through `conversations.create`.
* File upload limits and workspace features are controlled by the twin's configured tier and constraints, not by a live Slack workspace.
* The REST, OAuth, Slack CLI, and Slack MCP surfaces are the fidelity targets; websocket/Socket Mode behavior is not described as primary support here.
* Hosted package upload endpoints (`apps.hosted.generatePresignedPost`, `apps.hosted.upload`) accept the CLI lifecycle but do not execute hosted runtimes.
**MCP tools:** `get_twin_catalog`, `provision_twins`, `start_url_validation`, `get_validation_results`.
## Stripe
**Twin name:** `stripe`
**Supports**
* Stripe API v1 resources for customers, payment methods, payment intents, setup intents, charges, refunds, disputes, subscriptions, invoices, invoice items, credit notes, products, prices, plans, coupons, promotion codes, tax rates, shipping rates, tokens, sources, payouts, balance, balance transactions, billing meters, meter events, events, files, checkout sessions, payment links, quotes, billing portal sessions, subscription items, schedules, usage records, tax IDs, webhook endpoints, mandates, and test clocks.
* Stripe-compatible authentication errors, idempotency keys, signed webhooks, test cards for declines and 3D Secure, checkout pages, billing portal pages, dashboard pages, product catalog, and customer management.
* Seed endpoint for starter product, price, and webhook setup.
* Stripe MCP-compatible JSON-RPC server at `POST /mcp` (and `POST /mcp/v1`) for use by MCP clients and the `@stripe/mcp` CLI bridge. The twin routes `mcp.stripe.com` through this endpoint and serves Stripe's OAuth discovery documents at `GET /.well-known/oauth-protected-resource`, `GET /.well-known/oauth-protected-resource/mcp`, and `GET /.well-known/oauth-authorization-server`. Implements `initialize`, `notifications/initialized`, `tools/list`, and `tools/call`, advertising the same 31 tools as the official Stripe MCP server (`search_stripe_documentation`, `get_stripe_account_info`, `create_customer`, `list_customers`, `create_product`, `list_products`, `create_price`, `list_prices`, `create_payment_link`, `create_invoice`, `list_invoices`, `create_invoice_item`, `finalize_invoice`, `retrieve_balance`, `create_refund`, `list_refunds`, `list_payment_intents`, `list_subscriptions`, `cancel_subscription`, `update_subscription`, `list_coupons`, `create_coupon`, `update_dispute`, `list_disputes`, `search_stripe_resources`, `fetch_stripe_resources`, `stripe_integration_recommender`, `send_stripe_mcp_feedback`, `stripe_api_search`, `stripe_api_details`, `stripe_api_execute`). MCP tool calls share state with the Stripe API and Checkout surfaces — resources created via MCP are visible through the API, dashboard, and webhooks. Requests without a `Authorization: Bearer ` header return `401 Unauthorized`.
**Known limitations**
* Stripe resources start empty unless seeded or created by the app under test.
* API key validation recognizes Stripe-style key prefixes and simulates authentication behavior; no real Stripe account is contacted.
* The twin models the API resources listed above; newer or specialized Stripe products outside that surface may be absent or approximated.
**MCP tools:** `get_twin_catalog`, `provision_twins`, `start_url_validation`, `get_validation_results`.
## Waterfall
**Twin name:** `waterfall`
**Supports**
* Waterfall API workflows for company search, people search, enrichment, verification, and account endpoints.
* API-key authentication with UUID-shaped keys such as `ad18e456-0dd7-45e1-b094-43a0361aedfa`.
* Environment-variable rewrites through the wizard for `WATERFALL_API_KEY`, `WATERFALL_API_BASE_URL`, `WATERFALL_API_URL`, and `WATERFALL_BASE_URL`.
**Known limitations**
* Waterfall data starts empty unless seeded or created through API calls.
* The twin focuses on API-compatible enrichment and verification workflows; broader Waterfall dashboard behavior is outside the primary fidelity target.
* The Waterfall twin is backend-only; there is no browsable UI surface in the Arga app.
**MCP tools:** `get_twin_catalog`, `provision_twins`, `start_url_validation`, `get_validation_results`.
## Unified
**Twin name:** `unified`
**Supports**
* Unified.to integration, auth, connection, webhook, and passthrough-style flows for apps that call Unified instead of a provider API directly.
* Seeded provider connections for Slack, Google Mail, Google Drive, Google Calendar, Box, Notion, and Dropbox.
* Unified calendar, messaging, HRIS, storage, KMS/page, comment, and event routes over deterministic in-memory provider state.
**Known limitations**
* Use provider-specific twins when your app talks directly to Slack, Dropbox, Google Drive, Google Calendar, Box, Notion, or another upstream provider.
* The Unified twin models generic Unified behavior and selected provider bridges; it is not a replacement for every provider-specific API edge case.
* Missing connections or provider records return structured `404` or `400` errors.
**MCP tools:** `get_twin_catalog`, `provision_twins`, `start_url_validation`, `get_validation_results`.
## Unstructured
**Twin name:** `unstructured`
**Supports**
* Legacy partition endpoint at `POST /general/v0/general`.
* Workflow API routes for sources, destinations, connection checks, workflows, jobs, job cancellation, job details, failed files, job downloads, templates, and deterministic async job lifecycles.
* API-key authentication, scope families, document validation, event producers, webhook subscriptions, signed delivery attempts, retries, replay, failure injection, and admin inspection.
**Known limitations**
* Unsupported file extensions, encrypted files, invalid PDFs, retired VLM models, unsupported VLM provider/model pairs, and invalid auth scopes return structured errors.
* On-demand jobs enforce modeled constraints such as file count, file size, launch spacing, and concurrent active job limits.
* Some output-format behavior is approximated; unsupported output formats fall back to JSON unless callers request CSV explicitly.
**MCP tools:** `get_twin_catalog`, `provision_twins`, `start_url_validation`, `get_validation_results`.
# Scenarios
Source: https://docs.argalabs.com/features/custom-scenarios
Reusable starting state for Twin Runs
Scenarios define the starting state for one or more digital twins. They can contain Slack channels with message history, Stripe customers with subscriptions, GitHub repositories with open pull requests, and other provider-specific data.
Use a Scenario when you want a short-lived Twin Run to start from known data or a persistent twin environment to return to the same baseline after a reseed.
## Preset scenarios
Arga ships with 10 built-in scenario templates covering common testing patterns. These are available to all users and can be cloned to customize.
### Functionality
| Scenario | Twins | What's inside |
| --------------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **E-commerce Checkout** | Stripe, Slack | 3 customers on free/pro/enterprise plans, #orders channel with purchase confirmations, #support with billing questions |
| **SaaS Billing & Upgrades** | Stripe, Slack, Notion | Trial user expiring in 2 days, free/pro/enterprise customers, monthly+annual pricing, #billing alerts, pricing docs |
| **DevOps CI/CD Pipeline** | GitHub, Slack, Discord | 2 repos (passing and failing CI), merged and open PRs, #deploys and #incidents channels, #dev-alerts Discord |
| **Customer Support Portal** | Slack, Stripe, Notion | #support-tier1 with 8 open tickets, #support-escalated with 2 critical issues, disputed charges, knowledge base articles |
| **Document Collaboration** | Google Drive, Slack, Notion | Q2 Planning shared folder with 4 docs, #team-docs with file share notifications, project wiki pages |
### Security
| Scenario | Twins | What's inside |
| ------------------------------------ | --------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| **Payment Fraud & Edge Cases** | Stripe, Slack | Declined cards (insufficient funds, expired, stolen), \$500 chargeback, partial refunds, #fraud-alerts channel |
| **Access Control & Auth Boundaries** | GitHub, Slack, Notion | Protected branches, outside contributor PRs, confidential issues, admin/member/guest Slack roles, mixed-permission Notion pages |
### Edge cases
| Scenario | Twins | What's inside |
| ---------------------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| **High Volume Messaging** | Slack, Discord | 50+ messages in #general, 20 threaded discussions, 5 DM conversations, 30+ Discord messages per channel with embeds |
| **Internationalization & Unicode** | Slack, Stripe, Notion | Messages in Japanese/Arabic/Portuguese, emoji-heavy content, international addresses (JP, DE, BR), multi-currency (USD/EUR/JPY), RTL text |
| **Calendar Scheduling Conflicts** | Google Calendar, Slack | Overlapping meetings, back-to-back events, all-day events across timezones, cancelled-but-visible meetings, #scheduling channel |
### Using presets
**From the web app:** Open **Scenarios** in the sidebar. Preset templates appear at the top. Select **Use in Run** to open a Twin Run with that Scenario, or **Clone** to save an editable copy.
**From the API:**
```bash theme={null}
# List all presets
curl https://api.argalabs.com/scenarios/presets
# Filter presets by twin
curl "https://api.argalabs.com/scenarios/presets?twin=stripe"
```
**From the CLI:**
```bash theme={null}
# Provision twins from a preset
arga previews twins provision \
--twins stripe,slack \
--scenario-id \
--wait
```
You can list presets and manage custom scenarios with `arga test-runner scenarios ...`.
## Custom scenarios
Create your own scenarios tailored to your application. There are two ways to define the twin data:
* **Natural language** — describe what you want and Arga generates the seed configuration automatically
* **Explicit config** — provide the exact JSON for each twin
When you use a natural-language prompt, Arga runs a two-pass pipeline to generate the seed configuration:
1. **Twin selection** — a classifier reads your prompt and picks the single most relevant twin. It always prefers provider-specific twins (`slack`, `discord`, `notion`, `gmail`, `google_drive`, `google_docs`, `google_sheets`, `google_workspace`, `google_calendar`, `stripe`, `github`, `gitlab`, `dropbox`, `box`, `jira`, `salesforce`, `linear`, `postgres`, `unstructured`) over `unified`. The `unified` twin is only selected when the prompt explicitly mentions "unified" or "unified.to". Multiple twins are selected only when the prompt explicitly names more than one provider (for example, "a GitHub repo AND a Slack workspace").
2. **Config generation** — a second pass generates the seed JSON scoped to the selected twin(s). Any secondary details that don't map to the chosen twin's schema are either mapped to the closest available field or omitted.
If you need full control over which twins are included, pass the `twins` array explicitly alongside your `seed_config`.
### From the web app
1. Open **Scenarios** in the sidebar
2. Click **Create Scenario**
3. Enter a name and either a natural language prompt or raw JSON config
4. Save — Arga generates and stores the twin configuration
You can also save a Scenario while configuring a Twin Run, then reuse it later.
### From a twin dashboard
Browser-facing twin UIs (Box, Discord, Dropbox, GitHub, GitLab, Gmail, Google Calendar, Google Drive, Linear, LinkedIn, Notion, Slack, Stripe, Unified, Unstructured) include a **Save scenario** button in the dashboard header. Clicking it captures the twin's current state as a `seed_config` payload and hands it off to the Arga web app, which opens the scenario creation flow pre-filled with that configuration. Use it to turn a hand-crafted twin state into a reusable scenario without copying JSON manually.
### From the API
**With a natural language prompt:**
```bash theme={null}
curl -X POST https://api.argalabs.com/scenarios \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"name": "E-commerce checkout",
"description": "Stripe with test customers and Slack with support channel",
"prompt": "A Stripe account with 3 customers on different plans and a Slack workspace with a #support channel containing 10 recent messages about billing issues"
}'
```
**With explicit config:**
```bash theme={null}
curl -X POST https://api.argalabs.com/scenarios \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"name": "Onboarding flow",
"twins": ["slack", "stripe"],
"seed_config": {
"slack": {
"channels": [
{"name": "general", "messages": [{"text": "Welcome to the team!", "user": "admin"}]}
]
},
"stripe": {
"customers": [{"name": "Test User", "email": "test@example.com"}]
}
}
}'
```
### From the CLI
Create a scenario from a prompt:
```bash theme={null}
arga test-runner scenarios create \
--name "E-commerce checkout" \
--prompt "Stripe with 3 customers and Slack with #support billing messages" \
--twin stripe \
--twin slack \
--tag checkout
```
Import or export explicit seed JSON for agent-authored scenarios:
```bash theme={null}
arga test-runner scenarios import --file scenario.json
arga test-runner scenarios export --output scenario.json
arga test-runner scenarios update --file scenario.json
```
Use a Scenario to seed a Twin Run:
```bash theme={null}
arga previews twins provision \
--twins stripe,slack \
--scenario-id \
--wait
```
## Managing scenarios
### List
```bash theme={null}
curl https://api.argalabs.com/scenarios \
-H "Authorization: Bearer "
```
Filter by twin or tag:
```bash theme={null}
curl "https://api.argalabs.com/scenarios?twin=slack&tag=billing" \
-H "Authorization: Bearer "
```
Include presets alongside your scenarios:
```bash theme={null}
curl "https://api.argalabs.com/scenarios?include_presets=true" \
-H "Authorization: Bearer "
```
### Update
```bash theme={null}
curl -X PUT https://api.argalabs.com/scenarios/ \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{"prompt": "Updated description of the data I want"}'
```
If you update the prompt without providing a new `seed_config`, Arga regenerates the configuration from the updated prompt.
### Delete
```bash theme={null}
curl -X DELETE https://api.argalabs.com/scenarios/ \
-H "Authorization: Bearer "
```
## Use a Scenario with twins
To start fresh twins from a Scenario, pass both `twins` and `scenario_id` to the [Provision twins](/api-reference/post-provision-twins) API:
```bash theme={null}
curl -X POST https://api.argalabs.com/validate/twins/provision \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"twins": ["stripe", "slack"],
"scenario_id": "",
"ttl_minutes": 60
}'
```
Arga seeds the twins before the run becomes `ready`. Point your app or agent at the returned provider URLs, then run your tests against that software.
### Persistent twin environments
A saved Scenario can also own a persistent twin environment. From the Twin Runs UI, choose a persistent session and a saved Scenario. Arga creates stable twin URLs that you can inspect, reseed from the Scenario, or tear down later.
The API exposes create-or-get, status, reseed, and delete operations under `/scenarios/{scenario_id}/twin-environment`. The Python and TypeScript SDKs expose the same lifecycle through their `scenarios` resources.
## Supported twins
| Twin | What you can seed |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `slack` | Channels, messages, threads, users, OAuth bot scopes, OAuth user scopes, custom tokens, tier (`free`, `pro`, `business_plus`, `enterprise`), disabled scopes, [workspace constraints](/concepts/digital-twins#slack-twin-workspace-constraints) (file upload toggle, storage quotas, rate limits, message history limits, app install limits, workflow toggle) |
| `discord` | Guilds, channels, messages, members, boost level, file upload and emoji limits. Seed results include `guild_id` and `channel_ids` for referencing created resources. |
| `github` | Users, orgs, repos, files, branches, pull requests, merged PR refs, issues, labels, CI/status data, reviews, git references, branch protection, GitHub App configuration, default token scopes, disabled scopes |
| `gitlab` | Groups, projects, repository files, branches, issues, merge requests, pipelines, and hooks |
| `stripe` | Customers, products, prices, subscriptions, billing meters (with meter events) |
| `notion` | Pages, databases, blocks, workspace plan (`free`, `plus`, `business`, `enterprise`), disabled capabilities |
| `gmail` | Labels, messages, threads, and drafts |
| `google_drive` | Folders, files, storage tier (`free`, `basic`, `premium`, `ai_pro`), disabled scopes |
| `google_docs` | Documents with titles and body content |
| `google_sheets` | Spreadsheets, sheets, cell values, formulas, formatting, and developer metadata |
| `google_workspace` | People, contact groups, Workspace Events subscriptions, Apps Script projects, and Pub/Sub resources |
| `google_calendar` | Calendars, events |
| `jira` | Projects, issues, comments, worklogs, and webhooks |
| `salesforce` | Accounts, contacts, cases, and email templates |
| `box` | Folders, files |
| `dropbox` | Folders, files, account tier (`basic`, `plus`, `professional`, `business`) |
| `linear` | Teams, projects, cycles, issues, labels, and comments |
| `salesforce` | Accounts, contacts, cases, email templates, and email messages |
| `postgres` | Raw SQL statements applied to the mirrored data plane |
### Slack OAuth scope overrides
The Slack twin enforces OAuth scope requirements on API calls. You can customize the scopes granted to bot and user tokens by including `oauth_bot_scopes`, `oauth_user_scopes`, or `tokens` in the Slack seed configuration. This is useful for testing how your app handles missing permissions.
```json theme={null}
{
"slack": {
"channels": [{"name": "general"}],
"oauth_bot_scopes": ["chat:write", "channels:read"],
"oauth_user_scopes": ["search:read", "channels:read"],
"tokens": [
{
"token": "xoxb-custom-token",
"user_id": "UTWINBOT",
"scopes": ["chat:write", "channels:read", "files:write"],
"is_bot": true
}
]
}
}
```
Bot tokens always receive `chat:write` and `files:write` as minimum scopes, even if your configuration specifies a narrower set. See [configurable token scopes](/concepts/digital-twins#slack-twin-configurable-token-scopes) for the full list of available scopes and their corresponding API methods.
### Slack workspace constraints
You can configure workspace-level settings in the Slack seed to test how your app handles restricted environments — disabled file uploads, storage quotas, and rate limits.
```json theme={null}
{
"slack": {
"channels": [{"name": "general"}],
"file_uploads_enabled": false,
"max_storage_bytes": 5368709120,
"storage_used_bytes": 5000000000,
"rate_limiting_enabled": true,
"rate_limits": {
"files.getUploadURLExternal": {
"window_seconds": 60,
"max_requests": 5,
"retry_after_seconds": 30
}
}
}
}
```
| Field | Type | Default | Description |
| ----------------------- | ----------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `file_uploads_enabled` | `boolean` | `true` | Set to `false` to simulate a workspace with file uploads disabled. Returns a `file_uploads_disabled` error on upload attempts. |
| `max_storage_bytes` | `integer \| null` | `null` | Workspace storage quota in bytes. When set, uploads that would exceed the quota return a `storage_limit_reached` error. |
| `storage_used_bytes` | `integer` | `0` | Pre-existing storage usage in bytes. Combine with `max_storage_bytes` to simulate a nearly-full workspace. |
| `rate_limiting_enabled` | `boolean` | `false` | Whether per-method rate limiting is active. |
| `rate_limits` | `object` | `{}` | Map of Slack API method names to rate limit rules. Each rule specifies `window_seconds`, `max_requests`, and `retry_after_seconds`. |
See [workspace constraints](/concepts/digital-twins#slack-twin-workspace-constraints) for the full reference and error response shapes.
### GitHub repository seed config
Each entry in the GitHub seed's `repos` array creates one repository in the twin. You can describe the files inline with `files`, or clone a public GitHub repository to pre-populate the twin with its tracked files.
```json theme={null}
{
"github": {
"repos": [
{
"owner": "scenario-org",
"name": "my-app",
"repo_url": "https://github.com/octocat/Hello-World",
"source_ref": "main",
"branches": [{"name": "feature", "from": "main"}],
"issues": [{"title": "Bug report", "body": "Something broke"}]
}
]
}
}
```
| Field | Type | Description |
| ------------------------------------------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `owner` | `string` | Org or user login that owns the seeded repo. When the owner matches a seeded org, the repo is created under that org; otherwise it is created under the authenticated user. |
| `name` | `string` | Repository name. If omitted, the name is derived from `repo_url` when a clone source is provided, otherwise it falls back to `repo-`. |
| `repo_url` | `string` | Public HTTPS `github.com` repository URL or `owner/repo` shorthand. The runner shallow-clones the repo and seeds its tracked files into the twin. Aliases: `public_repo_url`, `clone_url`, `source_repo_url`. |
| `source_ref` | `string` | Branch or tag to clone from the public source repo. Falls back to `ref` when not set. Defaults to the source repo's default branch. |
| `files` | `array` | Inline files to seed after any cloned files. When `repo_url` is set, `files` is only used if the field is explicitly present in the spec. |
| `branches` | `array` | Additional branches to create on the seeded repo. |
| `issues` | `array` | Issues to seed on the repo. |
| `private`, `default_branch`, `language`, `description` | various | Standard repository metadata. |
When cloning from `repo_url`, the runner enforces these limits per repository to keep seeding fast and bounded:
* Only public HTTPS `github.com` URLs are accepted. Credentialed URLs are rejected.
* Up to 1,000 tracked files are copied.
* Each file must be 1 MiB or smaller; symlinks are skipped.
* The total cloned payload is capped at 25 MiB. Files beyond the limit are skipped.
## Tags
Organize scenarios with free-form tags for filtering:
```json theme={null}
{
"name": "Payment edge cases",
"tags": ["billing", "edge-cases", "stripe"]
}
```
Filter by tag in the API (`?tag=billing`) or web app.
# Use the Google Workspace CLI with Arga twins
Source: https://docs.argalabs.com/features/google-workspace-cli
Configure gws to use separate Arga Drive, Docs, and Sheets APIs with synchronized run-scoped state
Arga provisions Google Drive, Google Docs, and Google Sheets as separate twins. Docs and Sheets each include their provider-compatible API and an interactive editor UI. When you combine these twins under one Twin Run ID, they share synchronized file state while keeping their API surfaces separate. The Google Workspace CLI (`gws`) reads a separate Discovery document for each service, so one CLI session can use all three.
## Prerequisites
Install `jq`, `curl`, and `gws`, then authenticate the Arga CLI:
```bash theme={null}
uv tool install arga-cli
npm install -g @googleworkspace/cli
arga login
```
Provision only the services your workflow calls. This example includes Drive metadata and both editor APIs.
```bash theme={null}
TWIN_JSON="$(arga twin-runs create \
--twins google_drive,google_docs,google_sheets \
--ttl 60 \
--wait \
--json)"
RUN_ID="$(printf '%s' "$TWIN_JSON" | jq -r '.run_id')"
```
Create an isolated `gws` configuration directory and cache each provisioned service's Discovery document.
```bash theme={null}
export ARGA_DRIVE_URL="$(printf '%s' "$TWIN_JSON" \
| jq -r '.twins.google_drive.base_url')"
export ARGA_DOCS_URL="$(printf '%s' "$TWIN_JSON" \
| jq -r '.twins.google_docs.base_url')"
export ARGA_SHEETS_URL="$(printf '%s' "$TWIN_JSON" \
| jq -r '.twins.google_sheets.base_url')"
export GOOGLE_WORKSPACE_CLI_TOKEN="$(printf '%s' "$TWIN_JSON" \
| jq -r '.twins.google_drive.env_vars.GOOGLE_ACCESS_TOKEN')"
export GOOGLE_WORKSPACE_CLI_CONFIG_DIR="$(mktemp -d)"
mkdir -p "$GOOGLE_WORKSPACE_CLI_CONFIG_DIR/cache"
curl -fsSL \
"$ARGA_DRIVE_URL/discovery/v1/apis/drive/v3/rest" \
-o "$GOOGLE_WORKSPACE_CLI_CONFIG_DIR/cache/drive_v3.json"
curl -fsSL \
"$ARGA_DOCS_URL/discovery/v1/apis/docs/v1/rest" \
-o "$GOOGLE_WORKSPACE_CLI_CONFIG_DIR/cache/docs_v1.json"
curl -fsSL \
"$ARGA_SHEETS_URL/discovery/v1/apis/sheets/v4/rest" \
-o "$GOOGLE_WORKSPACE_CLI_CONFIG_DIR/cache/sheets_v4.json"
```
`gws` now generates its normal Drive, Docs, and Sheets commands from the three twin Discovery documents. Do not run `gws auth login`; the twin token provides authentication.
The default Drive metadata includes the same stable Docs and Sheets IDs exposed by the editor twins.
```bash theme={null}
gws drive files get \
--params '{"fileId":"google-docs-launch-notes"}'
gws docs documents get \
--params '{"documentId":"google-docs-launch-notes"}'
gws drive files get \
--params '{"fileId":"google-sheets-launch-plan"}'
gws sheets +read \
--spreadsheet google-sheets-launch-plan \
--range "Sheet1!A1:B10"
```
Open `$ARGA_DOCS_URL` or `$ARGA_SHEETS_URL` in your browser to inspect and edit each twin through its UI. UI and API changes use the same run-scoped state, so an edit in Docs or Sheets is reflected in the matching Drive file.
```bash theme={null}
arga twin-runs teardown "$RUN_ID"
```
Within one Twin Run ID, any two or more selected twins from `google_drive`, `google_docs`, and `google_sheets` share file metadata, content, permissions, revisions, creates, edits, renames, trash, and deletes. State never carries across different Twin Run IDs.
`TWIN_JSON` and `GOOGLE_WORKSPACE_CLI_TOKEN` contain credentials. Do not print, commit, or share them. Repeat the configuration step for each new Twin Run.
See the [Google Drive](/concepts/twin-reference#google-drive), [Google Docs](/concepts/twin-reference#google-docs), and [Google Sheets](/concepts/twin-reference#google-sheets) twin references for supported API and UI behavior.
# Testing integrations locally
Source: https://docs.argalabs.com/features/local-testing
Use digital twins as drop-in replacements for third-party APIs during local development
When your app integrates with services like Stripe, Slack, or Notion, testing locally means either hitting real APIs (risky, rate-limited, costs money) or maintaining hand-written mocks (fragile, always out of date). Arga's digital twins give you a third option: spin up API-compatible replicas of these services and point your local app at them.
## How it works
Each twin is a full API emulator that runs on Arga's infrastructure and is reachable via a public URL. Your app talks to the twin URL instead of `api.stripe.com` or `api.slack.com` — no code changes needed beyond swapping environment variables.
```text theme={null}
Your local app
│
├── SLACK_BOT_TOKEN → twin token
├── Slack API calls → https://...--slack.sandbox.argalabs.com
│
├── STRIPE_SECRET_KEY → sk_test_...
└── Stripe API calls → https://...--stripe.sandbox.argalabs.com
```
Twins maintain realistic state (users, channels, files, payments), support webhooks, and behave like the real service — so you can test end-to-end flows without side effects. Twins start with minimal auth infrastructure and no content; use [scenario seeding](/features/custom-scenarios) or API calls to populate the data your tests need.
## Spin up twins
From your project directory:
```bash theme={null}
npx arga-wizard
```
```bash theme={null}
arga wizard
```
The CLI version uses your saved API key from `arga login`, so you skip the key prompt.
The wizard walks you through three steps:
1. **Select twins** — pick the services your app uses (Slack, Stripe, Notion, etc.)
2. **Review `.env` changes** — the wizard detects your environment variables and rewrites them to point at twins. Your original `.env` is backed up to `.env.arga-backup`.
3. **Wait for provisioning** — twins spin up in under a minute
Once ready, start your app normally. All API calls to the selected services now route through twins.
## Example: testing a Stripe checkout flow
```bash theme={null}
# 1. Spin up a Stripe twin
npx arga-wizard
# → Select "Stripe", approve .env changes, wait for provisioning
# 2. Start your app as usual
npm run dev
# 3. Test checkout in your browser — payments go to the twin
# Use Stripe test card numbers (4242 4242 4242 4242, etc.)
# 4. When you're done, tear down or let the session expire
arga wizard teardown
```
The Stripe twin supports customers, payment intents, subscriptions, checkout sessions, webhooks, and more. Test card numbers trigger the same outcomes (declines, 3D Secure) as Stripe's own test mode.
## Example: testing Slack messaging workflows
```bash theme={null}
# 1. Spin up a Slack twin
npx arga-wizard
# → Select "Slack", approve .env changes
# 2. Start your app
npm run dev
# 3. Open the twin dashboard to send messages and inspect app behavior
# Dashboard URL is printed after provisioning
# 4. Reset state and test again
arga wizard reset
```
The Slack twin starts with a workspace and users but no channels — create them through [scenario seeding](/features/custom-scenarios) or the `conversations.create` API. It also supports OAuth flows if your app has an "Add to Slack" install step.
## Managing your session
Twin sessions last **10 minutes** by default. Use these commands from your project directory:
| Command | What it does |
| ---------------------- | ----------------------------------------------------- |
| `arga wizard status` | Check if twins are still running and when they expire |
| `arga wizard extend` | Add another 10 minutes |
| `arga wizard reset` | Reset all twins to their initial empty state |
| `arga wizard teardown` | Destroy the session immediately |
Session state is tracked in `.arga-session.json` in your project root. Add it to your `.gitignore`.
From that same project directory, `arga runs logs` can read `.arga-session.json` automatically, so you can inspect the current logs snapshot for the active run without passing a run ID. Add `--errors-only` to focus on failed worker logs and warning/error runtime logs.
## Restoring your original environment
```bash theme={null}
cp .env.arga-backup .env
```
Or just tear down the session — but remember to restore your `.env` manually since teardown doesn't revert it.
## Available twins
| Service | Type | What you can test |
| ------------------------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------- |
| [Stripe](/concepts/twin-reference#stripe) | UI | Payments, subscriptions, checkout, webhooks, billing portal, billing meters, dashboard |
| [Slack](/concepts/twin-reference#slack) | UI | Messaging workflows, OAuth install flow, file uploads |
| [Discord](/concepts/twin-reference#discord) | UI | Channel workflows, file uploads |
| [GitHub](/concepts/twin-reference#github) | UI | Repos, PRs, issues, branches, commits, check runs, webhooks, OAuth |
| [GitLab](/concepts/twin-reference#gitlab) | UI | Projects, merge requests, pipelines, hooks, REST and GraphQL |
| [Datadog](/concepts/twin-reference#datadog) | UI | Metrics, logs, monitors, dashboards, incidents, SLOs, downtime, and synthetics |
| [Gmail](/concepts/twin-reference#gmail) | UI | Mailbox flows, drafts, labels, threads, and watches |
| [Google Drive](/concepts/twin-reference#google-drive) | UI | Drive files, sharing, permissions, uploads, and native-file metadata |
| [Google Docs](/concepts/twin-reference#google-docs) | UI | Docs v1 documents plus document browsing, rich-text editing, sharing, and export |
| [Google Sheets](/concepts/twin-reference#google-sheets) | UI | Sheets v4 spreadsheets plus grid editing, formula input, sheet tabs, sharing, and export |
| [Google Workspace](/concepts/twin-reference#google-workspace) | Backend | People, Workspace Events, Apps Script, Pub/Sub, and helper task APIs |
| [Google Calendar](/concepts/twin-reference#google-calendar) | UI | Event CRUD, calendar management |
| [Dropbox](/concepts/twin-reference#dropbox) | UI | File storage, uploads, downloads |
| [Notion](/concepts/twin-reference#notion) | UI | Pages, databases, workspace management |
| [Box](/concepts/twin-reference#box) | Backend | File storage, enterprise management |
| [Jira](/concepts/twin-reference#jira) | Backend | Issues, projects, JQL, Agile, comments, and webhooks |
| [Linear](/concepts/twin-reference#linear) | Backend | GraphQL teams, projects, cycles, issues, labels, comments, OAuth, and webhooks |
| [Salesforce](/concepts/twin-reference#salesforce) | Backend | sObject CRUD, SOQL/SOSL, composite, limits and actions, support-style case and email-template flows |
| [Waterfall](/concepts/twin-reference#waterfall) | Backend | Company search, people search, enrichment, verification, and account lookups |
| [Unified](/concepts/twin-reference#unified) | Backend | Aggregated API across Slack, Drive, Calendar, Notion, Dropbox |
| [Unstructured](/concepts/twin-reference#unstructured) | Backend | Document parsing and partitioning |
**API + UI twins** have an interactive browser interface where you can see and manipulate state. **API-only twins** respond to API calls but don't have a visual interface.
See the [twin reference](/concepts/twin-reference) for per-twin support, limitations, and MCP tool coverage. See the [twins quickstart](/features/twins-quickstart) for quickstart state and environment variables.
## Tips
After spinning up twins and starting your app, run an Arga validation against your local deployment (exposed via a tunnel like ngrok or Cloudflare Tunnel) to get automated browser-level testing with twins backing every integration.
```bash theme={null}
# Expose your local app
ngrok http 3000
# Validate with Arga
arga test-runner runs url --url https://your-ngrok-url.ngrok.io --prompt "complete a checkout with Stripe"
```
You can provision twins in a CI pipeline by calling the API directly or running `npx arga-wizard` non-interactively. Set `ARGA_API_KEY` as a secret and the wizard will skip the key prompt.
Add these to your `.gitignore`:
```text theme={null}
.arga-session.json
.env.arga-backup
```
# PR Test Runs
Source: https://docs.argalabs.com/features/pr-validation
Run saved or generated tests from pull requests and branch pushes
PR Test Runs connect a GitHub repository to Arga. When the configured event occurs, Arga chooses relevant generated tests or selected Saved Tests, runs them against the repository's configured application URL, and publishes an **Arga Validation** check.
PR Test Runs do not create a per-PR application sandbox or redeploy the services changed by the pull request. Your application target must already be deployed and reachable by the runner.
## Set up PR Test Runs
In the web app, open **PR Test Runs** and select the repository you want to monitor.
Install the Arga GitHub App on the selected repository. This lets Arga receive repository events and publish checks.
Select one of these modes:
* **Pull requests** runs when a pull request is opened, reopened, marked ready for review, or updated.
* **Commits to branch** runs on pushes to one selected branch.
Add optional repository-specific instructions. For pull-request triggers, choose whether Arga should also post a bot comment when the run finishes.
Enable validation. New matching GitHub events now create PR Test Runs and publish the result as an **Arga Validation** check.
PR Test Runs require a Team or Paid plan.
## Choose which tests run
Open **Saved Tests**, select a test associated with the repository, and choose one of these modes:
* **Automatically run relevant tests** lets Arga select tests from the pull request or branch change.
* **Run selected saved tests** pins specific saved tests to the repository.
You create Saved Tests from completed [Test Runs](/features/validate-modes#test-runs). Saved tests remain editable, including their blocks, parameters, assertions, credentials, and repository association.
## Review runs
The **PR Test Runs** page shows recent activity for the selected repository. You can search by branch name or pull-request number and see the status, commit SHA, trigger type, and start time.
Open a row to inspect the run details. GitHub also links to the result from the **Arga Validation** check. If PR comments are enabled, Arga posts a completion summary on the pull request.
## Pause or skip validation
Use **Disable validation** to stop new automatic runs without removing the repository configuration.
To skip one head commit, include `[skip arga]` in its commit message. Arga completes the GitHub check with a neutral result instead of starting a run.
## CLI setup
```bash theme={null}
# Install validation for a repository
arga previews pr-checks install owner/repo
# Run on pull-request updates
arga previews pr-checks config-set owner/repo --trigger pr --comments on
# Or run on pushes to a branch
arga previews pr-checks config-set owner/repo \
--trigger branch \
--branch main
# Inspect enabled repositories
arga previews pr-checks enabled
```
You can also start a run manually:
```bash theme={null}
arga previews pr-checks run --repo owner/repo --pr 42
```
See the [CLI reference](/cli-and-mcp) and [PR Test Runs API](/api-reference/ci-github-save-config) for more options.
# Twins quickstart
Source: https://docs.argalabs.com/features/twins-quickstart
Set up digital twins for your staging environment in minutes
The `arga-wizard` CLI provisions [digital twins](/concepts/digital-twins) for your project and rewrites your environment config so your staging app talks to twins instead of real third-party APIs.
## Prerequisites
* **Node.js 18+** installed
* An **Arga API key** — either a quickstart key from [email signup](https://app.argalabs.com/get-started) (limited to 5 provisions) or a full-access key via `arga login` or from [Settings → API Keys](https://app.argalabs.com/settings/api-keys)
## Run the wizard
From your project directory:
```bash theme={null}
npx arga-wizard
```
Or if you already have the Arga CLI installed:
```bash theme={null}
arga wizard
```
The CLI version automatically passes your saved API key, so you skip the key prompt.
The wizard lists all available twins grouped by type. Pick the services your app integrates with.
```text theme={null}
? Which API twins do you need? (Space to select, Enter to confirm)
-- API + UI Twins (interactive browser interface) --
[ ] Attio api.attio.com
[ ] Check api.checkhq.com, sandbox.checkhq.com
[ ] Datadog api.datadoghq.com, http-intake.logs.datadoghq.com
[x] Discord discord.com, api.discord.com
[ ] Documenso app.documenso.com
[ ] Dropbox api.dropboxapi.com
[ ] GitHub api.github.com, github.com, raw.githubusercontent.com
[ ] GitLab gitlab.com
[ ] Gmail gmail.googleapis.com
[ ] Google Calendar www.googleapis.com/calendar/v3
[ ] Google Docs docs.googleapis.com
[ ] Google Drive www.googleapis.com/drive/v3
[ ] Google Sheets sheets.googleapis.com
[ ] LinkedIn api.linkedin.com, www.linkedin.com
[ ] Notion api.notion.com
[ ] QuickBooks quickbooks.api.intuit.com
[ ] Resend api.resend.com
[x] Slack api.slack.com, slack.com
[ ] Stripe api.stripe.com
[ ] Trolley api.trolley.com
-- API-only Twins --
[ ] Box api.box.com
[ ] Google Workspace people.googleapis.com, workspaceevents.googleapis.com, script.googleapis.com, pubsub.googleapis.com
[ ] HubSpot api.hubapi.com
[ ] Jira *.atlassian.net
[ ] Linear api.linear.app
[ ] Salesforce *.salesforce.com, *.force.com
[ ] Waterfall api.waterfall.io
[ ] Unified api.unified.to
[ ] Unstructured api.unstructuredapp.io
```
**API + UI twins** have an interactive browser interface, such as a dashboard, document editor, or spreadsheet editor. **API-only twins** respond to API calls but don't have a visual interface.
The wizard scans your project for `.env` files and detects environment variables that match your selected twins.
```text theme={null}
Detected changes for .env:
SLACK_BOT_TOKEN= -> xoxb-F9SXMECOSFOGYR3XKXWN
UNSTRUCTURED_API_KEY= -> test-unstructured-key
DROPBOX_APP_KEY=y4pd... -> dropbox-twin-app-key
? Apply these changes? (Y/n)
```
A backup is saved as `.env.arga-backup` before any changes are written.
The wizard spins up ephemeral twin instances. This typically takes under a minute thanks to pre-warmed VMs.
```text theme={null}
Provisioning twin instances...
[1/2] Discord twin .......... ready
[2/2] Slack twin .......... ready
Session expires in 10 minutes.
```
The wizard prints a summary with everything you need:
```text theme={null}
┌──────────────────────────────┐
│ Arga Twins — Ready! │
│ │
│ Dashboard: https://app.argalabs.com/runs/... │
│ │
│ Discord: https://...--discord.sandbox.... │
│ Slack: https://...--slack.sandbox.... │
│ │
│ Session expires: 2026-03-28T14:00:00Z │
│ │
│ Commands: │
│ arga wizard status Check health │
│ arga wizard reset Reset twin state │
│ arga wizard extend Extend by 10 min │
│ arga wizard teardown Destroy session │
└──────────────────────────────┘
```
Start your app normally — all API calls to the selected services are now routed through twins.
## Provision directly with the CLI
Use the catalog identifier with `arga twin-runs create`. Google services are
separate provisioning units, so request only the surfaces your app calls or
combine them in one run:
```bash theme={null}
arga twin-runs create --twins datadog --ttl 60 --wait
arga twin-runs create --twins google_docs --ttl 60 --wait
arga twin-runs create --twins google_sheets --ttl 60 --wait
arga twin-runs create --twins google_workspace --ttl 60 --wait
arga twin-runs create --twins google_drive,google_docs,google_sheets --ttl 60 --wait
```
When you include any two or more of `google_drive`, `google_docs`, and `google_sheets` in the same Twin Run, they keep one run-scoped file state synchronized across their separate APIs and UIs. Different Twin Run IDs remain isolated.
## What the wizard does
Under the hood, the wizard:
1. **Validates your API key** against the Arga API (or reads it from `~/.config/arga/config.json` if you've run `arga login`)
2. **Provisions twin containers** on Arga's infrastructure via `POST /validate/twins/provision`
3. **Rewrites your `.env`** to replace real API tokens with twin-compatible defaults
4. **Creates minimal auth infrastructure** (tokens, bot users, root folders) so twins are ready to accept API calls — content is populated through [scenario seeding](/features/custom-scenarios)
5. **Writes a `.arga-session.json`** file that tracks the session for subsequent commands
## Available twins
**Type:** UI twin (interactive CRM)
**Intercepts:** `api.attio.com`
**Supports:** Objects, attributes, records, lists, entries, notes, tasks, comments, meetings, files, webhooks, OAuth, and API rate limits.
**Type:** UI twin (Check Console)
**Intercepts:** `api.checkhq.com`, `sandbox.checkhq.com`
**Supports:** Companies, employees, contractors, payrolls, payments, reports, documents, webhooks, and deterministic payroll lifecycle testing without moving money.
**Type:** UI twin (interactive dashboard)
**Intercepts:** `discord.com`, `api.discord.com`, `discordapp.com`
**Quickstart state:**
* Server: "Default Server"
* Users: `twin-bot` (bot)
* Bot token: `fake-bot-token`
* Channels, roles, members, and messages start empty — populate them through [scenario seeding](/features/custom-scenarios) or API calls
**File uploads:** The Create Message endpoint accepts `multipart/form-data` requests with file attachments. Send files as `files[n]` or `file` form parts alongside a `payload_json` field (or a plain `content` field) and the twin records each upload as an attachment on the created message.
**Type:** UI twin (interactive dashboard)
**Intercepts:** `api.slack.com`, `slack.com`, `files.slack.com`
**Quickstart state:**
* Workspace: "Default Workspace"
* Users: `slack-twin-bot` (bot), `slack-twin-user` (human)
* Bot token: `xoxb-F9SXMECOSFOGYR3XKXWN`
* User token: `xoxp-slack-twin-user-token`
* OAuth client ID: `slack-twin-client-id`
* OAuth client secret: `slack-twin-client-secret`
* Default tier: `free` (1 GB max file upload, same as `pro`, `business_plus`, `enterprise`, and `paid` tiers; see the [admin API](/concepts/digital-twins#slack-twin-tier-limits) for tier details)
* Channels start empty — populate them through [scenario seeding](/features/custom-scenarios) or the `conversations.create` API
**OAuth support:** The Slack twin implements the OAuth 2.0 authorization code grant flow. Point your app's Slack OAuth URLs at the twin (via `SLACK_TWIN_BASE_URL`) to test "Add to Slack" install flows without hitting real Slack servers. The twin issues working `xoxb-`, `xoxp-`, and `xoxe.`-prefixed tokens that can be used for subsequent API calls.
**Scope enforcement:** The twin enforces OAuth scope requirements on every authenticated API call. If a token lacks the required scope for a method, the twin returns a `missing_scope` error — matching real Slack behavior. You can [configure the scopes](/concepts/digital-twins#slack-twin-configurable-token-scopes) granted to bot and user tokens via scenario seeding to test permission edge cases.
**Tier limits:** File uploads are subject to tier-based size limits. The twin starts on the `free` tier (1 GB cap — the same as paid tiers). Use the admin API to [switch tiers](/concepts/digital-twins#switching-tiers) (`pro`, `business_plus`, `enterprise`, or `paid`) to test tier-specific behavior. Each tier also controls message history limits, app install limits, and workflow availability.
**Workspace constraints:** The twin supports workspace-level controls for [disabling file uploads, enforcing storage quotas, and simulating rate limits](/concepts/digital-twins#slack-twin-workspace-constraints). Configure these via scenario seeding or the admin API to test how your app handles restricted workspaces.
**Multi-sender UI:** The inspector dashboard lets you post messages and add reactions as any user in the workspace via a sender picker, so you can test multi-user conversation flows without switching tokens manually.
**Type:** UI twin (interactive mailbox)
**Intercepts:** `gmail.googleapis.com`
**Supports:** Inboxes, threads, messages, drafts, labels, attachments, search, send behavior, and watch events.
**Type:** UI twin (interactive dashboard)
**Intercepts:** Drive v3, Drive content/upload, and Drive MCP routes
**Quickstart state:**
* Principals: Drive Twin Owner, Drive Twin Editor
* Owner token: `ya29.drive-twin-owner`
* Docs metadata: `google-docs-launch-notes`
* Sheets metadata: `google-sheets-launch-plan`
Provision `google_docs` or `google_sheets` separately for their editor APIs and UIs. When they share a Twin Run ID with Drive, their matching files stay synchronized with Drive metadata, content, permissions, revisions, and lifecycle changes.
**Type:** API + UI twin (document editor)
**Intercepts:** `docs.googleapis.com`
**Supports:** Docs v1 create, get, atomic batch updates, UTF-16 indexes, text and paragraph styling, and named ranges. The UI supports document browsing, blank-document creation, autosave, bold, italic, underline, sharing, and export. The twin does not publish Drive, Sheets, or the grouped Workspace APIs.
**Preset document:** `google-docs-launch-notes`
**Owner token:** `ya29.drive-twin-owner`
**Type:** API + UI twin (spreadsheet editor)
**Intercepts:** `sheets.googleapis.com`
**Supports:** Sheets v4 spreadsheets, A1 values, batch updates, formulas, formatting, developer metadata, and Discovery. The UI supports spreadsheet browsing, blank-spreadsheet creation, editable cells, a formula bar, sheet tabs, autosave, sharing, and CSV, XLSX, and PDF export. The twin does not publish Drive, Docs, or the grouped Workspace APIs.
**Preset spreadsheet:** `google-sheets-launch-plan`
**Owner token:** `ya29.drive-twin-owner`
When Sheets and Drive share a Twin Run ID, spreadsheet changes and matching Drive metadata stay synchronized.
**Type:** Backend-only
**Intercepts:** `people.googleapis.com`, `workspaceevents.googleapis.com`, `script.googleapis.com`, `pubsub.googleapis.com`
**Supports:** People contacts and groups; Workspace Events subscriptions and operations; Apps Script projects, versions, deployments, processes, and execution; Pub/Sub topics, subscriptions, pull, acknowledge, and IAM helpers; task stream and push-notification helpers.
It does not publish Drive, Docs, Sheets, Gmail, or Calendar routes.
**Type:** UI twin (monitoring overview)
**Intercepts:** Datadog API and log-intake hosts across supported Datadog sites
**Supports:** Metrics, logs, events, monitors, dashboards, notebooks, incidents, SLOs, downtime, and Synthetic API tests, including the common Datadog Pup CLI contracts.
**Credentials:** `DD_API_KEY`, `DD_APP_KEY`, or `DD_ACCESS_TOKEN`
**Type:** UI twin (dashboard, editor, and signing views)
**Intercepts:** `app.documenso.com`
**Supports:** Envelopes, documents, templates, recipients, signing and approval flows, PDF artifacts, captured email, and lifecycle webhooks.
**Type:** UI twin (interactive dashboard)
**Intercepts:** `api.dropboxapi.com`, `content.dropboxapi.com`
**Quickstart state:**
* Root folder initialized — files and folders start empty
* Populate content through [scenario seeding](/features/custom-scenarios) or API calls
**Type:** UI twin (interactive dashboard)
**Intercepts:** `api.github.com`, `github.com`, `raw.githubusercontent.com`
**Quickstart state:**
* Token: `ghp_test-github-twin-token`
* Users, organizations, and repositories start empty — populate them through [scenario seeding](/features/custom-scenarios) or API calls
**Supported resources:** Repositories, pull requests (with merge and reviewer requests), issues, branches (with protection rules), commits, check runs, check suites, git references, labels, pull request reviews, commit statuses, file contents (branch-aware), raw file downloads (`raw.githubusercontent.com/{owner}/{repo}/{ref}/{path}` and `github.com/{owner}/{repo}/raw/{ref}/{path}`, served as public content without a bearer token and resolving slash-containing branch names), search, organizations, users, GitHub App endpoints (installations, access tokens, app metadata, and the manifest registration flow for creating multiple GitHub Apps at runtime), webhooks, and OAuth flows.
**Scope enforcement:** The twin enforces OAuth scope requirements on API calls. Each route requires a specific scope (for example, `repo` for repository operations, `read:user` for user info). Parent scopes grant their children automatically — `repo` implies `repo:status`, `public_repo`, etc. Configure default token scopes via `default_token_scopes` and disable specific scopes via `disabled_scopes`. See [authentication handling](/concepts/digital-twins#authentication-handling) for details.
**State export:** `GET /admin/state` returns a compact summary of the twin by default — schema version, seed, base/logical clocks, high-level counts, and a ready-to-use `seed_config.github` block that can recreate the same state in a new twin. The exported `seed_config.github` includes a per-repo `merged_prs` list of compact merged PR refs alongside the full `prs`/`pull_requests` arrays so merged PR history is preserved on replay. Pass `?full=1` (`GET /admin/state?full=1`) to get the deterministic, replay-oriented snapshot with repos, branches, PR aliases, per-PR changed files with decoded before/after code and patches, webhooks, and check runs. The dashboard's **Save scenario** button hands the compact `seed_config.github` payload to the Arga web app and creates a reusable scenario from it without requiring you to copy JSON manually — see [Save scenario from a twin dashboard](/features/custom-scenarios#from-a-twin-dashboard) for the equivalent flow on other twins.
**Type:** UI twin (interactive dashboard)
**Intercepts:** `gitlab.com`
**Supports:** Projects, repositories, branches, files, commits, issues, merge requests, pipelines, jobs, webhooks, REST v4, GraphQL, `glab`, and GitLab MCP workflows.
**Type:** UI twin (interactive dashboard)
**Intercepts:** `api.notion.com`, `notion.so`
**Quickstart state:**
* Workspace: "Notion Twin Workspace"
* API key: `secret_notion-twin_seed`
* Pages, databases, and users start empty — populate them through [scenario seeding](/features/custom-scenarios) or API calls
**Type:** UI twin (company dashboard)
**Intercepts:** `quickbooks.api.intuit.com`
**Supports:** QuickBooks Online Accounting entities, queries, batch operations, change data capture, reports, attachments, OAuth, and webhooks.
**Type:** UI twin (interactive email dashboard)
**Intercepts:** `api.resend.com`
**Supports:** Single, batch, and scheduled email; domains; contacts; templates; broadcasts; API keys; inbound email; and webhook delivery without sending real email.
**Type:** UI twin (interactive checkout pages)
**Intercepts:** `api.stripe.com`, `files.stripe.com`, `connect.stripe.com`, `mcp.stripe.com`
**Quickstart state:**
* All Stripe API v1 resources start empty (no seeded data by default)
* Use the `/_twin/seed` endpoint to create a starter product, price, and webhook endpoint
* API key prefix: `sk_test_` (any key with a valid prefix is accepted)
**Supported resources:** Customers, payment methods, payment intents, setup intents, charges, refunds, disputes, subscriptions, invoices, invoice items, credit notes, products, prices, plans, coupons, promotion codes, tax rates, shipping rates, tokens, sources, payouts, balance, billing meters, meter events, meter event summaries, events, files, file links, checkout sessions, payment links, quotes, billing portal, subscription items, subscription schedules, usage records, tax IDs, webhook endpoints, mandates, and test clocks.
**Browser pages:** The twin serves browser-facing pages for checkout, billing portal, a multi-page dashboard (`/dashboard` with home, payments, subscriptions, invoices, and balances pages), product catalog (`/products`), and customer management (`/customers`). Use these to inspect twin state visually during a run — the dashboard home shows revenue, MRR, active subscribers, and recent payments; the products page shows all products and their prices; the customers page shows customers with their subscriptions. You can also test end-to-end payment flows including success, card decline, and 3D Secure scenarios through the checkout pages.
**Test cards:** Stripe-compatible test card numbers trigger specific outcomes (declines, 3D Secure challenges, processing errors) — matching the behavior of Stripe's own test mode.
**Webhook delivery:** Register webhook endpoints via the API and the twin delivers signed events (`Stripe-Signature` header) to your application, just like the real Stripe.
**Stripe MCP support:** The twin routes `mcp.stripe.com` and exposes a Stripe-compatible MCP JSON-RPC server at `POST /mcp` and `POST /mcp/v1`. OAuth discovery is served at `GET /.well-known/oauth-protected-resource`, `GET /.well-known/oauth-protected-resource/mcp`, and `GET /.well-known/oauth-authorization-server`. The server advertises the same 31 tools as the official Stripe MCP server (including `create_customer`, `list_customers`, `create_product`, `create_price`, `create_payment_link`, `create_invoice`, `list_subscriptions`, `update_subscription`, `cancel_subscription`, `create_refund`, `retrieve_balance`, `stripe_api_search`, `stripe_api_details`, `stripe_api_execute`, and others) and shares state with the Stripe API and Checkout surfaces. Use it from any MCP client or via the `@stripe/mcp` CLI bridge — requests without an `Authorization: Bearer ` header return `401`.
**Type:** UI twin (dashboard and recipient widget)
**Intercepts:** `api.trolley.com`
**Supports:** Recipients, payout accounts, payments, batches, invoices, balances, Trust verification, signed recipient widgets, and webhooks without moving money.
**Type:** Backend-only
**Intercepts:** `api.box.com`, `upload.box.com`, `app.box.com`
**Quickstart state:**
* Enterprise: "Box Twin Enterprise" (ID: `11446498`)
* Client ID: `box-twin-client-id`
* Client Secret: `box-twin-client-secret`
* Developer token: `box-developer-token`
* Root folder and admin user created — files, sub-folders, and additional users start empty
**Type:** UI twin (interactive dashboard)
**Intercepts:** `www.googleapis.com/calendar/v3`
Calendar v3 API emulator with event CRUD operations. Calendars and events start empty — populate them through [scenario seeding](/features/custom-scenarios) or API calls.
**Type:** Backend-only
**Intercepts:** `api.hubapi.com`
**Supports:** CRM objects, associations, properties, pipelines, owners, lists, files, forms, behavioral events, OAuth, and signed webhooks.
**Type:** Backend-only
**Intercepts:** `*.atlassian.net` (Jira Cloud REST API v3)
**Quickstart state:**
* Cloud site: `test-site.atlassian.net` (cloud ID `11223344-a1b2-3b33-c444-def123456789`)
* OAuth client ID: `jira-twin-client-id`
* OAuth client secret: `jira-twin-client-secret`
* Webhook signing secret: `test-jira-webhook-secret`
* Seeded metadata: priorities (`Highest`, `High`, `Medium`, `Low`, `Lowest`), statuses (`To Do`, `In Progress`, `Done`), issue types (`Task`, `Bug`, `Story`, `Epic`, `Subtask`), transitions, resolutions, and link types
* Projects, issues, comments, worklogs, attachments, components, versions, filters, dashboards, groups, sprints, and boards start empty — populate them through [scenario seeding](/features/custom-scenarios) or API calls
**Supported resources:** Issues (CRUD, bulk create, transitions, changelog, edit metadata, create metadata), projects, comments, worklogs, attachments, issue links, issue properties, votes, watchers, search and JQL search, users (`myself`, search, bulk, assignable, view-issue), components, versions, remote links, filters, dashboards, groups (and group members), fields, priorities, resolutions, statuses, status categories, issue types, server info, webhooks, and Agile endpoints (`/rest/agile/1.0/` boards, sprints, backlog).
**API versioning:** Routes registered under `/rest/api/3/` are also reachable via the `/rest/api/2/` and `/rest/api/latest/` aliases, matching the real Jira Cloud REST API behavior.
**ADF content:** Comments and issue descriptions are stored as [Atlassian Document Format](https://developer.atlassian.com/cloud/jira/platform/apis/document/structure/). Plain strings on input are auto-wrapped in a minimal ADF document so existing SDK calls continue to work.
**OAuth and scope enforcement:** The twin implements the OAuth 2.0 authorization code grant flow at `/authorize` and `/oauth/token`. Every authenticated API call requires a `Bearer` token and is checked against the route's required scope. See [authentication handling](/concepts/digital-twins#authentication-handling) for details on default token scopes (`read:jira-work`, `write:jira-work`, `read:jira-user`, `manage:jira-project`, `manage:jira-webhook`, `manage:jira-configuration`), parent-child scope expansion, and disabling scopes for testing.
**Webhook delivery:** Register webhook endpoints via `POST /rest/api/3/webhook` and the twin delivers signed events for issue and comment changes.
**Admin endpoints:** `GET /admin/state`, `POST /admin/reset`, `POST /admin/clock` (advance the twin's clock by `seconds`), `GET /admin/stub-hits`, and `POST /admin/stub-hits/clear`.
**Type:** Backend-only
**Intercepts:** `api.linear.app`, `linear.app`
**Quickstart state:**
* GraphQL endpoint ready at `POST /graphql`
* Default personal API key: `lin_api_twin_owner_personal_key_0001` (sent in `Authorization` with no `Bearer` prefix)
* Teams, projects, cycles, issues, labels, comments, tokens, and webhooks start empty — populate them through [scenario seeding](/features/custom-scenarios) or API calls
**Supported resources:** GraphQL queries and mutations for teams, projects, cycles, issues, labels, comments, workflow states, users, organization, and webhooks. Built to match the schema documented at [Linear's GraphQL reference](https://linear.app/developers/graphql) and the wire-level behavior of the [`@linear/sdk`](https://www.npmjs.com/package/@linear/sdk) client.
**Authentication:** Personal API keys are sent in `Authorization` without a `Bearer` prefix. OAuth 2.0 tokens are sent as `Authorization: Bearer ` and issued through `GET`/`POST /oauth/authorize`, `POST /oauth/token`, and `POST /oauth/revoke`, with scope enforcement and refresh tokens.
**SDK compatibility:** Responses include `__typename` on every entity, relations are returned as `{ id }` in default selections, and error envelopes surface `extensions.type` values the SDK dispatches on (`"authentication error"`, `"invalid input"`, `"ratelimited"`, `"feature not accessible"`).
**Webhook delivery:** Register subscriptions via `POST /admin/webhooks`. Deliveries include `Linear-Signature` (lowercase-hex HMAC-SHA256), `Linear-Delivery`, `Linear-Event`, and `Linear-Timestamp` headers. Inspect, flush, and replay through `/admin/webhook-events` and `/admin/webhook-deliveries`.
**Admin endpoints:** `GET /admin/state`, `GET`/`PUT`/`PATCH /admin/config`, `POST /admin/reset`, `POST /admin/clock/advance`, `POST`/`DELETE /admin/webhooks`, `GET /admin/webhook-events`, `GET /admin/webhook-deliveries`, `POST /admin/webhook-events/flush`, `POST /admin/webhook-events/{id}/replay`, and `GET /admin/fidelity`.
**Type:** UI twin (interactive member and post views)
**Intercepts:** `api.linkedin.com`, `www.linkedin.com`
**Supports:** OAuth and OpenID Connect, member profiles, people and email lookup, connections, posts, shares, and media uploads.
**Type:** Backend-only
**Intercepts:** `login.salesforce.com`, `test.salesforce.com`, `*.salesforce.com`, `*.force.com`, `*.my.salesforce.com`
**Quickstart state:**
* Access token: `00D000000000001!salesforce-twin-token`
* Instance URL: `http://twin-salesforce:8080` (replaced with the provisioned twin URL at runtime)
* REST discovery, sObject CRUD, query/search, composite, and limits endpoints ready under `/services/data/v{version}/`
* Accounts, contacts, cases, email templates, email messages, and users start empty — populate them through [scenario seeding](/features/custom-scenarios) or API calls
**Supported resources:** sObject CRUD for Accounts, Contacts, Cases, EmailTemplates, EmailMessages, Users, and related standard objects (including `describe`, `describe/layouts`, `describe/compactLayouts`, `listviews`, relationship traversal, and updated/deleted feeds), SOQL (`/query`, `/queryAll`, `/query/{locator}`), SOSL (`/search`, `/parameterizedSearch`, `/search/scopeOrder`, `/search/layout`), composite endpoints (`/composite`, `/composite/batch`, `/composite/graph`, `/composite/tree/{sobject}`), Bulk API v2 job shells (`/jobs/query`, `/jobs/ingest`), invocable actions (`/actions`, `/actions/standard`, `/actions/custom`) for case creation and email-template send flows, and a Tooling API surface for sobjects, queries, and basic discovery.
**Authentication:** OAuth 2.0 token exchange at `/services/oauth2/token` (and `/oauth2/token`), `userinfo` at `/services/oauth2/userinfo`, identity URLs at `/id/{org_id}/{user_id}`, and bearer-token authentication on every API call.
**Admin endpoints:** `POST /admin/reset`, `GET /admin/state`, `POST /admin/clock`, plus a liveness check at `GET /healthz` (also `GET /health`).
**Type:** Backend-only
**Intercepts:** `api.waterfall.io`
**Quickstart state:**
* Starts empty by default
* API key: `ad18e456-0dd7-45e1-b094-43a0361aedfa`
* Supports company search, people search, enrichment, verification, and account endpoints
**Type:** Backend-only
**Intercepts:** `api.unified.to`, `unified.to`
Creates Unified.to integration connections that proxy to Slack, Google Mail, Google Drive, Google Calendar, Box, Notion, and Dropbox. Use this twin only when your app talks to Unified.to directly. For actual provider data (channels, files, pages, repos, etc.), use the provider-specific twin instead.
**Type:** Backend-only
**Intercepts:** `api.unstructuredapp.io`, `platform.unstructuredapp.io`
**Quickstart state:**
* Partition endpoint ready at `/general/v0/general`
* Jobs endpoint ready at `/api/v1/jobs/`
* API key: `test-unstructured-key`
* Workflow templates start empty — populate them through [scenario seeding](/features/custom-scenarios)
## Environment variables
The wizard recognizes these environment variables per twin and replaces them with twin-compatible defaults:
| Twin | Variables the wizard detects |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------- |
| Discord | `DISCORD_TOKEN`, `DISCORD_BOT_TOKEN` |
| Slack | `SLACK_BOT_TOKEN`, `SLACK_TOKEN`, `SLACK_SIGNING_SECRET`, `SLACK_CLIENT_ID`, `SLACK_CLIENT_SECRET`, `SLACK_TWIN_BASE_URL` |
| Stripe | `STRIPE_SECRET_KEY`, `STRIPE_API_KEY`, `STRIPE_TWIN_BASE_URL`, `STRIPE_TWIN_WEBHOOK_SECRET` |
| Google Drive | `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET`, `GOOGLE_ACCESS_TOKEN` |
| Google Docs | `GOOGLE_ACCESS_TOKEN`, `GOOGLE_DOCS_TOKEN`, `GOOGLE_DOCS_API_URL` |
| Google Sheets | `GOOGLE_ACCESS_TOKEN`, `GOOGLE_SHEETS_TOKEN`, `GOOGLE_SHEETS_API_URL` |
| Google Workspace | `GOOGLE_ACCESS_TOKEN`, `GOOGLE_WORKSPACE_TOKEN`, `GOOGLE_WORKSPACE_API_URL` |
| Datadog | `DD_API_KEY`, `DD_APP_KEY`, `DD_ACCESS_TOKEN`, `DD_API_URL`, `DD_SITE` |
| Dropbox | `DROPBOX_APP_KEY`, `DROPBOX_APP_SECRET`, `DROPBOX_ACCESS_TOKEN` |
| Notion | `NOTION_API_KEY`, `NOTION_TOKEN` |
| Box | `BOX_CLIENT_ID`, `BOX_CLIENT_SECRET`, `BOX_DEVELOPER_TOKEN` |
| Google Calendar | `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` |
| Jira | `JIRA_BASE_URL`, `JIRA_HOST`, `JIRA_CLIENT_ID`, `JIRA_CLIENT_SECRET`, `JIRA_API_TOKEN` |
| Linear | `LINEAR_API_KEY` |
| Salesforce | `SALESFORCE_ACCESS_TOKEN`, `SALESFORCE_INSTANCE_URL` |
| Waterfall | `WATERFALL_API_KEY`, `WATERFALL_API_BASE_URL`, `WATERFALL_API_URL`, `WATERFALL_BASE_URL` |
| Unstructured | `UNSTRUCTURED_API_KEY` |
| Unified | `UNIFIED_API_KEY` |
Variables not associated with a selected twin are left untouched. The original file is always backed up to `.env.arga-backup`.
## Session management
Twin sessions are ephemeral and expire after 10 minutes by default. Use these commands from your project directory:
```bash theme={null}
# Check if your twins are still running
arga wizard status # or: npx arga-wizard status
# Reset all twins to their initial empty state
arga wizard reset # or: npx arga-wizard reset
# Add another 10 minutes to the session
arga wizard extend # or: npx arga-wizard extend
# Tear down immediately and clean up
arga wizard teardown # or: npx arga-wizard teardown
```
Session state is stored in `.arga-session.json` in your project root. Add it to your `.gitignore`.
## Inspect twin session logs
If twin provisioning stalls or a twin behaves unexpectedly, inspect the run logs from your project directory:
```bash theme={null}
arga runs logs
arga runs logs --errors-only
arga runs logs --json
```
Because the wizard writes `.arga-session.json`, `arga runs logs` can resolve the active run automatically from that directory.
These logs describe the Twin Run rather than your app's own application logs. They include worker logs for build, deploy, and warm-up jobs plus runtime logs from the services Arga uses to provision and route the twins. Use `--errors-only` when you want a faster view of failed worker jobs and warning/error runtime entries.
For the full CLI reference and response shape, see [CLI](/cli-and-mcp) and [Get run logs](/api-reference/get-get-run-logs).
## Re-run just the .env step
If you need to update your `.env` without re-provisioning:
```bash theme={null}
arga-wizard env
```
This re-runs twin selection and .env rewriting without spinning up new instances.
## Restoring your original .env
To revert to your original environment variables:
```bash theme={null}
cp .env.arga-backup .env
```
## Next steps
Learn how twins intercept API calls and maintain state.
See support, limitations, and MCP tools for every twin.
Full CLI reference including authentication and validation commands.
Install Arga context tools into your IDE agent.
# Test workflows
Source: https://docs.argalabs.com/features/validate-modes
Choose between Test Runs, Saved Tests, Twin Runs, Scenarios, and PR Test Runs
The Arga web app separates service setup from test execution.
| I want to... | Use |
| --------------------------------------------- | ----------------------------- |
| Run a browser flow against a reachable URL | [Test Runs](#test-runs) |
| Edit and reuse a browser flow | [Saved Tests](#saved-tests) |
| Start realistic replicas of external services | [Twin Runs](#twin-runs) |
| Reuse the same twin starting state | [Scenarios](#scenarios) |
| Run repository tests from GitHub events | [PR Test Runs](#pr-test-runs) |
## Test Runs
Use **Test Runs** when your application is already reachable at an HTTP or HTTPS URL.
1. Open **Test Runs** in the sidebar.
2. Enter the starting URL and describe the flow.
3. Start the run and watch the browser frame and event stream.
4. Review the generated blocks, parameters, screenshots, and summary.
5. Edit and rerun the flow, or save it as a reusable test.
Test blocks can navigate, click, type, press a key, wait, assert visible state, or ask for user input.
```bash theme={null}
arga test-runner runs url \
--url https://staging.example.com \
--prompt "Sign in and confirm the current plan"
```
## Saved Tests
Use **Saved Tests** to keep a browser flow after a successful Test Run. A saved test stores its prompt, starting URL, blocks, parameters, assertions, and optional encrypted credentials.
From **Saved Tests**, you can:
* edit blocks and parameters;
* change the starting URL or repository association;
* choose whether a repository's PR Test Runs may select the test;
* rerun or delete the test.
```bash theme={null}
arga test-runner tests list
arga test-runner tests run --url https://staging.example.com
```
## Twin Runs
Use **Twin Runs** to provision service twins without deploying application code.
1. Open **Twin Runs** in the sidebar.
2. Select one or more services.
3. Choose an empty state, a saved Scenario, or a natural-language seed description.
4. Choose a short-lived or persistent session.
5. Start the run and copy the returned URLs or environment variables into your app.
Short-lived runs can be reset, extended within your plan limit, locked from public access, or torn down. Persistent twin environments are attached to saved Scenarios and can be reseeded later.
```bash theme={null}
arga previews twins provision \
--twins slack,stripe \
--scenario-id \
--ttl 60 \
--wait
```
## Scenarios
Use **Scenarios** to save seed data for one or more twins. You can create a Scenario from a prompt, explicit JSON, selected production data, or the current state of a twin dashboard.
Scenarios do not run browser tests. They define the baseline used when a Twin Run starts or when a persistent twin environment is reseeded.
See [Scenarios](/features/custom-scenarios) for the schema and creation methods.
## PR Test Runs
Use **PR Test Runs** to trigger repository tests when a pull request changes or a configured branch receives a commit.
1. Install the Arga GitHub App on the repository.
2. Choose **Pull requests** or **Commits to branch**.
3. Add optional repository-specific instructions and PR comments.
4. In **Saved Tests**, let Arga choose relevant tests or pin selected tests to the repository.
5. Review the **Arga Validation** check in GitHub or open the run from Arga.
PR Test Runs exercise the application URL configured for the repository. They do not deploy the changed application into a per-PR Arga environment.
See [PR Test Runs](/features/pr-validation) for setup details.
# Arga
Source: https://docs.argalabs.com/index
Stateful service twins and repeatable tests for apps and agents
Arga lets you test software against realistic replicas of the services it acts on. Your app or agent can read, write, retry, and fail safely without changing production data.
Arga is built around four connected parts:
* **Twin Runs** provision one or more service twins and return the URLs, credentials, and environment variables needed to use them.
* **Scenarios** save the starting state for those twins so you can reset and repeat the same conditions.
* **Test Runs and Saved Tests** exercise a URL in a browser, capture evidence, and turn successful flows into editable test blocks.
* **PR Test Runs** run saved or generated tests when a pull request changes or a configured branch receives a commit.
Arga provisions the service environment. Your application continues to run wherever you deploy it: locally, in staging, or at an existing preview URL. PR Test Runs do not create a new application sandbox for every pull request.
Run a browser test or provision your first twins.
See how twins, scenarios, and tests fit together.
Explore stateful replicas of APIs, CLIs, MCPs, and user interfaces.
Choose between Test Runs, Saved Tests, and PR Test Runs.
Save and reuse exact twin seed state.
Import scoped production data into reusable scenarios.
## Common workflows
Give the browser runner a URL and a natural-language task, then inspect its steps and screenshots.
Provision the services your software uses and point its provider configuration at the returned endpoints.
Seed twins from a saved scenario and reset them to the same baseline between attempts.
Trigger repository tests from pull requests or pushes to a selected branch.
# Integrations
Source: https://docs.argalabs.com/integrations
Create reusable twin scenarios from selected production data
Integrations copy scoped data from supported production tools into an Arga Scenario. The Scenario can then seed a Twin Run without giving the test access to the production provider.
## Supported sources
| Provider | What you can select |
| ------------------- | --------------------------------------------------- |
| **Slack** | Joined channels and message threads |
| **Discord** | Channels allowed by the connected bot's server role |
| **Gmail** | Labels, date ranges, and Gmail search results |
| **Google Drive** | Files and folders granted to the app |
| **Google Calendar** | Calendars and an event date range |
GitHub access is used for repository selection and PR Test Runs. It is not a general production-data source for Scenario imports.
## Create a Scenario from production data
Open [Integrations](https://app.argalabs.com/integrations) and select **Connect** for a provider.
Select the exact channels, messages, files, labels, calendars, events, or date ranges to copy. The available controls depend on the provider.
Arga normalizes the selected provider records into twin seed data. Review the selection before saving it.
Give the Scenario a name and save it. It appears on the **Scenarios** page and can be used in a Twin Run.
## Safety boundaries
* Arga reads only the resources included in the connected account's granted scope.
* Importing creates a Scenario; it does not write changes back to the production provider.
* Actions taken later against the seeded twins change only twin state.
* You can inspect and edit the saved Scenario before reusing it.
* Reseeding a persistent twin environment restores the Scenario baseline.
## Next steps
Inspect, edit, import, and reuse twin seed data.
Provision services from a saved Scenario.
# MCP
Source: https://docs.argalabs.com/mcp
Use Twin Runs and browser tests from a coding agent
Arga's MCP server lets supported coding agents provision twins, inspect twin environments, start browser tests, and run Saved Tests.
## Prerequisites
```bash theme={null}
uv tool install arga-cli
arga login
arga whoami
```
## Install
```bash theme={null}
arga mcp install
```
The installer adds an `arga-context` server entry to supported local clients:
* `~/.cursor/mcp.json`
* `~/.claude/mcp.json`
* `~/.config/codex/mcp.json`
It preserves existing `mcpServers` entries and uses the device credential stored by `arga login`.
The installed server points to `/mcp` with a bearer authorization header:
```json theme={null}
{
"mcpServers": {
"arga-context": {
"url": "https://api.argalabs.com/mcp",
"headers": {
"Authorization": "Bearer "
}
}
}
}
```
## Custom API URL
```bash theme={null}
arga mcp install --api-url http://localhost:8000
```
You can also set `ARGA_API_URL` before running the installer.
## Twin tools
Lists available twin names, labels, surface kinds, and twin-hosted MCP paths where available.
Provisions and optionally seeds one or more twins.
| Parameter | Required | Description |
| ----------------- | -------- | ---------------------------------------------------------- |
| `twins` | Yes | Comma-separated twin names. |
| `scenario_id` | No | Saved Scenario used for seed state. |
| `scenario_prompt` | No | Natural-language seed description. |
| `ttl_minutes` | No | Session TTL. Defaults to `60` and is limited by your plan. |
| `public` | No | Whether returned base URLs are public. Defaults to `true`. |
The result contains the Twin Run ID. Poll `get_twin_run` until the status is `ready` or `failed`.
Returns status, per-twin URLs, environment variables, access details, and seed results for a Twin Run.
Restores a ready short-lived Twin Run to the baseline captured at provisioning time.
Extends a Twin Run within the TTL allowed by your plan.
Ends a short-lived Twin Run immediately.
## Persistent Scenario environment tools
Creates or returns the persistent twin environment attached to a saved Scenario. Pass `scenario_id`, optional comma-separated `twins`, and optional `public` access.
Returns the status and stable twin URLs for one Scenario.
Restores a ready persistent environment from its saved Scenario.
Tears down the persistent environment attached to one Scenario.
Lists persistent Scenario environments owned by the authenticated account.
## Browser test tools
Starts an ad hoc browser Test Run.
| Parameter | Required | Description |
| ------------------ | -------- | -------------------------------------------------------------------- |
| `prompt` | Yes | Natural-language browser task. |
| `start_url` | Usually | Reachable application URL. It may instead be included in the prompt. |
| `test_config_json` | No | Existing TestConfig JSON for deterministic execution. |
| `repo` | No | Repository metadata in `owner/repo` format. |
| `branch` | No | Branch metadata. |
| `pr_url` | No | Pull-request metadata. |
Point the application at any required twin endpoints before starting the Test Run.
Runs a Saved Test by `test_id`. Pass `start_url` to override the URL stored with the test and `prompt` to add run-specific guidance.
Returns status, events, artifacts, editable TestConfig, and summary fields for a Test Run.
Lists Saved Tests. Pass `repo_full_name` to filter them to one repository.
## Compatibility tools
Older servers may also expose `start_url_validation`, `get_validation_results`, `cancel_validation_run`, `provision_twins`, `get_twin_provision_status`, and `cancel_run`. Prefer the Twin Run and Test Run tools above for new agent workflows.
Your MCP client's `tools/list` response is the authoritative list for the server version you are connected to.
# Plans and limits
Source: https://docs.argalabs.com/plans
Compare Free, Team, and Paid limits
All plans include the web app, CLI, MCP setup, Twin Runs, Scenarios, Test Runs, and Saved Tests.
## Plan comparison
| Feature | Free | Team | Paid |
| ----------------------------- | ---------- | ----------- | ----------- |
| **Twin Runs** | Yes | Yes | Yes |
| **Scenarios** | Yes | Yes | Yes |
| **Test Runs and Saved Tests** | Yes | Yes | Yes |
| **PR Test Runs** | — | Yes | Yes |
| **URL Test Runs per month** | 10 | Unlimited | Unlimited |
| **PR Test Runs per month** | — | 500 | Unlimited |
| **CI checks per month** | — | 500 | Unlimited |
| **Twins per short-lived run** | 1 | Unlimited | Unlimited |
| **Maximum twin TTL** | 10 minutes | 480 minutes | 480 minutes |
| **Team workspace** | — | Yes | Yes |
## Free
The Free plan is intended for individual evaluation:
* 10 URL Test Runs per month;
* one service twin per short-lived Twin Run;
* a fixed 10-minute twin TTL;
* access to Scenarios, Saved Tests, the CLI, and MCP setup.
## Team
The Team plan adds collaboration and repository automation:
* unlimited URL Test Runs;
* up to 500 PR Test Runs and 500 CI checks per month;
* multiple twins in one run;
* twin TTLs from 1 to 480 minutes;
* a shared workspace linked to a GitHub organization.
## Paid
The Paid plan removes the monthly PR and CI limits while keeping the 480-minute maximum Twin Run TTL. Contact [founders@argalabs.com](mailto:founders@argalabs.com) for pricing.
## Twin Run TTL
The default short-lived Twin Run lasts 10 minutes on Free and 60 minutes on Team or Paid. Team and Paid users can request a TTL from 1 to 480 minutes and extend a ready run within that limit.
## Upgrade
1. Open [Settings](https://app.argalabs.com/settings).
2. Select **Upgrade subscription**.
3. Complete checkout.
Use the same page to open the billing portal or review current usage.
# Quickstart
Source: https://docs.argalabs.com/quickstart
Run a browser test and provision service twins
Start with a browser test against an existing URL. Add service twins when you need safe, repeatable external-service state.
## Run your first browser test
```bash theme={null}
uv tool install arga-cli
arga login
arga whoami
```
Point Arga at a deployed application URL and describe the flow to test:
```bash theme={null}
arga test-runner runs url \
--url https://staging.example.com \
--prompt "Sign in and verify the billing page"
```
Arga opens a browser, executes the flow, and records events, screenshots, and editable test blocks.
Use the run ID printed by the CLI:
```bash theme={null}
arga test-runner runs get
arga test-runner runs logs
```
You can also open [app.argalabs.com/test-runs](https://app.argalabs.com/test-runs) to watch runs and inspect their results.
### Test an authenticated flow
Provide credentials for a test account in your application:
```bash theme={null}
arga test-runner runs url \
--url https://staging.example.com \
--prompt "Sign in and complete onboarding" \
--email testuser@example.com \
--password your-test-password
```
Both `--email` and `--password` are required when either flag is present. These are credentials for the application under test, not your Arga account.
## Add service twins
Use a Twin Run when your software needs to act on Slack, Stripe, GitHub, Gmail, Google Calendar, or another supported service without touching the real provider.
```bash theme={null}
arga previews twins provision \
--twins slack,stripe \
--ttl 60 \
--wait
```
Run `arga previews twins list` to see the current catalog.
The ready response includes a base URL and environment variables for each twin. Apply those values to the app or agent you are testing, then start it normally.
If you want Arga to detect provider variables and update a local `.env` file, run:
```bash theme={null}
arga wizard
```
The wizard creates `.env.arga-backup` before changing the file.
Exercise the app manually or run a browser Test Run against its reachable URL. Reset the twins to their original seed state before repeating the test:
```bash theme={null}
arga previews twins reset
```
For reusable state, create a [Scenario](/features/custom-scenarios) and pass its ID when you provision the twins.
## Next steps
Manage twin URLs, state, access, TTL, reset, and teardown.
Save browser flows and configure PR Test Runs.
Define repeatable twin data with a prompt or explicit JSON.
Create scenarios from selected production data.
# Overview
Source: https://docs.argalabs.com/sdks/overview
Official Python and TypeScript clients for Arga
Arga provides official SDKs for Python and TypeScript.
Synchronous and asynchronous clients for Python 3.10+.
A zero-dependency client built on native `fetch` for Node 18+.
## Resources
Both SDKs expose the same three top-level resources:
| Resource | What it does |
| ----------- | --------------------------------------------------------------------------------------------------------------------------- |
| `runs` | Start URL runs, inspect status, stream results, wait, and cancel. It also retains compatibility helpers for manual PR runs. |
| `twins` | List services and provision, inspect, reset, extend, or tear down short-lived Twin Runs. |
| `scenarios` | Create and read Scenarios, then manage their persistent twin environments. |
The current SDK releases do not expose the browser runner's Saved Test or Test Run resources. Use the [REST API](/api-reference) or [CLI](/cli-and-mcp) for those workflows.
## Authentication
Create or retrieve an API key with the CLI:
```bash theme={null}
arga login
```
```python Python theme={null}
from arga_sdk import Arga
client = Arga(api_key="arga_...")
```
```typescript TypeScript theme={null}
import { Arga } from 'arga-sdk';
const client = new Arga({ apiKey: 'arga_...' });
```
## Base URL
Both clients default to `https://app.argalabs.com`.
```python Python theme={null}
client = Arga(api_key="...", base_url="https://your-instance.example.com")
```
```typescript TypeScript theme={null}
const client = new Arga({ apiKey: '...', baseUrl: 'https://your-instance.example.com' });
```
# Python SDK
Source: https://docs.argalabs.com/sdks/python
Install and use the Arga Python SDK
## Installation
```bash theme={null}
uv add arga-py-sdk
```
You can also run `pip install arga-py-sdk`.
## Quickstart
```python theme={null}
from arga_sdk import Arga
client = Arga(api_key="arga_...")
run = client.runs.create_url_run(
url="https://staging.example.com",
prompt="Verify the checkout flow",
)
detail = client.runs.wait(run.run_id, timeout=300)
print(detail.status, detail.results_json)
```
## Async client
```python theme={null}
import asyncio
from arga_sdk import AsyncArga
async def main():
async with AsyncArga(api_key="arga_...") as client:
result = await client.twins.provision(
twins=["slack", "stripe"],
ttl_minutes=60,
)
print(result["run_id"])
asyncio.run(main())
```
## Reference
Start URL runs, inspect results, stream events, wait, and cancel.
Provision and manage short-lived Twin Runs.
Save seed state and manage persistent twin environments.
Handle SDK errors and use context managers.
## Source
[github.com/ArgaLabs/arga-python-sdk](https://github.com/ArgaLabs/arga-python-sdk)
# Python errors and clients
Source: https://docs.argalabs.com/sdks/python/errors
Handle Python SDK errors and manage client lifecycles
## Error handling
```python theme={null}
from arga_sdk import Arga, ArgaAPIError, ArgaError
client = Arga(api_key="arga_sk_...")
try:
detail = client.runs.get("nonexistent")
except ArgaAPIError as e:
print(e.status_code) # 404
print(e.message) # "Not found"
except ArgaError as e:
# Base class for all SDK errors (network issues, etc.)
print(e.message)
```
## Context managers
Both clients support `with` blocks for automatic cleanup:
```python theme={null}
with Arga(api_key="arga_sk_...") as client:
run = client.runs.create_url_run(url="https://staging.myapp.com")
async with AsyncArga(api_key="arga_sk_...") as client:
run = await client.runs.create_url_run(url="https://staging.myapp.com")
```
# Python examples
Source: https://docs.argalabs.com/sdks/python/examples
Reference material for the Python SDK
The current Python SDK surface is covered by the quick-start snippets in this docs section plus the repository test suite.
| Reference | What it covers |
| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| [`/sdks/python/runs`](/sdks/python/runs) | URL runs, polling, streaming, cancellation, and PR compatibility |
| [`/sdks/python/twins`](/sdks/python/twins) | Twin catalog, provisioning, reset, TTL extension, and teardown |
| [`/sdks/python/scenarios`](/sdks/python/scenarios) | Scenario creation, seeded Twin Runs, and persistent environments |
| [`arga-python-sdk/tests`](https://github.com/ArgaLabs/arga-python-sdk/tree/main/tests) | Concrete request and response shapes exercised by the current client |
Use these references together with your own `ARGA_API_KEY` and target URLs when adapting the SDK to your environment.
## Source
[github.com/ArgaLabs/arga-python-sdk](https://github.com/ArgaLabs/arga-python-sdk)
# Python runs
Source: https://docs.argalabs.com/sdks/python/runs
Start and inspect URL runs with the Python SDK
## Create a URL run
```python theme={null}
run = client.runs.create_url_run(
url="https://staging.example.com",
prompt="Test the checkout flow",
credentials={"email": "test@example.com", "password": "pass"},
)
print(run.run_id, run.status)
```
The SDK also accepts optional twin and Scenario metadata for compatibility with the validation API. Provision and connect required twins before testing the application URL.
## Get details
```python theme={null}
detail = client.runs.get(run.run_id)
print(detail.status)
print(detail.results_json)
print(detail.step_summaries)
print(detail.event_log_json)
```
## Stream results
```python theme={null}
for event in client.runs.stream_results(run.run_id):
print(event)
```
With `AsyncArga`:
```python theme={null}
async for event in client.runs.stream_results(run.run_id):
print(event)
```
## Wait for completion
```python theme={null}
detail = client.runs.wait(
run.run_id,
poll_interval=2.5,
timeout=600,
)
```
Terminal statuses are `completed`, `failed`, and `cancelled`.
## Cancel a run
```python theme={null}
client.runs.cancel(run.run_id)
```
## Manual PR run compatibility
`client.runs.create_pr_run(...)` remains available for integrations using the legacy `/validate/pr-run` route. It does not guarantee a per-PR application deployment. New repository automation should be configured as [PR Test Runs](/features/pr-validation) through the web app, CLI, or REST API.
# Python scenarios
Source: https://docs.argalabs.com/sdks/python/scenarios
Create reusable scenarios and seed twin runs with the Python SDK
## Create a scenario
Create with a natural language prompt. Arga generates the seed config.
```python theme={null}
scenario = client.scenarios.create(
name="E-commerce checkout",
prompt="A Stripe account with 3 customers on different plans",
description="For testing checkout flows", # optional
tags=["checkout", "stripe"], # optional
)
```
Or create with an explicit seed config:
```python theme={null}
scenario = client.scenarios.create(
name="Support channel",
twins=["slack"],
seed_config={
"slack": {
"channels": [{"name": "support", "messages": ["Help needed"]}]
}
},
)
```
## List scenarios
```python theme={null}
# All scenarios
scenarios = client.scenarios.list()
# Filter by twin or tag
scenarios = client.scenarios.list(twin="stripe")
scenarios = client.scenarios.list(tag="checkout")
```
## Get a scenario
```python theme={null}
scenario = client.scenarios.get("scenario-id")
print(scenario.name, scenario.twins, scenario.seed_config)
```
## Use a scenario when provisioning twins
Use a saved scenario to seed a short-lived twin session:
```python theme={null}
result = client.twins.provision(
twins=["stripe", "slack"],
scenario_id="scenario-id",
)
run_id = result["run_id"]
status = client.twins.get_status(run_id)
if status.status == "ready":
for name, twin in status.twins.items():
print(f"{name}: {twin.base_url}")
print(f" Admin: {twin.admin_url}")
print(f" Env vars: {twin.env_vars}")
```
## Persistent twin environment
Create or return the persistent environment attached to a Scenario:
```python theme={null}
environment = client.scenarios.ensure_twin_environment(
"scenario-id",
twins=["stripe", "slack"],
public=True,
)
```
Inspect, reseed, list, or tear down persistent environments:
```python theme={null}
environment = client.scenarios.get_twin_environment("scenario-id")
environment = client.scenarios.reseed_twin_environment("scenario-id")
environments = client.scenarios.list_twin_environments()
environment = client.scenarios.delete_twin_environment("scenario-id")
```
# Python twins
Source: https://docs.argalabs.com/sdks/python/twins
Provision and manage Twin Runs with the Python SDK
## List twins
```python theme={null}
for twin in client.twins.list():
print(twin.name, twin.label, twin.kind)
```
## Provision
```python theme={null}
result = client.twins.provision(
twins=["stripe", "slack"],
ttl_minutes=60,
scenario_id="scenario-id", # optional
public=True,
)
run_id = result["run_id"]
```
Poll until ready:
```python theme={null}
status = client.twins.get_status(run_id)
if status.status == "ready":
for name, twin in status.twins.items():
print(name, twin.base_url, twin.env_vars)
```
## Reset, extend, and tear down
```python theme={null}
client.twins.reset(run_id)
client.twins.extend(run_id, ttl_minutes=90)
client.twins.teardown(run_id)
```
`reset` restores the baseline captured when the Twin Run was provisioned. `teardown` ends the run immediately.
# TypeScript SDK
Source: https://docs.argalabs.com/sdks/typescript
Install and use the Arga TypeScript SDK
## Installation
```bash theme={null}
npm install arga-sdk
```
The package requires Node 18+ and has no runtime dependencies.
## Quickstart
```typescript theme={null}
import { Arga } from 'arga-sdk';
const client = new Arga({ apiKey: 'arga_...' });
const run = await client.runs.createUrlRun({
url: 'https://staging.example.com',
prompt: 'Verify the checkout flow',
});
const detail = await client.runs.wait(run.runId);
console.log(detail.status, detail.resultsJson);
```
## Reference
Start URL runs, inspect results, stream events, wait, and cancel.
Provision and manage short-lived Twin Runs.
Save seed state and manage persistent twin environments.
Handle API errors and wait timeouts.
## Source
[github.com/ArgaLabs/arga-typescript-sdk](https://github.com/ArgaLabs/arga-typescript-sdk)
# TypeScript error handling
Source: https://docs.argalabs.com/sdks/typescript/errors
Handle API errors from the TypeScript SDK
```typescript theme={null}
import { Arga, ArgaAPIError } from 'arga-sdk';
const client = new Arga({ apiKey: 'arga_sk_...' });
try {
await client.runs.get('nonexistent');
} catch (err) {
if (err instanceof ArgaAPIError) {
console.error(err.statusCode); // 404
console.error(err.message); // "Not found"
}
}
```
# TypeScript examples
Source: https://docs.argalabs.com/sdks/typescript/examples
Reference material for the TypeScript SDK
The current TypeScript SDK surface is covered by the quick-start snippets in this docs section plus the repository test suite.
| Reference | What it covers |
| ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| [`/sdks/typescript/runs`](/sdks/typescript/runs) | URL runs, polling, streaming, cancellation, and PR compatibility |
| [`/sdks/typescript/twins`](/sdks/typescript/twins) | Twin catalog, provisioning, reset, TTL extension, and teardown |
| [`/sdks/typescript/scenarios`](/sdks/typescript/scenarios) | Scenario creation, seeded Twin Runs, and persistent environments |
| [`arga-typescript-sdk/tests`](https://github.com/ArgaLabs/arga-typescript-sdk/tree/main/tests) | Concrete request and response shapes exercised by the current client |
Use these references together with your own `ARGA_API_KEY` and target URLs when adapting the SDK to your environment.
## Source
[github.com/ArgaLabs/arga-typescript-sdk](https://github.com/ArgaLabs/arga-typescript-sdk)
# TypeScript runs
Source: https://docs.argalabs.com/sdks/typescript/runs
Start and inspect URL runs with the TypeScript SDK
## Create a URL run
```typescript theme={null}
const run = await client.runs.createUrlRun({
url: 'https://staging.example.com',
prompt: 'Test the checkout flow',
credentials: { email: 'test@example.com', password: 'pass' },
});
console.log(run.runId, run.status);
```
The SDK also accepts optional twin and Scenario metadata for compatibility with the validation API. Provision and connect required twins before testing the application URL.
## Get details
```typescript theme={null}
const detail = await client.runs.get(run.runId);
console.log(detail.status);
console.log(detail.resultsJson);
console.log(detail.stepSummaries);
console.log(detail.eventLogJson);
```
## Stream results
```typescript theme={null}
for await (const event of client.runs.streamResults(run.runId)) {
console.log(event);
}
```
## Wait for completion
```typescript theme={null}
const detail = await client.runs.wait(run.runId, {
pollInterval: 2500,
timeout: 600000,
});
```
Terminal statuses are `completed`, `failed`, and `cancelled`.
## Cancel a run
```typescript theme={null}
await client.runs.cancel(run.runId);
```
## Manual PR run compatibility
`client.runs.createPrRun(...)` remains available for integrations using the legacy `/validate/pr-run` route. It does not guarantee a per-PR application deployment. New repository automation should be configured as [PR Test Runs](/features/pr-validation) through the web app, CLI, or REST API.
# TypeScript scenarios
Source: https://docs.argalabs.com/sdks/typescript/scenarios
Create reusable scenarios and seed twin runs with the TypeScript SDK
## Create a scenario
Create with a natural language prompt. Arga generates the seed config.
```typescript theme={null}
const scenario = await client.scenarios.create({
name: 'E-commerce checkout',
prompt: 'A Stripe account with 3 customers on different plans',
description: 'For testing checkout flows', // optional
tags: ['checkout', 'stripe'], // optional
});
```
Or create with an explicit seed config:
```typescript theme={null}
const scenario = await client.scenarios.create({
name: 'Support channel',
twins: ['slack'],
seedConfig: {
slack: {
channels: [{ name: 'support', messages: ['Help needed'] }],
},
},
});
```
## List scenarios
```typescript theme={null}
// All scenarios
const scenarios = await client.scenarios.list();
// Filter by twin or tag
const stripeScenarios = await client.scenarios.list({ twin: 'stripe' });
const checkoutScenarios = await client.scenarios.list({ tag: 'checkout' });
```
## Get a scenario
```typescript theme={null}
const scenario = await client.scenarios.get('scenario-id');
console.log(scenario.name, scenario.twins, scenario.seedConfig);
```
## Use a scenario when provisioning twins
Use a saved scenario to seed a short-lived twin session:
```typescript theme={null}
const { runId } = await client.twins.provision({
twins: ['stripe', 'slack'],
scenarioId: 'scenario-id',
});
const status = await client.twins.getStatus(runId);
if (status.status === 'ready') {
for (const [name, twin] of Object.entries(status.twins)) {
console.log(`${name}: ${twin.baseUrl}`);
console.log(` Admin: ${twin.adminUrl}`);
console.log(` Env vars:`, twin.envVars);
}
}
```
## Persistent twin environment
Create or return the persistent environment attached to a Scenario:
```typescript theme={null}
const environment = await client.scenarios.ensureTwinEnvironment('scenario-id', {
twins: ['stripe', 'slack'],
public: true,
});
```
Inspect, reseed, list, or tear down persistent environments:
```typescript theme={null}
const current = await client.scenarios.getTwinEnvironment('scenario-id');
const reseeded = await client.scenarios.reseedTwinEnvironment('scenario-id');
const environments = await client.scenarios.listTwinEnvironments();
const deleted = await client.scenarios.deleteTwinEnvironment('scenario-id');
```
# TypeScript twins
Source: https://docs.argalabs.com/sdks/typescript/twins
Provision and manage Twin Runs with the TypeScript SDK
## List twins
```typescript theme={null}
for (const twin of await client.twins.list()) {
console.log(twin.name, twin.label, twin.kind);
}
```
## Provision
```typescript theme={null}
const { runId } = await client.twins.provision({
twins: ['stripe', 'slack'],
ttlMinutes: 60,
scenarioId: 'scenario-id', // optional
public: true,
});
```
Poll until ready:
```typescript theme={null}
const status = await client.twins.getStatus(runId);
if (status.status === 'ready' && status.twins) {
for (const [name, twin] of Object.entries(status.twins)) {
console.log(name, twin.baseUrl, twin.envVars);
}
}
```
## Reset, extend, and tear down
```typescript theme={null}
await client.twins.reset(runId);
await client.twins.extend(runId, { ttlMinutes: 90 });
await client.twins.teardown(runId);
```
`reset` restores the baseline captured when the Twin Run was provisioned. `teardown` ends the run immediately.
# Troubleshooting
Source: https://docs.argalabs.com/troubleshooting
Common issues and how to fix them
## CLI authentication
### "Not authenticated. Run `arga login`."
The CLI can't find a saved API key. This happens when:
* You haven't logged in yet — run `arga login` to authenticate.
* The config file at `~/.config/arga/config.json` was deleted or corrupted. Run `arga login` again to regenerate it.
* The API key was revoked from the [Settings page](https://app.argalabs.com/settings) under **Authorized CLI devices**. Run `arga login` to create a new device key.
### "Device code expired. Run `arga login` again."
The browser approval window wasn't completed in time. Device codes expire after 10 minutes. Run `arga login` again and approve the device in the browser before the code expires.
### "Device code already used. Run `arga login` again."
Each device code can only be used once. If you cancelled a login attempt or the flow was interrupted, run `arga login` to start a fresh authorization.
### "Timed out waiting for authentication approval."
The CLI waited 10 minutes for browser approval and gave up. Make sure you complete the approval at the URL shown in your terminal. If the browser didn't open automatically, copy the URL and open it manually.
***
## Test Run errors
### "A valid public http(s) URL is required."
Arga can only test publicly accessible URLs. This error appears when:
* The URL uses `localhost` or a private IP address (e.g. `127.0.0.1`, `192.168.x.x`)
* The URL scheme is not `http://` or `https://`
* The URL is malformed or unreachable
If you're testing a local dev server, deploy it to a publicly accessible staging environment first, or use a tunnel service to expose it.
### "A prompt is required."
Every browser Test Run needs a prompt describing what to do. Add `--prompt` to your CLI command:
```bash theme={null}
arga test-runner runs url --url https://your-app.com --prompt "test the login flow"
```
### "Email and password must both be provided."
You passed `--email` without `--password` or vice versa. Both must be provided together:
```bash theme={null}
arga test-runner runs url \
--url https://your-app.com \
--prompt "test the checkout flow" \
--email test@example.com \
--password your-test-password
```
### Need more detail from a run
Use the Test Runner commands to inspect a browser run:
```bash theme={null}
arga test-runner runs get
arga test-runner runs logs
```
Use `--json` for machine-readable output.
### Run stuck in "queued" status
If a run stays in `queued` for more than a few minutes:
1. Check the run: `arga test-runner runs get `.
2. Inspect its events: `arga test-runner runs logs `.
3. Start a new run if the worker did not begin.
4. If the issue persists, contact [founders@argalabs.com](mailto:founders@argalabs.com).
***
## Plan limits
### "Monthly free plan limit reached."
Free plan users get 10 URL Test Runs per month. Limits reset on the first day of each month. Check your remaining usage with:
```bash theme={null}
arga whoami
```
To get more runs, [upgrade to the Team plan](https://app.argalabs.com/settings).
### "Free plan allows 1 twin per run."
Free plan users can provision one digital twin per short-lived Twin Run. To provision multiple twins together, upgrade to the Team plan.
### "Automatic PR validation requires a Team or Paid plan."
PR Test Runs and CI checks are Team plan features. [Upgrade](https://app.argalabs.com/settings) to enable repository automation.
### "Team plan limit of N CI checks/month reached."
Team plan includes 500 CI checks per month. If you need more, contact [founders@argalabs.com](mailto:founders@argalabs.com) about usage-based pricing.
***
## Twin provisioning
### "Quickstart API key has no provisions remaining."
Your quickstart key (issued via email signup) is limited to 5 twin provisions and has been used up. Run `arga login` to authenticate with GitHub and get a full-access key with no provision limit.
### Twins stuck in "provisioning"
Twin instances typically start in under a minute. If provisioning takes longer than 2 minutes:
1. Check status: `arga previews twins status ` or poll the [status endpoint](/api-reference/get-get-twin-provision-status).
2. Inspect provisioning/runtime logs: `arga runs logs --errors-only`.
3. Cancel and retry with a fresh run
4. If using the CLI wizard (`npx arga-wizard`), exit and re-run it
When a `scenario_id` or `scenario_prompt` is attached to a provision request, the status remains `provisioning` until twin seeding completes and `seed_results` are available. This is expected and ensures twins are fully initialized before the status transitions to `ready`.
### "At least one valid twin name is required."
The twin names you provided don't match any available twins. List valid twin names from the [twin catalog](/api-reference/get-list-available-twins) or check spelling. Common twin names: `slack`, `stripe`, `datadog`, `google_drive`, `google_docs`, `google_sheets`, `google_workspace`, `jira`, and `github`.
### Twins expired during testing
Short-lived Twin Runs default to 10 minutes on Free and 60 minutes on Team or Paid. If your twins expire mid-test:
* Extend the session with `arga wizard extend` or the [extend endpoint](/api-reference/post-extend-twin-provision-ttl)
* Set a longer initial TTL (up to 480 minutes) when provisioning via the API directly
Re-run the wizard to start a fresh session.
***
## MCP connection issues
### MCP server not connecting in your IDE
1. **Verify you're logged in:** Run `arga whoami` to confirm your API key is valid.
2. **Reinstall MCP config:** Run `arga mcp install` to rewrite the config files.
3. **Check the config file** for your IDE:
* Cursor: `~/.cursor/mcp.json`
* Claude Code: `~/.claude/mcp.json`
* Codex: `~/.config/codex/mcp.json`
4. **Verify the API key** in the config matches your current key (run `arga whoami` to see it).
5. **Restart your IDE** after updating the MCP config.
### MCP tools returning errors
If MCP tools return "Error: Not authenticated" or similar:
* Your API key may have been revoked. Check [Settings > Authorized CLI devices](https://app.argalabs.com/settings) and run `arga login` + `arga mcp install` if the key was revoked.
* The MCP config may have an outdated key. Run `arga mcp install` to refresh it.
### MCP tools not appearing in your IDE
Some IDEs cache MCP tool definitions. After running `arga mcp install`:
1. Restart the IDE completely (not just reload)
2. Check that the `arga-context` server entry exists in the MCP config file
3. Look for MCP connection errors in your IDE's output/logs panel
***
## GitHub integration
### "GitHub not connected"
Open **PR Test Runs**, select the repository, and follow the prompt to install or authorize the Arga GitHub App.
### "GitHub reauthentication required"
Your GitHub authorization has expired or been revoked. Open **PR Test Runs** and select **Reconnect GitHub**.
### "GitHub integration required for validation."
PR Test Runs require the Arga GitHub App on the selected repository. Install it from **PR Test Runs** before running `arga previews pr-checks run` or enabling a trigger.
***
## Email verification
### "Email is already verified"
The email address you submitted is already verified on your account. No action needed. Run `arga whoami` to confirm your verified email.
### "Wait before requesting another verification code"
Verification codes can only be requested once per minute. Wait a moment and try again.
### "Too many verification attempts. Request a new code"
You've used all 5 attempts for the current code. Click to request a new verification code and try again with the fresh code.
### "No active verification code found for that email"
The verification code has expired (codes last 10 minutes) or was never requested for this email address. Request a new code and enter it within 10 minutes.
### "Only one account can use an email address. This email is already linked to another account."
Each email address can only be used by one Arga account. If you receive this `409` error when requesting a verification code, confirming a code, or signing up, the email is already in use on a different account. Sign in to the account that owns the email, or use a different email address.
### "github\_identity\_already\_linked" (during GitHub sign-in or repository setup)
The GitHub account you authorized — or the email returned by GitHub — is already associated with a different Arga account. Sign in to the original account, use a different GitHub account, or contact [founders@argalabs.com](mailto:founders@argalabs.com) if the old account is inaccessible.
***
## General
### Network errors
If you see "Network error" from the CLI, check:
1. Your internet connection
2. That `https://api.argalabs.com` is reachable: `curl https://api.argalabs.com/health`
3. If using a custom API URL (`--api-url` or `ARGA_API_URL`), verify it's correct
### Something else?
If your issue isn't covered here, reach out at [founders@argalabs.com](mailto:founders@argalabs.com).
# Web app
Source: https://docs.argalabs.com/web-app
Use Twin Runs, Scenarios, Saved Tests, Test Runs, and PR Test Runs
The Arga web app is available at [app.argalabs.com](https://app.argalabs.com). Sign in with GitHub or create an account with email.
## Sidebar
| Section | Page | Use it for |
| --------- | ------------ | ------------------------------------------------------- |
| **Twins** | Twin Runs | Provision short-lived or persistent service twins |
| **Twins** | Scenarios | Save and reuse twin seed state |
| **Tests** | Saved Tests | Edit reusable browser flows and repository associations |
| **Tests** | Test Runs | Run browser tests against a URL |
| **Tests** | PR Test Runs | Configure GitHub-triggered repository tests |
| — | Integrations | Import selected production data into Scenarios |
| — | MCP | Configure Arga tools in a supported coding agent |
| — | Settings | Manage your profile, plan, workspace, and API keys |
## Twin Runs
Open **Twin Runs** to select services and create a twin environment. You can seed the twins from a Scenario or a natural-language description, choose a short-lived or persistent session, and inspect the returned URLs and environment variables.
Ready short-lived runs include controls to reset state, extend the TTL, lock public access, open a twin dashboard, or tear the run down.
## Scenarios
Open **Scenarios** to manage reusable twin state. Presets and custom Scenarios can be used in a new Twin Run. You can also import Scenario JSON or save the current state from a supported twin dashboard.
## Test Runs
Open **Test Runs** to start a browser test against a reachable URL. Enter the URL and task, then inspect:
* the live browser frame;
* runner events and chat;
* editable blocks and parameters;
* screenshots and the final result.
When a run has generated blocks, you can rerun it or save it as a reusable test.
## Saved Tests
Open **Saved Tests** to edit test metadata, repository association, parameters, assertions, blocks, and encrypted credentials. A repository can let Arga select relevant tests automatically or pin specific saved tests for PR Test Runs.
## PR Test Runs
Open **PR Test Runs** to install the Arga GitHub App, select a repository, choose a pull-request or branch trigger, configure comments and instructions, and review recent runs.
PR Test Runs publish an **Arga Validation** check. They use your configured application target and do not create a per-PR Arga deployment.
## Integrations
The Integrations page contains the production sources that can create Scenarios: Slack, Discord, Gmail, Google Drive, and Google Calendar. After connecting a provider, select the data you want to copy and save it as a Scenario.
## MCP
The MCP page shows the install command and configuration for Cursor, Claude Code, and Codex. The recommended setup is:
```bash theme={null}
arga login
arga mcp install
```
## Settings
Use **Settings** to manage:
* your profile and email verification;
* subscription and usage;
* Team workspace membership and invitations;
* CLI devices and API keys;
* logout.