> For the complete documentation index, see [llms.txt](https://k-ai.gitbook.io/knowledge-ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://k-ai.gitbook.io/knowledge-ai/get-started/automate-quickstart.md).

# Quickstart — Automate with an API key

Five minutes to a backend script driving the K-AI Platform API with an organization role — no browser, no user sign-in. Use this when a service needs to manage organizations, instances, or members, or to call the Audit and Retrieval APIs as a service account.

## Prerequisites

* An organization administrator to create the key (the `API_KEYS_MANAGE` permission, held by `ADMIN` and `ORG_OWNER`).
* The roles the integration needs — grant the **minimum** (see [Organization API keys](/knowledge-ai/authentication/organization-api-keys.md#roles)).

## 1. Create a key

In the K-AI Studio portal: **Organization → API keys → Create key**. Pick a name, the roles, and an optional expiry. Copy the `ks_org_…` value — it is shown **once**.

{% hint style="warning" %}
Store the key in a secret manager, never in source control or client-side code. A leaked key carries the full access of its roles within the organization.
{% endhint %}

## 2. Exchange the key for a token

{% tabs %}
{% tab title="curl" %}

```bash
TOKEN=$(curl -s -X POST https://back.kai-studio.ai/core/api-key/token \
  -H "Content-Type: application/json" \
  -d '{"api_key": "'"$KAI_ORG_KEY"'"}' | jq -r '.response.access_token')
```

{% endtab %}

{% tab title="Python" %}

```python
import os, httpx

resp = httpx.post(
    "https://back.kai-studio.ai/core/api-key/token",
    json={"api_key": os.environ["KAI_ORG_KEY"]},
)
resp.raise_for_status()
token = resp.json()["response"]["access_token"]
```

{% endtab %}

{% tab title="TypeScript" %}

```typescript
const resp = await fetch("https://back.kai-studio.ai/core/api-key/token", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ api_key: process.env.KAI_ORG_KEY }),
});
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
const token = (await resp.json()).response.access_token;
```

{% endtab %}
{% endtabs %}

## 3. First call

List the organizations and roles the key can act on. The token is sent as a Bearer credential; the response is wrapped in a `{ "response": ... }` envelope.

{% tabs %}
{% tab title="curl" %}

```bash
curl -s -X POST https://back.kai-studio.ai/studio/organization/my-access \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}' | jq '.response'
```

{% endtab %}

{% tab title="Python" %}

```python
resp = httpx.post(
    "https://back.kai-studio.ai/studio/organization/my-access",
    headers={"Authorization": f"Bearer {token}"},
    json={},
)
print(resp.json()["response"])
```

{% endtab %}

{% tab title="TypeScript" %}

```typescript
const access = await fetch(
  "https://back.kai-studio.ai/studio/organization/my-access",
  {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${token}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({}),
  },
).then((r) => r.json());
console.log(access.response);
```

{% endtab %}
{% endtabs %}

Take an `organization_id` from the result and list its instances with `POST /studio/organization/list-instances`.

## 4. Reuse the token

The token is short-lived and has **no refresh token** — when a call returns `401`, exchange the key again (step 2) and retry. Cache the token in memory for its lifetime rather than exchanging on every request.

## Next steps

* [Organization API keys](/knowledge-ai/authentication/organization-api-keys.md) — full auth model, roles, and lifecycle.
* [Platform API reference](/knowledge-ai/reference/platform-api.md) — all 40 management operations.
* The same token works on the [Audit API](/knowledge-ai/k-ai-audit/audit.md) and [Retrieval API](/knowledge-ai/k-ai-mcp/retrieval-tools.md) — call them as your service account.
