> For the complete documentation index, see [llms.txt](https://docs.akenza.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.akenza.io/device-management/managing-an-organization/api-keys.md).

# API keys

Issue credentials for the akenza APIs, restrict them to specific workspaces, and grant only the permissions they need.

An **API key** is a static secret that lets an application reach akenza without a user account. It is sent in the `x-api-key` header on every request, and the [REST API](/reference/api-documentation.md), the [WebSocket API](/reference/websocket-api.md), and integrations such as the [Grafana data source](/tutorials/bi-tools/grafana-data-source-plugin.md) all authenticate this way.

Keys belong to the organization and are managed under **Settings > API Keys**.

{% hint style="info" %}
API keys are one of two credential types. [OAuth2 clients](#oauth2-clients) are the other, and they carry the same scope and permission model.
{% endhint %}

## Who can manage API keys

Only the **organization owner** and **organization admins** can create and view API keys. For everyone else the API credential management is not available at all, which means a key never exposes more than the people who could already administer the organization.

## Creating an API key

{% stepper %}
{% step %}

### Open the creation form

Select *Create API Key* on the API Keys page.
{% endstep %}

{% step %}

### Name it

Give the key a **name** and, optionally, a **description**. Name it after the system that will use it, for example `Grafana` or `Data Consumer`, and use the description to record what it is for. Both are shown in the list, and they are the only way to tell later which key belongs to which integration.
{% endstep %}

{% step %}

### Choose the scope

By default a key reaches **every workspace** in the organization, including workspaces created later. Enable *Restrict permissions to specific Workspaces* and select the workspaces it may reach to narrow that down.
{% endstep %}

{% step %}

### Select the permissions

Under **Permissions**, expand a group and tick the individual verbs it may use. *All permissions* selects everything at once, which is worth avoiding for anything but a throwaway key.

<figure><img src="https://2165942204-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MMKXTFIN5ZlLOjBlfC4%2Fuploads%2FWY3XQER4fLbMIlBnOX9H%2Fscreely-1685093330043.png?alt=media&amp;token=b28c84dd-80ae-4770-9937-129e9615c49f" alt="The Create new API Key form, with permission groups expanded into their individual verbs"><figcaption><p>Each permission group expands into the verbs the key may use</p></figcaption></figure>
{% endstep %}

{% step %}

### Create and store the secret

Select *Create API key*. Copy the generated secret into your password manager or secret store before you leave the page, and configure it in the application that needs it.
{% endstep %}
{% endstepper %}

## Permissions

Permissions are granted per group and per verb. The groups cover organization users, billing, workspaces and workspace users, devices, device types, data flows, integrations, rules, custom logic, dashboards, and the [Data Fusion Layer](/data-fusion-layer/data-fusion-layer.md). Depending on the group, the available verbs are `create`, `read`, `update`, `delete`, and `manage`.

**Organization read** is always granted and cannot be removed, because a key has to be able to resolve the organization it belongs to. Everything beyond that is off until you grant it.

{% hint style="warning" %}
Grant the smallest set that does the job. A key that only feeds a reporting tool needs `asset: read` and nothing else, while a key with `manage` on workspace members can change who has access to your data. Keys do not expire, so an over-permissioned key stays over-permissioned until someone notices.
{% endhint %}

The permission names shown when you open a key are the same scope names used by the API, such as `asset`, `dataFlow`, `workspace.member`, and `organization.member`. See [Authentication](/reference/api-documentation/authentication.md) for the full list and for how they map onto requests.

## Viewing, copying, and deleting a key

Selecting a key's name opens a panel with everything it can do:

* The **API key** itself.
* Its **permissions**, listed as scope and verbs, for example `organization: read` and `asset: all`.
* Its **scope**, the organization and either *All workspaces* or the workspaces it was restricted to.

*Copy* in the list row copies the key. *Delete* revokes it immediately, and any application still using it starts receiving `401` responses, so check what the key is wired into before removing it.

{% hint style="danger" %}
A key's permissions and scope cannot be edited after creation. To change what a key may do, create a replacement, move your integrations across to it, and then delete the old one.
{% endhint %}

## Using the key

Send the secret in the `x-api-key` header:

```bash
curl -s 'https://api.akenza.io/v3/assets' \
  -H 'x-api-key: 099123122.2ab1000..'
```

A request that carries both an `Authorization` header and an `x-api-key` header is rejected, so send exactly one. If a call returns `403 permission denied`, the key is missing either the scope and verb for that endpoint or access to the workspace the object lives in.

{% hint style="info" %}
Actions taken with an API key appear in the [audit logs](/device-management/managing-an-organization/audit-logs.md) alongside actions taken by users, which is another reason to give each integration a key of its own rather than sharing one.
{% endhint %}

## OAuth2 clients

An **OAuth2 client** is the second credential type for machine-to-machine access. Instead of sending a long-lived secret on every request, your application exchanges a client ID and client secret for an access token using the **OAuth2 client credentials grant**, then sends that token as a standard bearer token. Tokens are valid for 15 minutes and there are no refresh tokens.

Both credential types are issued per organization, can be restricted to specific workspaces, and use the same permissions, so the choice is about how the credential is handled rather than about what it may do:

<table><thead><tr><th width="190"></th><th>API keys</th><th>OAuth2 clients</th></tr></thead><tbody><tr><td><strong>Sent as</strong></td><td>A static secret in the <code>x-api-key</code> header</td><td>A short-lived bearer token in the <code>Authorization</code> header</td></tr><tr><td><strong>Lifetime</strong></td><td>Long-lived until deleted</td><td>15 minutes per token</td></tr><tr><td><strong>Rotation</strong></td><td>Delete and recreate the key</td><td>Rotate the client secret in place</td></tr><tr><td><strong>Tooling</strong></td><td>Any HTTP client</td><td>Any OAuth2 or OpenID Connect client library</td></tr><tr><td><strong>Permission model</strong></td><td colspan="2">Identical</td></tr></tbody></table>

Choose **API keys** when simplicity matters and you have no requirement for short-lived credentials or secret rotation. Choose **OAuth2 clients** when your organization expects standard OAuth2 tooling, wants credentials that expire on their own, or needs to rotate a secret without a gap in service, since rotation keeps already-issued tokens working until they expire.

{% content-ref url="/pages/96f516551ed529475d80541161c6b76e45f9240a" %}
[Authentication](/reference/api-documentation/authentication.md)
{% endcontent-ref %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.akenza.io/device-management/managing-an-organization/api-keys.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
