API Reference
REST API endpoints for automation control. All endpoints require authentication via a Bearer token in the Authorization header.
Authorization: Bearer your_api_token.POST /api/v2/devices/launchAutomation
Launches a saved automation project on one or more devices. Use this to run automations created and saved in the IDE.
Request Parameters
| Name | Type | Description |
|---|---|---|
device_ids | string[] | Array of device IDs to run the automation on |
automationId | string | The ID of the saved automation project |
command | string | Command to execute: "start" or "stop" |
automationParameters? | object | Parameters defined in the automation schema |
jobVariables? | object | Job-specific variables for the automation |
{
"device_ids": ["device_123456", "device_789012"],
"automationId": "83ba7359-d8eb-4374-8ecb-055af01fddfe",
"command": "start",
"automationParameters": { "maxRetries": 3, "timeout": 30000 },
"jobVariables": { "email": "user@example.com", "password": "secret123" }
}{ "success": true, "message": "Action performed successfully" }{ "success": false, "message": "Some devices offline or not found." }POST /api/v2/devices/launchDirectAutomation
Launches automation code directly on a device without saving it as a project. You provide a unique launch ID (UUID) to track the automation and retrieve logs.
Request Parameters
| Name | Type | Description |
|---|---|---|
device_id | string | The ID of the device to run automation on |
launch_id | string (UUID) | Unique identifier for this automation launch (generate a UUID) |
command | string | Command to execute: "start" or "stop" |
code | string | JavaScript/TypeScript code to execute on the device |
automationParameters? | object | Parameters accessible via agent.arguments.automationParameters |
jobVariables? | object | Variables accessible via agent.arguments.jobVariables |
{
"device_id": "device_123456",
"launch_id": "550e8400-e29b-41d4-a716-446655440000",
"command": "start",
"code": "console.log('Hello from automation!');",
"automationParameters": { "maxRetries": 3 },
"jobVariables": { "targetUrl": "https://example.com" }
}{ "success": true, "message": "Action performed successfully" }{ "success": false, "message": "Some devices offline or not found." }launch_id you provide tracks this specific automation instance. Use the same ID when calling automationLogs to retrieve its logs.POST /api/v2/devices/stopAllAutomations
Stops all running automations on the specified device.
Request Parameters
| Name | Type | Description |
|---|---|---|
device_id | string | The ID of the device to stop automations on |
{ "device_id": "device_123456" }{ "success": true, "message": "All automations stopped successfully" }{ "success": false, "message": "Invalid device_id or device not found" }POST /api/v2/devices/automationLogs
Retrieves console logs from running automations. Only returns logs from the last 10 minutes. Use the from parameter for pagination to get logs after a specific log ID.
Request Parameters
| Name | Type | Description |
|---|---|---|
device_id | string | The ID of the device to get logs from |
automation_ids | string[] | Array of automation IDs or launch IDs (for direct automations) to get logs for |
from? | string | Log ID to get logs after (for pagination) |
launch_id you provided in the automation_ids array to retrieve that automation's logs.{
"device_id": "device_123456",
"automation_ids": ["550e8400-e29b-41d4-a716-446655440000"],
"from": "e0e1a3ef-7b2a-42b5-8f21-b845fa41c8b9"
}{
"logs": [
{
"id": "e0e1a3ef-7b2a-42b5-8f21-b845fa41c8b9",
"automationId": "550e8400-e29b-41d4-a716-446655440000",
"message": "Processing screen content...",
"lineNumber": 42,
"messageLevel": "log",
"timestamp": 1755811585870
}
]
}Log Levels
| Name | Type | Description |
|---|---|---|
log | string | Standard console.log output |
warn | string | Warning messages from console.warn |
error | string | Error messages from console.error |
PUT /api/v2/automation/file/:id
Creates or updates a file within an automation project. For TypeScript files, the content is automatically compiled to JavaScript. URL parameter id is the automation project ID.
Request Body
| Name | Type | Description |
|---|---|---|
path | string | Relative file path within the project (e.g., main.ts, utils/helpers.ts) |
content | string | The file content (max ~50MB) |
{
"path": "main.ts",
"content": "async function main() {\n console.log('Hello!');\n stopCurrentAutomation();\n}\n\nmain();"
}{ "success": true, "path": "main.ts", "compiledPath": "main.js", "compiled": true }{
"success": false,
"message": "TypeScript compilation failed",
"errors": ["Error at 5:10: Property 'foo' does not exist on type 'string'."]
}{ "message": "Automation project not found or access denied" }.ts files, both the source (.ts) and compiled (.js) files are saved. You cannot directly edit .js files that have a paired .ts source.GET /api/v2/automation/file/:id
Reads the content of a file within an automation project. URL parameter id is the automation project ID; query parameter path is the relative file path.
curl "https://xgodo.com/api/v2/automation/file/83ba7359-d8eb-4374-8ecb-055af01fddfe?path=main.ts" \
-H "Authorization: Bearer your_api_token"{
"success": true,
"content": "async function main() {\n console.log('Hello!');\n stopCurrentAutomation();\n}\n\nmain();",
"path": "main.ts"
}{ "message": "File or automation project not found" }POST /api/v2/automation/commit/:id
Creates a new commit with all current changes in the automation project. The project must have uncommitted changes. URL parameter id is the automation project ID.
Request Body
| Name | Type | Description |
|---|---|---|
message | string | The commit message describing the changes (1-1000 characters) |
{ "message": "Add error handling to main automation flow" }{
"success": true,
"commit": {
"hash": "a1b2c3d4e5f6789012345678901234567890abcd",
"message": "Add error handling to main automation flow"
}
}{ "success": false, "message": "No changes to commit" }{ "message": "Automation project not found or access denied" }GET /api/v2/automation-project/out-of-steps
Retrieves out of steps records for automations where you are the owner or a shared editor. These records contain screenshots and UI data captured when an automation encounters an unknown screen or runs out of steps. Returns one record at a time with cursor-based pagination.
Query Parameters
| Name | Type | Description |
|---|---|---|
cursor? | string | Direct link to a specific record by ID |
before_cursor? | string | Get records older than this cursor (for "next" pagination) |
after_cursor? | string | Get records newer than this cursor (for "prev" pagination) |
automation_id? | string | Filter by automation ID |
type? | string | Filter by type: outOfSteps, timeout, debug, crash |
status? | string | Filter by status: pending, solved, skipped |
partial? | string | Filter by partial: true or false |
{
"success": true,
"result": {
"device_info": { "brand": "Samsung", "model": "Galaxy S21" },
"automation_name": "My Automation",
"out_of_steps_id": "507f1f77bcf86cd799439011",
"automation_id": "507f1f77bcf86cd799439012",
"type": "outOfSteps",
"status": "pending",
"screens": [
{
"_id": "507f1f77bcf86cd799439013",
"uiUrl": "https://server.com/outofsteps/.../ui_....json",
"screenshot": {
"screenshotUrl": "https://server.com/outofsteps/.../screenshot_....jpeg",
"compressedWidth": 540,
"compressedHeight": 1200,
"originalWidth": 1080,
"originalHeight": 2400
},
"nextStage": "main",
"screenState": "unknown",
"maxSteps": 0,
"timestamp": 1705334400000
}
],
"added": "2024-01-15T12:00:00.000Z"
},
"total": 100,
"currentPage": 1,
"currentCursor": "507f1f77bcf86cd799439011",
"hasNext": true,
"hasPrev": false
}uiUrl (URL to the UI JSON accessibility tree), screenshot.screenshotUrl (URL to the screenshot JPEG), nextStage(stage the automation was attempting to reach), screenState (identified screen state, or "unknown"), and maxSteps (remaining steps when captured; 0 = out of steps).PATCH /api/v2/automation-project/out-of-steps/:id/status
Mark an out of steps record as solved or skipped. Only automation editors (owner or shared_editor) can mark status, and once marked it cannot be changed. URL parameter id is the out of steps record ID.
Request Body
| Name | Type | Description |
|---|---|---|
status | string | The status to set: "solved" or "skipped" |
{ "status": "solved" }{ "success": true, "message": "Out of steps marked as solved", "status": "solved" }{ "success": false, "message": "Status already marked as \"solved\". Cannot change status once marked." }{ "message": "You don't have permission to mark this out of steps record" }solved or skipped, it cannot be changed. Make sure you have addressed the issue before marking it.Usage Example
A complete example of launching a direct automation and polling for logs.
const API_BASE = "https://xgodo.com";
const TOKEN = "your_api_token";
async function runDirectAutomation(deviceId: string, code: string) {
const launchId = crypto.randomUUID();
const launchRes = await fetch(`${API_BASE}/api/v2/devices/launchDirectAutomation`, {
method: "POST",
headers: { "Content-Type": "application/json", "Authorization": `Bearer ${TOKEN}` },
body: JSON.stringify({
device_id: deviceId,
launch_id: launchId,
command: "start",
code,
automationParameters: { maxRetries: 3 },
jobVariables: { targetUrl: "https://example.com" }
})
});
const launchData = await launchRes.json();
if (!launchData.success) throw new Error(launchData.message);
let lastLogId: string | undefined;
const pollLogs = async () => {
const logsRes = await fetch(`${API_BASE}/api/v2/devices/automationLogs`, {
method: "POST",
headers: { "Content-Type": "application/json", "Authorization": `Bearer ${TOKEN}` },
body: JSON.stringify({ device_id: deviceId, automation_ids: [launchId], from: lastLogId })
});
const logsData = await logsRes.json();
for (const log of logsData.logs) {
console.log(`[${log.messageLevel}] ${log.message}`);
lastLogId = log.id;
}
};
const interval = setInterval(pollLogs, 2000);
setTimeout(async () => {
clearInterval(interval);
await fetch(`${API_BASE}/api/v2/devices/stopAllAutomations`, {
method: "POST",
headers: { "Content-Type": "application/json", "Authorization": `Bearer ${TOKEN}` },
body: JSON.stringify({ device_id: deviceId })
});
}, 60000);
}