Skip to content

Agent Computer API

Try it in the API Playground.

https://api.rebyte.ai/v1

Every request requires an API_KEY header. Get your key from Settings > API Keys.

Terminal window
curl https://api.rebyte.ai/v1/tasks \
-H "API_KEY: rbk_your_key_here"

The header name is case-insensitive. API_KEY, api-key, and x-api-key all work.


MethodPathDescription
POST/tasksCreate a task
GET/tasksList tasks
GET/tasks/:idGet task with status and prompt history
POST/tasks/:id/promptsSend a follow-up prompt
PATCH/tasks/:id/visibilityChange task visibility
DELETE/tasks/:idSoft-delete a task
GET/tasks/:id/eventsSSE stream of execution events
POST/filesGet a signed file upload URL
POST/webhooksRegister a webhook
GET/webhooksList webhooks
GET/webhooks/:idGet webhook details
DELETE/webhooks/:idDelete a webhook
All paths are relative to the base URL (https://api.rebyte.ai/v1).

POST /tasks

Creates a new task. By default, provisions a new VM (Agent Computer). Pass workspaceId to run the task on an existing workspace instead — this skips provisioning and is significantly faster.

The call blocks until the VM is provisioned and the first prompt is submitted.

Request body:

FieldTypeRequiredDescription
promptstringYesTask description (max 100,000 chars)
executorstringNoclaude (default), gemini, codex, opencode
modelstringNoModel tier for the executor. See Models.
workspaceIdstringNoUUID of an existing workspace to reuse
filesobject[]NoFiles from POST /files. Each: {"id": "...", "filename": "..."}
skillsstring[]NoSkill slugs (e.g., ["deep-research", "pdf"])
githubUrlstringNoGitHub repo in owner/repo format
branchNamestringNoBranch name (default: main)
Terminal window
curl -X POST https://api.rebyte.ai/v1/tasks \
-H "API_KEY: rbk_xxx" \
-H "Content-Type: application/json" \
-d '{
"prompt": "Build a REST API with Express and add tests",
"executor": "claude",
"skills": ["deep-research"],
"githubUrl": "your-org/your-repo"
}'

Response (201):

{
"id": "550e8400-e29b-41d4-a716-446655440000",
"workspaceId": "660e8400-e29b-41d4-a716-446655440001",
"url": "https://app.rebyte.ai/run/550e8400-e29b-41d4-a716-446655440000",
"status": "running",
"createdAt": "2026-01-28T12:00:00.000Z"
}

Save the workspaceId from the response to create follow-on tasks on the same Agent Computer:

Terminal window
# First task -- provisions a new VM
RESP=$(curl -s -X POST https://api.rebyte.ai/v1/tasks \
-H "API_KEY: rbk_xxx" -H "Content-Type: application/json" \
-d '{"prompt": "Set up the project"}')
WS_ID=$(echo $RESP | jq -r '.workspaceId')
# Second task -- reuses the same VM (much faster)
curl -s -X POST https://api.rebyte.ai/v1/tasks \
-H "API_KEY: rbk_xxx" -H "Content-Type: application/json" \
-d "{\"prompt\": \"Now add tests\", \"workspaceId\": \"$WS_ID\"}"

Available models depend on the executor:

ExecutorAvailable ModelsDefault
claudeclaude-sonnet-4.6, claude-opus-4.6, gemini-3.1-pro, gpt-5.3-codex, gpt-5.4, minimax-m2.7, kimi-k2.5, glm-5, gemini-3-flashclaude-sonnet-4.6
codexgpt-5.4, gpt-5.3-codexgpt-5.4
geminiauto-gemini-3 (auto-routes between flash and pro)auto-gemini-3
opencodeSame as claudegemini-3.1-pro

With BYOK (bring your own API key), only the executor’s native provider models are available (e.g., claude executor with BYOK only gets claude-sonnet-4.6 and claude-opus-4.6).

