# Runs (/web/api/runs)





Four endpoints cover the run lifecycle:

| Endpoint                              | Method | Scope   | Purpose                                   |
| ------------------------------------- | ------ | ------- | ----------------------------------------- |
| `/api/v1/mogplex/runs`                | POST   | `write` | Start a run                               |
| `/api/v1/mogplex/runs/{runId}`        | GET    | `read`  | Get a run's current state                 |
| `/api/v1/mogplex/runs/{runId}/events` | GET    | `read`  | List run events (sanitized, oldest-first) |
| `/api/v1/mogplex/runs/{runId}/cancel` | POST   | `write` | Request cancellation                      |

## Start a run [#start-a-run]

`POST /api/v1/mogplex/runs`

Required headers:

* `Authorization: Bearer mog_...`
* `Content-Type: application/json`
* `Idempotency-Key` — see [Authentication → Idempotency-Key](/web/api/authentication#idempotency-key-required-on-mutations)

Request body:

```typescript
type StartMogplexApiRunRequest = {
  repoId: string;                          // Required — get from GET /repos
  prompt: string;                          // Required — max 100,000 chars
  harness?: "codex" | "claude-code";       // Default: "codex"
  baseBranch?: string;                     // Default: repo default_branch (or "main")
  workingBranch?: string;                  // Default: baseBranch (or a generated name when createBranch=true)
  createBranch?: boolean;                  // If true, create/use the generated working branch
  rootDirectory?: string | null;           // Monorepo subpath
  conversationId?: string | null;          // Attach to an existing conversation
  workspaceSessionId?: string | null;      // Attach to an existing workspace session
  mode?: string | null;                    // Mode hint for the runtime
};
```

### Example [#example]

```bash
export MOGPLEX_BASE_URL="https://www.mogplex.com"
export MOGPLEX_TOKEN="mog_..."

curl -sS \
  -X POST \
  -H "Authorization: Bearer $MOGPLEX_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "repoId": "8f3a2b1c-1234-4abc-9def-1234567890ab",
    "prompt": "Refactor the auth module to use bearer tokens instead of cookies.",
    "harness": "codex",
    "baseBranch": "main",
    "createBranch": true
  }' \
  "$MOGPLEX_BASE_URL/api/v1/mogplex/runs"
```

Response (HTTP `202 Accepted`):

```json
{
  "ok": true,
  "data": {
    "runId": "run-uuid",
    "aiCallId": "call-uuid",
    "sandboxRecordId": "sandbox-record-uuid",
    "sandboxId": null,
    "repoId": "8f3a2b1c-1234-4abc-9def-1234567890ab",
    "harness": "codex",
    "status": "pending",
    "branch": {
      "base": "main",
      "working": "mogplex/run/2026-05-17/refactor-auth",
      "createBranch": true
    },
    "rootDirectory": null,
    "eventsUrl": "/api/v1/mogplex/runs/run-uuid/events",
    "cancelUrl": "/api/v1/mogplex/runs/run-uuid/cancel",
    "createdAt": "2026-05-17T10:14:00.000Z",
    "updatedAt": "2026-05-17T10:14:00.000Z",
    "error": null,
    "runtime": {
      "provider": "trigger",
      "runId": "trigger-run-uuid"
    },
    "replayed": false
  }
}
```

If you POST the same body with the same `Idempotency-Key`, `replayed` becomes
`true` and `runId` matches the first call.

### Status values [#status-values]

| Status      | Meaning                                            |
| ----------- | -------------------------------------------------- |
| `pending`   | Accepted, waiting on sandbox + runtime allocation  |
| `streaming` | Agent is actively producing events                 |
| `success`   | Terminal — agent completed without error           |
| `failed`    | Terminal — agent or sandbox failed                 |
| `cancelled` | Terminal — cancellation requested and acknowledged |

### Errors [#errors]

| Code                   | HTTP | Cause                                                                                      |
| ---------------------- | ---- | ------------------------------------------------------------------------------------------ |
| `UNAUTHORIZED`         | 401  | Missing/invalid PAT                                                                        |
| `FORBIDDEN`            | 403  | PAT lacks `write` scope                                                                    |
| `BAD_REQUEST`          | 400  | Missing `Idempotency-Key`, missing `repoId`/`prompt`, invalid harness, invalid branch name |
| `NOT_FOUND`            | 404  | `repoId` doesn't belong to the caller                                                      |
| `IDEMPOTENCY_CONFLICT` | 409  | Same key used with a different body                                                        |
| `RATE_LIMITED`         | 429  | Per-PAT (60/min) or per-user run-start budget exceeded                                     |
| `SERVICE_UNAVAILABLE`  | 503  | Limit-check backend unavailable                                                            |
| `INTERNAL_ERROR`       | 500  | Unexpected server error                                                                    |

See [Errors](/web/api/errors).

## Get a run [#get-a-run]

`GET /api/v1/mogplex/runs/{runId}`

```bash
curl -sS \
  -H "Authorization: Bearer $MOGPLEX_TOKEN" \
  "$MOGPLEX_BASE_URL/api/v1/mogplex/runs/run-uuid"
```

Response:

```json
{
  "ok": true,
  "data": {
    "run": {
      "runId": "run-uuid",
      "status": "streaming",
      "harness": "codex",
      "repoId": "8f3a2b1c-...",
      "branch": { "base": "main", "working": "feat/x", "createBranch": true },
      "sandboxId": "vsb_abc",
      "createdAt": "2026-05-17T10:14:00.000Z",
      "updatedAt": "2026-05-17T10:15:30.000Z",
      "error": null,
      "eventsUrl": "/api/v1/mogplex/runs/run-uuid/events",
      "cancelUrl": "/api/v1/mogplex/runs/run-uuid/cancel",
      "runtime": { "provider": "trigger", "runId": "..." }
    }
  }
}
```

Errors: `UNAUTHORIZED` (401), `NOT_FOUND` (404), `RATE_LIMITED` (429), `INTERNAL_ERROR` (500).

## List run events [#list-run-events]

`GET /api/v1/mogplex/runs/{runId}/events`

Returns the event stream for a run, oldest first. Useful for polling, replay,
or tailing from CI.

Query parameters:

| Param   | Type    | Default | Notes |
| ------- | ------- | ------- | ----- |
| `limit` | integer | 100     | 1–200 |

```bash
curl -sS \
  -H "Authorization: Bearer $MOGPLEX_TOKEN" \
  "$MOGPLEX_BASE_URL/api/v1/mogplex/runs/run-uuid/events?limit=50"
```

Response:

```json
{
  "ok": true,
  "data": {
    "run": { /* same shape as GET /runs/{runId} */ },
    "events": [
      {
        "id": "event-uuid",
        "type": "stream_started",
        "toolName": null,
        "message": "Agent started",
        "payload": {},
        "createdAt": "2026-05-17T10:14:10.000Z"
      },
      {
        "id": "event-uuid-2",
        "type": "tool_call",
        "toolName": "edit_file",
        "message": "Editing src/auth.ts",
        "payload": { "path": "src/auth.ts" },
        "createdAt": "2026-05-17T10:14:15.000Z"
      }
    ]
  }
}
```

<Callout>
  Event payloads are sanitized server-side: sensitive keys (env vars, GitHub
  tokens, AI billing source) are redacted; strings over 2,000 chars are
  truncated; arrays/objects are capped at 25 items / depth 3 / 20 KB JSON. The
  goal is safe inclusion in dashboards and logs without leaking secrets.
</Callout>

### Polling for terminal status [#polling-for-terminal-status]

Polling pattern in pseudocode:

```
loop:
  events = GET /runs/{id}/events
  emit events.events (de-duped by id)
  if events.run.status in {success, failed, cancelled}: break
  sleep 1.5s
```

The CLI's `mogplex runs events <id> --follow` implements this with a 1.5s poll
interval and a configurable `--timeout` (default 1800s).

Errors: `UNAUTHORIZED` (401), `NOT_FOUND` (404), `RATE_LIMITED` (429), `INTERNAL_ERROR` (500).

## Cancel a run [#cancel-a-run]

`POST /api/v1/mogplex/runs/{runId}/cancel`

Idempotent. Requesting cancellation on a run that's already terminal returns
the terminal state with no side effects.

```bash
curl -sS \
  -X POST \
  -H "Authorization: Bearer $MOGPLEX_TOKEN" \
  "$MOGPLEX_BASE_URL/api/v1/mogplex/runs/run-uuid/cancel"
```

Response:

```json
{
  "ok": true,
  "data": {
    "run": { /* MogplexApiRunDetail */ },
    "status": "cancellation_requested"
  }
}
```

Possible `status` values:

* `cancellation_requested` — agent signaled, will reach `cancelled` shortly
* `already_terminal` — run was already in `success` / `failed` / `cancelled`

Errors: `UNAUTHORIZED` (401), `FORBIDDEN` (403, missing `write` scope), `NOT_FOUND` (404), `CONFLICT` (409, sandbox unreachable), `INTERNAL_ERROR` (500).

## CLI equivalents [#cli-equivalents]

```bash
# Start
mogplex run --repo <id> --harness codex "Refactor auth module"

# Inspect
mogplex runs get <id>
mogplex runs events <id> --follow --timeout 600
mogplex runs cancel <id>
```

See [Headless runs](/cli/automation/headless-runs) for a fuller walkthrough.

## Read next [#read-next]

* [Errors](/web/api/errors) — full error code table
* [Authentication](/web/api/authentication) — PAT scopes and idempotency
* [MCP](/web/api/mcp) — the same surface exposed as a JSON-RPC MCP server
