Skip to main content
The Replica API lets you programmatically create workspaces, send messages to coding agents, manage chats, and monitor workspace state.
The Replica API and Automations are the only sanctioned channels for programmatic use of Replicas. Scripting against the dashboard, automating the CLI, or driving interactive surfaces from headless browsers is prohibited under our Terms of Service.

Authentication

Organization admins can generate org API keys from Settings > API Keys. You can generate personal API keys from Account > API Keys. Include it as a Bearer token in requests:
curl -X GET "https://api.tryreplicas.com/v1/replica" \
  -H "Authorization: Bearer YOUR_API_KEY"
The API key identifies your organization automatically - no additional headers are needed. Organization API keys can manage org resources. Personal API keys can manage org automations and personal automations owned by that user.

Org vs Personal API Keys

Org API KeyPersonal API Key
Created byOrg adminsAny member
Workspace attributionReplicas bot (no user)Owning user
Can manage org automationsYesYes
Can manage personal automationsNoOwn automations only
Use caseCI/CD, shared integrationsPersonal automations, user-attributed workspaces
The CLI interacts with this API through JWT authentication, meaning usage through the CLI does not incur API usage costs.

Quick Start

1. List Available Repositories

Before creating a replica, list the repositories available in your organization:
curl "https://api.tryreplicas.com/v1/replica/repositories" \
  -H "Authorization: Bearer YOUR_API_KEY"

2. Create a Replica

The name field must not contain whitespace (e.g. fix-auth-bug, not fix auth bug).
curl -X POST "https://api.tryreplicas.com/v1/replica" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "fix-auth-bug",
    "environment_id": "ENVIRONMENT_UUID",
    "message": "Fix the login timeout issue in src/auth.ts",
    "coding_agent": "claude",
    "model": "sonnet"
  }'
The selected environment determines which repository or repository set is checked out, and which variables, files, skills, MCPs, hooks, warm pool, and system prompt apply. Optional coding_agent chooses the agent for the initial message. Valid values are claude, codex, cursor, and opencode. Cursor requires a Cursor API key in Coding Agents settings; Opencode requires an OpenRouter API key there. Optional lifecycle_policy controls what happens when work is done:
  • default - workspace sleeps after inactivity and is deleted after 7 days asleep (default)
  • delete_when_done - workspace is deleted when the agent finishes (useful for CI/CD)
  • delete_after_inactivity - workspace is deleted after a period of inactivity
Optional size picks the compute envelope and per-minute price for this replica:
sizeComputePrice
small2 vCPU, 8 GB memory, 20 GB disk$0.008 / min
large4 vCPU, 16 GB memory, 32 GB disk$0.016 / min
Omit size to keep the legacy behaviour: the workspace inherits your org’s sandbox tier (including any team-plan auto-bump) and is billed at the standard rate. Pick small to opt into the lower per-minute price for cheap, frequent jobs; pick large for memory or CPU-bound work. Mixed fleets bill correctly; each workspace charges at its own rate. Optional config controls per-workspace behavior. API-created replicas default to capabilities.pr_followups: true, meaning Replicas will auto-reply to CI failures and review comments on matching PRs created or touched by that workspace; set it to false for a read-only replica. Set preferences.keep_open_on_pr_merge: true when that workspace should remain open after its tracked PR merges. See Automations: Pull request management for how this default flips for automation-created workspaces. The replica boots asynchronously and the message is delivered once ready.

3. Send a Follow-up Message

curl -X POST "https://api.tryreplicas.com/v1/replica/{id}/messages" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "Also add tests for the fix"
  }'
If the replica is sleeping, it wakes automatically. Messages queue if the agent is busy.

4. Check Status

curl "https://api.tryreplicas.com/v1/replica/{id}?include=environment" \
  -H "Authorization: Bearer YOUR_API_KEY"
Use include=environment to get detailed environment info, or include=diffs for full git diffs. The status response also includes lastChatMessage, a preview of the most recent input message across the workspace’s chats (its text, the agent that received it (claude, codex, cursor, or opencode), and a timestamp), so you can surface recent activity without fetching full chat history. Each chat object likewise exposes lastMessageText, the preview for that individual chat.

