---
title: Public automation API
description: Trigger approved automations from Lovable, v0, Next, Vercel, and other external apps with scoped API keys or hosted webhook URLs.
---

Use the public automation API when an external app needs to start an approved AKOS automation without exposing the internal JSON-RPC surface. Create scoped keys in **[Connections](/docs/using-the-app/connections)** › **External apps**. For workspace-internal webhook triggers (sidecar paths, not hosted automation URLs), see **[Triggers](/docs/using-the-app/triggers)**.

## Choose a path

| Path | Use it when | Secret handling |
|---|---|---|
| **API key run** | Your app has a server route, server action, edge function, or backend job. | Keep the API key in server-side environment variables only. |
| **Hosted webhook** | You want a stable automation URL generated from Triggers. | Current hosted ingress uses the same server-side API key auth. |

Never put `AGENTSKIT_API_KEY` in browser code, public `.env` files, client components, or generated frontend snippets.

## Create an API key

1. Open **Connections**.
2. Select **External apps**.
3. Create a scoped key with the automations it may run.
4. Copy the raw key once and store it in your server environment as `AGENTSKIT_API_KEY`.

Keys are stored by hash. AKOS shows the raw secret only when the key is created.

## Server-side run

```ts
export async function POST(req: Request) {
  const input = await req.json()
  const res = await fetch(`${process.env.AGENTSKIT_API_URL}/v1/automations/run`, {
    method: 'POST',
    headers: {
      'content-type': 'application/json',
      authorization: `Bearer ${process.env.AGENTSKIT_API_KEY}`,
      'idempotency-key': input.id ?? crypto.randomUUID(),
    },
    body: JSON.stringify({
      automationId: 'lead-intake',
      input,
      mode: 'real',
    }),
  })

  if (!res.ok) return Response.json({ error: 'automation_failed' }, { status: 502 })
  return Response.json(await res.json())
}
```

Use this from Lovable, v0, Next, Vercel, or any app builder by calling your own server endpoint. The app builder should never receive the AKOS key.

## Hosted webhook

Create or edit a webhook trigger in **Automations > Triggers**. The form shows the hosted endpoint:

```http
POST https://your-akos-host/v1/automations/webhooks/lead-intake
Authorization: Bearer ak_live_...
Content-Type: application/json
Idempotency-Key: lead-form-123
```

Example:

```bash
curl -X POST 'https://your-akos-host/v1/automations/webhooks/lead-intake' \
  -H 'content-type: application/json' \
  -H 'authorization: Bearer <AGENTSKIT_API_KEY>' \
  -H 'idempotency-key: lead-form-123' \
  -d '{"email":"ana@acme.com","message":"hello"}'
```

The request body becomes the automation input.

## Read run status

```bash
curl 'https://your-akos-host/v1/automation-runs/pipe_123' \
  -H 'authorization: Bearer <AGENTSKIT_API_KEY>'
```

Status reads are scoped to runs created by the calling key.

## Security notes

- Keys are org-scoped and may be limited to specific automation ids.
- Revoked keys stop before reaching the runner.
- `/rpc` remains internal-only; external apps only use `/v1/automations/*`.
- Use `Idempotency-Key` for form submissions and retries.
- Hosted webhook HMAC secrets are not part of this first version. Use API key auth until a dedicated webhook signing secret is available.

## Related screens

| Need | Go to |
|---|---|
| Create / revoke API keys | [Connections](/docs/using-the-app/connections) › External apps |
| Workspace webhook paths | [Automations](/docs/using-the-app/triggers) |
| Target workflows | [Workflows](/docs/using-the-app/flows) |
| Run history | [Activity](/docs/using-the-app/runs-and-observability) |
