donobu
Version:
Create browser automations with an LLM agent and replay them as Playwright scripts.
1,315 lines (1,255 loc) • 78.9 kB
YAML
openapi: '3.0.0'
info:
title: 'Donobu API'
version: '3.19.1'
description: |
The Donobu API provides a comprehensive suite of endpoints for automating web browser interactions
through AI-driven and deterministic flows. A **flow** is Donobu's core resource: it represents a
sequence of browser actions executed against a target website, driven by an AI agent, explicit user
instructions, or a predetermined script.
## Key Capabilities
- **Flow Management** — Create, monitor, query, rename, and delete automation flows.
- **AI-Powered Automation** — Leverage large language models (via configurable GPT configurations)
to autonomously navigate websites and accomplish high-level objectives.
- **Deterministic Replay** — Re-run previously recorded flows exactly as they occurred, or export
them as Playwright test scripts for integration into CI/CD pipelines.
- **Tool Call Inspection** — Retrieve the full chronological history of actions taken during a flow,
including parameters, outcomes, timing, and screenshots.
- **Media Retrieval** — Access screenshots and video recordings captured during flow execution.
- **Configuration Management** — Manage GPT provider configurations, agent-to-configuration
mappings, and environment variables consumed by flows.
- **Tool Discovery** — Query the set of browser automation tools available in the Donobu runtime.
## Run Modes
Flows operate in one of three execution modes:
| Mode | Description |
|-----------------|-------------|
| `AUTONOMOUS` | An AI agent decides what actions to take based on the overall objective. Requires a GPT configuration. |
| `INSTRUCT` | The flow waits for explicit user-submitted tool calls at each step. No GPT configuration required. |
| `DETERMINISTIC` | The flow executes a fixed sequence of tool calls provided at creation time. No AI decision-making. |
## Flow Lifecycle
A flow transitions through the following states:
`UNSTARTED` → `INITIALIZING` → (`RUNNING_ACTION` ↔ `QUERYING_LLM_FOR_NEXT_ACTION` | `WAITING_ON_USER_FOR_NEXT_ACTION`) → `SUCCESS` or `FAILED`
Flows may also be `PAUSED` and later `RESUMING` during execution.
## Getting Started
1. **Configure a GPT provider** via `POST /api/gpt-configs/{name}` (required for `AUTONOMOUS` mode).
2. **Assign the configuration to an agent** via `POST /api/agents/{name}`.
3. **Create a flow** via `POST /api/flows` with a `targetWebsite` and `overallObjective`.
4. **Poll the flow** via `GET /api/flows/{flowId}` until it reaches a terminal state (`SUCCESS` or `FAILED`).
5. **Inspect results** via tool calls, screenshots, video, or the flow's `result` field.
servers:
- url: 'http://localhost:31000'
description: 'Local Donobu app server'
tags:
- name: 'flows'
description: 'Create, manage, query, and inspect automation flows. Flows are the core resource in Donobu — each flow represents a sequence of browser actions executed against a target website to achieve an objective.'
- name: 'tools'
description: 'Discover the browser automation tools available in the Donobu runtime. Tools represent individual actions (e.g., clicking, typing, navigating) that can be invoked during flow execution.'
- name: 'agents'
description: 'Manage the mapping between Donobu agents and GPT configurations. Agents are the AI decision-makers that drive autonomous flows; each agent is linked to a specific GPT configuration that determines which model and provider it uses.'
- name: 'configs'
description: 'Manage GPT provider configurations and environment variables. GPT configurations define connection parameters and model settings for AI providers (Anthropic, OpenAI, Google, etc.). Environment variables provide key-value data accessible to flows at runtime.'
- name: 'system'
description: 'System-level endpoints for health checks and API documentation retrieval.'
paths:
#
# ── Flows ──────────────────────────────────────────────────────────────────
#
/api/flows:
get:
operationId: 'listFlows'
summary: 'List flows'
description: |
Retrieves a paginated list of flows with optional filtering. Results are ordered by
`startedAt` in descending order (newest first). Use the `nextPageToken` from the response
to fetch subsequent pages.
tags:
- 'flows'
parameters:
- name: 'name'
in: 'query'
description: 'Filter by exact flow name match.'
required: false
schema:
type: 'string'
- name: 'startedAfter'
in: 'query'
description: 'Include only flows whose `startedAt` is greater than or equal to this value. Unix epoch timestamp in milliseconds.'
required: false
schema:
type: 'number'
- name: 'startedBefore'
in: 'query'
description: 'Include only flows whose `startedAt` is less than or equal to this value. Unix epoch timestamp in milliseconds.'
required: false
schema:
type: 'number'
- name: 'runMode'
in: 'query'
description: 'Filter by execution mode.'
required: false
schema:
$ref: '#/components/schemas/RunMode'
- name: 'state'
in: 'query'
description: 'Filter by current flow state.'
required: false
schema:
$ref: '#/components/schemas/FlowState'
- name: 'limit'
in: 'query'
description: 'Maximum number of flows to return per page. Valid range is 1–100.'
required: false
schema:
type: 'integer'
minimum: 1
maximum: 100
- name: 'pageToken'
in: 'query'
description: "Opaque pagination token returned in a previous response's `nextPageToken` field. Pass it as-is to retrieve the next page of results."
required: false
schema:
type: 'string'
responses:
'200':
description: 'A paginated list of flows matching the query criteria.'
content:
application/json:
schema:
type: 'object'
required:
- 'flows'
properties:
flows:
type: 'array'
description: 'The list of flow metadata objects for this page.'
items:
$ref: '#/components/schemas/FlowMetadata'
nextPageToken:
type: 'string'
nullable: true
description: 'An opaque token to pass as the `pageToken` query parameter to retrieve the next page. Absent or null when there are no more results.'
'400':
$ref: '#/components/responses/ValidationError'
post:
operationId: 'createFlow'
summary: 'Create a flow'
description: |
Creates and starts a new Donobu flow. The flow begins executing asynchronously after
creation. Poll `GET /api/flows/{flowId}` to track progress.
At a minimum, `targetWebsite` is required. For `AUTONOMOUS` mode, an `overallObjective`
and a valid GPT configuration (either via the default agent or `gptConfigNameOverride`)
are also required.
tags:
- 'flows'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateFlowRequest'
responses:
'200':
description: 'The newly created flow. Its state will be `UNSTARTED` or `INITIALIZING`.'
content:
application/json:
schema:
$ref: '#/components/schemas/FlowMetadata'
'400':
$ref: '#/components/responses/ValidationError'
/api/flows/{flowId}:
get:
operationId: 'getFlow'
summary: 'Get a flow'
description: 'Retrieves the complete metadata for a specific flow, including its current state, configuration, execution statistics, and result.'
tags:
- 'flows'
parameters:
- $ref: '#/components/parameters/flowId'
responses:
'200':
description: 'The flow metadata.'
content:
application/json:
schema:
$ref: '#/components/schemas/FlowMetadata'
'404':
$ref: '#/components/responses/NotFoundError'
delete:
operationId: 'deleteFlow'
summary: 'Delete a flow'
description: |
Permanently deletes a flow and all associated data, including metadata, tool calls,
screenshots, and video recordings. This operation cannot be undone.
A flow that is currently running cannot be deleted; cancel it first.
tags:
- 'flows'
parameters:
- $ref: '#/components/parameters/flowId'
responses:
'200':
description: 'The flow was successfully deleted.'
'404':
$ref: '#/components/responses/NotFoundError'
'409':
description: 'The flow is still running and cannot be deleted.'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/api/flows/{flowId}/rename:
post:
operationId: 'renameFlow'
summary: 'Rename a flow'
description: 'Updates the display name of an existing flow.'
tags:
- 'flows'
parameters:
- $ref: '#/components/parameters/flowId'
requestBody:
required: true
content:
application/json:
schema:
type: 'object'
required:
- 'name'
properties:
name:
type: 'string'
description: 'The new name for the flow.'
responses:
'200':
description: 'The updated flow metadata.'
content:
application/json:
schema:
$ref: '#/components/schemas/FlowMetadata'
'400':
$ref: '#/components/responses/ValidationError'
'404':
$ref: '#/components/responses/NotFoundError'
/api/flows/{flowId}/rerun:
get:
operationId: 'getFlowAsRerun'
summary: 'Get flow as rerun payload'
description: |
Converts a completed flow into a `CreateFlowRequest` payload suitable for deterministic
replay. The returned object includes the original tool calls configured for sequential
re-execution and can be submitted directly to `POST /api/flows`.
tags:
- 'flows'
parameters:
- $ref: '#/components/parameters/flowId'
responses:
'200':
description: 'A `CreateFlowRequest` payload that will deterministically replay the flow.'
content:
application/json:
schema:
$ref: '#/components/schemas/CreateFlowRequest'
'404':
$ref: '#/components/responses/NotFoundError'
/api/flows/{flowId}/code:
get:
operationId: 'getFlowAsCode'
summary: 'Generate Playwright code for a flow'
description: |
Generates a Playwright test script that replays the actions of a completed flow.
The generated code uses the Donobu Playwright extension and can be executed
independently as part of a test suite.
tags:
- 'flows'
parameters:
- $ref: '#/components/parameters/flowId'
- name: 'areElementIdsVolatile'
in: 'query'
description: "If `true`, ID-only selectors (e.g. `#submit-btn`) are dropped because the element's `id` attribute is considered volatile. When every candidate selector is ID-based, the list is left unchanged."
required: false
schema:
type: 'boolean'
- name: 'disableSelectorFailover'
in: 'query'
description: 'If `true`, only the first (most specific) selector is used, disabling automatic fail-over to broader selectors.'
required: false
schema:
type: 'boolean'
- name: 'disableSelfHealingTests'
in: 'query'
description: 'If `true`, disables self-healing test behavior where selectors are automatically updated on mismatch.'
required: false
schema:
type: 'boolean'
- name: 'disablePullRequestCreation'
in: 'query'
description: 'If `true`, disables automatic pull request creation for tests that have self-healed.'
required: false
schema:
type: 'boolean'
- name: 'runInHeadedMode'
in: 'query'
description: 'If `true`, the generated test runs with a visible browser window instead of headless mode. Useful for debugging and demos.'
required: false
schema:
type: 'boolean'
- name: 'slowMotionDelay'
in: 'query'
description: 'Delay in milliseconds between actions in the generated test. Set to `0` to disable. Useful for debugging and demos.'
required: false
schema:
type: 'number'
minimum: 0
- name: 'playwrightScriptVariant'
in: 'query'
description: 'Choose whether the generated test uses `page.ai()` calls (`ai`) or classic tool-by-tool Playwright API calls (`classic`).'
required: false
schema:
type: 'string'
enum:
- 'ai'
- 'classic'
responses:
'200':
description: 'The generated Playwright test script.'
content:
application/json:
schema:
type: 'object'
required:
- 'script'
properties:
script:
type: 'string'
description: 'The generated Playwright test script source code.'
'404':
$ref: '#/components/responses/NotFoundError'
/api/flows/project:
post:
operationId: 'getFlowsAsProject'
summary: 'Generate a Playwright project for multiple flows'
description: |
Generates a complete Playwright project structure containing test files for one or more
flows, along with configuration and dependency files. The resulting project can be
written to disk and executed directly with Playwright.
tags:
- 'flows'
requestBody:
required: true
content:
application/json:
schema:
type: 'object'
required:
- 'flowIds'
properties:
flowIds:
type: 'array'
description: 'The IDs of flows to include in the project.'
items:
type: 'string'
options:
$ref: '#/components/schemas/CodeGenerationOptions'
responses:
'200':
description: 'The generated project files.'
content:
application/json:
schema:
type: 'object'
required:
- 'files'
properties:
files:
type: 'array'
description: 'The list of generated project files.'
items:
$ref: '#/components/schemas/ProjectFile'
'400':
$ref: '#/components/responses/ValidationError'
'404':
$ref: '#/components/responses/NotFoundError'
#
# ── Flow Tool Calls ────────────────────────────────────────────────────────
#
/api/flows/{flowId}/tool-calls:
get:
operationId: 'listToolCalls'
summary: 'List tool calls for a flow'
description: |
Retrieves the complete chronological history of tool calls executed within a flow.
Each tool call includes the action name, input parameters, outcome, timing, the
page URL at the time of execution, and a reference to a post-call screenshot (if available).
tags:
- 'flows'
parameters:
- $ref: '#/components/parameters/flowId'
responses:
'200':
description: 'The ordered list of tool calls.'
content:
application/json:
schema:
type: 'array'
items:
$ref: '#/components/schemas/ToolCall'
'404':
$ref: '#/components/responses/NotFoundError'
post:
operationId: 'proposeToolCall'
summary: 'Propose a tool call'
description: |
Submits a tool call for execution in an active flow. This is primarily used during
`INSTRUCT` mode to direct the flow's next action. The proposed tool call is validated
and queued; execution happens asynchronously.
The target flow must be actively running and the tool name must correspond to a valid,
available tool whose parameters conform to its expected schema.
tags:
- 'flows'
parameters:
- $ref: '#/components/parameters/flowId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ProposedToolCall'
responses:
'200':
description: 'The tool call was accepted and queued for execution.'
'400':
$ref: '#/components/responses/ValidationError'
'404':
$ref: '#/components/responses/NotFoundError'
/api/flows/{flowId}/tool-calls/{toolCallId}:
get:
operationId: 'getToolCall'
summary: 'Get a specific tool call'
description: 'Retrieves detailed information about a single tool call within a flow, including its input parameters, outcome, timing, and associated metadata.'
tags:
- 'flows'
parameters:
- $ref: '#/components/parameters/flowId'
- name: 'toolCallId'
in: 'path'
required: true
description: 'The unique identifier of the tool call.'
schema:
type: 'string'
responses:
'200':
description: 'The tool call details.'
content:
application/json:
schema:
$ref: '#/components/schemas/ToolCall'
'404':
$ref: '#/components/responses/NotFoundError'
#
# ── Flow Files ─────────────────────────────────────────────────────────────
#
/api/flows/{flowId}/images/{imageId}:
get:
operationId: 'getFlowImage'
summary: 'Get a flow screenshot'
description: 'Retrieves a screenshot image captured during flow execution. The response is the raw image binary in PNG or JPEG format.'
tags:
- 'flows'
parameters:
- $ref: '#/components/parameters/flowId'
- name: 'imageId'
in: 'path'
required: true
description: "The unique identifier of the image. Corresponds to a tool call's `postCallImageId`."
schema:
type: 'string'
responses:
'200':
description: 'The screenshot image.'
content:
image/png:
schema:
type: 'string'
format: 'binary'
image/jpeg:
schema:
type: 'string'
format: 'binary'
'404':
description: 'The flow or image was not found.'
/api/flows/{flowId}/video:
get:
operationId: 'getFlowVideo'
summary: 'Get a flow video recording'
description: |
Retrieves the video recording of a flow execution in WebM format. Supports HTTP range
requests for efficient streaming and seeking.
To stream the video, send a `Range` header (e.g. `Range: bytes=0-1048575`). The server
will respond with `206 Partial Content` and the requested byte range.
tags:
- 'flows'
parameters:
- $ref: '#/components/parameters/flowId'
- name: 'Range'
in: 'header'
required: false
description: 'Standard HTTP range header for partial content requests (e.g. `bytes=0-1048575`).'
schema:
type: 'string'
responses:
'200':
description: 'The full video recording.'
headers:
Accept-Ranges:
description: 'Indicates that the server supports range requests.'
schema:
type: 'string'
example: 'bytes'
Content-Length:
description: 'The size of the video in bytes.'
schema:
type: 'integer'
content:
video/webm:
schema:
type: 'string'
format: 'binary'
'206':
description: 'A partial video segment in response to a range request.'
headers:
Accept-Ranges:
description: 'Indicates that the server supports range requests.'
schema:
type: 'string'
example: 'bytes'
Content-Range:
description: 'The byte range and total size of the video (e.g. `bytes 0-1048575/5242880`).'
schema:
type: 'string'
Content-Length:
description: 'The size of the returned segment in bytes.'
schema:
type: 'integer'
content:
video/webm:
schema:
type: 'string'
format: 'binary'
'404':
description: 'The flow or video recording was not found.'
'416':
description: 'The requested byte range is not satisfiable (e.g. the end offset is before the start offset).'
/api/flows/{flowId}/browser-state:
get:
operationId: 'getFlowBrowserState'
summary: 'Get browser state for a flow'
description: |
Retrieves the persisted browser storage state for a flow. This includes cookies,
localStorage, and sessionStorage data captured from the browser context. The state
is only available if the flow was configured with `browser.persistState: true`.
tags:
- 'flows'
parameters:
- $ref: '#/components/parameters/flowId'
responses:
'200':
description: 'The browser storage state.'
content:
application/json:
schema:
$ref: '#/components/schemas/BrowserStorageState'
'404':
description: 'The flow or browser state was not found.'
#
# ── Tools ──────────────────────────────────────────────────────────────────
#
/api/tools:
get:
operationId: 'listTools'
summary: 'List available tools'
description: |
Returns the set of browser automation tools available for use within flows. Each tool
includes its name, description, input JSON Schema, and whether it requires a GPT
configuration to operate.
Use tool names from this list when specifying `allowedTools` or `toolCallsOnStart`
in a `CreateFlowRequest`, or when proposing tool calls via `POST /api/flows/{flowId}/tool-calls`.
tags:
- 'tools'
responses:
'200':
description: 'The list of available tools.'
content:
application/json:
schema:
type: 'array'
items:
$ref: '#/components/schemas/SupportedTool'
#
# ── Agents ─────────────────────────────────────────────────────────────────
#
/api/agents:
get:
operationId: 'listAgents'
summary: 'List all agent mappings'
description: |
Retrieves a mapping of all Donobu agents to their assigned GPT configuration names.
Agents without an assigned configuration will have a `null` value.
tags:
- 'agents'
responses:
'200':
description: 'A mapping of agent names to their assigned GPT configuration names.'
content:
application/json:
schema:
type: 'object'
description: 'A key-value map where keys are agent names and values are GPT configuration names (or null).'
additionalProperties:
type: 'string'
nullable: true
example:
flow-runner: 'my-anthropic-config'
/api/agents/{name}:
get:
operationId: 'getAgent'
summary: "Get an agent's configuration"
description: 'Retrieves the GPT configuration name currently assigned to a specific agent.'
tags:
- 'agents'
parameters:
- $ref: '#/components/parameters/agentName'
responses:
'200':
description: "The agent's current GPT configuration assignment."
content:
application/json:
schema:
type: 'object'
required:
- 'gptConfigName'
properties:
gptConfigName:
type: 'string'
nullable: true
description: 'The name of the GPT configuration assigned to this agent, or `null` if none is assigned.'
post:
operationId: 'setAgent'
summary: "Set an agent's configuration"
description: |
Assigns a GPT configuration to a specific agent. The referenced GPT configuration must
already exist. Setting `gptConfigName` to `null` unlinks the agent from any configuration,
which will prevent it from being used in autonomous flows.
tags:
- 'agents'
parameters:
- $ref: '#/components/parameters/agentName'
requestBody:
required: true
content:
application/json:
schema:
type: 'object'
required:
- 'gptConfigName'
properties:
gptConfigName:
type: 'string'
nullable: true
description: 'The name of the GPT configuration to assign, or `null` to unlink.'
responses:
'200':
description: 'The updated agent assignment.'
content:
application/json:
schema:
type: 'object'
required:
- 'gptConfigName'
properties:
gptConfigName:
type: 'string'
nullable: true
description: 'The name of the GPT configuration now assigned to this agent.'
'400':
$ref: '#/components/responses/ValidationError'
#
# ── GPT Configs ────────────────────────────────────────────────────────────
#
/api/gpt-configs:
get:
operationId: 'listGptConfigs'
summary: 'List all GPT configurations'
description: |
Retrieves all stored GPT configurations. Sensitive fields such as API keys and
secret access keys are automatically redacted in the response.
tags:
- 'configs'
responses:
'200':
description: 'A mapping of configuration names to their settings. Sensitive fields are redacted.'
content:
application/json:
schema:
type: 'object'
description: 'A key-value map where keys are configuration names and values are GPT configuration objects.'
additionalProperties:
$ref: '#/components/schemas/GptConfig'
/api/gpt-configs/{name}:
get:
operationId: 'getGptConfig'
summary: 'Get a GPT configuration'
description: 'Retrieves a specific GPT configuration by name. Sensitive fields are automatically redacted.'
tags:
- 'configs'
parameters:
- $ref: '#/components/parameters/gptConfigName'
responses:
'200':
description: 'The GPT configuration with sensitive fields redacted.'
content:
application/json:
schema:
$ref: '#/components/schemas/GptConfig'
'404':
$ref: '#/components/responses/NotFoundError'
post:
operationId: 'setGptConfig'
summary: 'Create or update a GPT configuration'
description: |
Creates or updates a GPT configuration. The configuration is validated against the
provider's requirements and a test request is made to verify connectivity and
authentication before the configuration is saved.
Sensitive fields are redacted in the response — the original credentials are securely
stored but never returned.
tags:
- 'configs'
parameters:
- $ref: '#/components/parameters/gptConfigName'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/GptConfig'
responses:
'200':
description: 'The saved GPT configuration with sensitive fields redacted.'
content:
application/json:
schema:
$ref: '#/components/schemas/GptConfig'
'400':
$ref: '#/components/responses/ValidationError'
delete:
operationId: 'deleteGptConfig'
summary: 'Delete a GPT configuration'
description: |
Permanently deletes a GPT configuration. Any agents that reference this configuration
are automatically unlinked (their `gptConfigName` is set to `null`).
tags:
- 'configs'
parameters:
- $ref: '#/components/parameters/gptConfigName'
responses:
'200':
description: 'The configuration was successfully deleted.'
content:
application/json:
schema:
type: 'object'
description: 'An empty object indicating success.'
#
# ── Environment Data ───────────────────────────────────────────────────────
#
/api/env:
get:
operationId: 'listEnvData'
summary: 'List all environment data'
description: 'Retrieves all environment key-value pairs that are available for use by flows.'
tags:
- 'configs'
responses:
'200':
description: 'A key-value map of all environment data.'
content:
application/json:
schema:
type: 'object'
additionalProperties:
type: 'string'
description: 'A key-value map where keys are environment variable names and values are their string values.'
/api/env/{key}:
get:
operationId: 'getEnvDatum'
summary: 'Get an environment datum'
description: 'Retrieves a single environment datum by its key.'
tags:
- 'configs'
parameters:
- $ref: '#/components/parameters/envKey'
responses:
'200':
description: 'The environment datum.'
content:
application/json:
schema:
type: 'object'
required:
- 'key'
- 'value'
properties:
key:
type: 'string'
description: 'The environment variable name.'
value:
type: 'string'
description: 'The environment variable value.'
'404':
description: 'The environment datum was not found.'
content:
application/json:
schema:
type: 'object'
properties:
error:
type: 'string'
description: 'A message indicating the datum was not found.'
post:
operationId: 'setEnvDatum'
summary: 'Create or update an environment datum'
description: 'Creates a new environment datum or updates the value of an existing one.'
tags:
- 'configs'
parameters:
- $ref: '#/components/parameters/envKey'
requestBody:
required: true
content:
application/json:
schema:
type: 'object'
required:
- 'value'
properties:
value:
type: 'string'
description: 'The value to set for the environment datum.'
responses:
'201':
description: 'The environment datum was created or updated.'
content:
application/json:
schema:
type: 'object'
required:
- 'key'
- 'value'
properties:
key:
type: 'string'
description: 'The environment variable name.'
value:
type: 'string'
description: 'The environment variable value.'
'400':
$ref: '#/components/responses/ValidationError'
delete:
operationId: 'deleteEnvDatum'
summary: 'Delete an environment datum'
description: 'Permanently removes an environment datum by its key.'
tags:
- 'configs'
parameters:
- $ref: '#/components/parameters/envKey'
responses:
'200':
description: 'The environment datum was successfully deleted.'
#
# ── System ─────────────────────────────────────────────────────────────────
#
/api/ping:
get:
operationId: 'ping'
summary: 'Health check'
description: 'A lightweight endpoint that returns HTTP 200 to confirm the server is running and accepting requests.'
tags:
- 'system'
responses:
'200':
description: 'The server is healthy.'
/api/schema:
get:
operationId: 'getSchema'
summary: 'Get OpenAPI schema'
description: |
Returns the OpenAPI specification for the Donobu API. The response format depends on
the `Accept` header: `text/html` returns an interactive HTML documentation page,
otherwise the raw YAML specification is returned.
tags:
- 'system'
parameters:
- name: 'Accept'
in: 'header'
required: false
description: 'Set to `text/html` to receive an interactive HTML documentation page. Otherwise, the raw YAML specification is returned.'
schema:
type: 'string'
responses:
'200':
description: 'The OpenAPI schema in YAML or HTML format.'
content:
application/yaml:
schema:
type: 'string'
description: 'The raw OpenAPI YAML specification.'
text/html:
schema:
type: 'string'
description: 'An interactive HTML documentation page.'
#
# ═══════════════════════════════════════════════════════════════════════════════
# COMPONENTS
# ═══════════════════════════════════════════════════════════════════════════════
#
components:
# ── Parameters ─────────────────────────────────────────────────────────────
parameters:
flowId:
name: 'flowId'
in: 'path'
required: true
description: 'The unique identifier of the flow.'
schema:
type: 'string'
agentName:
name: 'name'
in: 'path'
required: true
description: 'The agent name. Currently only `flow-runner` is supported.'
schema:
type: 'string'
enum:
- 'flow-runner'
gptConfigName:
name: 'name'
in: 'path'
required: true
description: 'The name of the GPT configuration. Must be 1–100 characters and contain only alphanumeric characters, spaces, underscores, and hyphens.'
schema:
type: 'string'
minLength: 1
maxLength: 100
pattern: '^[a-zA-Z0-9_ -]+$'
envKey:
name: 'key'
in: 'path'
required: true
description: 'The environment variable name.'
schema:
type: 'string'
# ── Responses ──────────────────────────────────────────────────────────────
responses:
ValidationError:
description: 'The request contained invalid or malformed parameters.'
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationErrorResponse'
NotFoundError:
description: 'The requested resource was not found.'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
# ── Schemas ────────────────────────────────────────────────────────────────
schemas:
# ── Flow Lifecycle ─────────────────────────────────────────────────────
FlowState:
type: 'string'
description: |
The possible states of a flow:
- `UNSTARTED` — Created but not yet initialized.
- `INITIALIZING` — Setting up the browser context and initial state.
- `RUNNING_ACTION` — Executing a tool call.
- `QUERYING_LLM_FOR_NEXT_ACTION` — The AI agent is determining the next action (AUTONOMOUS mode).
- `WAITING_ON_USER_FOR_NEXT_ACTION` — Waiting for user input (INSTRUCT mode).
- `PAUSED` — Execution temporarily suspended.
- `RESUMING` — Transitioning from paused to active state.
- `FAILED` — Terminated unsuccessfully.
- `SUCCESS` — Completed successfully.
enum:
- 'UNSTARTED'
- 'INITIALIZING'
- 'QUERYING_LLM_FOR_NEXT_ACTION'
- 'WAITING_ON_USER_FOR_NEXT_ACTION'
- 'PAUSED'
- 'RESUMING'
- 'RUNNING_ACTION'
- 'FAILED'
- 'SUCCESS'
RunMode:
type: 'string'
description: |
The execution mode that determines how a flow operates and makes decisions:
- `AUTONOMOUS` — The flow is driven by an AI agent that autonomously decides what actions
to take based on the overall objective. Requires a valid GPT configuration.
- `INSTRUCT` — The flow waits for explicit user-submitted tool calls at each step.
No GPT configuration is required.
- `DETERMINISTIC` — The flow executes a predetermined sequence of tool calls without any
AI decision-making. Commonly used for replaying previously recorded flows.
enum:
- 'AUTONOMOUS'
- 'INSTRUCT'
- 'DETERMINISTIC'
# ── Flow Metadata ──────────────────────────────────────────────────────
FlowMetadata:
type: 'object'
description: 'Complete metadata describing a Donobu flow, including its configuration, current state, execution statistics, and result.'
required:
- 'id'
- 'name'
- 'createdWithDonobuVersion'
- 'browser'
- 'envVars'
- 'gptConfigName'
- 'hasGptConfigNameOverride'
- 'customTools'
- 'defaultMessageDuration'
- 'runMode'
- 'isControlPanelEnabled'
- 'callbackUrl'
- 'targetWebsite'
- 'overallObjective'
- 'allowedTools'
- 'resultJsonSchema'
- 'result'
- 'inputTokensUsed'
- 'completionTokensUsed'
- 'maxToolCalls'
- 'startedAt'
- 'completedAt'
- 'state'
- 'nextState'
properties:
id:
type: 'string'
description: 'The unique identifier of this flow.'
name:
type: 'string'
nullable: true
description: 'The display name of this flow.'
createdWithDonobuVersion:
type: 'string'
description: 'The version of Donobu that was used to create this flow.'
browser:
$ref: '#/components/schemas/BrowserConfig'
envVars:
type: 'array'
nullable: true
description: 'The names of environment variables that were made available to this flow.'
items:
type: 'string'
gptConfigName:
type: 'string'
nullable: true
description: 'The name of the GPT configuration used for this flow.'
hasGptConfigNameOverride:
type: 'boolean'
description: 'If `true`, the `gptConfigName` was explicitly overridden when the flow was created (via `gptConfigNameOverride`).'
customTools:
type: 'array'
nullable: true
description: 'Custom user-defined tools that were available to this flow.'
items:
$ref: '#/components/schemas/CustomTool'
defaultMessageDuration:
type: 'number'
nullable: true
description: 'The default duration (in milliseconds) that in-browser messages from the flow agent are displayed to the user.'
runMode:
$ref: '#/components/schemas/RunMode'
isControlPanelEnabled:
type: 'boolean'
description: 'Whether the in-browser control panel was enabled for this flow.'
callbackUrl:
type: 'string'
nullable: true
description: 'The URL that receives an HTTP POST when the flow completes. The POST body contains `{ "id": "<flowId>" }`.'
targetWebsite:
type: 'string'
description: 'The website URL that the flow started at.'
overallObjective:
type: 'string'
nullable: true
description: 'The high-level objective the flow was tasked to accomplish.'
allowedTools:
type: 'array'
description: 'The complete set of tool names this flow is permitted to use. Automatically populated by combining explicitly specified tools, custom tools, and tools referenced in `toolCallsOnStart`.'
items:
type: 'string'
resultJsonSchema:
nullable: true
description: 'If non-null, the JSON Schema that the `result` field conforms to when the flow succeeds.'
result:
type: 'object'
nullable: true
additionalProperties: true
description: |
The final output of the flow, populated when the flow reaches a terminal state. The content
depends on how the flow completes: if `resultJsonSchema` is specified and extraction succeeds,
this contains a conforming object; if extraction fails, this contains error details; otherwise,
this contains metadata from the final tool call, or `null` if no tools were executed.
inputTokensUsed:
type: 'number'
description: 'The total number of LLM input tokens consumed during this flow.'
completionTokensUsed:
type: 'number'
description: 'The total number of LLM completion tokens consumed during this flow.'
maxToolCalls:
type: 'number'
nullable: true
description: 'If non-null, the maximum number of tool calls allowed for this flow.'
startedAt:
type: 'number'
nullable: true
description: 'The Unix epoch millisecond timestamp of when the flow started.'
completedAt:
type: 'number'
nullable: true
description: 'The Unix epoch millisecond timestamp of when the flow completed.'
state:
$ref: '#/components/schemas/FlowState'
nextState:
nullable: true
description: 'The planned next state of the flow, if a state transition is pending.'
allOf:
- $ref: '#/components/schemas/FlowState'
videoDisabled:
type: 'boolean'
nullable: true
description: 'If `true`, video recording was disabled for this flow. Useful for long-running flows where recordings may become too large.'
# ── Create Flow Request ────────────────────────────────────────────────
CreateFlowRequest:
type: 'object'
description: 'The request payload for creating a new Donobu flow.'
required:
- 'targetWebsite'
properties:
name:
type: 'string'
nullable: true
maxLength: 256
description: 'An optional display name for the flow. Must be fewer than 256 characters.'
browser:
nullable: true
description: 'Browser configuration for the flow. If omitted, a default local Chromium browser is used.'
allOf:
- $ref: '#/components/schemas/BrowserConfig'
envVars:
type: 'array'
nullable: true
description: 'Names of environment variables (previously stored via `/api/env`) to make available to the flow.'
items:
type: 'string'
customTools:
type: 'array'
nullable: true
description: 'Custom user-defined tools to make available during the flow.'
items:
$ref: '#/components/schemas/CustomTool'
defaultMessageDuration:
type: 'number'
nullable: true
description: 'Default duration (in milliseconds) for in-browser messages from the flow agent.'
callbackUrl:
type: 'string'
nullable: true
description: 'A URL to receive an HTTP POST when the flow completes. The POST body will contain `{ "id": "<flowId>" }`.'
targetWebsite:
type: 'string'
description: 'The website URL to navigate to when starting the flow.'
overallObjective:
type: 'string'
nullable: true
description: 'The high-level objective for the flow to accomplish. Required when `initialRunMode` is `AUTONOMOUS`; may be omitted for `INSTRUCT` or `DETERMINISTIC` modes.'
allowedTools:
type: 'array'
nullable: true
description: 'An explicit list of tool names the flow is permitted to use. If omitted, the default tool set is used.'
items:
type: 'string'
resultJsonSchema:
nullable: true
description: "A JSON Schema defining the expected structure of the flow's result. When specified, Donobu will attempt to extract a conforming result object upon flow completion."
maxToolCalls:
type: 'number'
nullable: true
description: 'The maximum number of tool calls the flow may execute. Only used when `initialRunMode` is `AUTONOMOUS`.'
videoDisabled:
type: 'boolean'
nullable: true
description: 'If `true`, disables video recording for the flow. Useful for long-running flows.'
gptConfigNameOverride:
type: 'string'
nullable: true
description: "The name of a specific GPT configuration to use instead of the agent's default. If the configuration does not exist, the default agent configuration is used."
initialRunMode:
nullable: true
description: 'The execution mode for the flow. If omitted, defaults to `AUTONOMOUS`.'
allOf:
- $ref: '#/components/schemas/RunMode'
isControlPanelEnabled:
type: 'boolean'
nullable: true
description: 'If `true`, enables the in-browser control panel overlay. Ignored when the browser is running in headless mode.'
toolCallsOnStart:
type: 'array'
nullable: true
description: 'An ordered list of tool calls to execute immediately when the flow starts. Commonly used with `DETERMINISTIC` mode for replaying recorded flows.'
items:
$ref: '#/components/schemas/ProposedToolCall'
# ── Browser Config ─────────────────────────────────────────────────────
BrowserConfig:
type: 'object'
description: 'Configuration for the browser instance used by a flow.'
required:
- 'using'
properties:
initialState:
description: 'A reference to a source of browser state (cookies, localStorage, sessionStorage) to restore when starting the flow.'
$ref: '#/components/schemas/BrowserStateReference'
persistState:
type: 'boolean'
description: 'If `true`, the browser state is saved at the end of the flow and can be retrieved via `GET /api/flows/{flowId}/browser-state`.'
using:
description: 'The browser backend configuration. Exactly one of `device`, `remoteInstance`, or `browserBase`.'
oneOf:
- $ref: '#/components/schemas/DeviceBrowserConfig'
- $ref: '#/components/schemas/RemoteInstanceBrowserConfig'
- $ref: '#/components/schemas/BrowserBaseBrowserConfig'
discriminator:
propertyName: 'type'
mapping:
device: '#/components/schemas/DeviceBrowserConfig'
remoteInstance: '#/components/schemas/RemoteInstanceBrowserConfig'
browserBase: '#/components/schemas/BrowserBaseBrowserConfig'
DeviceBrowserConfig:
type: 'object'
description: 'Configuration for a locally launched browser using a device profile.'
required:
- 'type'
properties:
type:
type: 'string'
enum:
- 'device'
description: 'Identifies this as a local device browser configuration.'
deviceName:
type: 'string'
description: 'The name of the device profile to emulate (e.g. `Desktop Chromium`, `iPhone 14`). Defaults to `Desktop Chromium`.'
headless:
type: 'boolean'
description: 'If `true`, the browser runs without a visible window.'
proxy:
$ref: '#/components/schemas/ProxyConfig'
RemoteInstanceBrowserConfig:
type: 'object'
description: 'Configuration for connecting to a remote brows