5. Delete a Replica

curl -X DELETE "https://api.tryreplicas.com/v1/replica/{id}" \
  -H "Authorization: Bearer YOUR_API_KEY"
Deleting a replica is idempotent for replicas in your organization: if the replica was already deleted, the API still returns 200 OK with { "success": true }. IDs that never existed or belong to another organization return 404.

6. Stream Events (SSE)

curl -N "https://api.tryreplicas.com/v1/replica/{id}/events" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: text/event-stream"
Receive real-time updates including chat turns, repository changes, and hook progress.

7. Webhook Callbacks (alternative to polling)

Pass webhook_url when creating a replica to receive status updates without polling:
curl -X POST "https://api.tryreplicas.com/v1/replica" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "fix-auth-bug",
    "environment_id": "ENVIRONMENT_UUID",
    "message": "Fix the login timeout issue",
    "webhook_url": {
      "url": "https://your-app.example.com/replicas/webhook",
      "secret": "whsec_your_shared_secret"
    }
  }'
webhook_url accepts either a bare URL string ("https://...") or an object { url, secret }. The platform POSTs a JSON body for every event with these headers:
HeaderDescription
X-Replicas-EventEvent type, e.g. replica.turn_completed
X-Replicas-Event-IdStable per-event ID. Reuse for idempotent processing.
X-Replicas-DeliveryUnique delivery ID for this event delivery. Retry attempts reuse the same value.
X-Replicas-Replica-IdThe replica’s workspace ID
X-Replicas-Signaturesha256=<hex HMAC-SHA256(secret, raw body)> (only present when a secret is set)
Emitted event types:
  • replica.ready: the workspace finished provisioning (or finished waking) and is reachable. Use this as the “your replica is ready” signal instead of polling GET /v1/replica/:id.
  • replica.turn_completed: the coding agent finished a turn. Payload includes per-repository branches and any newly opened PR URLs.
  • replica.deleted: the workspace was deleted. Payload data is empty.
  • replica.error: the workspace went into an unrecoverable terminal state. The replica is being soft-deleted; the payload includes the failure message.
Example replica.turn_completed body:
{
  "id": "wh_4f3c…",
  "type": "replica.turn_completed",
  "created_at": "2026-05-26T07:31:12.000Z",
  "replica": {
    "id": "11111111-1111-1111-1111-111111111111",
    "name": "fix-auth-bug",
    "status": "active",
    "source": "api",
    "created_at": "2026-05-26T07:29:55.000Z"
  },
  "data": {
    "repository_statuses": [
      {
        "repository": "monorepo",
        "branch": "fix-auth-bug",
        "default_branch": "main",
        "pr_urls": ["https://github.com/o/r/pull/482"]
      }
    ],
    "pr_urls": ["https://github.com/o/r/pull/482"]
  }
}
Delivery is retried up to 3× with exponential backoff on network errors, 5xx, and 429 responses. 4xx responses (other than 429) are treated as permanent failures and not retried. Configure your endpoint to respond 2xx within 10 seconds. To verify the signature in Node:
import { createHmac, timingSafeEqual } from 'node:crypto';

function verify(rawBody, signatureHeader, secret) {
  const expected = `sha256=${createHmac('sha256', secret).update(rawBody, 'utf8').digest('hex')}`;
  return signatureHeader?.length === expected.length
    && timingSafeEqual(Buffer.from(signatureHeader), Buffer.from(expected));
}

Key Concepts

Environments

Workspaces are created from environments. Each environment can be bound to a repository or repository set and carries the runtime configuration for the workspace (variables, files, skills, MCPs, warm hooks). The full environment management surface is available via the API — see Environments API below.

Chat Management

Each workspace can have multiple chat sessions with different coding agents:
# List chats
curl "https://api.tryreplicas.com/v1/replica/{id}/chats" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Create a new chat
curl -X POST "https://api.tryreplicas.com/v1/replica/{id}/chats" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "provider": "cursor", "title": "Refactoring" }'

