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

# Authentication

> Authenticate server-side requests with a workspace-scoped Biqli API key.

Biqli authenticates workspace API requests with secret Bearer tokens. Every
API key belongs to exactly one workspace and begins with `biqli_`.

<Warning>
  A Biqli API key is a server-side secret. Never expose it in browser code,
  mobile applications, frontend bundles, public repositories, screenshots, or
  logs.
</Warning>

## Create an API key

<Steps>
  <Step title="Open the workspace API key settings">
    Select the workspace you want the integration to manage, then open
    **Workspace settings → API Keys**.
  </Step>

  <Step title="Name the integration">
    Select **Create API key** and enter a recognizable name, such as
    `Production link sync` or `Staging automation`.
  </Step>

  <Step title="Choose permissions">
    Use **Restricted** whenever possible and grant only the resources and
    operations the integration needs.
  </Step>

  <Step title="Copy and store the secret">
    The full key is displayed only once. Store it in a secret manager or
    protected server environment variable before closing the dialog.

    ```bash .env theme={null}
    BIQLI_API_KEY=biqli_xxxxxxxxxxxxxxxxxxxxxxxx
    ```
  </Step>
</Steps>

Keys do not expire automatically. They remain valid until revoked, the key
creator loses the required workspace access, or the workspace is deleted.

## Authenticate a request

Send the key using the `Authorization` request header and the `Bearer` scheme:

```http theme={null}
Authorization: Bearer biqli_xxxxxxxxxxxxxxxxxxxxxxxx
```

For example:

```bash theme={null}
curl --request GET \
  --url 'https://biq.li/api/v1/link?page_size=10' \
  --header "Authorization: Bearer $BIQLI_API_KEY" \
  --header 'Accept: application/json'
```

Do not send API keys in URLs, query parameters, JSON bodies, or cookies. These
locations are more likely to be recorded by browsers, proxies, and application
logs.

## Workspace scope

The key itself selects the workspace. Never add `workspaceId` or
`workspace_id` to public API requests.

Resources are isolated by workspace. If a public resource ID is missing or
belongs to another workspace, the API returns the same
`404 resource_not_found` response. This avoids revealing whether a resource
exists outside the key's workspace.

## Permission modes

When creating or editing a key, choose one of three modes:

| Mode           | Access                                                                                           |
| :------------- | :----------------------------------------------------------------------------------------------- |
| **All**        | Read and write access to every resource currently exposed by the workspace API.                  |
| **Read Only**  | Read access to every exposed resource, without create, update, attach, detach, or delete access. |
| **Restricted** | Explicitly choose **None**, **Read**, or **Write** for each resource type.                       |

Selecting **Write** for a resource includes its read, create, update, and delete
abilities. Use the least privilege needed for the integration.

### Resource permissions

| Resource        | Read ability           | Write abilities                                                              |
| :-------------- | :--------------------- | :--------------------------------------------------------------------------- |
| Links           | `links.view`           | `links.create`, `links.update`, `links.delete`                               |
| QR codes        | `qr_codes.view`        | `qr_codes.create`, `qr_codes.update`, `qr_codes.delete`                      |
| Biolinks        | `biolinks.view`        | `biolinks.create`, `biolinks.update`, `biolinks.delete`                      |
| Link groups     | `link_groups.view`     | `link_groups.create`, `link_groups.update`, `link_groups.delete`             |
| Tracking pixels | `tracking_pixels.view` | `tracking_pixels.create`, `tracking_pixels.update`, `tracking_pixels.delete` |
| Custom domains  | `custom_domains.view`  | `custom_domains.create`, `custom_domains.update`, `custom_domains.delete`    |
| Tags            | `tags.view`            | `tags.create`, `tags.update`, `tags.delete`                                  |

Every workspace key also receives the internal `api.access` ability required to
use the public API.

### Cross-resource operations

Some writes reference a second resource. The key must be able to read every
referenced resource in addition to writing the primary resource.

For example, creating a link with `domain_id`, `folder_ids`, `tag_ids`, or
`pixel_ids` requires:

* `links.create`
* `custom_domains.view` when selecting a domain
* `link_groups.view` when selecting folders
* `tags.view` when selecting tags
* `tracking_pixels.view` when selecting tracking pixels

The same rule applies when updating associations. A `403 insufficient_scope`
response identifies the missing permission.

## Key ownership and revocation

An API key cannot grant more access than its creator currently has in the
workspace. Requests stop working when:

* the key is revoked;
* its creator loses workspace access or required role permissions; or
* the workspace is deleted.

Revocation takes effect on the next request.

## Rotate a key safely

<Steps>
  <Step title="Create a replacement">
    Create a new key in the same workspace with the required permissions.
  </Step>

  <Step title="Deploy the replacement">
    Update your server secret and verify a request succeeds with the new key.
  </Step>

  <Step title="Revoke the old key">
    Revoke the previous key only after every integration instance uses the
    replacement.
  </Step>
</Steps>

## Authentication errors

| Status | Error code           | Meaning                                                       |
| :----- | :------------------- | :------------------------------------------------------------ |
| `401`  | `invalid_token`      | The key is missing, malformed, invalid, or revoked.           |
| `403`  | `insufficient_scope` | The key is valid but lacks a required permission.             |
| `403`  | `upgrade_required`   | The workspace plan does not include the requested capability. |
| `404`  | `resource_not_found` | The requested resource is unavailable in the key's workspace. |

Read [Errors](/docs/api-reference/errors) for the complete response envelope,
request tracing, and retry guidance.

<Note>
  Biqli currently provides secret workspace API keys for server-side use. It
  does not provide a client-side publishable key or an OAuth partner flow.
</Note>