GET /tasks?limit=50&offset=0

Returns tasks created via the API, sorted by creation time (newest first).

ParamTypeDefaultDescription
limitnumber50Results per page (max 100)
offsetnumber0Pagination offset
Terminal window
curl "https://api.rebyte.ai/v1/tasks?limit=10" \
-H "API_KEY: rbk_xxx"

Response:

{
"data": [
{
"id": "550e8400-...",
"url": "https://app.rebyte.ai/run/550e8400-...",
"title": "Build REST API with Express",
"executor": "claude",
"model": "claude-sonnet-4.6",
"createdAt": "2026-01-28T12:00:00.000000+00:00",
"completedAt": "2026-01-28T12:05:00.000000+00:00"
}
],
"total": 42,
"limit": 10,
"offset": 0
}
GET /tasks/:id

Returns full task details including prompt history and derived status.

Terminal window
curl https://api.rebyte.ai/v1/tasks/550e8400-... \
-H "API_KEY: rbk_xxx"

Response:

{
"id": "550e8400-...",
"url": "https://app.rebyte.ai/run/550e8400-...",
"status": "running",
"title": "Build REST API with Express",
"executor": "claude",
"model": "claude-sonnet-4.6",
"createdAt": "2026-01-28T12:00:00.000000+00:00",
"completedAt": null,
"prompts": [
{
"id": "660e8400-...",
"status": "running",
"submittedAt": "2026-01-28T12:05:00.000000+00:00",
"completedAt": null
},
{
"id": "550e8400-...",
"status": "succeeded",
"submittedAt": "2026-01-28T12:00:01.000000+00:00",
"completedAt": "2026-01-28T12:03:00.000000+00:00"
}
]
}

Task status is derived from prompt states:

StatusCondition
runningAny prompt is pending or running
completedAll prompts terminal, latest is succeeded
failedAll prompts terminal, latest is failed
canceledAll prompts terminal, latest is canceled
POST /tasks/:id/prompts

Send a follow-up prompt to a running or completed task. If the VM is stopped, it is automatically resumed.

FieldTypeRequiredDescription
promptstringYesFollow-up prompt (max 100,000 chars)
skillsstring[]NoAdditional skill slugs for this prompt
Terminal window
curl -X POST https://api.rebyte.ai/v1/tasks/550e8400-.../prompts \
-H "API_KEY: rbk_xxx" \
-H "Content-Type: application/json" \
-d '{"prompt": "Now add authentication with JWT"}'

Response (201):

{
"promptId": "770f9500-..."
}
GET /tasks/:id/events

Opens a Server-Sent Events stream for the task’s latest prompt. Events include agent output (stdout, stderr), tool calls, and completion signals.

Terminal window
curl -N https://api.rebyte.ai/v1/tasks/550e8400-.../events \
-H "API_KEY: rbk_xxx"

The stream emits two event types:

  • event — execution events (agent output, tool calls)
  • done — final event with completion status, then the stream closes
PATCH /tasks/:id/visibility
FieldTypeRequiredDescription
visibilitystringYesprivate, shared, or public
LevelWho can view
privateOnly the API key owner
sharedAll organization members (default)
publicAnyone with the link (read-only)
Terminal window
curl -X PATCH https://api.rebyte.ai/v1/tasks/550e8400-.../visibility \
-H "API_KEY: rbk_xxx" \
-H "Content-Type: application/json" \
-d '{"visibility": "public"}'

When set to public, the response includes a shareUrl for unauthenticated access.

DELETE /tasks/:id

Soft-deletes the task. Returns 204 No Content.

Terminal window
curl -X DELETE https://api.rebyte.ai/v1/tasks/550e8400-... \
-H "API_KEY: rbk_xxx"

Upload files to attach to tasks. Uses a two-step signed-URL flow.

POST /files
FieldTypeRequiredDescription
filenamestringYesFile name (max 255 chars)
contentTypestringNoMIME type (default: application/octet-stream)