# Send to a specific chat
curl -X POST "https://api.tryreplicas.com/v1/replica/{id}/messages" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "message": "Continue the refactoring", "chat_id": "CHAT_ID" }'

Queue Management

Messages queue automatically when the agent is busy. You can inspect, clear, reorder, and remove queued messages:
# Get the current queue for a chat
curl "https://api.tryreplicas.com/v1/replica/{id}/chats/{chatId}/queue" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Remove a message from the queue
curl -X DELETE "https://api.tryreplicas.com/v1/replica/{id}/chats/{chatId}/queue/{messageId}" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Clear all queued messages
curl -X DELETE "https://api.tryreplicas.com/v1/replica/{id}/chats/{chatId}/queue" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Reorder a queued message (move to a new position)
curl -X PATCH "https://api.tryreplicas.com/v1/replica/{id}/chats/{chatId}/queue/reorder" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "messageId": "MSG_ID", "position": 0 }'
The queue endpoint returns:
{
  "chatId": "CHAT_ID",
  "processing": true,
  "queue": [
    {
      "id": "msg_123",
      "message": "Fix the failing tests",
      "queuedAt": "2025-01-01T00:00:00.000Z",
      "senderDisplayName": "Connor"
    }
  ]
}

Mode Flags

Set plan_mode, goal_mode, or fast_mode to enable mode-specific behavior. goal_mode is only available for Codex. Leading slash commands (/plan, /goal, /fast) are also accepted at the start of message; Replicas strips them from the sent message and combines them with these flags.
curl -X POST "https://api.tryreplicas.com/v1/replica/{id}/messages" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "/fast Refactor the auth module",
    "plan_mode": true,
    "goal_mode": true
  }'
Also supported in POST /v1/replica when creating a replica.

Thinking Level

Control how much reasoning the agent applies with thinking_level:
curl -X POST "https://api.tryreplicas.com/v1/replica/{id}/messages" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "Architect a new microservice for payments",
    "thinking_level": "max"
  }'
LevelClaudeCodexCursorOpencodeDescription
lowlowlowlownative variant when supportedMinimal thinking, fastest responses
mediummediummediummediumnative variant when supportedModerate reasoning depth
highhighhighhighnative variant when supportedDeep reasoning
maxmaxxhighmaxstrongest native variant when supportedMaximum effort
Provider defaults when omitted: Claude = high, Codex = medium, Cursor = medium, Opencode = medium. Opencode thinking levels use the selected model’s native variants when available; models without a matching variant use Opencode’s model default. Also supported in POST /v1/replica when creating a replica.

Images

Attach images (screenshots, diagrams) to messages:
curl -X POST "https://api.tryreplicas.com/v1/replica/{id}/messages" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "Fix the layout issue shown in this screenshot",
    "images": [{
      "type": "image",
      "source": {
        "type": "base64",
        "media_type": "image/png",
        "data": "BASE64_DATA"
      }
    }]
  }'

Chat History

Read the message history for a chat (replaces the deprecated /read endpoint):
curl "https://api.tryreplicas.com/v1/replica/{id}/history?chat_id={chatId}&limit=50" \
  -H "Authorization: Bearer YOUR_API_KEY"

Hooks

View warm and start hook execution logs:
curl "https://api.tryreplicas.com/v1/replica/{id}/hooks" \
  -H "Authorization: Bearer YOUR_API_KEY"

Canvas

Read files the agent drops into the workspace Canvas (~/.replicas/canvas/). Supported kinds: markdown, html, image, video, audio, other. Per-item size is capped at 5MB; use replicas media upload for anything larger. When Workspace History is enabled, Canvas items remain available after the workspace sleeps. List items:
curl "https://api.tryreplicas.com/v1/replica/{id}/canvas" \
  -H "Authorization: Bearer YOUR_API_KEY"
Each item: { filename, kind, sizeBytes }. Get a single item:
curl "https://api.tryreplicas.com/v1/replica/{id}/canvas/{filename}" \
  -H "Authorization: Bearer YOUR_API_KEY"
