> ## Documentation Index
> Fetch the complete documentation index at: https://docs.omnicommerce.sg/llms.txt
> Use this file to discover all available pages before exploring further.

# AOP API

> Create, configure, execute, retry, and poll Agent Operating Procedures over REST.

Use the developer AOP API to run saved Agent Operating Procedures from an external system.

For a known operation on a large product ID list, [run a Windmill script directly](https://docs.omnicommerce.sg/guides/scripts.md). Direct script execution does not require an AOP and keeps the ID list out of model context. OmniCommerce's script routes require an app session; they do not use this guide's developer bearer-token authentication.

Interactive playground: [API reference](https://docs.omnicommerce.sg/api-reference.md) · Spec: [openapi.json](https://docs.omnicommerce.sg/openapi.json)

## Authentication

```http theme={null}
Authorization: Bearer $OMNI_API_KEY
Content-Type: application/json
```

| Endpoint | Required scope |
| - | - |
| `POST /api/v1/aop/{aopId}/execute` | `aops:write` |
| `POST /api/v1/aop/retry` | `aops:write` |
| `POST /api/v1/aop/create` | `aops:write` |
| `PUT /api/v1/aop/{aopId}/config` | `aops:write` |
| `GET /api/v1/aop/{aopId}/config` | `aops:read` |
| `GET /api/v1/threads/{thread_id}/status` | `aops:read` |

> [!NOTE]
>
> API keys created from organization settings receive all developer scopes by
> default. Existing keys created before this API shipped need `aops:read` /
> `aops:write` added in organization settings.

OAuth clients must include the scope on the client. Session-authenticated calls must include `organizationId` in the query (GET) or JSON body (writes). Do **not** send `organizationId` for API-key requests.

`aopId` in the path (and `aop_id` in JSON responses) is the OmniCommerce AOP id from `/app/{organizationId}/aops`.

## Execute an AOP

```http theme={null}
POST /api/v1/aop/{aopId}/execute
```

**1. Start the run**

The AOP id is in the path. Optional `user_inputs` go in the JSON body. The response returns immediately with a `thread_id`.

```bash theme={null}
curl -X POST "https://omnicommerce.sg/api/v1/aop/aop_1/execute" \
  -H "Authorization: Bearer $OMNI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "user_inputs": {
      "company": "Acme Corp",
      "quarter": "Q1 2024"
    }
  }'
```

**2. Poll until terminal**

```bash theme={null}
curl "https://omnicommerce.sg/api/v1/threads/THREAD_ID/status" \
  -H "Authorization: Bearer $OMNI_API_KEY"
```

Status values: `running`, `completed`, `failed`. Terminal responses include conversation messages by default. Pass `include_messages=true` to force messages while the run is still in progress.

### Request body

`user_inputs` values are strings (up to 8,000 characters each), numbers, or booleans. Objects and arrays are not accepted directly.

| Field | Required | Description |
| - | - | - |
| `user_inputs` | No | Key/value inputs appended as a `--- User Inputs ---` block and bound to `[[ placeholder ]]` variables. |
| `dry_run` | No | When `true`, run as a Test run: read-only tools execute, side-effectful tools are captured. |
| `organizationId` | Session | Required for session auth. |

### Response

```json theme={null}
{
  "status": "started",
  "thread_id": "agent-aop-run_1",
  "trigger_type": "api",
  "aop_id": "aop_1",
  "aop_title": "Market Research Report Generator",
  "base_prompt": "Generate a comprehensive market research report",
  "final_prompt": "Generate a comprehensive market research report\n\n--- User Inputs ---\ncompany: Acme Corp\nquarter: Q1 2024\n",
  "aop_config": { "agentId": "research" },
  "message": "Task execution started successfully. Use the thread_id to track progress."
}
```

`trigger_type` is always `api` for this endpoint.

## Poll status

```http theme={null}
GET /api/v1/threads/{thread_id}/status
```

```bash theme={null}
curl "https://omnicommerce.sg/api/v1/threads/agent-aop-run_1/status?include_messages=true" \
  -H "Authorization: Bearer $OMNI_API_KEY"
```

| Query | Description |
| - | - |
| `include_messages` | `true` to include messages while the run is still in progress. Terminal runs include them by default. |
| `organizationId` | Session auth only. |

`conversation_asset` includes `linked_aops`, `last_message`, and `metadata.run_status` (including `awaiting_approval`).

## Retry a failed run

```http theme={null}
POST /api/v1/aop/retry
```

```bash theme={null}
curl -X POST "https://omnicommerce.sg/api/v1/aop/retry" \
  -H "Authorization: Bearer $OMNI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "thread_id": "agent-aop-run_1" }'
```

Only failed AOP runs can be retried. Optional `user_inputs` replace the original values; omit them to reuse the failed run's inputs. Response:

```json theme={null}
{
  "status": "started",
  "new_thread_id": "agent-aop-run_2",
  "message": "Retry execution started successfully."
}
```

## Create an AOP

```http theme={null}
POST /api/v1/aop/create
```

```bash theme={null}
curl -X POST "https://omnicommerce.sg/api/v1/aop/create" \
  -H "Authorization: Bearer $OMNI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Market Research Report",
    "prompt": "Generate a comprehensive market research report for [[ company ]]",
    "agentId": "research"
  }'
```

Use `[[ placeholder ]]` in the prompt for execution-time inputs. Omni validates a name of at least 2 characters and a prompt of at least 10 characters.

| Field | Description |
| - | - |
| `title` | AOP name. Defaults to `Untitled AOP`. |
| `prompt` | Instructions. `[[ company ]]` becomes a `user_inputs.company` field. |
| `agentId` | Assigned agent template id. Defaults to Omni. |
| `structured_output` | JSON Schema for structured results. |
| `agent_config` | Optional `chatModel`, `planModeEnabled`, `enabledTools`, and `enabledToolkits`. Selections use canonical tool names and toolkit IDs (up to 256 per array). |
| `parent_folder_id` | Optional workstream id. |
| `user_notification_configs` | Per-user outcome notification map. |
| `organizationId` | Session auth only. |

Response includes `aop_id`, `title`, `status: "created"`, and `parent_folder_id`.

Tool and toolkit selections combine with structured `@mention` links in the prompt to form the AOP run's allowed tools. When neither is specified, the run inherits its assigned agent's tools. Plan mode and result submission remain available as run controls. Model selection follows AOP override, Project model (for Project sessions), assigned agent model, then organization default.

## Read and overwrite config

```http theme={null}
GET /api/v1/aop/{aopId}/config
PUT /api/v1/aop/{aopId}/config
```

`GET` returns prompt, `agentId`, `structured_inputs` (computed from placeholders), `structured_output`, and notification settings.

`PUT` updates provided fields only. Omitted fields keep their current values. Send `user_notification_configs: null` to clear notification overrides.

```bash theme={null}
curl "https://omnicommerce.sg/api/v1/aop/aop_1/config" \
  -H "Authorization: Bearer $OMNI_API_KEY"

curl -X PUT "https://omnicommerce.sg/api/v1/aop/aop_1/config" \
  -H "Authorization: Bearer $OMNI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Generate a weekly pricing brief for [[ marketplace ]]",
    "agentId": "pricing"
  }'
```

## Errors

| Status | Meaning |
| - | - |
| `400` | Invalid JSON, missing `thread_id`, failed-run retry on a non-failed thread, or AOP draft validation. |
| `401` | Missing or invalid bearer token. |
| `402` | Organization is out of AI credits. |
| `403` | Token is missing `aops:read` or `aops:write`. |
| `404` | AOP or thread was not found in the authenticated organization. |
| `429` | Rate limit. Retry later. |

## Field notes

| Field | Meaning |
| - | - |
| `aop_id` | Organization AOP id |
| `organizationId` | Session auth organization id |
| `user_inputs` | AOP variable values |
| `parent_folder_id` | Assigned workstream id |
| `dry_run` | Test run (`simulation: { "mode": "read_only" }`) |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.