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

# Authentication

> Generate a Semji API key from Settings, send it as a Bearer token on every request, and handle 401 Unauthorized and 403 Forbidden errors in your integration.

Every request to the Semji API must include a valid API key in the `Authorization` header. The API uses HTTP Bearer authentication — there are no sessions, cookies, or OAuth flows. This page explains how to generate a key, attach it to requests, and handle authentication errors.

## Generating an API key

API keys are created in the Semji app. Go to [**Settings > Organization > API Keys**](https://app.semji.com) and click **Create API Key**. Give the key a descriptive name (for example, the name of the integration or tool that will use it) so you can identify and revoke it later.

Each key:

* Begins with `sk_`
* Is scoped to the **user and organization** that created it — it has the same permissions as that user
* Is shown only once at creation time; copy and store it securely before closing the dialog

<Warning>
  Never commit API keys to source control. Store them in environment variables or a secrets manager such as AWS Secrets Manager, HashiCorp Vault, or your CI/CD platform's secret store. If a key is accidentally exposed, revoke it immediately from **Settings > Organization > API Keys** and generate a new one.
</Warning>

## Sending the API key

Include the key in the `Authorization` header of every request:

```
Authorization: Bearer sk_your_api_key_here
```

The header value must start with `Bearer sk_` exactly. Any other format — including a bare token without `Bearer`, or a key that doesn't start with `sk_` — will be rejected with `401 Unauthorized`.

<CodeGroup>
  ```typescript title="TypeScript" theme={null}
  const apiKey = process.env.SEMJI_API_KEY;

  async function semjiGet(path: string) {
    const response = await fetch(`https://api.semji.com/v1${path}`, {
      headers: {
        Authorization: `Bearer ${apiKey}`,
      },
    });

    if (!response.ok) {
      const error = await response.json();
      throw new Error(`${response.status}: ${error.error.message}`);
    }

    return response.json();
  }

  const user = await semjiGet("/me");
  console.log(user.email);
  ```

  ```python title="Python" theme={null}
  import os
  import requests

  api_key = os.environ["SEMJI_API_KEY"]

  def semji_get(path: str) -> dict:
      response = requests.get(
          f"https://api.semji.com/v1{path}",
          headers={"Authorization": f"Bearer {api_key}"},
      )
      response.raise_for_status()
      return response.json()

  user = semji_get("/me")
  print(user["email"])
  ```

  ```bash title="cURL" theme={null}
  curl https://api.semji.com/v1/me \
    -H "Authorization: Bearer sk_your_api_key_here"
  ```
</CodeGroup>

## Verifying your key

Call `GET /v1/me` to confirm your key is valid and inspect the associated user and organization:

```bash title="cURL" theme={null}
curl https://api.semji.com/v1/me \
  -H "Authorization: Bearer sk_your_api_key_here"
```

```json title="200 OK" theme={null}
{
  "id": "usr_01hx9z3k4m5n6p7q8r9s0t1u",
  "firstName": "Alice",
  "lastName": "Martin",
  "email": "alice@example.com",
  "profileImageUrl": null,
  "jobTitle": "SEO Lead",
  "languageCode": "en",
  "organization": {
    "id": "org_01hx9z3k4m5n6p7q8r9s0t2v",
    "name": "Example Corp",
    "createdAt": "2024-01-10T08:00:00Z",
    "brandName": null,
    "brandImageUrl": null,
    "credits": {
      "analysis": 47,
      "aiWriting": 12,
      "contentIdeasSearches": 5
    },
    "usersCount": 3,
    "workspacesCount": 2
  },
  "createdAt": "2024-03-15T09:12:00Z"
}
```

## Authentication errors

### 401 Unauthorized

Returned when the `Authorization` header is missing, malformed, or contains an invalid or revoked key.

```json title="401 Unauthorized" theme={null}
{
  "error": {
    "code": "unauthorized",
    "message": "A valid API key is required. Use Authorization: Bearer sk_xxx."
  }
}
```

**What to check:**

* The header name is `Authorization` (capitalized correctly)
* The value starts with `Bearer ` (note the trailing space) followed by your full key
* The key starts with `sk_` and has not been revoked
* You're not accidentally including extra whitespace or newline characters

### 403 Forbidden

Returned when your key is valid but the authenticated user does not have permission to access the requested resource. This happens if, for example, you request a workspace that your user is not a member of.

```json title="403 Forbidden" theme={null}
{
  "error": {
    "code": "forbidden",
    "message": "You do not have access to this resource."
  }
}
```

A `403` is not a key problem — the key itself is recognized. You need to use a key belonging to a user with access to the resource, or ask a workspace admin to grant your user the required permissions.