Text kinds (markdown, html) return content (UTF-8 string). Binary kinds return base64. Items over the size cap return tooLarge: true with no payload.

Environments API

Environments are the primitive that ties together a repository binding plus the runtime configuration (variables, files, skills, MCPs, warm hooks) applied to every workspace created from them. See Environments for feature details. Every organization has a singleton Global environment that applies to every workspace. You can address it in any URL by passing the literal string global instead of a UUID — there’s no need to look up its ID first.
# These are equivalent once you know the UUID
curl ".../v1/environments/global"           -H "Authorization: Bearer KEY"
curl ".../v1/environments/<global-uuid>"    -H "Authorization: Bearer KEY"

List Environments

curl "https://api.tryreplicas.com/v1/environments" \
  -H "Authorization: Bearer YOUR_API_KEY"
Returns every environment in the organization, including the Global env, with counts of attached variables / files / skills / MCPs.

Get an Environment

curl "https://api.tryreplicas.com/v1/environments/{id}" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Or address the org's Global environment directly:
curl "https://api.tryreplicas.com/v1/environments/global" \
  -H "Authorization: Bearer YOUR_API_KEY"

Create an Environment

curl -X POST "https://api.tryreplicas.com/v1/environments" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "staging",
    "description": "Staging deploys",
    "repository_id": "REPO_UUID",
    "system_prompt": "You target staging only — never push to main."
  }'
repository_id and repository_set_id are mutually exclusive; both can be omitted if you want an unbound environment.

Update an Environment

curl -X PATCH "https://api.tryreplicas.com/v1/environments/{id}" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "staging-eu",
    "system_prompt": "Region: eu-west-1."
  }'
The Global environment’s metadata cannot be edited via PATCH (only its nested resources — variables, files, etc.).

Delete an Environment

curl -X DELETE "https://api.tryreplicas.com/v1/environments/{id}" \
  -H "Authorization: Bearer YOUR_API_KEY"
Returns 409 when an automation still references the environment, or when called against the Global environment.

Variables

# List
curl "https://api.tryreplicas.com/v1/environments/{environmentId}/variables" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Create
curl -X POST "https://api.tryreplicas.com/v1/environments/{environmentId}/variables" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "key": "DATABASE_URL", "value": "postgres://..." }'

# Update
curl -X PATCH "https://api.tryreplicas.com/v1/environments/{environmentId}/variables/{id}" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "value": "postgres://new-host/db" }'

# Delete
curl -X DELETE "https://api.tryreplicas.com/v1/environments/{environmentId}/variables/{id}" \
  -H "Authorization: Bearer YOUR_API_KEY"
Values are encrypted at rest. {environmentId} accepts global for the Global environment.

Files

Files are placed inside workspaces at the configured path. Max content size is 64 KB.
# Create
curl -X POST "https://api.tryreplicas.com/v1/environments/{environmentId}/files" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "AGENTS",
    "path": "~/AGENTS.md",
    "content": "# Project conventions\n..."
  }'
Same PATCH / DELETE / GET shape as variables.

Skills

Skills come from skills.sh. Search the catalog, then enable a skill on a specific environment.
# Search the catalog
curl "https://api.tryreplicas.com/v1/environment-skills/search?q=docker" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Enable a skill on an environment
curl -X POST "https://api.tryreplicas.com/v1/environments/{environmentId}/skills" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "docker",
    "slug": "docker",
    "source": "https://skills.sh/skill/docker"
  }'

# List enabled skills
curl "https://api.tryreplicas.com/v1/environments/{environmentId}/skills" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Disable a skill
curl -X DELETE "https://api.tryreplicas.com/v1/environments/{environmentId}/skills/{id}" \
  -H "Authorization: Bearer YOUR_API_KEY"

Skill registries

Add GitHub repositories as skill registries so their skills install into workspaces at provisioning time.
# List registries for an environment
curl "https://api.tryreplicas.com/v1/environments/{environmentId}/skills-registries" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Add a registry
curl -X POST "https://api.tryreplicas.com/v1/environments/{environmentId}/skills-registries" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://github.com/org/skills-repo"
  }'

