RoveOps API Reference
Drive AI browser workers programmatically. Describe a task in plain language, pick a speed tier, and get structured results back — the same pipeline the RoveOps dashboard runs on. Save any task as a reusable Worker and run it on demand.
The API is vendor-neutral by design: it never exposes the underlying automation engine, model names, or infrastructure cost. You integrate against RoveOps' contract — speed tiers and EUR pricing — which stays stable even as the engine underneath changes.
Introduction
All endpoints live under the /api/v1 prefix and return JSON. The base URL is:
https://www.roveopsai.comAPI access is included on the Pro and Business plans. Generate a key in the dashboard under API keys. Every task draws down your monthly usage balance; a run is refused before any work starts if the balance can't cover it.
Authentication
Authenticate with your secret key as a Bearer token in the Authorization header. Keys are shown once at creation — store them securely and never expose them in client-side code.
curl https://www.roveopsai.com/api/v1/account \
-H "Authorization: Bearer rok_live_your_key_here"Requests without a valid key return 401 unauthorized. A valid key on a plan without API access returns 403.
Errors
Errors use standard HTTP status codes and a JSON body with an error field.
| Field | Type | Description |
|---|---|---|
| 400 | bad_request | Malformed JSON body. |
| 401 | unauthorized | Missing or invalid API key. |
| 402 | insufficient_credits | Out of usage balance. Body includes balance_eur, required_eur and top_up_url. Retrying won't help until you top up. |
| 403 | forbidden | Your plan doesn't include API access. |
| 403 | worker_limit | Creating the Worker would exceed your plan's Worker limit. Body includes limit. |
| 404 | not_found | The task or worker doesn't exist or isn't yours. |
| 422 | invalid_request | Validation failed. Body includes a details object with per-field errors. |
| 429 | concurrency_limit | Your plan's concurrent-run limit is reached. Body includes limit and active; a Retry-After header suggests when to retry. |
{
"error": "insufficient_credits",
"message": "You're out of usage credits. Top up or upgrade your plan to run more tasks.",
"balance_eur": 0.05,
"required_eur": 0.1,
"top_up_url": "https://www.roveopsai.com/dashboard/billing"
}Speed & pricing
Every task picks a speed tier that trades cost for depth. You're only ever charged the final EUR price — returned as cost_eur — and a run is only billed once it completes.
| Field | Type | Description |
|---|---|---|
| fast | ~€0.10–0.40 | Extraction, short navigation, simple lookups. |
| smart | ~€0.40–1.20 | Standard research and multi-step tasks. Default. |
| deep | ~€1.00–3.50 | Complex research and long-running automations. |
Tasks
A task is a single browser-automation run. Create one, then poll it until it reaches a terminal status (completed, failed, or canceled).
Create a task
/api/v1/tasks| Field | Type | Description |
|---|---|---|
| prompt* | string | What the browser agent should do, in plain language (8–2000 chars). |
| url | string | Optional starting URL. |
| input_data | string | Optional CSV or plain-text data the agent should work through (max 20,000 chars), e.g. a list of companies to research. |
| speed | "fast" | "smart" | "deep" | Speed tier. Defaults to "smart". |
| agent | object | Optional advanced controls (Pro/Business). See below. |
curl -X POST https://www.roveopsai.com/api/v1/tasks \
-H "Authorization: Bearer rok_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"prompt": "Find exhibitors and their marketing contacts",
"url": "https://example-congress.com/exhibitors",
"speed": "smart"
}'Returns 202 Accepted with the created task:
{
"id": "task_9f2c...",
"status": "running",
"prompt": "Find exhibitors and their marketing contacts",
"url": "https://example-congress.com/exhibitors",
"speed": "smart",
"steps": 0,
"cost_eur": 0,
"summary": null,
"result": null,
"worker_id": null,
"created_at": "2026-09-22T23:31:07.019Z",
"finished_at": null,
"url_self": "https://www.roveopsai.com/api/v1/tasks/task_9f2c..."
}Retrieve a task
/api/v1/tasks/{id}Poll this to watch progress. Adds a live progress (0–1) and error field. On completion, result holds the structured table.
curl https://www.roveopsai.com/api/v1/tasks/task_9f2c... \
-H "Authorization: Bearer rok_live_your_key_here"{
"id": "task_9f2c...",
"status": "completed",
"progress": 1,
"speed": "smart",
"steps": 17,
"cost_eur": 0.75,
"summary": "Verified marketing contacts found across the target companies.",
"result": {
"columns": ["Company", "Contact", "Role", "Email", "Website"],
"rows": [
{ "Company": "Acme Robotics", "Contact": "Dana Lee", "Role": "Head of Marketing", "Email": "dana@acme.example", "Website": "acme.example" }
]
},
"error": null,
"url_self": "https://www.roveopsai.com/api/v1/tasks/task_9f2c..."
}List tasks
/api/v1/tasksReturns the 50 most recent tasks for the account under a data array.
curl https://www.roveopsai.com/api/v1/tasks \
-H "Authorization: Bearer rok_live_your_key_here"Cancel a task
/api/v1/tasks/{id}Stops an in-flight run. No-op (but not an error) if it already finished.
curl -X DELETE https://www.roveopsai.com/api/v1/tasks/task_9f2c... \
-H "Authorization: Bearer rok_live_your_key_here"{ "id": "task_9f2c...", "status": "canceled" }Workers
A Worker is a saved task template — prompt, URL, speed and agent config frozen together — that you can run on demand without re-sending the whole request. Perfect for recurring research or monitoring jobs.
Create a worker
/api/v1/workers| Field | Type | Description |
|---|---|---|
| name* | string | Human-friendly name (1–80 chars). |
| prompt* | string | Task instructions (8–2000 chars). |
| url | string | Optional starting URL. |
| speed | "fast" | "smart" | "deep" | Defaults to "smart". |
| schedule | "manual" | "hourly" | "daily" | "weekly" | How often the Worker runs itself in the background. Defaults to "manual". |
| agent | object | Optional advanced controls (Pro/Business). |
curl -X POST https://www.roveopsai.com/api/v1/workers \
-H "Authorization: Bearer rok_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"name": "Daily exhibitor scan",
"prompt": "Find exhibitors and their marketing contacts",
"url": "https://example-congress.com/exhibitors",
"speed": "smart",
"schedule": "daily"
}'{
"id": "worker_7e4a...",
"name": "Daily exhibitor scan",
"prompt": "Find exhibitors and their marketing contacts",
"url": "https://example-congress.com/exhibitors",
"speed": "smart",
"schedule": "daily",
"run_count": 0,
"created_at": "2026-09-22T23:31:33.505Z",
"last_run_at": null,
"url_self": "https://www.roveopsai.com/api/v1/workers/worker_7e4a..."
}List & retrieve workers
/api/v1/workers/api/v1/workers/{id}# list all workers
curl https://www.roveopsai.com/api/v1/workers \
-H "Authorization: Bearer rok_live_your_key_here"
# one worker
curl https://www.roveopsai.com/api/v1/workers/worker_7e4a... \
-H "Authorization: Bearer rok_live_your_key_here"Update a worker
/api/v1/workers/{id}Send any subset of name, prompt, url, speed, schedule.
curl -X PATCH https://www.roveopsai.com/api/v1/workers/worker_7e4a... \
-H "Authorization: Bearer rok_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{ "name": "Weekly exhibitor scan", "schedule": "weekly" }'Run a worker
/api/v1/workers/{id}/runStarts a task from the worker's saved config and returns it (202). The task's worker_id links back to the worker, and the worker's run_count / last_run_at are updated. Poll the returned task id like any other task. Refused with 402 when out of credits.
curl -X POST https://www.roveopsai.com/api/v1/workers/worker_7e4a.../run \
-H "Authorization: Bearer rok_live_your_key_here"Delete a worker
/api/v1/workers/{id}curl -X DELETE https://www.roveopsai.com/api/v1/workers/worker_7e4a... \
-H "Authorization: Bearer rok_live_your_key_here"{ "id": "worker_7e4a...", "deleted": true }Leads
Companies found by Lead Finder searches, de-duplicated per account. Start searches from the dashboard; recurring searches are Workers with lead_search: true and can be run with POST /api/v1/workers/{id}/run. Filter with status (new, contacted, qualified, disqualified), task_id, worker_id and limit (max 1000).
/api/v1/leadscurl "https://www.roveopsai.com/api/v1/leads?status=new&limit=50" \
-H "Authorization: ******"{
"data": [
{
"id": "lead_91c2...",
"company": "Clinica Sorriso",
"website": "https://sorriso.pt",
"domain": "sorriso.pt",
"contact_name": "Ana Silva",
"role": "Owner",
"email": "ana@sorriso.pt",
"phone": "+351 21 000 0000",
"linkedin": null,
"location": "Lisbon, Portugal",
"industry": "Dental clinic",
"fit_reason": "Independent clinic hiring a receptionist.",
"status": "new",
"task_id": "task_3f9a...",
"worker_id": null,
"created_at": "2025-01-02T10:00:00.000Z"
}
]
}Account
Check the account's plan, status and remaining usage balance — useful for pre-flighting whether a run will be accepted, or surfacing balance in your own UI.
/api/v1/accountcurl https://www.roveopsai.com/api/v1/account \
-H "Authorization: Bearer rok_live_your_key_here"{
"plan": "pro",
"plan_name": "Pro",
"status": "active",
"api_access": true,
"balance_eur": 149,
"included_eur": 149,
"period_end": null
}Webhooks
On Pro and Business, configure an HTTPS endpoint under Dashboard → API and we'll POST an event whenever a task finishes — including scheduled Worker runs. Failed deliveries are retried up to 3 times.
| Field | Type | Description |
|---|---|---|
| task.completed | event | The task finished successfully. data is the task object, including result. |
| task.failed | event | The task failed. data.error explains why. |
| task.canceled | event | The task was canceled. |
| webhook.test | event | Sent when you press “Send test” in the dashboard. |
{
"id": "evt_task_9f2c..._completed",
"type": "task.completed",
"created_at": "2025-01-01T12:00:00.000Z",
"data": { "id": "task_9f2c...", "status": "completed", "result": { ... }, "error": null }
}Every request carries a RoveOps-Signature: t=<unix>,v1=<hex> header, where v1 is the HMAC-SHA256 of `${t}.${rawBody}` using your signing secret (whsec_…). Verify it and reject timestamps older than 5 minutes. Use the event id to deduplicate.
import crypto from "node:crypto";
function verify(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
if (Math.abs(Date.now() / 1000 - Number(parts.t)) > 300) return false;
const expected = crypto
.createHmac("sha256", secret)
.update(`${parts.t}.${rawBody}`)
.digest("hex");
const a = Buffer.from(expected);
const b = Buffer.from(parts.v1 ?? "");
return a.length === b.length && crypto.timingSafeEqual(a, b);
}Advanced agent controls
Pro and Business callers can pass an optional agent object on task and worker creation to fine-tune a run. It's always safe to send: fields your plan doesn't unlock are silently ignored, so one request shape works on every plan.
| Field | Type | Description |
|---|---|---|
| model | string | Named agent to run the task. Omit for the speed tier's default. |
| effort | "low" | "medium" | "high" | … | How hard the agent reasons before acting. |
| proxy_country | string | null | Two-letter ISO country to route the exit IP through. null runs without a proxy (allowed on every plan). |
| max_cost_usd | number | Hard per-run spend ceiling, capped at the account-wide maximum. |
curl -X POST https://www.roveopsai.com/api/v1/tasks \
-H "Authorization: Bearer rok_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"prompt": "Deep competitor pricing research",
"speed": "deep",
"agent": { "effort": "high", "proxy_country": "de", "max_cost_usd": 5 }
}'TypeScript SDK
@roveops/sdk is the official, typed client. It wraps every endpoint above and adds runTask / waitForTask polling helpers.
npm install @roveops/sdkimport { RoveOpsClient } from "@roveops/sdk";
const client = new RoveOpsClient({
apiKey: process.env.ROVEOPS_API_KEY!,
baseUrl: "https://www.roveopsai.com", // omit in production
});
// Create + poll to completion in one call
const task = await client.runTask({
prompt: "Find all exhibitors and their marketing contacts.",
url: "https://example-congress.com/exhibitors",
speed: "smart",
});
console.log(task.status, task.costEur, task.result);Manual control, Workers and account balance:
// Manual create + poll
const created = await client.createTask({ prompt: "…", speed: "fast" });
const status = await client.getTask(created.id);
await client.cancelTask(created.id);
// Reusable Workers
const worker = await client.createWorker({
name: "Daily exhibitor scan",
prompt: "Find exhibitors and their marketing contacts",
speed: "smart",
schedule: "daily",
});
const run = await client.runWorker(worker.id);
await client.updateWorker(worker.id, { schedule: "weekly" });
await client.listWorkers();
await client.deleteWorker(worker.id);
// Usage balance
const account = await client.getAccount();
console.log(account.balanceEur, account.plan);Out of credits throws RoveOpsApiError with isInsufficientCredits — treat it as terminal:
import { RoveOpsApiError } from "@roveops/sdk";
try {
await client.createTask({ prompt: "…" });
} catch (err) {
if (err instanceof RoveOpsApiError && err.isInsufficientCredits) {
const { top_up_url } = err.body as { top_up_url: string };
console.error("Out of credits — top up at", top_up_url);
} else {
throw err;
}
}Ready to build?
Create an account, upgrade to Pro or Business, and generate a key.