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

# Widget Launch API

> Create widget links from your own server — one personal conversation per person, with values the visitor can't change.

Use the Widget Launch API when your server already knows who the visitor is — a candidate opening their interview invitation, a customer on their order page — and you want the conversation to start with that context. Your server creates a [widget link](/conversation-flows/channels/widget-links) for the person; you send them the link or put the returned embed code on your own page.

Values sent through the API are stored on our side. The page only ever contains a random code, so visitors can't read or change the values. Compare with [values in the embed code](/conversation-flows/channels/widget-parameters), which visitors can see and edit.

## Before you start

1. **An agent with a widget channel.** A Chat & Voice Agent (conversation flow) with a **Widget** channel, and the [Initial Parameters](/conversation-flows/build/flow-settings#initial-parameters) you want to pass.
2. **Its ids.** In the widget channel, click **Install Widget**: the snippet's `data-flow-id` is the agent's id (`flowId`) and `data-channel-id` is the widget channel's id (`channelId`).
3. **A widget key.** In **Settings → API access → Widget keys**, click **Create**. Workspace Owners and Admins can create keys. Optionally limit the key to some agents and set an expiry. The key is shown **once** — store it in your server's secrets.

<Warning>
  A widget key belongs on your server only. Never put it in a web page, a mobile app or a public repository. The API refuses calls from browsers.
</Warning>

A key can create, look up and revoke widget links — nothing else. It can't read your agents or conversations. If the person who created a key leaves the workspace, the key keeps working; revoke it in **Widget keys** when you no longer need it.

## Base URL and authentication

```text theme={null}
https://embed.cogniagent.ai/v1/widget/launches
```

Send the key in either header:

```http theme={null}
Authorization: Bearer csk_…
x-api-key: csk_…
```

## Create a link

`POST /v1/widget/launches`

| Field | Type | Required | What it is |
| - | - | - | - |
| `flowId` | string | yes | The agent's id |
| `channelId` | string | yes | The widget channel's id |
| `parameters` | object | | Values for the agent's Initial Parameters |
| `participant.name` | string | | The person's name; the agent sees it |
| `participant.externalId` | string | | Your own id for the person, e.g. a candidate id; returned by this API and in workflow events |
| `globalTask` | string | | An extra instruction for this one conversation |
| `expiresInSeconds` | number | | How long the link can be opened. Default 7 days (`604800`), minimum 5 minutes, maximum 90 days |

```bash theme={null}
curl -X POST https://embed.cogniagent.ai/v1/widget/launches \
  -H "Authorization: Bearer $COGNIAGENT_WIDGET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "flowId": "cmpcx1c1l000f017egdf42v5",
    "channelId": "ch_widget_main",
    "parameters": {
      "candidate_name": "Jane Candidate",
      "job_title": "Senior Backend Engineer",
      "employment_type": "full-time"
    },
    "participant": { "name": "Jane Candidate", "externalId": "cand_8812" },
    "expiresInSeconds": 604800
  }'
```

Response `201`:

```json theme={null}
{
  "id": "clz3k9q0e0000abcd1234efgh",
  "status": "pending",
  "expiresAt": "2026-10-16T09:00:00.000Z",
  "token": "wlt_Q2l0eS1z…",
  "url": "https://embed.cogniagent.ai/#launch=wlt_Q2l0eS1z…",
  "embedHtml": "<script type=\"text/javascript\">…</script>"
}
```

* **`url`** — the hosted chat. Send it to the person (email, SMS, your app).
* **`embedHtml`** — the embed code. Put it in the page your server renders for this person to show the conversation on your own site.
* **`token`** — the link's code, returned **only in this response**. Keep it only as long as you need it; anyone who has it can open the conversation.

Values are checked strictly: a parameter the agent doesn't define, a value of the wrong type (`"42"` for a number), a value outside a parameter's options, or a missing required parameter is refused with `invalid_parameters`. Nothing is converted for you.

## Look up a link

`GET /v1/widget/launches/{id}`

```json theme={null}
{
  "id": "clz3k9q0e0000abcd1234efgh",
  "status": "active",
  "expiresAt": "2026-10-16T09:00:00.000Z",
  "participant": { "name": "Jane Candidate", "externalId": "cand_8812" },
  "conversation": {
    "sessionId": "clz3kb1xy0001abcd5678ijkl",
    "status": "in-progress",
    "startedAt": "2026-10-09T09:12:44.000Z",
    "endedAt": null
  }
}
```

| `status` | Meaning |
| - | - |
| `pending` | Created, not opened yet |
| `active` | Opened; the conversation is in progress |
| `ended` | The conversation has ended |
| `expired` | Never opened, and the expiry has passed |
| `revoked` | Revoked through this API |

The values you sent and the token are never returned.

## Revoke a link

`DELETE /v1/widget/launches/{id}` → `204`

The link stops opening and stops resuming. Revoking again also returns `204`.

## Errors

Errors look like `{ "error": { "code": "…", "message": "…", "details": [] } }`.

| HTTP | `code` | When |
| - | - | - |
| 400 | `invalid_request` | The body isn't valid JSON or has unknown or malformed fields (`details` lists them) |
| 400 | `invalid_parameters` | A parameter value was refused; `details` is `[{ "code", "name" }]` |
| 401 | `invalid_key` | Missing, unknown, revoked or expired key |
| 403 | `insufficient_scope` | The key can't do this |
| 403 | `forbidden_flow` | The key is limited to other agents |
| 404 | `widget_not_found` | No such agent in this workspace, or it has no widget channel with that id |
| 404 | `not_found` | No such link in this workspace |
| 409 | `too_many_pending_links` | The workspace already has 10,000 links nobody has opened yet |
| 413 | `invalid_request` | The body is over 32 KB |
| 429 | `rate_limited` | More than 120 requests a minute with this key; retry after the `Retry-After` header |

## What happens when the link opens

The link behaves like any widget link: on an **Initiator** agent the agent speaks first; on a **Responder** agent the person writes first. One link is one conversation, reopening it continues the same conversation, and it stops opening at its expiry. See [Widget links](/conversation-flows/channels/widget-links) for the details.


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