# Remove a registry
curl -X DELETE "https://api.tryreplicas.com/v1/environments/{environmentId}/skills-registries/{skillsRegistryId}" \
  -H "Authorization: Bearer YOUR_API_KEY"

MCPs

# List MCPs
curl "https://api.tryreplicas.com/v1/environments/{environmentId}/mcps" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Create a stdio MCP
curl -X POST "https://api.tryreplicas.com/v1/environments/{environmentId}/mcps" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "linear",
    "transport": "stdio",
    "config": {
      "command": "npx",
      "args": ["-y", "@linear/mcp"],
      "env": { "LINEAR_API_KEY": "..." }
    }
  }'

# Create an http MCP
curl -X POST "https://api.tryreplicas.com/v1/environments/{environmentId}/mcps" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "internal-tools",
    "transport": "http",
    "config": {
      "url": "https://mcp.example.com",
      "headers": { "Authorization": "Bearer ..." }
    }
  }'
transport may be stdio, http, or sse. PATCH and DELETE work on /v1/environments/{environmentId}/mcps/{id}.

Warm Hooks

Each environment has at most one active warm hook (a shell script that runs while pre-warming workspaces). The Global environment’s warm hook applies to every pool.
# Read the active warm hook + warm pool config for an environment
curl "https://api.tryreplicas.com/v1/environments/{environmentId}/warm-hooks" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Read the per-repo warm hooks defined in `replicas.json` / `replicas.yaml` for the env's bound repositories
curl "https://api.tryreplicas.com/v1/environments/{environmentId}/warm-hooks/repository-hooks" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Test a script without saving (useful while iterating)
curl -X POST "https://api.tryreplicas.com/v1/environments/global/warm-hooks/test" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "content": "#!/usr/bin/env bash\nset -euo pipefail\nbun install\n" }'

# Save without testing — persists and activates the hook immediately
curl -X POST "https://api.replicas.dev/v1/environments/global/warm-hooks/save" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "content": "#!/usr/bin/env bash\nset -euo pipefail\nbun install\n" }'

# Save and test — only persists the new active version when the test succeeds
curl -X POST "https://api.tryreplicas.com/v1/environments/global/warm-hooks/save-test" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "content": "#!/usr/bin/env bash\nset -euo pipefail\nbun install\n" }'

# Stream save & test with SSE (recommended — avoids gateway timeouts)
curl -N -X POST "https://api.replicas.dev/v1/environments/global/warm-hooks/save-test/stream" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{ "content": "#!/usr/bin/env bash\nset -euo pipefail\nbun install\n", "mode": "save_test" }'
# Streams SSE events: progress, output, complete (or error)

# Enable / disable the warm pool for an environment
curl -X PUT "https://api.tryreplicas.com/v1/environments/{environmentId}/warm-pools" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "enabled": true }'
Warm pools are enabled by default on environments created via POST /v1/environments, so this PUT is only needed to disable a pool or re-enable one that was previously turned off. Existing environments are unaffected. There are three mutation endpoints: test-only (runs without persisting), save-only (persists and activates immediately without testing), and save-and-test (persists only if the test passes). The test and save-test endpoints spin up a real isolated sandbox and run your script there. The streaming endpoint (POST .../warm-hooks/save-test/stream) returns Server-Sent Events so the connection stays alive during long-running hooks — use it instead of the synchronous save-test endpoint to avoid gateway timeouts. Events include progress (status messages), output (captured stdout/stderr), and complete (final exit_code, timed_out, and the saved warm_hook record on success). The mode field can be "save_test" (default, persists on success) or "test_only".

Start Hooks