Response (201):

{
"id": "550e8400-...",
"filename": "data.csv",
"uploadUrl": "https://storage.googleapis.com/...",
"maxFileSize": 52428800
}

The upload URL expires in 1 hour.

Terminal window
curl -X PUT "UPLOAD_URL_FROM_STEP_1" \
-H "Content-Type: application/octet-stream" \
--data-binary @data.csv

Pass id and filename from Step 1 when creating a task:

{
"prompt": "Analyze the uploaded data",
"files": [
{"id": "550e8400-...", "filename": "data.csv"}
]
}

Files are automatically copied into the task’s VM when execution begins.


Receive HTTP POST notifications when task events occur. Webhooks are universal — they fire for all tasks in your organization, whether created via API, UI, or any other channel.

EventFires when
task.createdA new task is created
task.runningThe agent starts executing
task.completedTask finishes successfully
task.failedTask fails
task.canceledTask is canceled by user
POST /webhooks
FieldTypeRequiredDescription
urlstringYesHTTPS endpoint URL
eventsstring[]YesEvents to subscribe to
descriptionstringNoHuman-readable label (max 500 chars)
secretstringNoPre-shared secret (max 500 chars). When set, included as X-Webhook-Secret header in every delivery.
Terminal window
# Webhook without secret
curl -X POST https://api.rebyte.ai/v1/webhooks \
-H "API_KEY: rbk_xxx" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/webhook",
"events": ["task.completed", "task.failed"]
}'
# Webhook with pre-shared secret
curl -X POST https://api.rebyte.ai/v1/webhooks \
-H "API_KEY: rbk_xxx" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/webhook",
"events": ["task.completed", "task.failed"],
"secret": "my-shared-secret-value"
}'

Response (201):

{
"id": "880e8400-...",
"url": "https://your-server.com/webhook",
"events": ["task.completed", "task.failed"],
"description": null,
"hasSecret": true,
"isActive": true,
"createdAt": "2026-01-28T12:00:00.000Z",
"lastTriggeredAt": null,
"failureCount": 0
}

Behavior notes:

  • Duplicate URLs: registering the same URL twice returns the existing webhook (idempotent)
  • Limit: maximum 3 webhooks per organization. The 4th returns limit_exceeded.
  • Secret storage: the secret value is never returned in any response. Only hasSecret: true/false is exposed.
GET /webhooks

Returns all webhooks for your organization with status info (lastTriggeredAt, failureCount, isActive). Secrets are never exposed.

GET /webhooks/:id
DELETE /webhooks/:id

Returns 204 No Content. Deleted webhooks immediately stop receiving deliveries.

When a task event matches a webhook’s subscribed events, Rebyte sends an HTTP POST to the webhook URL.

Payload:

{
"event": "task.completed",
"taskId": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": 1706443200,
"data": {
"status": "succeeded",
"taskUrl": "https://app.rebyte.ai/run/550e8400-...",
"result": "Created CSV file with 10 Hacker News posts..."
}
}
  • status — prompt status: pending (task.created), running (task.running), succeeded (task.completed), failed (task.failed), canceled (task.canceled)
  • taskUrl — direct link to the task in the Rebyte UI (always present)
  • result — final AI output text (present on terminal events: task.completed, task.failed, task.canceled; absent on task.created and task.running)

Call GET /tasks/:id for full task details including prompt history.

Delivery headers:

HeaderAlways presentDescription
Content-TypeYesapplication/json
X-Webhook-SignatureYesBase64-encoded RSA-SHA256 signature
X-Webhook-TimestampYesUnix timestamp (seconds)
X-Webhook-SecretOnly if secret configuredThe pre-shared secret value you set on creation

Timeout: deliveries time out after 10 seconds.

Failure handling:

  • Delivery is fire-and-forget — no automatic retries on failure
  • Non-2xx responses increment failureCount
  • After 10 consecutive failures, the webhook is automatically disabled (isActive: false)
  • Successful deliveries reset failureCount to 0

