---
title: Action Gateway Data Plane (public)
product: Managed Agents
url: https://docs.digitalocean.com/reference/api/reference/action-gateway-data-plane/
---

> **For AI agents:** The documentation index is at [https://docs.digitalocean.com/llms.txt](https://docs.digitalocean.com/llms.txt). Markdown versions of pages use the same URL with `index.html.md` in place of the HTML page (for example, append `index.html.md` to the directory path instead of opening the HTML document).

# Action Gateway Data Plane (public)

[View full API reference](https://docs.digitalocean.com/reference/api/reference/index.html.md)

The Action Gateway data plane finds and runs tools in a session. These endpoints are the REST forms of the session's MCP meta tools:

- `POST /tools/search` is `action_search`.
- `POST /tools/invoke` is `action_invoke`.
- `POST /code/execute` is `action_code`.

`GET /tools` lists the tools that a session can call, and the `/approvals` endpoints approve or deny calls waiting for approval.

**Note:** The data plane uses a separate base URL, `https://actions.do-ai.run`, the same host as a session's `mcpUrl`. It is independent of the control-plane API at `https://api.digitalocean.com`.

### Authentication and Sessions

Authenticate with a DigitalOcean personal access token in the `Authorization: Bearer` header. Custom-scoped tokens need the `action_gateway:execute` scope. Every request also acts in one session. Create the session with the [Create a Session](https://docs.digitalocean.com/reference/api/reference/action-gateway/index.html.md#sessions_create) endpoint, then send its UUID in the `X-Session-Id` header or in the request path. The UUID is the value at the end of the session's `sessionUrn` and `mcpUrl`.

The token must belong to the user who created the session, in the session's team. The session's `tools` selection limits which tools are available, and its `policy` decides whether each call is allowed, needs approval, or is denied. Policy is enforced the same way on these endpoints and on the session's MCP URL. Tools that use connections run with the connections of the session's `actorId`.

### Results and Errors

Successful requests to `/tools/search` and `/code/execute` return a tool result. Check `status` before reading `output`. `/tools/invoke` returns one tool result per call, and a well-formed request returns `200` even when some calls fail.

Failed requests return the same shape with `status` set to `failed` and an `error` object. Branch on `error.class`, `error.retriable`, and `error.recovery_hint` rather than on `error.message`. Request bodies are limited to 1 MiB.

### Approvals

When a session policy sets `ask` for a call, the call does not run. Instead, its result fails with `_meta.status` set to `requires_approval`, an `approval_id`, an `expires_at` time, and a `decide` object describing the approval request. The session owner sends that request with their own token. The caller then repeats the call with the same arguments. Over MCP, clients that support elicitation can approve the call while it waits.

Base URL `https://actions.do-ai.run`

## Endpoints

- **GET** [List Session Tools](#gatewayTools_list)
- **POST** [Search Session Tools](#gatewayTools_list_search)
- **POST** [Invoke Session Tools](#gatewayTools_run)
- **POST** [Execute Code](#gatewayCode_run)
- **POST** [Decide a Pending Approval](#gatewaySessionApprovals_update)
- **POST** [Decide a Pending Approval by Session Header](#gatewayApprovals_update)

## GET List Session Tools

`/tools`

**Authorizations: bearer_auth (1 scope)**

Http: Bearer

Required scopes: action_gateway:execute

### OAuth Authentication

In order to interact with the DigitalOcean API, you or your application must authenticate.

The DigitalOcean API handles this through OAuth, an open standard for authorization. OAuth allows you to delegate access to your account. Scopes can be used to grant full access, read-only access, or access to a specific set of endpoints.

You can generate an OAuth token by visiting the [Apps & API](https://cloud.digitalocean.com/account/api/tokens) section of the DigitalOcean control panel for your account.

An OAuth token functions as a complete authentication request. In effect, it acts as a substitute for a username and password pair.

Because of this, it is absolutely **essential** that you keep your OAuth tokens secure. In fact, upon generation, the web interface will only display each token a single time in order to prevent the token from being compromised.

DigitalOcean access tokens begin with an identifiable prefix in order to distinguish them from other similar tokens.

- `dop_v1_` for personal access tokens generated in the control panel
- `doo_v1_` for tokens generated by applications using [the OAuth flow](https://docs.digitalocean.com/reference/api/oauth-api/index.html.md)
- `dor_v1_` for OAuth refresh tokens

#### Scopes

Scopes act like permissions assigned to an API token. These permissions determine what actions the token can perform. You can create API tokens that grant read-only access, full access, or limited access to specific endpoints by using custom scopes.

Generally, scopes are designed to match HTTP verbs and common CRUD operations (Create, Read, Update, Delete).

| HTTP Verb | CRUD Operation | Scope |
|---|---|---|
| GET | Read | `<resource>:read` |
| POST | Create | `<resource>:create` |
| PUT/PATCH | Update | `<resource>:update` |
| DELETE | Delete | `<resource>:delete` |

For example, creating a new Droplet by making a `POST` request to the `/v2/droplets` endpoint requires the `droplet:create` scope while listing Droplets by making a `GET` request to the `/v2/droplets` endpoint requires the `droplet:read` scope.

Each endpoint below specifies which scope is required to access it when using custom scopes.

#### How to Authenticate with OAuth

In order to make an authenticated request, include a bearer-type `Authorization` header containing your OAuth token. All requests must be made over HTTPS.

#### Authenticate with a Bearer Authorization Header

```
curl -X $HTTP_METHOD -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/$OBJECT"
```

Lists the catalog tools that a session can call, ordered by name. The list applies the session's `tools` selection and omits tools that its policy always denies.

Each page includes an `ETag` header. Send it in `If-None-Match` to receive `304 Not Modified` while the page is unchanged.

#### Query Parameters

`page_size` integer 1 – 100 optional

Example: `20`

The number of tools returned per page, from 1 to 100. Defaults to 20 when omitted. Other values are rejected with 400.

Default: `20`

`page_token` string optional

Example: `eyJ2IjoxLCJhZnRlciI6ImV4YV93ZWJfc2VhcmNoIiwiZnAiOiI5YzFlNWI3YTNkMmY0ZTYwIn0`

The `next_page_token` from the previous response. A token is only valid for the session that received it.

#### Header Parameters

`X-Session-Id` string (uuid) required

Example: `2b3c9f0e-1a4d-4e5f-8a7b-6c5d4e3f2a1b`

The session to act in: the UUID at the end of the session's `sessionUrn` and `mcpUrl`. The session must belong to the authenticated user and team.

`If-None-Match` string optional

Example: `"3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8c"`

The `ETag` from a previous response for the same page. If the page is unchanged, the response is `304 Not Modified` with no body.

##### Request: `/tools`

### cURL

```bash
curl -X GET \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  -H "X-Session-Id: $SESSION_ID" \
  "https://actions.do-ai.run/tools?page_size=20"
```

#### Responses

**200** A page of tools.

Response Headers

`ETag` string

An identifier for this page's contents.

Response Schema: `application/json`

`next_page_token` string optional

Example: `ZXhhX3dlYl9zZWFyY2hAMQ`

An opaque cursor for the next page of results. Pass it back verbatim as `page_token`. It is empty on the last page.

`tools` array of object optional

Tools ordered by name.

**Show child properties**

`_meta` object optional

Example: `{"parallelizable":true,"streaming_safe":false,"version":"1"}`

Additional tool metadata.

`annotations` object optional Nullable

Advisory hints about a tool's behavior, with the meaning of MCP tool annotations. Do not rely on them for security decisions.

**Show child properties**

`destructiveHint` boolean optional Nullable

Example: `false`

The tool may perform destructive updates.

`idempotentHint` boolean optional

Example: `true`

Repeating a call with the same arguments has no additional effect.

`openWorldHint` boolean optional Nullable

Example: `true`

The tool interacts with external systems beyond the provider's own data.

`readOnlyHint` boolean optional

Example: `true`

The tool does not modify anything.

`title` string optional

Example: `Web Search`

Human-readable tool title.

`description` string optional

Example: `Search the public web and return ranked results with titles and URLs.`

`inputSchema` object optional

The JSON Schema for the tool's `arguments`.

`name` string optional

Example: `exa_web_search`

The provider-qualified tool name. Pass it as `tool` to invoke the tool.

`outputSchema` object optional

Example: `{"type":"object"}`

The JSON Schema for the tool's output, or for the output view bound to the tool in the session.

`parallelizable` boolean optional

Example: `true`

Whether the tool can run alongside other calls in one invoke request.

`streamingSafe` boolean optional

Example: `false`

`title` string optional

Example: `Web Search`

`version` string optional

Example: `1`

The immutable tool version.

`version` string optional

Example: `v1`

The catalog version.

304

The page is unchanged since the `ETag` in `If-None-Match`.

**400** The request is invalid: the body is not valid JSON, a required field is missing, or a value is out of range.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**401** The token is missing, invalid, or expired. This response uses the standard DigitalOcean API error format.

Response Schema: `application/json`

`id` string required

Example: `not_found`

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

`message` string required

Example: `The resource you were accessing could not be found.`

A message providing additional information about the error, including details to help resolve it when possible.

`request_id` string optional

Example: `4d9d8375-3c56-4925-a3e7-eb137fed17e9`

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

**403** The token or session cannot be used for this request. Tokens without the action_gateway:execute scope, and accounts that are not in good standing, are rejected with the standard DigitalOcean API error format. Session failures return a tool result: the session ID is missing or invalid, the session belongs to another user or team, the session has no policy, or the session policy denies the operation.

Response Schema: `application/json`

### Tool Result Error

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

### Error

`id` string required

Example: `not_found`

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

`message` string required

Example: `The resource you were accessing could not be found.`

A message providing additional information about the error, including details to help resolve it when possible.

`request_id` string optional

Example: `4d9d8375-3c56-4925-a3e7-eb137fed17e9`

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

**412** Your team is not enabled for Action Gateway, or the session or its connection is not set up for this call. For example, the session needs an actorId for OAuth tools, an OAuth connection must be reconnected, or the connection's private network does not match what the MCP server requires.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**429** A rate limit was exceeded. Wait for the number of seconds in Retry-After, when present, before retrying.

Response Headers

`Retry-After` integer

The number of seconds to wait before retrying.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**500** The gateway failed to process the request. Retry later.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**503** The gateway or a service it depends on is temporarily unavailable. Retry later.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

##### Response

**200**

```json
{
  "next_page_token": "eyJ2IjoxLCJhZnRlciI6ImV4YV93ZWJfc2VhcmNoIiwiZnAiOiI5YzFlNWI3YTNkMmY0ZTYwIn0",
  "tools": [
    {
      "_meta": {
        "parallelizable": true,
        "streaming_safe": false,
        "version": "1"
      },
      "annotations": {
        "openWorldHint": true,
        "readOnlyHint": true,
        "title": "Web Search"
      },
      "description": "Search the public web and return ranked results with titles and URLs.",
      "inputSchema": {
        "properties": {
          "max_results": {
            "type": "integer"
          },
          "query": {
            "type": "string"
          }
        },
        "required": [
          "query"
        ],
        "type": "object"
      },
      "name": "exa_web_search",
      "parallelizable": true,
      "streamingSafe": false,
      "title": "Web Search",
      "version": "1"
    }
  ],
  "version": "v1"
}
```

**400**

```json
{
  "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
  "error": {
    "class": "invalid_argument",
    "message": "Request is invalid. Fix request arguments and retry.",
    "recovery_hint": "fix_args",
    "retriable": false
  },
  "status": "failed"
}
```

**401**

```json
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
```

**403**

```json
{
  "call_id": "",
  "error": {
    "class": "forbidden",
    "message": "A valid session ID is required to invoke tools.",
    "recovery_hint": "fix_args",
    "retriable": false
  },
  "status": "failed"
}
```

**412**

```json
{
  "call_id": "",
  "error": {
    "class": "forbidden",
    "message": "Your team is not enabled for Action Gateway. Contact support to request access.",
    "recovery_hint": "contact_support",
    "retriable": false
  },
  "status": "failed"
}
```

**429**

```json
{
  "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
  "error": {
    "class": "rate_limited",
    "message": "Rate limit exceeded. Retry after the indicated delay.",
    "recovery_hint": "retry_later",
    "retriable": true
  },
  "status": "failed"
}
```

**500**

```json
{
  "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
  "error": {
    "class": "unavailable",
    "message": "The server failed to process the request.",
    "recovery_hint": "retry_later",
    "retriable": true
  },
  "status": "failed"
}
```

**503**

```json
{
  "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
  "error": {
    "class": "unavailable",
    "message": "Gateway is temporarily unavailable. Retry later.",
    "recovery_hint": "retry_later",
    "retriable": true
  },
  "status": "failed"
}
```

* * *

## POST Search Session Tools

`/tools/search`

Finds the catalog tools that fit one or more use cases. This is the REST form of the `action_search` MCP tool. Each query is searched independently and returns its own result group, so you can see which tools serve which goal. Results include each tool's `inputSchema`, so you can call a tool with `POST /tools/invoke` without another lookup.

Results include only tools that the session can call. If the session policy requires approval for `action_search`, the response is a failed result with `_meta.status` set to `requires_approval`.

#### Header Parameters

`X-Session-Id` string (uuid) required

Example: `2b3c9f0e-1a4d-4e5f-8a7b-6c5d4e3f2a1b`

The session to act in: the UUID at the end of the session's `sessionUrn` and `mcpUrl`. The session must belong to the authenticated user and team.

#### Request Body: `application/json`

`limit` integer optional

Example: `3`

The maximum number of tools returned per query. Values above 50 are capped at 50.

`providers` array of string optional

Example: `["exa"]`

Restricts every query to these providers.

`queries` array of object required

Independent search queries. Split separate actions into separate queries. Each query is searched on its own and gets its own result group.

**Show child properties**

`known_fields` string optional

Example: `project:checkout`

Known workflow inputs as one string of comma-separated `key:value` pairs, such as identifiers or settings. Used as context, not for keyword matching.

`use_case` string required

Example: `search the public web for current information`

A normalized English description of one complete use case: the action and the intended outcome, including any app the user named. Put personal identifiers in `known_fields` instead. Up to 512 bytes and 32 search terms, with at least one letter or digit.

`tags` array of string optional

Example: `["web-search"]`

Restricts every query to tools with these tags.

##### Request: `/tools/search`

### Payload

Content type `application/json`

```json
{
  "limit": 3,
  "queries": [
    {
      "use_case": "search the public web for current information"
    }
  ]
}
```

### cURL

```bash
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  -H "X-Session-Id: $SESSION_ID" \
  -d '{"queries":[{"use_case":"search the public web for current information"}],"limit":3}' \
  "https://actions.do-ai.run/tools/search"
```

#### Responses

**200** The search ran, or it is waiting for approval. Check status before reading output.

Response Schema: `application/json`

`_meta` object optional

Additional result metadata. Keys include:

- `status`: `requires_approval`, `requires_authorization`, or `requires_connection_configuration` when the call stopped before running.
- `approval_id`, `tool_name`, `expires_at`, and `decide`: present with `requires_approval`. `decide` gives the `method`, `path`, and `body` of the approval request to send. Approve the call, then repeat it with the same arguments before `expires_at`.
- `retry`: `{"attempt_count": N, "exhausted": bool}` when the gateway retried the call.
- `output_view`: the output view applied to the result.

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this call. Include it when contacting support.

`error` object optional

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`output` object optional

**Show child properties**

`results` array of object optional

One result group per query, in request order.

**Show child properties**

`guidance` string optional

Example: `No catalog tools matched this query. Retry with different terms.`

A suggested next step. Present only when no tools matched.

`index` integer optional

Example: `1`

The 1-based position of the query in the request.

`results` array of object optional

**Show child properties**

`description` string optional

Example: `Search the public web and return ranked results with titles and URLs.`

`inputSchema` object optional

Example: `{"properties":{"query":{"type":"string"}},"required":["query"],"type":"object"}`

The JSON Schema for the tool's `arguments`.

*Additional nested properties not shown. Refer to the [full API spec](https://github.com/digitalocean/openapi) for details.*

`name` string optional

Example: `exa_web_search`

The provider-qualified tool name. Pass it as `tool` to invoke the tool.

`score` number optional

Example: `0.92`

The relevance score. Higher is more relevant.

`title` string optional

Example: `Web Search`

`version` string optional

Example: `1`

`use_case` string optional

Example: `search the public web for current information`

The query's `use_case`.

`status` string, one of: succeeded, failed required

Example: `succeeded`

**400** The request is invalid: the body is not valid JSON, a required field is missing, or a value is out of range.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**401** The token is missing, invalid, or expired. This response uses the standard DigitalOcean API error format.

Response Schema: `application/json`

`id` string required

Example: `not_found`

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

`message` string required

Example: `The resource you were accessing could not be found.`

A message providing additional information about the error, including details to help resolve it when possible.

`request_id` string optional

Example: `4d9d8375-3c56-4925-a3e7-eb137fed17e9`

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

**403** The token or session cannot be used for this request. Tokens without the action_gateway:execute scope, and accounts that are not in good standing, are rejected with the standard DigitalOcean API error format. Session failures return a tool result: the session ID is missing or invalid, the session belongs to another user or team, the session has no policy, or the session policy denies the operation.

Response Schema: `application/json`

### Tool Result Error

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

### Error

`id` string required

Example: `not_found`

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

`message` string required

Example: `The resource you were accessing could not be found.`

A message providing additional information about the error, including details to help resolve it when possible.

`request_id` string optional

Example: `4d9d8375-3c56-4925-a3e7-eb137fed17e9`

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

**412** Your team is not enabled for Action Gateway, or the session or its connection is not set up for this call. For example, the session needs an actorId for OAuth tools, an OAuth connection must be reconnected, or the connection's private network does not match what the MCP server requires.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**413** The request body is larger than 1 MiB.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**429** A rate limit was exceeded. Wait for the number of seconds in Retry-After, when present, before retrying.

Response Headers

`Retry-After` integer

The number of seconds to wait before retrying.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**500** The gateway failed to process the request. Retry later.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**503** The gateway or a service it depends on is temporarily unavailable. Retry later.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

##### Response

**200**

```json
{
  "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
  "output": {
    "results": [
      {
        "index": 1,
        "results": [
          {
            "description": "Search the public web and return ranked results with titles and URLs.",
            "inputSchema": {
              "properties": {
                "max_results": {
                  "type": "integer"
                },
                "query": {
                  "type": "string"
                }
              },
              "required": [
                "query"
              ],
              "type": "object"
            },
            "name": "exa_web_search",
            "score": 0.92,
            "title": "Web Search",
            "version": "1"
          }
        ],
        "use_case": "search the public web for current information"
      }
    ]
  },
  "status": "succeeded"
}
```

**400**

```json
{
  "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
  "error": {
    "class": "invalid_argument",
    "message": "Request is invalid. Fix request arguments and retry.",
    "recovery_hint": "fix_args",
    "retriable": false
  },
  "status": "failed"
}
```

**401**

```json
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
```

**403**

```json
{
  "call_id": "",
  "error": {
    "class": "forbidden",
    "message": "A valid session ID is required to invoke tools.",
    "recovery_hint": "fix_args",
    "retriable": false
  },
  "status": "failed"
}
```

**412**

```json
{
  "call_id": "",
  "error": {
    "class": "forbidden",
    "message": "Your team is not enabled for Action Gateway. Contact support to request access.",
    "recovery_hint": "contact_support",
    "retriable": false
  },
  "status": "failed"
}
```

**413**

```json
{
  "call_id": "",
  "error": {
    "class": "invalid_argument",
    "message": "Request body is too large.",
    "recovery_hint": "fix_args",
    "retriable": false
  },
  "status": "failed"
}
```

**429**

```json
{
  "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
  "error": {
    "class": "rate_limited",
    "message": "Rate limit exceeded. Retry after the indicated delay.",
    "recovery_hint": "retry_later",
    "retriable": true
  },
  "status": "failed"
}
```

**500**

```json
{
  "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
  "error": {
    "class": "unavailable",
    "message": "The server failed to process the request.",
    "recovery_hint": "retry_later",
    "retriable": true
  },
  "status": "failed"
}
```

**503**

```json
{
  "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
  "error": {
    "class": "unavailable",
    "message": "Gateway is temporarily unavailable. Retry later.",
    "recovery_hint": "retry_later",
    "retriable": true
  },
  "status": "failed"
}
```

* * *

## POST Invoke Session Tools

`/tools/invoke`

Runs 1 to 10 tool calls in parallel and returns one result per call, in request order. This is the REST form of the `action_invoke` MCP tool.

Each call is checked against the session's tool selection and policy, uses the session actor's connections, and applies any output view bound to the tool in the session. A well-formed request returns `200` even when some calls fail. Check each item's `result.status`, and use `success_count` and `error_count` to branch without scanning every item.

A call whose policy requires approval fails with `_meta.status` set to `requires_approval`. Have the session's owner approve it, then repeat the call with the same arguments. A call that needs the end user to connect a provider fails with `_meta.status` set to `requires_authorization` or `requires_connection_configuration`.

#### Header Parameters

`X-Session-Id` string (uuid) required

Example: `2b3c9f0e-1a4d-4e5f-8a7b-6c5d4e3f2a1b`

The session to act in: the UUID at the end of the session's `sessionUrn` and `mcpUrl`. The session must belong to the authenticated user and team.

#### Request Body: `application/json`

`rationale` string optional

Example: `Find current information about DigitalOcean.`

One sentence explaining why the tools are being called. Values longer than 512 characters are truncated.

`tools` array of object required

The tool calls to run in parallel.

**Show child properties**

`arguments` object optional

Example: `{"max_results":1,"query":"DigitalOcean cloud computing"}`

The tool's arguments, matching its `inputSchema`.

`tool` string required

Example: `exa_web_search`

The tool name, as returned by `GET /tools` or `POST /tools/search`. Names are case-insensitive.

`version` string optional

Example: `1`

An immutable tool version. Omit to use the released version.

##### Request: `/tools/invoke`

### Payload

Content type `application/json`

```json
{
  "rationale": "Find current information about DigitalOcean.",
  "tools": [
    {
      "arguments": {
        "max_results": 1,
        "query": "DigitalOcean cloud computing"
      },
      "tool": "exa_web_search"
    }
  ]
}
```

### cURL

```bash
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  -H "X-Session-Id: $SESSION_ID" \
  -d '{"rationale":"Find current information about DigitalOcean.","tools":[{"tool":"exa_web_search","arguments":{"query":"DigitalOcean cloud computing","max_results":1}}]}' \
  "https://actions.do-ai.run/tools/invoke"
```

#### Responses

**200** The calls ran. Each item reports its own success or failure.

Response Schema: `application/json`

`error_count` integer optional

Example: `0`

`results` array of object optional

One result per call, in request order.

**Show child properties**

`index` integer optional

Example: `0`

The 0-based position of the call in the request.

`result` object optional

The result of one tool call. Check `status` before reading `output`. A call that needs approval, authorization, or connection setup fails with a `_meta.status` that names the step to complete.

**Show child properties**

`_meta` object optional

Additional result metadata. Keys include:

- `status`: `requires_approval`, `requires_authorization`, or `requires_connection_configuration` when the call stopped before running.
- `approval_id`, `tool_name`, `expires_at`, and `decide`: present with `requires_approval`. `decide` gives the `method`, `path`, and `body` of the approval request to send. Approve the call, then repeat it with the same arguments before `expires_at`.
- `retry`: `{"attempt_count": N, "exhausted": bool}` when the gateway retried the call.
- `output_view`: the output view applied to the result.

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this call. Include it when contacting support.

`error` object optional

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`output` object optional

Example: `{"provider":"exa","results":[{"title":"DigitalOcean","url":"https://www.digitalocean.com/"}]}`

The tool's JSON output. Present when `status` is `succeeded`. Its shape is the tool's output schema, or the output view bound to the tool in the session.

`status` string, one of: succeeded, failed required

Example: `succeeded`

`tool` string optional

Example: `exa_web_search`

The canonical tool name.

`version` string optional

Example: `1`

The tool version that ran.

`success_count` integer optional

Example: `1`

`total_count` integer optional

Example: `1`

**400** The request is invalid: the body is not valid JSON, a required field is missing, or a value is out of range.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**401** The token is missing, invalid, or expired. This response uses the standard DigitalOcean API error format.

Response Schema: `application/json`

`id` string required

Example: `not_found`

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

`message` string required

Example: `The resource you were accessing could not be found.`

A message providing additional information about the error, including details to help resolve it when possible.

`request_id` string optional

Example: `4d9d8375-3c56-4925-a3e7-eb137fed17e9`

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

**402** Your team must add prepayment before it can make more tool calls.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**403** The token or session cannot be used for this request. Tokens without the action_gateway:execute scope, and accounts that are not in good standing, are rejected with the standard DigitalOcean API error format. Session failures return a tool result: the session ID is missing or invalid, the session belongs to another user or team, the session has no policy, or the session policy denies the operation.

Response Schema: `application/json`

### Tool Result Error

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

### Error

`id` string required

Example: `not_found`

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

`message` string required

Example: `The resource you were accessing could not be found.`

A message providing additional information about the error, including details to help resolve it when possible.

`request_id` string optional

Example: `4d9d8375-3c56-4925-a3e7-eb137fed17e9`

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

**412** Your team is not enabled for Action Gateway, or the session or its connection is not set up for this call. For example, the session needs an actorId for OAuth tools, an OAuth connection must be reconnected, or the connection's private network does not match what the MCP server requires.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**413** The request body is larger than 1 MiB.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**429** A rate limit was exceeded. Wait for the number of seconds in Retry-After, when present, before retrying.

Response Headers

`Retry-After` integer

The number of seconds to wait before retrying.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**500** The gateway failed to process the request. Retry later.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**503** The gateway or a service it depends on is temporarily unavailable. Retry later.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

##### Response

**200**

Example

```json
{
  "error_count": 1,
  "results": [
    {
      "index": 0,
      "result": {
        "_meta": {
          "approval_id": "7d3c2b1a-9e8f-4a6b-8c5d-4e3f2a1b0c9d",
          "decide": {
            "body": "{\"decision\": \"approve\"}",
            "method": "POST",
            "path": "/approvals/session/2b3c9f0e-1a4d-4e5f-8a7b-6c5d4e3f2a1b/7d3c2b1a-9e8f-4a6b-8c5d-4e3f2a1b0c9d"
          },
          "expires_at": "2026-10-09T18:30:00Z",
          "status": "requires_approval",
          "tool_name": "exa_web_search"
        },
        "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
        "error": {
          "class": "execution_failed",
          "message": "Tool \"exa_web_search\" requires user approval before it can run. Ask the user to approve approval_id 7d3c2b1a-9e8f-4a6b-8c5d-4e3f2a1b0c9d (expires 2026-10-09T18:30:00Z) using their own credentials, then call the tool again with the same arguments.",
          "recovery_hint": "retry_later",
          "retriable": true
        },
        "status": "failed"
      },
      "tool": "exa_web_search",
      "version": "1"
    }
  ],
  "success_count": 0,
  "total_count": 1
}
```

```json
{
  "error_count": 0,
  "results": [
    {
      "index": 0,
      "result": {
        "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
        "output": {
          "provider": "exa",
          "results": [
            {
              "title": "DigitalOcean | Cloud Infrastructure for Developers",
              "url": "https://www.digitalocean.com/"
            }
          ]
        },
        "status": "succeeded"
      },
      "tool": "exa_web_search",
      "version": "1"
    }
  ],
  "success_count": 1,
  "total_count": 1
}
```

**400**

```json
{
  "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
  "error": {
    "class": "invalid_argument",
    "message": "Request is invalid. Fix request arguments and retry.",
    "recovery_hint": "fix_args",
    "retriable": false
  },
  "status": "failed"
}
```

**401**

```json
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
```

**402**

```json
{
  "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
  "error": {
    "class": "forbidden",
    "message": "Prepayment is required before additional tool calls can be made.",
    "recovery_hint": "contact_support",
    "retriable": false
  },
  "status": "failed"
}
```

**403**

```json
{
  "call_id": "",
  "error": {
    "class": "forbidden",
    "message": "A valid session ID is required to invoke tools.",
    "recovery_hint": "fix_args",
    "retriable": false
  },
  "status": "failed"
}
```

**412**

```json
{
  "call_id": "",
  "error": {
    "class": "forbidden",
    "message": "Your team is not enabled for Action Gateway. Contact support to request access.",
    "recovery_hint": "contact_support",
    "retriable": false
  },
  "status": "failed"
}
```

**413**

```json
{
  "call_id": "",
  "error": {
    "class": "invalid_argument",
    "message": "Request body is too large.",
    "recovery_hint": "fix_args",
    "retriable": false
  },
  "status": "failed"
}
```

**429**

```json
{
  "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
  "error": {
    "class": "rate_limited",
    "message": "Rate limit exceeded. Retry after the indicated delay.",
    "recovery_hint": "retry_later",
    "retriable": true
  },
  "status": "failed"
}
```

**500**

```json
{
  "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
  "error": {
    "class": "unavailable",
    "message": "The server failed to process the request.",
    "recovery_hint": "retry_later",
    "retriable": true
  },
  "status": "failed"
}
```

**503**

```json
{
  "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
  "error": {
    "class": "unavailable",
    "message": "Gateway is temporarily unavailable. Retry later.",
    "recovery_hint": "retry_later",
    "retriable": true
  },
  "status": "failed"
}
```

* * *

## POST Execute Code

`/code/execute`

Runs Python code in an ephemeral sandbox and returns its `stdout`, `stderr`, and `exit_code`. This is the REST form of the `action_code` MCP tool. Use it for computation, parsing, and data processing, or to chain several catalog tools in one request.

The sandbox provides `invoke_digitalocean_tool(name, arguments)`, which calls a catalog tool and returns a tool result. Those calls follow the session's tool selection and policy. Each request runs in a fresh sandbox, so state is not kept between requests. Execution, including tool calls, is time limited. Code that runs too long fails with a `timeout` error.

A nonzero exit code is still a `succeeded` result; check `output.exit_code`. If the session policy requires approval for `action_code`, the response is a failed result with `_meta.status` set to `requires_approval`.

#### Header Parameters

`X-Session-Id` string (uuid) required

Example: `2b3c9f0e-1a4d-4e5f-8a7b-6c5d4e3f2a1b`

The session to act in: the UUID at the end of the session's `sessionUrn` and `mcpUrl`. The session must belong to the authenticated user and team.

#### Request Body: `application/json`

`code` string required

Example: `print("hello from Action Gateway")`

Python source to run. The sandbox provides `invoke_digitalocean_tool(name: str, arguments: dict) -> dict`, which calls a catalog tool under the session's policy and returns a tool result.

##### Request: `/code/execute`

### Payload

Content type `application/json`

```json
{
  "code": "print(\"hello from Action Gateway\")"
}
```

### cURL

```bash
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  -H "X-Session-Id: $SESSION_ID" \
  -d '{"code":"print(\"hello from Action Gateway\")"}' \
  "https://actions.do-ai.run/code/execute"
```

#### Responses

**200** The code ran, or it is waiting for approval. Check status before reading output.

Response Schema: `application/json`

`_meta` object optional

Additional result metadata. Keys include:

- `status`: `requires_approval`, `requires_authorization`, or `requires_connection_configuration` when the call stopped before running.
- `approval_id`, `tool_name`, `expires_at`, and `decide`: present with `requires_approval`. `decide` gives the `method`, `path`, and `body` of the approval request to send. Approve the call, then repeat it with the same arguments before `expires_at`.
- `retry`: `{"attempt_count": N, "exhausted": bool}` when the gateway retried the call.
- `output_view`: the output view applied to the result.

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this call. Include it when contacting support.

`error` object optional

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`output` object optional

**Show child properties**

`exit_code` integer (int32) optional

Example: `0`

The process exit code. A nonzero exit code is still a succeeded result.

`stderr` string optional

Omitted when empty.

`stdout` string optional

`status` string, one of: succeeded, failed required

Example: `succeeded`

**400** The request is invalid: the body is not valid JSON, a required field is missing, or a value is out of range.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**401** The token is missing, invalid, or expired. This response uses the standard DigitalOcean API error format.

Response Schema: `application/json`

`id` string required

Example: `not_found`

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

`message` string required

Example: `The resource you were accessing could not be found.`

A message providing additional information about the error, including details to help resolve it when possible.

`request_id` string optional

Example: `4d9d8375-3c56-4925-a3e7-eb137fed17e9`

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

**403** The token or session cannot be used for this request. Tokens without the action_gateway:execute scope, and accounts that are not in good standing, are rejected with the standard DigitalOcean API error format. Session failures return a tool result: the session ID is missing or invalid, the session belongs to another user or team, the session has no policy, or the session policy denies the operation.

Response Schema: `application/json`

### Tool Result Error

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

### Error

`id` string required

Example: `not_found`

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

`message` string required

Example: `The resource you were accessing could not be found.`

A message providing additional information about the error, including details to help resolve it when possible.

`request_id` string optional

Example: `4d9d8375-3c56-4925-a3e7-eb137fed17e9`

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

**412** Your team is not enabled for Action Gateway, or the session or its connection is not set up for this call. For example, the session needs an actorId for OAuth tools, an OAuth connection must be reconnected, or the connection's private network does not match what the MCP server requires.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**413** The request body is larger than 1 MiB.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**429** A rate limit was exceeded. Wait for the number of seconds in Retry-After, when present, before retrying.

Response Headers

`Retry-After` integer

The number of seconds to wait before retrying.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**500** The gateway failed to process the request. Retry later.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**503** The gateway or a service it depends on is temporarily unavailable. Retry later.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**504** The code did not finish within the execution time limit.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

##### Response

**200**

```json
{
  "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
  "output": {
    "exit_code": 0,
    "stdout": "hello from Action Gateway\n"
  },
  "status": "succeeded"
}
```

**400**

```json
{
  "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
  "error": {
    "class": "invalid_argument",
    "message": "Request is invalid. Fix request arguments and retry.",
    "recovery_hint": "fix_args",
    "retriable": false
  },
  "status": "failed"
}
```

**401**

```json
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
```

**403**

```json
{
  "call_id": "",
  "error": {
    "class": "forbidden",
    "message": "A valid session ID is required to invoke tools.",
    "recovery_hint": "fix_args",
    "retriable": false
  },
  "status": "failed"
}
```

**412**

```json
{
  "call_id": "",
  "error": {
    "class": "forbidden",
    "message": "Your team is not enabled for Action Gateway. Contact support to request access.",
    "recovery_hint": "contact_support",
    "retriable": false
  },
  "status": "failed"
}
```

**413**

```json
{
  "call_id": "",
  "error": {
    "class": "invalid_argument",
    "message": "Request body is too large.",
    "recovery_hint": "fix_args",
    "retriable": false
  },
  "status": "failed"
}
```

**429**

```json
{
  "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
  "error": {
    "class": "rate_limited",
    "message": "Rate limit exceeded. Retry after the indicated delay.",
    "recovery_hint": "retry_later",
    "retriable": true
  },
  "status": "failed"
}
```

**500**

```json
{
  "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
  "error": {
    "class": "unavailable",
    "message": "The server failed to process the request.",
    "recovery_hint": "retry_later",
    "retriable": true
  },
  "status": "failed"
}
```

**503**

```json
{
  "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
  "error": {
    "class": "unavailable",
    "message": "Gateway is temporarily unavailable. Retry later.",
    "recovery_hint": "retry_later",
    "retriable": true
  },
  "status": "failed"
}
```

**504**

```json
{
  "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
  "error": {
    "class": "timeout",
    "message": "Tool execution timed out.",
    "recovery_hint": "retry_later",
    "retriable": true
  },
  "status": "failed"
}
```

* * *

## POST Decide a Pending Approval

`/approvals/session/{session_id}/{approval_id}`

Approves or denies a tool call that is waiting for approval. A tool result returns `_meta.status` set to `requires_approval` when the session policy sets `ask` for the call, and its `_meta.decide` gives this request's path.

Send the decision with the session owner's token. Approval is a separate control request, not a tool, so an agent cannot approve its own calls. After approving, repeat the original call with the same arguments before `expires_at`. An approval applies only to that session, tool version, and set of arguments, and is used once. To ask again after a denial or expiry, repeat the tool call.

#### Path Parameters

`session_id` string (uuid) required

Example: `2b3c9f0e-1a4d-4e5f-8a7b-6c5d4e3f2a1b`

The session UUID: the value at the end of the session's `sessionUrn` and `mcpUrl`. The session must belong to the authenticated user and team.

`approval_id` string (uuid) required

Example: `7d3c2b1a-9e8f-4a6b-8c5d-4e3f2a1b0c9d`

The `approval_id` from a tool result whose `_meta.status` is `requires_approval`.

#### Request Body: `application/json`

`decision` string, one of: approve, deny required

Example: `approve`

Whether to let the pending call run.

##### Request: `/approvals/session/{session_id}/{approval_id}`

### Payload

Content type `application/json`

```json
{
  "decision": "approve"
}
```

### cURL

```bash
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  -d '{"decision":"approve"}' \
  "https://actions.do-ai.run/approvals/session/$SESSION_ID/$APPROVAL_ID"
```

#### Responses

**200** The decision was recorded.

Response Schema: `application/json`

`expires_at` string (date-time) optional

Example: `2026-10-09T18:30:00Z`

Repeat an approved call with the same arguments before this time.

`id` string optional

Example: `7d3c2b1a-9e8f-4a6b-8c5d-4e3f2a1b0c9d`

The approval ID.

`status` string, one of: approved, denied optional

Example: `approved`

**400** The request is invalid: the body is not valid JSON, a required field is missing, or a value is out of range.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**401** The token is missing, invalid, or expired. This response uses the standard DigitalOcean API error format.

Response Schema: `application/json`

`id` string required

Example: `not_found`

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

`message` string required

Example: `The resource you were accessing could not be found.`

A message providing additional information about the error, including details to help resolve it when possible.

`request_id` string optional

Example: `4d9d8375-3c56-4925-a3e7-eb137fed17e9`

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

**403** The token or session cannot be used for this request. Tokens without the action_gateway:execute scope, and accounts that are not in good standing, are rejected with the standard DigitalOcean API error format. Session failures return a tool result: the session ID is missing or invalid, the session belongs to another user or team, the session has no policy, or the session policy denies the operation.

Response Schema: `application/json`

### Tool Result Error

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

### Error

`id` string required

Example: `not_found`

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

`message` string required

Example: `The resource you were accessing could not be found.`

A message providing additional information about the error, including details to help resolve it when possible.

`request_id` string optional

Example: `4d9d8375-3c56-4925-a3e7-eb137fed17e9`

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

**404** The approval does not exist or belongs to another session. Approvals for other callers are reported as not found.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**409** The approval was already decided or has expired. Repeat the tool call to request a new approval.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**412** Your team is not enabled for Action Gateway, or the session or its connection is not set up for this call. For example, the session needs an actorId for OAuth tools, an OAuth connection must be reconnected, or the connection's private network does not match what the MCP server requires.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**429** A rate limit was exceeded. Wait for the number of seconds in Retry-After, when present, before retrying.

Response Headers

`Retry-After` integer

The number of seconds to wait before retrying.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**500** The gateway failed to process the request. Retry later.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**503** The gateway or a service it depends on is temporarily unavailable. Retry later.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

##### Response

**200**

```json
{
  "expires_at": "2026-10-09T18:30:00Z",
  "id": "7d3c2b1a-9e8f-4a6b-8c5d-4e3f2a1b0c9d",
  "status": "approved"
}
```

**400**

```json
{
  "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
  "error": {
    "class": "invalid_argument",
    "message": "Request is invalid. Fix request arguments and retry.",
    "recovery_hint": "fix_args",
    "retriable": false
  },
  "status": "failed"
}
```

**401**

```json
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
```

**403**

```json
{
  "call_id": "",
  "error": {
    "class": "forbidden",
    "message": "A valid session ID is required to invoke tools.",
    "recovery_hint": "fix_args",
    "retriable": false
  },
  "status": "failed"
}
```

**404**

```json
{
  "call_id": "",
  "error": {
    "class": "invalid_argument",
    "message": "The requested route is not supported.",
    "recovery_hint": "fix_args",
    "retriable": false
  },
  "status": "failed"
}
```

**409**

```json
{
  "call_id": "",
  "error": {
    "class": "invalid_argument",
    "message": "The approval is no longer pending. Re-invoke the tool to request a new approval.",
    "recovery_hint": "fix_args",
    "retriable": false
  },
  "status": "failed"
}
```

**412**

```json
{
  "call_id": "",
  "error": {
    "class": "forbidden",
    "message": "Your team is not enabled for Action Gateway. Contact support to request access.",
    "recovery_hint": "contact_support",
    "retriable": false
  },
  "status": "failed"
}
```

**429**

```json
{
  "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
  "error": {
    "class": "rate_limited",
    "message": "Rate limit exceeded. Retry after the indicated delay.",
    "recovery_hint": "retry_later",
    "retriable": true
  },
  "status": "failed"
}
```

**500**

```json
{
  "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
  "error": {
    "class": "unavailable",
    "message": "The server failed to process the request.",
    "recovery_hint": "retry_later",
    "retriable": true
  },
  "status": "failed"
}
```

**503**

```json
{
  "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
  "error": {
    "class": "unavailable",
    "message": "Gateway is temporarily unavailable. Retry later.",
    "recovery_hint": "retry_later",
    "retriable": true
  },
  "status": "failed"
}
```

* * *

## POST Decide a Pending Approval by Session Header

`/approvals/{approval_id}`

Approves or denies a tool call that is waiting for approval, identifying the session with the `X-Session-Id` header. It behaves the same as `POST /approvals/session/{session_id}/{approval_id}`, which is the path returned in a result's `_meta.decide`.

#### Path Parameters

`approval_id` string (uuid) required

Example: `7d3c2b1a-9e8f-4a6b-8c5d-4e3f2a1b0c9d`

The `approval_id` from a tool result whose `_meta.status` is `requires_approval`.

#### Header Parameters

`X-Session-Id` string (uuid) required

Example: `2b3c9f0e-1a4d-4e5f-8a7b-6c5d4e3f2a1b`

The session to act in: the UUID at the end of the session's `sessionUrn` and `mcpUrl`. The session must belong to the authenticated user and team.

#### Request Body: `application/json`

`decision` string, one of: approve, deny required

Example: `approve`

Whether to let the pending call run.

##### Request: `/approvals/{approval_id}`

### Payload

Content type `application/json`

```json
{
  "decision": "deny"
}
```

### cURL

```bash
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  -H "X-Session-Id: $SESSION_ID" \
  -d '{"decision":"deny"}' \
  "https://actions.do-ai.run/approvals/$APPROVAL_ID"
```

#### Responses

**200** The decision was recorded.

Response Schema: `application/json`

`expires_at` string (date-time) optional

Example: `2026-10-09T18:30:00Z`

Repeat an approved call with the same arguments before this time.

`id` string optional

Example: `7d3c2b1a-9e8f-4a6b-8c5d-4e3f2a1b0c9d`

The approval ID.

`status` string, one of: approved, denied optional

Example: `approved`

**400** The request is invalid: the body is not valid JSON, a required field is missing, or a value is out of range.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**401** The token is missing, invalid, or expired. This response uses the standard DigitalOcean API error format.

Response Schema: `application/json`

`id` string required

Example: `not_found`

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

`message` string required

Example: `The resource you were accessing could not be found.`

A message providing additional information about the error, including details to help resolve it when possible.

`request_id` string optional

Example: `4d9d8375-3c56-4925-a3e7-eb137fed17e9`

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

**403** The token or session cannot be used for this request. Tokens without the action_gateway:execute scope, and accounts that are not in good standing, are rejected with the standard DigitalOcean API error format. Session failures return a tool result: the session ID is missing or invalid, the session belongs to another user or team, the session has no policy, or the session policy denies the operation.

Response Schema: `application/json`

### Tool Result Error

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

### Error

`id` string required

Example: `not_found`

A short identifier corresponding to the HTTP status code returned. For example, the ID for a response returning a 404 status code would be "not_found."

`message` string required

Example: `The resource you were accessing could not be found.`

A message providing additional information about the error, including details to help resolve it when possible.

`request_id` string optional

Example: `4d9d8375-3c56-4925-a3e7-eb137fed17e9`

Optionally, some endpoints may include a request ID that should be provided when reporting bugs or opening support tickets to help identify the issue.

**404** The approval does not exist or belongs to another session. Approvals for other callers are reported as not found.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**409** The approval was already decided or has expired. Repeat the tool call to request a new approval.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**412** Your team is not enabled for Action Gateway, or the session or its connection is not set up for this call. For example, the session needs an actorId for OAuth tools, an OAuth connection must be reconnected, or the connection's private network does not match what the MCP server requires.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**429** A rate limit was exceeded. Wait for the number of seconds in Retry-After, when present, before retrying.

Response Headers

`Retry-After` integer

The number of seconds to wait before retrying.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**500** The gateway failed to process the request. Retry later.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

**503** The gateway or a service it depends on is temporarily unavailable. Retry later.

Response Schema: `application/json`

`call_id` string required

Example: `call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e`

A unique identifier for this request, when one was assigned.

`error` object required

Describes why a request or tool call failed and whether retrying can help.

**Show child properties**

`class` string (enum) optional

Example: `invalid_argument`

The failure class. Branch on this value rather than on `message`, which may change.

`message` string optional

Example: `Request is invalid. Fix request arguments and retry.`

A human-readable explanation that is safe to show to an agent or end user.

`recovery_hint` string (enum) optional

Example: `fix_args`

The suggested next step.

`retriable` boolean optional

Example: `false`

Whether retrying the same request later can succeed.

`status` string, one of: failed required

Example: `failed`

##### Response

**200**

```json
{
  "expires_at": "2026-10-09T18:30:00Z",
  "id": "7d3c2b1a-9e8f-4a6b-8c5d-4e3f2a1b0c9d",
  "status": "denied"
}
```

**400**

```json
{
  "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
  "error": {
    "class": "invalid_argument",
    "message": "Request is invalid. Fix request arguments and retry.",
    "recovery_hint": "fix_args",
    "retriable": false
  },
  "status": "failed"
}
```

**401**

```json
{
  "id": "unauthorized",
  "message": "Unable to authenticate you."
}
```

**403**

```json
{
  "call_id": "",
  "error": {
    "class": "forbidden",
    "message": "A valid session ID is required to invoke tools.",
    "recovery_hint": "fix_args",
    "retriable": false
  },
  "status": "failed"
}
```

**404**

```json
{
  "call_id": "",
  "error": {
    "class": "invalid_argument",
    "message": "The requested route is not supported.",
    "recovery_hint": "fix_args",
    "retriable": false
  },
  "status": "failed"
}
```

**409**

```json
{
  "call_id": "",
  "error": {
    "class": "invalid_argument",
    "message": "The approval is no longer pending. Re-invoke the tool to request a new approval.",
    "recovery_hint": "fix_args",
    "retriable": false
  },
  "status": "failed"
}
```

**412**

```json
{
  "call_id": "",
  "error": {
    "class": "forbidden",
    "message": "Your team is not enabled for Action Gateway. Contact support to request access.",
    "recovery_hint": "contact_support",
    "retriable": false
  },
  "status": "failed"
}
```

**429**

```json
{
  "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
  "error": {
    "class": "rate_limited",
    "message": "Rate limit exceeded. Retry after the indicated delay.",
    "recovery_hint": "retry_later",
    "retriable": true
  },
  "status": "failed"
}
```

**500**

```json
{
  "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
  "error": {
    "class": "unavailable",
    "message": "The server failed to process the request.",
    "recovery_hint": "retry_later",
    "retriable": true
  },
  "status": "failed"
}
```

**503**

```json
{
  "call_id": "call_8b7c6d5e-4f3a-4b2c-9d1e-0f9a8b7c6d5e",
  "error": {
    "class": "unavailable",
    "message": "Gateway is temporarily unavailable. Retry later.",
    "recovery_hint": "retry_later",
    "retriable": true
  },
  "status": "failed"
}
```

* * *

Learn more: [Action Gateway Pricing](https://docs.digitalocean.com/products/managed-agents/action-gateway/details/pricing/index.html.md), [How to Configure Server-Side Approval](https://docs.digitalocean.com/products/managed-agents/action-gateway/how-to/configure-server-side-approval/index.html.md), [Action Gateway Limits](https://docs.digitalocean.com/products/managed-agents/action-gateway/details/limits/index.html.md)