Each environment has at most one active start hook (a shell script that runs at workspace startup, before repository-level start hooks). The Global environment’s start hook applies to every workspace. See Start Hooks for feature details.
# Read the active start hook for an environment
curl "https://api.tryreplicas.com/v1/environments/{environmentId}/start-hooks" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Read per-repo start hooks defined in `replicas.json` / `replicas.yaml` for the env's bound repositories
curl "https://api.tryreplicas.com/v1/environments/{environmentId}/start-hooks/repository-hooks" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Save - persists and activates the start hook immediately
curl -X POST "https://api.tryreplicas.com/v1/environments/global/start-hooks/save" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "content": "#!/usr/bin/env bash\nnpm run dev &\n" }'

# Test without saving (synchronous - returns the full result once the hook finishes)
curl -X POST "https://api.tryreplicas.com/v1/environments/global/start-hooks/test" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "content": "#!/usr/bin/env bash\nnpm run dev &\n" }'

# Test with streaming output (provisions a sandbox, runs the script, tears down)
curl -N -X POST "https://api.tryreplicas.com/v1/environments/global/start-hooks/test/stream" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{ "content": "#!/usr/bin/env bash\nnpm run dev &\n" }'
The synchronous test endpoint runs the script in an isolated sandbox and returns { test: { exit_code, output, timed_out } } once the hook finishes - use it from CLI tooling and short-lived clients. The streaming endpoint emits SSE events (progress, output, complete, error) and is recommended for long-running hooks to avoid gateway timeouts. The Global environment can be addressed as "global" in any URL, no UUID lookup required.

Automations API

Automations let you trigger replicas on a schedule or in response to GitHub or GitLab events. The full CRUD is available via the API. See Automations for feature details. Automations default to scope: "org". Set scope: "user" when creating an automation with a personal API key or JWT auth to make it personal to that user inside the current organization. Org API keys cannot read, edit, run, or delete personal automations.

List Automations

curl "https://api.tryreplicas.com/v1/automations?page=1&limit=20" \
  -H "Authorization: Bearer YOUR_API_KEY"
Use scope=user to list your personal automations, or scope=all to list org automations plus your personal automations.

Create an Automation

Create a cron-triggered automation that runs every weekday at 9am:
curl -X POST "https://api.tryreplicas.com/v1/automations" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "daily-code-review",
    "scope": "user",
    "prompt": "Review open PRs and leave comments on code quality issues",
    "environment_id": "ENVIRONMENT_UUID",
    "triggers": [
      {
        "type": "cron",
        "config": {
          "schedule": "0 9 * * 1-5",
          "timezone": "America/New_York"
        }
      }
    ]
  }'
Create a GitHub-triggered automation that fires when a PR is opened, and pin it to Claude with Opus 4.8 (1M) and high thinking:
curl -X POST "https://api.tryreplicas.com/v1/automations" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "pr-review",
    "prompt": "Review this PR for bugs and suggest improvements",
    "environment_id": "ENVIRONMENT_UUID",
    "triggers": [
      {
        "type": "github",
        "config": {
          "event": "pull_request.opened"
        }
      }
    ],
    "workspace_lifecycle_policy": "delete_when_done",
    "workspace_size": "small",
    "agent_provider": "claude",
    "model": "opus[1m]",
    "thinking_level": "high"
  }'
The automation runs against the repository (or repository set) bound to the chosen environment. See Environments for how to obtain an environment_id. Use "type": "gitlab" with events like "merge_request.opened" for GitLab project automations:
curl -X POST "https://api.tryreplicas.com/v1/automations" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "mr-review",
    "prompt": "Review this merge request for bugs and suggest improvements",
    "environment_id": "ENVIRONMENT_UUID",
    "triggers": [
      {
        "type": "gitlab",
        "config": {
          "event": "merge_request.opened"
        }
      }
    ]
  }'