Every delivery is signed with your organization’s RSA-2048 key pair, regardless of whether a pre-shared secret is configured.

How it works:

  1. Rebyte concatenates {timestamp}.{body} (e.g., 1706443200.{"event":"task.completed",...})
  2. Signs the string with RSA-SHA256 using your org’s private key
  3. Sends the base64-encoded signature in X-Webhook-Signature

Get your public key: contact support or retrieve it from the Rebyte dashboard. The RSA-2048 key pair is generated automatically on first webhook creation and persists for the organization.

Verification example (Node.js):

const crypto = require('crypto');
function verifyWebhook(rawBody, timestamp, signature, publicKey) {
const payload = `${timestamp}.${rawBody}`;
const verifier = crypto.createVerify('RSA-SHA256');
verifier.update(payload);
return verifier.verify(publicKey, signature, 'base64');
}
// In your webhook handler:
app.post('/webhook', (req, res) => {
const rawBody = req.body; // must be raw string, not parsed JSON
const timestamp = req.headers['x-webhook-timestamp'];
const signature = req.headers['x-webhook-signature'];
if (!verifyWebhook(rawBody, timestamp, signature, PUBLIC_KEY)) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(rawBody);
console.log(`Task ${event.taskId}: ${event.event}`);
res.status(200).send('OK');
});

Verification example (Python):

from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding
import base64
def verify_webhook(raw_body: str, timestamp: str, signature: str, public_key_pem: str) -> bool:
public_key = serialization.load_pem_public_key(public_key_pem.encode())
payload = f"{timestamp}.{raw_body}".encode()
try:
public_key.verify(
base64.b64decode(signature),
payload,
padding.PKCS1v15(),
hashes.SHA256()
)
return True
except Exception:
return False

Webhooks support two independent verification methods that can be used together:

MethodHeaderHow it worksUse case
RSA signatureX-Webhook-SignatureCryptographic proof the payload came from RebyteTamper-proof verification
Pre-shared secretX-Webhook-SecretStatic string you set on creation, echoed back in every deliverySimple shared-secret check

RSA signatures are always present. The pre-shared secret is optional — set it when creating the webhook if you want a simpler verification path.


Complete example: create a task, poll until completion, then send a follow-up.

Terminal window
# Create task
TASK_ID=$(curl -s -X POST https://api.rebyte.ai/v1/tasks \
-H "API_KEY: rbk_xxx" \
-H "Content-Type: application/json" \
-d '{"prompt": "Write a Python CLI that converts CSV to JSON"}' | jq -r '.id')
echo "Task: https://app.rebyte.ai/run/$TASK_ID"
# Poll until done
while true; do
STATUS=$(curl -s https://api.rebyte.ai/v1/tasks/$TASK_ID \
-H "API_KEY: rbk_xxx" | jq -r '.status')
echo "Status: $STATUS"
[[ "$STATUS" == "completed" || "$STATUS" == "failed" ]] && break
sleep 5
done
# Send a follow-up
curl -s -X POST https://api.rebyte.ai/v1/tasks/$TASK_ID/prompts \
-H "API_KEY: rbk_xxx" \
-H "Content-Type: application/json" \
-d '{"prompt": "Now add support for nested JSON objects"}'

All errors follow this structure:

{
"error": {
"code": "validation_error",
"message": "Invalid request body"
}
}
CodeHTTP StatusDescription
missing_api_key401API_KEY header not provided
invalid_api_key401Invalid or expired API key
validation_error400Request body failed validation
not_found404Resource does not exist or is not accessible
limit_exceeded400Organization limit reached (e.g., max webhooks)
agent_disabled403The requested executor is disabled for this organization
internal_error500Server-side failure

The API does not currently enforce per-key rate limits. Each POST /tasks provisions a real VM, so costs scale with usage. Use webhooks instead of aggressive polling to reduce unnecessary requests.