Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions content/docs/cli/automation/ci-integration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ a workflow.

## Prereqs

1. A PAT with the `write` scope, issued at
[mogplex.com/settings/api-keys](https://mogplex.com/settings/api-keys).
1. A PAT with the `write` scope and **Full access**, issued at
[mogplex.com/settings/api-keys](https://mogplex.com/settings/api-keys). A
key set to [Automations only](/web/settings#key-access), or held to
automations by its team, cannot start runs and gets
`403 AUTOMATION_REQUIRED`.
2. Store the token in your CI's secret store. Never commit it.
3. Pick the repo ID(s) you want to operate on:
```bash
Expand Down
144 changes: 144 additions & 0 deletions content/docs/integrations/api-triggers.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
---
title: API Triggers
description: Let another system start a Mogplex automation with a Mogplex API key and typed inputs, and limit that key to triggering automations.
---

An API trigger lets a server you run start a published automation with a
Mogplex API key. The automation owns the instructions, the repositories it may
touch, its agents and models, and the inputs it accepts. The caller supplies
values for those inputs and nothing else.

Use an API trigger when the caller already holds a Mogplex API key and needs a
run id, a working branch, and run logs back. Use a
[signed webhook](/integrations/webhooks) when the sender can only send a signed
HTTP POST.

## Set up the automation

1. Open [Automations](/web/automations) and select the workflow's start node.
2. Set the trigger event to **API (integrations)**.
3. Under **Repository scope**, select the repositories the caller may start
work in. A trigger for any other repository returns `403 FORBIDDEN`.
4. Declare the inputs under **Inputs (JSON)**. See [Inputs](#inputs).
5. Write each agent node's instructions. Use the test payload field to try
them.
6. Publish the workflow and enable it.

The start node shows the **Trigger endpoint** to call.

## Inputs

**Inputs (JSON)** is an array of fields:

```json
[
{ "key": "site_url", "type": "string", "required": true, "maxLength": 500, "pattern": "https://.+" },
{ "key": "page_count", "type": "integer" },
{ "key": "tone", "type": "string", "enum": ["plain", "playful"] },
{ "key": "brief", "type": "json", "maxBytes": 16384 }
]
```

| Property | Applies to | Meaning |
| --- | --- | --- |
| `key` | All | Up to 64 lowercase letters, digits, and underscores, starting with a letter. |
| `type` | All | `string`, `integer`, `boolean`, or `json`. |
| `required` | All | The caller must send this field. |
| `description` | All | A note for whoever edits or calls the automation. |
| `maxLength` | `string` | Longest accepted value. Default 2,000 characters. |
| `pattern` | `string` | Regular expression the whole value must match. |
| `enum` | `string` | The value must be one of these. |
| `maxBytes` | `json` | Largest serialized value. Default 64 KB. |

An automation can declare up to 32 fields, and a request's inputs can total
at most 512 KB. A request with a key that is not
declared is refused rather than ignored.

The agent receives the inputs as JSON after the automation's instructions,
marked as untrusted data. An input cannot replace the instructions, the
repository, the branch, or the permissions.

## Trigger a run

```bash
curl -X POST "https://mogplex.com/api/v1/mogplex/automations/$AUTOMATION_ID/trigger" \
-H "Authorization: Bearer $MOGPLEX_TOKEN" \
-H "Idempotency-Key: build-4821" \
-H "Content-Type: application/json" \
--data '{"repoId":"'"$REPO_ID"'","input":{"site_url":"https://example.com"}}'
```

Get `repoId` from [`GET /repos`](/reference/api#list-repositories). The key
needs the `write` scope.

A `202 Accepted` response returns the run:

```json
{
"data": {
"run": {
"automationId": "…",
"versionId": "…",
"versionNumber": 3,
"jobRunId": "…",
"workingBranch": "mogplex/automation-0123456789abcdef",
"outcome": "queued",
"replayed": false,
"started": true,
"status": "running"
}
}
}
```

The agent commits and pushes to `workingBranch`. It never pushes to the
default branch, merges, or enables auto-merge, and it opens a pull request only
when the automation's instructions ask for one.

### Refusals

Each refusal is returned before anything is queued, so no run, sandbox, or
branch is created.

| Status | Code | Meaning |
| --- | --- | --- |
| `400` | `BAD_REQUEST` | The input failed validation. The message names each problem, including undeclared keys. |
| `403` | `FORBIDDEN` | The repository is outside the automation's repository scope. |
| `403` | `AUTOMATION_REQUIRED` | The key is held to automations, by its own access or its team's, and this automation has no API trigger. |
| `404` | `NOT_FOUND` | The automation or repository does not exist or is not owned by this account. |
| `409` | `CONFLICT` | The automation is unpublished or disabled. |
| `409` | `IDEMPOTENCY_CONFLICT` | The `Idempotency-Key` was already used with different input. |

### Retries

Idempotency keys are scoped to the account and the automation. Sending the
same key with the same input returns the original run with `replayed: true`
and starts nothing. Each key maps to one working branch, so a retried unit of
work returns to the same branch. Use a new key for new work.

## Follow a run

```txt
GET /api/v1/mogplex/automations/{automationId}/runs/{jobRunId}
POST /api/v1/mogplex/automations/{automationId}/runs/{jobRunId}/cancel
```

The run detail includes `status`, node runs, AI calls, and `metadata`. The
metadata records the automation version (`flow_version_id`,
`flow_version_number`), the accepted `input` and its `input_hash`,
`working_branch`, and `trigger` (credential kind, key id, and key name).

In the app, the same runs appear on the automation's **Runs** tab with the
version, trigger, input, branch, and links to the transcript and sandbox.

## Limit the key to automations

A key that only needs to trigger automations should not be able to do anything
else. Set its access to **Automations only** in
[Settings → Mogplex Keys](/web/settings#mogplex-keys). The key can still read,
and it can start work only by triggering an automation with an API trigger.
See [Key access](/web/settings#key-access) for the full list of what it is
refused.

A team owner can hold every member's key to the same rule on the team's
repositories. See [Team key access](/web/settings#team-key-access).
3 changes: 2 additions & 1 deletion content/docs/integrations/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"claude-code-and-codex",
"vercel",
"---Triggers---",
"webhooks"
"webhooks",
"api-triggers"
]
}
7 changes: 7 additions & 0 deletions content/docs/mcp/security.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@ PAT in the `Authorization: Bearer mog_...` header and protect it like a password
| `read` | List and detail operations for repos, agents, models, automations, runs, sandboxes, logs, and env var keys on the linked Vercel project (keys and targets only — never values). |
| `write` | Sandbox creation; env var creation, update, and deletion on the linked Vercel project; and automation creation, update, publication, model changes, triggers, and run cancellation. |

A PAT's owner can limit it to **Automations only** in
[Settings → Mogplex Keys](/web/settings#key-access). MCP tools call the API
with the PAT, so such a key can read, cancel runs, and trigger automations that
have an [API trigger](/integrations/api-triggers). Tools that start runs or
sandboxes, or change automations, environment variables, or settings, return
`AUTOMATION_REQUIRED`. OAuth logins are not affected.

<Callout type="warn" title="Do not expose PATs">
Never place a PAT in a prompt, issue, chat transcript, repository, or
checked-in client configuration. Prefer browser OAuth whenever the client
Expand Down
33 changes: 32 additions & 1 deletion content/docs/reference/api.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,26 @@ installing the [Mogplex MCP server](/mcp/install) in a supported local client.

A valid token without the required scope returns `403 FORBIDDEN`.

### Key access

Each PAT also has an access level, set by its owner in
[Settings → Mogplex Keys](/web/settings#key-access):

| Access | Effect |
| --- | --- |
| Full access | The scopes above apply unchanged. This is the default. |
| Automations only | `read` endpoints work. Of the `write` endpoints, only triggering an automation with an [API trigger](/integrations/api-triggers) is allowed. |

A team owner can also hold every member's PAT to automations on the team's
repositories ([Team key access](/web/settings#team-key-access)).

A PAT held to automations gets `403 AUTOMATION_REQUIRED` from `POST /runs`,
`POST /sandboxes`, `POST /pr-reviews/rerun`, and the automation create,
update, publish, model, and delete endpoints, before anything is created.
Cancelling a run is still allowed. Triggering an automation whose
start node is not an API trigger returns the same error. OAuth access tokens
are not affected.

### Rate limits

PAT requests are limited to 60 requests per 60 seconds. Run starts also use
Expand Down Expand Up @@ -583,6 +603,12 @@ type TriggerAutomationRequest = {
};
```

For an automation with an [API trigger](/integrations/api-triggers), `input`
must match the start node's declared fields. Undeclared keys and invalid values
return `400 BAD_REQUEST`, and a repository outside the start node's repository
scope returns `403 FORBIDDEN`. Reusing an `Idempotency-Key` with the same input
returns the original run with `replayed: true`.

Example payload:

```json
Expand All @@ -601,9 +627,13 @@ the same GitHub installation. The response is `202 Accepted`:
type TriggerAutomationData = {
run: {
automationId: string;
versionId: string;
versionNumber: number;
jobRunId: string | null;
workingBranch: string | null; // Set for API-trigger automations.
outcome: string;
reason: string | null;
replayed: boolean;
started: boolean;
status: string;
runtime: {
Expand Down Expand Up @@ -1055,7 +1085,8 @@ Send `Accept: application/json, text/event-stream`. The endpoint also accepts
| --- | --- | --- | --- |
| `BAD_REQUEST` | 400 | JSON, query, graph, branch, or field validation failed. | Correct the request before retrying. |
| `UNAUTHORIZED` | 401 | Bearer token is missing, invalid, expired, revoked, or has the wrong OAuth audience. | Authenticate again or replace the token. |
| `FORBIDDEN` | 403 | The token lacks the required scope. | Issue a token with the required scope. |
| `FORBIDDEN` | 403 | The token lacks the required scope, or the repository is outside the automation's repository scope. | Issue a token with the required scope, or use an allowed repository. |
| `AUTOMATION_REQUIRED` | 403 | The PAT is held to automations, by its own access or its team's. | Trigger an automation with an API trigger, or ask the key's owner or team owner for full access. |
| `NOT_FOUND` | 404 | The user does not own the requested resource, or it does not exist. | Verify the id using a list endpoint. |
| `CONFLICT` | 409 | Current resource state prevents the operation. | Read the resource, then decide whether the operation still applies. |
| `IDEMPOTENCY_CONFLICT` | 409 | The key was already used for a different request. | Use the original body or a new key. |
Expand Down
40 changes: 40 additions & 0 deletions content/docs/web/settings.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,20 @@ Open **Settings → Provider Keys** to add or remove your own model-provider cre
This page supports AI Gateway, Anthropic, OpenAI, and OpenRouter.
Personal keys belong to your account. Team keys use the selected team's permissions.

### Team key access

Team Settings → **Provider Keys** also has a **Mogplex API keys** setting for
the team's repositories:

- **Each key's own access**: a member's key can do what its owner allows. This
is the default.
- **Automations only**: every member's key is held to the
[automations-only rule](#key-access) on the team's repositories, whatever
the key itself allows.

Only a team owner can change it. Admins and other members see it read-only.
Every change is written to the team audit log.

<span id="access-tokens" />

## Mogplex Keys
Expand All @@ -293,8 +307,34 @@ The page supports:
- one-time token display at creation
- copy-on-create flow
- last-used metadata
- an access level for each key
- revocation

### Key access

Every key has one of two access levels. You choose it when you create the key,
it is shown on the key, and **Limit to automations** or **Allow full access**
changes it later. A change applies to the key's next request.

| Access | What the key can do |
| --- | --- |
| **Full access** | Everything its scopes allow. This is the default, and every key created before access levels existed has it. |
| **Automations only** | Read, and start work only by triggering an automation with an [API trigger](/integrations/api-triggers). |

An automations-only key gets `403 AUTOMATION_REQUIRED` before anything is
created when it tries to start runs or sandboxes, rerun a PR review, create,
edit, publish, or delete automations, change a model override or repository
environment variables, use hosted CLI inference, or change settings and saved
MCP servers.
MCP tools follow the same rules because they call the API with the key.

Use **Automations only** for a key held by another system, such as a build
service that should start one named automation and nothing else. Keep **Full
access** for CI jobs and scripts that start runs directly.

Signing in to Mogplex, and the CLI and MCP clients signed in with OAuth, do not
use these keys and are not affected.

Hosted model and sandbox access comes from the account plan, not from
user-supplied provider or sandbox credentials.

Expand Down
Loading