Optional workspace_size picks the compute envelope (and per-minute price) for every workspace the automation fires off. Accepts small (2 vCPU, 8 GB, 20 GB; $0.008/min) or large (4 vCPU, 16 GB, 32 GB; $0.016/min). Defaults to small. The same field is accepted on PATCH /v1/automations/:id. Personal automation runs create workspaces with the automation owner’s user_id, but the workspace source remains automation. They are billed as automation metered usage, not seat usage. agent_provider, model, and thinking_level are all optional. Omit any of them to inherit the organization’s default agent and the agent’s own defaults. Valid agent_provider values are claude, codex, cursor, and opencode. model must be one of the models supported by the chosen provider (e.g. opus[1m], sonnet, haiku for Claude; gpt-5.5, gpt-5.4, gpt-5.4-mini, gpt-5.3-codex, gpt-5.2 for Codex; composer-2, composer-2.5 for Cursor; z-ai/glm-5.2, minimax/minimax-m3, xiaomi/mimo-v2.5-pro, moonshotai/kimi-k2.6:free for Opencode via OpenRouter). thinking_level is one of low, medium, high, max. Optional debounce_seconds sets a per-automation debounce window (0-86400 seconds, where 0 or null disables debouncing). When greater than 0, bursty trigger events update one pending run and the latest payload fires after the automation stops receiving events for the configured window. Accepts integers or null. Defaults to null (disabled). The same field is accepted on PATCH /v1/automations/:id.

Get an Automation

curl "https://api.tryreplicas.com/v1/automations/{id}" \
  -H "Authorization: Bearer YOUR_API_KEY"

Update an Automation

curl -X PATCH "https://api.tryreplicas.com/v1/automations/{id}" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "enabled": false
  }'
agent_provider, model, and thinking_level are also patchable. Send null for any field to clear the override and fall back to the default. Note that changing agent_provider without also providing a new model clears the stored model, since the previous model may not be valid for the new provider.

Delete an Automation

curl -X DELETE "https://api.tryreplicas.com/v1/automations/{id}" \
  -H "Authorization: Bearer YOUR_API_KEY"

Manually Trigger an Automation

Only works for automations with a cron trigger:
curl -X POST "https://api.tryreplicas.com/v1/automations/{id}/trigger" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

List Execution History

curl "https://api.tryreplicas.com/v1/automations/{id}/executions?page=1&limit=20" \
  -H "Authorization: Bearer YOUR_API_KEY"

Workspace Lifecycle

StatusDescription
preparingWorkspace is being created and initialized
activeWorkspace is running and ready for messages
sleepingWorkspace is paused (auto-wakes on interaction)
errorTerminal state: the underlying sandbox died unrecoverably (e.g. OOM during a heavy build). The workspace cannot be woken or messaged. See the workspaces overview for next steps.
When you interact with a sleeping workspace, it wakes automatically. The response will include waking: true. When a warm pool is configured for the target repository or repository set, expect setup times under 10 seconds. Otherwise, expect 10-60 seconds depending on repository size. POST /v1/replica/{id}/wake and the engine-proxy endpoints (messages, chats, history, canvas, logs, previews, events) return 409 Conflict when the workspace is in sleeping or error, so clients can branch on that status instead of retrying indefinitely. To distinguish the recoverable (sleeping, can wake) and terminal (error) cases, read the workspace’s status field from GET /v1/replica/:id rather than parsing the 409 body.

API Versioning

POST /v1/replica supports an optional dated version header:
X-Replicas-Api-Version: 2026-05-17
Header valueBehavior
(omitted)Legacy. Request blocks until the workspace reaches active, then returns. Engine details are populated in the response.
2026-05-17Fire-and-forget. Request returns immediately with a preparing workspace. The initial message is still delivered to the agent in the background; poll GET /v1/replica/:id or stream GET /v1/replica/:id/events to follow progress.
Pin a specific version when you want stable behavior across future API changes. We will continue to ship dated versions for breaking changes and announce sunset dates ahead of removing prior contracts.

Prerequisites

Before using the API:
  1. Add your repository in the dashboard
  2. Configure credentials for your coding agent

Use Cases

  • CI/CD Integration - Trigger replicas from GitHub Actions or other pipelines
  • Batch Operations - Create multiple replicas for parallel task execution
  • Custom Workflows - Build internal tools that leverage AI coding agents
  • Monitoring - Stream events and poll workspace state for dashboards

Billing

API workspaces are metered separately from your seat subscription. See Billing for rates, rounding, and plan details.

API Reference

See the API Reference tab for complete endpoint documentation with request/response schemas.