Documentation
API reference and the automation SDK guide for building on Xgodo.
- 18
- v1 routers
- 201
- endpoints
- 60
- pages
Start here
Client API (v2)
The stable public client API. For the complete internal surface, see the v1 reference.
Jobs
Jobs
Manage job postings, retrieve applicants, and handle job-related operations.
/api/v2/jobs/applicantsRetrieve job applicants
Retrieves a list of job applicants for a specified job. Allows for sorting, pagination, and searching within job applicants. Note: per-job task count aggregates (`total_task`, `job_done`, `running_tasks`, `pending_tasks`, `satisfied_tasks`, `declined_tasks`, `failed_tasks`) are intentionally NOT included in the v2 response — they were rarely consumed and computing them under concurrent load is the cluster's hottest read. If you need them, derive client-side by paging with `status` filters.
Request body
| Name | Type | Required | Description |
|---|---|---|---|
job_id | string | Yes | The ID of the job for which to retrieve applicants |
task_id | string | No | The ID of the job task or planned task. Accepts either a job_task_id or planned_task_id - if a planned_task_id is provided, it will be resolved to its associated job_task_id. Used when only one task details is needed. If present, the task result list array will contain only one task or empty array if task not found. |
sortby | string | No | Field by which to sort job applicants |
order | string | No | Sort order. Can be 'asc' for ascending or 'desc' for descending |
page | integer | No | Page number for pagination |
limit | integer | No | Number of applicants per page |
hours_ago | integer | No | The day interval, specified as the number of days starting from the given hours_ago up to today |
status | string | No | The status of the task ('processing', 'confirmed', 'notcomplete', 'declined', 'pending') |
search | string | No | Search term to filter applicants based on worker name, job proof, job title, comment, or worker IP |
Responses
| Status | Description |
|---|---|
| 200 | Successfully retrieved job applicantsReturns job details with applicant information including planned_task, job tasks (each carrying its own `job_price` in USD — the actual amount paid for that task; defaults to the parent job's `job_price` at task creation and may diverge thereafter), total tasks, job done count, pending tasks, satisfied tasks, declined tasks, and failed tasks |
| 400 | Invalid request data or planned task exists but has no associated job task{"error": "Invalid task_id format"} or {"error": "Planned task {id} exists but has no associated job task (job_task_id is null)"} |
| 404 | Job not found, task_id is neither a valid job task ID nor a planned task ID{"error": "Job with this Id not found"} or {"error": "task_id {id} is neither a valid job task ID nor a planned task ID"} |
/api/v2/jobs/applicantsUpdate job applicants' task statuses
Updates the status of specified job tasks. It supports changing the status, adding comments, and handles referral bonuses if the task is confirmed.
Request body
| Name | Type | Required | Description |
|---|---|---|---|
JobTasks_Ids | array | Yes | An array of job task IDs or planned task IDs to be updated. Accepts a mix of job_task_ids and planned_task_ids - planned task IDs will be resolved to their associated job_task_ids. |
status | string | Yes | The new status to set for the job tasks |
job_id | string | Yes | The ID of the job to which the tasks belong |
comment | string | No | Optional comment to add regarding the task update |
Responses
| Status | Description |
|---|---|
| 200 | Successfully updated job task statuses.Returns the updated job task details |
| 400 | Bad request. Invalid input data, invalid status provided, or planned task exists but has no associated job task.{"error": "Invalid status..."} or {"error": "Planned task {id} exists but has no associated job task (job_task_id is null)"} |
| 404 | Job or job tasks not found, or ID is neither a valid job task ID nor a planned task ID.{"error": "Job Task with this Id not found"} or {"error": "ID {id} is neither a valid job task ID nor a planned task ID"} |
/api/v2/jobs/detailsGet job details by ID
Returns job details for a specific job ID. When the job is linked to an automation (`automation_id` is set), the response also includes the automation's `automation_parameters_schema`, `job_variables_schema`, and `bucket_schema` so callers can validate / build UIs around the `automationParameters`, `jobVariables`, and bucket payloads accepted by the automation. Each schema follows the `IInputSchema` shape (`{ fields: IFieldSchema[] }`) and is `null` when the automation has no schema configured or the job has no linked automation. Note: per-job task count fields (`totla_tasks_count`, `tasks_done_count`, `tasks_confirmed_count`, `tasks_running_count`, `tasks_pending_count`) are intentionally NOT included in the v2 response — they were rarely consumed and computing them under concurrent load is the cluster's hottest read.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
job_id | string | No | Unique identifier for the job |
{
"_id": "68910c4a5e1c7092a1fdc03a",
"job_id": "68910c4a5e1c7092a1fdc03a",
"job_type": "devices_automation",
"payment_type": "action",
"title": "Create a Google account",
"category": ["Google"],
"description": "Create a Google account. ...",
"proof": "Google account email. ...",
"Target_Workers": ["worldwide"],
"few_times": true,
"premium": false,
"featured": false,
"duration": "3",
"positions": "3",
"job_price": 0.06,
"price": "0.30",
"status": "active",
"files": [...],
"added": "2025-08-04T19:38:50.204Z",
"user": {...},
"automation_id": "83ba7359-d8eb-4374-8ecb-055af01fddfe",
"automation_parameters_schema": {
"fields": [
{ "name": "maxRetries", "type": "number", "required": false, "min": 1, "max": 10 }
]
},
"job_variables_schema": {
"fields": [
{ "name": "email", "type": "string", "required": true },
{ "name": "password", "type": "string", "required": true }
]
},
"bucket_schema": {
"fields": [
{ "name": "sessionToken", "type": "string", "required": false }
]
}
}/api/v2/jobs/check-uniquenesCheck for uniqueness of job proofs
This endpoint checks if a given search term exists in the job proofs. You can specify the search option to look for exact words or substrings.
Request body
| Name | Type | Required | Description |
|---|---|---|---|
search | string | Yes | The term to search for in job proofs |
option | string | No | The search option to use. Can be "word" for exact word matching or "charactor" for substring matching |
Responses
| Status | Description |
|---|---|
| 200 | Successfully checked for uniquenessReturns a boolean indicating if the search term is unique |
| 400 | Bad request. Either the search term is missing, or an invalid search option is providedError message describing the validation error |
/api/v2/jobs/myjobsRetrieve a list of jobs that you have posted
Returns a paginated list of jobs the caller has posted under `data` (with `count`, paginated by `page`), plus a separate list of jobs shared with the caller under `shared_data` (with `shared_count`, paginated independently by `shared_page` — the current shared page is echoed back as `shared_page`). Each entry in `shared_data` carries `permission: "view" | "edit"` and `owner_username`. The response is a thin projection of the Job documents — `job_price` and `price` are stringified. Results are sorted by `added` descending. Note: per-job task counters (`job_done`, `running_task`, `pending_task`) and planned-task counters (`used_planned_tasks`, `added_planned_tasks`) are not included. To get per-task data for a specific job, use the `/api/v2/jobs/applicants` endpoint.
Request body
| Name | Type | Required | Description |
|---|---|---|---|
page | integer | No | Page number for the jobs you posted (the `data` list) |
limit | integer | No | Number of items per page (applies to both lists; default 10, max 200) |
shared_page | integer | No | Page number for the jobs shared with you (the `shared_data` list). Paginates independently of `page`. Defaults to 1. |
job_id | string | No | Filter jobs by a specific job ID |
status | string | No | Filter jobs by status (e.g., 'active', 'completed') |
orientation | string | No | The orientation for the data sorting (e.g., 'asc' or 'desc') |
Query | string | No | Search query for job title or description |
SortBY | string | No | Field to sort the results by |
/api/v2/jobs/searchSearch and filter jobs
Returns a paginated list of jobs matching the provided filters. Supports search, category, price, location, and other filters.
Request body
| Name | Type | Required | Description |
|---|---|---|---|
page | string | No | Page number for pagination |
limit | string | No | Number of jobs per page |
searchTerm | string | No | Search term for job title or description |
job_category | string | No | Filter by job category |
min_price | string | No | Minimum job price |
location | string | No | Filter by worker location |
Featured | boolean | No | Filter for featured jobs |
Premium | boolean | No | Filter for premium jobs |
orientation | string | No | Sort orientation (asc, desc) |
SortBY | string | No | Field to sort by |
/api/v2/jobs/submitCreate a new job posting
This endpoint allows users to create a new job posting. It requires specific details about the job, including title, description, category, number of positions, job price, and duration.
Request body
| Name | Type | Required | Description |
|---|---|---|---|
title | string | Yes | The title of the job posting |
category | string | Yes | Category of the job |
description | string | Yes | Detailed description of the job |
proof | string | Yes | Proof or evidence related to the job posting |
is_proof_file | boolean | No | Indicates if the proof is a file or text |
auto_rate | boolean | No | Whether the job should be automatically rated |
vcode | string | No | Verification code for the job posting |
Target_Workers | array | No | List of target workers or countries |
few_times | boolean | No | Indicates if the job can be posted a few times |
premium | boolean | No | Indicates if the job is premium |
featured | boolean | No | Whether the job is featured or not |
duration | integer | Yes | Duration for which the job is posted (in days) |
positions | integer | Yes | Number of available positions for the job |
daily_limit | integer | No | Daily limit for the job posting |
job_price | number | Yes | Price for posting the job |
Responses
| Status | Description |
|---|---|
| 201 | Job created successfullySuccess message indicating job creation |
| 400 | Bad request. Invalid or missing required fieldsList of validation error messages |
/api/v2/jobs/update-statusUpdate job status
Updates the status of a specific job.
Request body
| Name | Type | Required | Description |
|---|---|---|---|
job_id | string | Yes | The ID of the job |
status | string | Yes | New status for the job (active, inactive) |
Responses
| Status | Description |
|---|---|
| 204 | Job status updated successfully |
| 400 | Invalid request body or status |
| 401 | Unauthorized action |
| 404 | Job not found or invalid job_id |
Devices
Devices
Device management and information retrieval endpoints.
/api/v2/devicesGet debuggable devices
Retrieves a list of devices that are either owned by the user or rented with live payment type.
Responses
| Status | Description |
|---|---|
| 200 | Successfully retrieved devices list |
| 401 | Unauthorized or missing token |
| 500 | Server error |
[
{
"remote_device_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"added": "2025-08-19T10:00:00Z",
"automations": [],
"brand": "Samsung",
"country": "US",
"isEmulator": false,
"model": "Galaxy S21",
"name": "Atomic Mammal",
"networkType": "wifi",
"numberOfCores": 8,
"online": true,
"processor": "Snapdragon 888",
"ramMb": 8192,
"sdkVersion": "31",
"version": "12"
}
]/api/v2/devices/marketList market devices (action / online)
Returns devices that are listed on the market with payment_type 'action' and currently online. Each item includes the device name, country, and an isAvailable flag (false when the device has at least one job task in 'running' status, true otherwise). Results can be filtered by country and are sorted by country.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
country | string | No | Filter devices by country. |
sortDirection | string | No | Sort direction for the country field. "asc" or "desc". Defaults to "asc". |
Responses
| Status | Description |
|---|---|
| 200 | Successfully retrieved the list of online, action-payment market devices. |
| 401 | Unauthorized or missing token |
| 500 | Server error |
[
{
"name": "Atomic Mammal",
"country": "BR",
"isAvailable": true
},
{
"name": "Enormous Elephant",
"country": "US",
"isAvailable": false
}
]/api/v2/devices/verified-phone-numberGet the device's verified phone number
Agent-scoped endpoint. Identifies the device from the automation agent token and returns the phone number stored on the device record only when phoneNumberVerified is true. Returns null otherwise. Backs `agent.info.getVerifiedPhoneNumber` in the automation bootstrap.
Responses
| Status | Description |
|---|---|
| 200 | Returns the verified phone number stored on the device record, or null when the device has no verified phone number. |
| 400 | Token is not bound to a device (e.g. user-scoped token rather than an automation agent token). |
| 401 | Unauthorized or missing token |
| 404 | Device not found |
| 500 | Server error |
{
"phoneNumber": "+14155550123"
}Bucket
Bucket
Per-(job, device) JSON bucket — the persistent state automations attach to a single hire on a single device. The endpoints below are the **employer-facing** surface, gated by job ownership / share permission. They mirror the same model as the **Buckets** tab on the Job details page. (The agent surface used from inside automations is `agent.utils.bucket` — see the automation docs.)
/api/v2/bucket/:job_idList buckets for a job
Returns a paginated list of every bucket attached to this job, with the device display name resolved for each.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
job_id | string (ObjectId) | Yes | Path param. The job's `job_id`. Caller must own the job, or have it shared to them (`view` for reads, `edit` for writes/deletes). |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
page | integer | No | 1-indexed page. Defaults to `1`. |
limit | integer | No | Page size. Defaults to `20`. Capped at `100`. |
Responses
| Status | Description |
|---|---|
| 200 | Paginated list of buckets for this job (newest first by `updated_at`). Each entry is enriched with the device's display name. |
| 404 | Job not found, or caller does not own / does not have the required share permission (`view` for reads, `edit` for writes / deletes).{ "error": "Job not found" } |
| 500 | Unexpected DB error.{ "error": "Internal server error" } |
{
"buckets": [
{
"_id": "65f1...",
"job_id": "65aa...",
"remote_device_id": "8b2f-uuid",
"data": { "sessionToken": "abc123", "loggedIn": true },
"updated_at": "2026-04-15T08:14:00.000Z",
"device_name": "Pixel 5 — Lab"
}
],
"total": 1,
"page": 1,
"pages": 1
}/api/v2/bucket/:job_idDelete all buckets for a job
Wipes every bucket associated with this job. Caller must have `edit` access (owner or shared-edit).
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
job_id | string (ObjectId) | Yes | Path param. The job's `job_id`. Caller must own the job, or have it shared to them (`view` for reads, `edit` for writes/deletes). |
Responses
| Status | Description |
|---|---|
| 200 | All buckets for this job removed. Returns the count deleted.{ "success": true, "deleted": 12 } |
| 404 | Job not found, or caller does not own / does not have the required share permission (`view` for reads, `edit` for writes / deletes).{ "error": "Job not found" } |
| 500 | Unexpected DB error.{ "error": "Internal server error" } |
/api/v2/bucket/:job_id/:device_idRead a single bucket
Returns the bucket for this `(job_id, device_id)` pair. 404 when none exists or the job is inaccessible.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
job_id | string (ObjectId) | Yes | Path param. The job's `job_id`. Caller must own the job, or have it shared to them (`view` for reads, `edit` for writes/deletes). |
device_id | string (UUID) | Yes | Path param. Device's `remote_device_id`. |
Responses
| Status | Description |
|---|---|
| 200 | Returns the bucket document for this `(job_id, device_id)` pair. |
| 404 | Either the job is inaccessible to the caller, or no bucket exists for this device.{ "error": "Bucket not found" } |
| 500 | Unexpected DB error.{ "error": "Internal server error" } |
{
"bucket": {
"_id": "65f1...",
"job_id": "65aa...",
"remote_device_id": "8b2f-uuid",
"data": { "sessionToken": "abc123", "loggedIn": true },
"updated_at": "2026-04-15T08:14:00.000Z"
}
}/api/v2/bucket/:job_id/:device_idWrite a bucket
Replaces the bucket payload for this `(job_id, device_id)` pair (no merge — `data` becomes the new bucket). Validated against the automation's `bucket_schema` when one is defined. Caller must have `edit` access.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
job_id | string (ObjectId) | Yes | Path param. The job's `job_id`. Caller must own the job, or have it shared to them (`view` for reads, `edit` for writes/deletes). |
device_id | string (UUID) | Yes | Path param. Device's `remote_device_id`. |
Request body
| Name | Type | Required | Description |
|---|---|---|---|
data | object | Yes | New bucket payload. Replaces the existing object (no merge). If the linked automation defines a `bucket_schema`, `data` is validated against it. |
Responses
| Status | Description |
|---|---|
| 200 | Bucket created or replaced for this `(job_id, device_id)` pair. Returns the saved document. |
| 400 | `data` missing / not an object, or schema validation against the automation's `bucket_schema` failed.{ "error": "Invalid bucket data" } |
| 404 | Job not found, or caller does not own / does not have the required share permission (`view` for reads, `edit` for writes / deletes).{ "error": "Job not found" } |
| 500 | Unexpected DB error.{ "error": "Internal server error" } |
/api/v2/bucket/:job_id/:device_idDelete a bucket
Removes the bucket for this `(job_id, device_id)` pair. Caller must have `edit` access.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
job_id | string (ObjectId) | Yes | Path param. The job's `job_id`. Caller must own the job, or have it shared to them (`view` for reads, `edit` for writes/deletes). |
device_id | string (UUID) | Yes | Path param. Device's `remote_device_id`. |
Responses
| Status | Description |
|---|---|
| 200 | Bucket for this `(job_id, device_id)` pair removed.{ "success": true } |
| 404 | Job not found, or caller does not own / does not have the required share permission (`view` for reads, `edit` for writes / deletes).{ "error": "Job not found" } |
| 500 | Unexpected DB error.{ "error": "Internal server error" } |
Device Bucket
Device Bucket
Per-device JSON bucket, shared across every job and automation running on the device. Useful for cross-job state — login cookies, account tokens, app config. Distinct from the per-job bucket: there is no `bucket_schema` validation, and no job context is required, so direct-run automations can use it too. The agent calls these via `agent.utils.deviceBucket`.
/api/v2/device-bucketRead device bucket
Reads the device-scoped bucket. The `remote_device_id` is taken from the token when it carries a device context; non-agent callers must supply it in the body.
Request body
| Name | Type | Required | Description |
|---|---|---|---|
remote_device_id | string (UUID) | No | The device's `remote_device_id`. Optional when the token already carries a device context (agent tokens). Required for plain Client API tokens. Must point to a device the caller owns or is currently running on. |
Responses
| Status | Description |
|---|---|
| 200 | Returns the device-scoped bucket. `deviceBucket` is `{}` on first read. |
| 400 | Token has no device context and `remote_device_id` was not supplied.{ "error": "Device bucket requires a device context (remote_device_id)" } |
{
"deviceBucket": {
"accountToken": "xyz",
"username": "user@example.com"
}
}/api/v2/device-bucket/setMerge into device bucket
Merges the supplied object into the existing device bucket. Existing keys not in the payload are preserved.
Request body
| Name | Type | Required | Description |
|---|---|---|---|
remote_device_id | string (UUID) | No | The device's `remote_device_id`. Optional when the token already carries a device context (agent tokens). Required for plain Client API tokens. Must point to a device the caller owns or is currently running on. |
data | object | Yes | Non-null, non-array JSON object. Top-level keys are merged with the stored bucket — existing keys not in the payload are preserved. |
Responses
| Status | Description |
|---|---|
| 200 | Bucket merged and persisted. Returns the full merged object. |
| 400 | Missing device context or `data` is missing / null / an array / not an object.{ "error": "Invalid data. Must be a non-null object." } |
{
"success": true,
"deviceBucket": {
"accountToken": "xyz",
"username": "user@example.com"
}
}