> For the complete documentation index, see [llms.txt](https://docs.kosmoslabs.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.kosmoslabs.ai/product-documentation/managing-api-keys-and-webhooks.md).

# Managing API Keys and Webhooks

***

Kosmos gives you programmatic access to your account through the public API, and push notifications through webhooks. Both are managed in the app, so you can set them up without involving the Kosmos team.

API keys and webhook endpoints live in **Settings → Developer**, separate from **Settings → Integrations**. Integrations are the systems Kosmos reads from to build correlations. Developer settings are how your own systems talk to Kosmos.

***

### API Keys

#### Creating a key

1. Go to **Settings → Developer**
2. Click **Create API Key**
3. Give the key a name that identifies what will use it
4. Choose an expiration: **30, 60, 90, or 180 days**. 90 days is the default.
5. Click **Create**

**The plaintext key is shown exactly once.** Copy it and store it in your secret manager before closing the dialog. Kosmos stores only a hash, so there is no way to retrieve the value again. If you lose it, rotate the key and store the replacement.

There is no scope selector when creating a key. Every key is granted the full set of available scopes:

| Scope                    | Grants                                         |
| ------------------------ | ---------------------------------------------- |
| `whoami:read`            | Read-only access to your organization identity |
| `knowledge_objects:read` | Read-only access to Knowledge Objects          |

The identity endpoint reports the scopes a given key resolves to; see the API reference below for its exact path.

A tenant can hold **20 active keys** at a time. Creating a twenty-first is rejected until you revoke one.

Key creation and revocation are themselves rate-limited per tenant.

#### Reviewing your keys

The key list shows each key you own with:

* **Status** — Active, Expired, or Revoked
* **Last used** — when the key last authenticated a request, or an indication that it has not been used yet
* **Rotation lineage** — if a key was created by rotating an older one, or has since been rotated into a newer one, the related key is named directly so you do not have to infer history from timestamps

Plaintext values never appear in this list.

#### Rotating and revoking

* **Rotate** — issues a replacement key and revokes the old one. The new plaintext value is shown exactly once, same as creation. The old record is kept and linked to its replacement.
* **Revoke** — invalidates the key with no replacement.

Both actions are permanent and cannot be undone. A revoked key stops authenticating within seconds; propagation is near-instant but bounded by a short credential cache interval, so allow a moment before testing that a revoked key is actually dead.

Anything still using the old key will start receiving authentication errors, so update your systems before rotating a key in active use.

Rotate and revoke are unavailable for keys that are already Revoked or Expired. Those states are terminal.

#### Expiration

Keys are deactivated automatically once they pass their expiration date. The check runs every few minutes, so a key expires promptly rather than at an exact timestamp. Once deactivated, requests using it return `401`.

Plan rotation ahead of the expiration date. Nothing in Kosmos extends the life of an existing key.

#### Admin management

Tenant admins see and manage every API key in the tenant, not just their own. Admins can rotate or revoke any key using the same flows.

When an admin rotates or revokes a key belonging to another user, an audit record captures the acting admin, the key owner, and the action taken.

There is no delete action separate from revocation. Revoked keys are retained indefinitely to support audit and SOC 2 requirements. They are excluded from the default view and remain reachable through the **Revoked** filter.

***

### Authenticating Requests

Public API keys are prefixed `kosmos_api_` and passed as a bearer token:

```
Authorization: Bearer kosmos_api_...
```

The public API is served from `api.kosmoslabs.ai`.

An identity endpoint is available to confirm a key is working; it returns the tenant context and the scopes the key resolves to. See the API reference below for its path.

Responses you should expect to handle:

| Condition                                            | Response |
| ---------------------------------------------------- | -------- |
| Missing, malformed, unknown, expired, or revoked key | `401`    |
| Per-key rate limit exceeded                          | `429`    |

Every authenticated request produces an audit record capturing the key identifier, tenant, endpoint, method, response status, timestamp, and client IP.

#### Rate limit headers

Rate limit state is returned on every response, not only on rejections, so you can back off before you are throttled:

| Header                  | Meaning                                  |
| ----------------------- | ---------------------------------------- |
| `X-RateLimit-Limit`     | Requests permitted in the current window |
| `X-RateLimit-Remaining` | Requests left in the current window      |
| `X-RateLimit-Reset`     | When the window resets                   |

The default limit is **60 requests per 60-second window**, roughly one request per second.

Limits resolve in order: a per-key override if one is configured, then your tenant default, then this global default. If your workload needs more headroom, contact your Kosmos team about a per-key override. Read `X-RateLimit-Remaining` rather than assuming the default, since the limit applied to your key may differ from it.

#### API reference

The full OpenAPI 3.0 specification is published and requires no authentication to read. It is the source of truth for available endpoints, request and response shapes, and paths. Point your tooling or client generator at it.

The spec contains only public endpoints; internal endpoints are excluded. Ask your Kosmos team for the spec URL if you cannot locate it.

**A public API key is not an OpenTelemetry ingest key.** If you are configuring an OTel collector, you need the key generated under **Settings → Integrations → OpenTelemetry**, which is a separate credential with a different prefix and a different header. See [Connecting OpenTelemetry](/product-documentation/connecting-opentelemetry-preview.md).

***

### Webhooks

Webhooks let Kosmos push events to your systems instead of you polling for them.

#### Registering an endpoint

1. Go to **Settings → Developer**
2. In the webhooks section, click **Register Endpoint**
3. Enter the URL that should receive deliveries
4. Select the events you want delivered
5. Save

A unique signing secret is generated and shown once when the endpoint is registered. Store it; you will need it to verify deliveries.

#### Available events

| Event                  | Fires when                         |
| ---------------------- | ---------------------------------- |
| `risk-event-created`   | Kosmos surfaces a new Risk Event   |
| `risk-event-promoted`  | A Risk Event is promoted to an RCA |
| `risk-event-dismissed` | A Risk Event is dismissed          |

#### Verifying deliveries

Every delivery carries an HMAC signature in the `X-Kosmos-Signature-256` header, so you can confirm a payload came from Kosmos and not a third party posting to your URL.

The signature is an HMAC-SHA256 hex digest of the **raw request body**, computed with your signing secret, formatted as `sha256=<hexdigest>`.

To verify a delivery:

1. Take the raw request body exactly as received. Do not parse, re-serialize, or reformat it first; any change to the bytes changes the digest and the check will fail.
2. Compute `HMAC-SHA256(signing_secret, raw_body)` as a hex digest.
3. Prefix it with `sha256=` and compare it to the header value using a constant-time comparison.
4. Reject the delivery if the values do not match.

```python
import hashlib
import hmac

def verify(raw_body: bytes, header_value: str, signing_secret: str) -> bool:
    digest = hmac.new(
        signing_secret.encode(), raw_body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(f"sha256={digest}", header_value)
```

Use a constant-time comparison such as `hmac.compare_digest` rather than `==`, so the check does not leak information through timing.

#### Delivery and retries

Failed deliveries are retried with exponential backoff. Kosmos records the outcome of each attempt, including the target URL, response status, timestamp, and attempt count, so a delivery problem can be traced rather than guessed at.

#### Testing an endpoint

Send a test delivery to any endpoint you own to confirm it is reachable before relying on it for real events. The result reports whether the delivery succeeded, the HTTP status your endpoint returned, and the response time, so you can debug a failure without leaving Kosmos.

#### Managing endpoints

You see and manage the endpoints you registered. Deleting or disabling one stops all further deliveries to it.

Tenant admins see and manage every endpoint in the tenant and can delete any of them. This matters when an endpoint goes stale or is compromised and the person who registered it is unavailable.

Webhook subscriptions are scoped to your tenant and cannot be viewed or triggered from another tenant.

#### Payload contents

Payloads currently carry enough to identify the event type and the resource that triggered it. **Treat the payload shape as provisional.** It is being expanded, and the schema is expected to change before it is stable, so build against the event type and fetch the detail you need from the API rather than depending on payload fields.

We will document the payload schema here once it is settled. If you are building against it now, your Kosmos team can walk you through the current shape and flag changes before they ship.

***

### Questions?

Contact your Kosmos team or email <support@kosmoslabs.ai>.

***

**Questions?** Contact <support@kosmoslabs.ai> | [app.kosmoslabs.ai](https://app.kosmoslabs.ai/)

© 2026 Kosmos AI Labs, Inc.
