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

# Authentication

> Learn how to authenticate your API requests using API keys

## Overview

The Sendook API uses **API keys** for authentication. API keys are organization-scoped tokens that authenticate requests to the v1 API endpoints.

<Note>
  All API requests must include an `Authorization` header with your API key as a Bearer token.
</Note>

## Authentication Methods

Sendook supports two authentication strategies:

### 1. API Key Authentication (Recommended)

Used for all v1 API endpoints. API keys are associated with your organization and provide full access to organization resources.

### 2. Bearer Token Authentication

Used for non-API endpoints (like `/auth`, `/organizations`). These are user-scoped access tokens obtained through the authentication flow.

<Warning>
  This guide focuses on API key authentication for the v1 API. For dashboard and user authentication, see the [Dashboard Guide](/guides/dashboard).
</Warning>

## Getting Your API Key

You can create and manage API keys through the Sendook dashboard or via the API itself.

### Via Dashboard

1. Log in to your [Sendook dashboard](https://app.sendook.com)
2. Navigate to **Settings** → **API Keys**
3. Click **Create API Key**
4. Give your key a descriptive name (e.g., "Production", "Staging")
5. Copy and securely store your API key

<Warning>
  API keys are shown only once upon creation. Store them securely and never commit them to version control.
</Warning>

### Via API

You can also manage API keys programmatically:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.sendook.com/v1/api_keys \
    -H "Authorization: Bearer your_existing_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Production Key"
    }'
  ```

  ```javascript Node.js theme={null}
  import Sendook from '@sendook/node';

  const client = new Sendook('your_api_key');

  const apiKey = await client.apiKeys.create({
    name: 'Production Key'
  });

  console.log('API Key:', apiKey.key);
  ```

  ```python Python theme={null}
  from sendook import Sendook

  client = Sendook('your_api_key')

  api_key = client.api_keys.create(name='Production Key')
  print(f'API Key: {api_key.key}')
  ```
</CodeGroup>

**Response:**

```json theme={null}
{
  "_id": "507f1f77bcf86cd799439011",
  "name": "Production Key",
  "key": "sk_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
  "organizationId": "507f191e810c19729de860ea",
  "active": true,
  "createdAt": "2024-03-01T10:00:00.000Z",
  "updatedAt": "2024-03-01T10:00:00.000Z"
}
```

## Making Authenticated Requests

Include your API key in the `Authorization` header as a Bearer token:

```bash theme={null}
curl https://api.sendook.com/v1/inboxes \
  -H "Authorization: Bearer your_api_key"
```

### Request Flow

When you make an authenticated request:

1. Your API key is extracted from the `Authorization` header
2. Sendook validates the key using the `api_key` Passport strategy
3. The associated organization is loaded and attached to the request
4. Your request proceeds with organization-scoped access

From the source code at `~/workspace/source/api/routes/v1/index.ts:13-18`:

```typescript theme={null}
router.use(
  passport.authenticate("api_key", { session: false }),
  (req, res, next) => {
    req.organization = req.user as HydratedDocument<Organization>;
    next();
  }
);
```

## API Key Validation

API keys are validated using Passport.js with a custom bearer strategy. Here's how it works under the hood:

<Steps>
  <Step title="Extract Token">
    The API key is extracted from the `Authorization: Bearer <token>` header
  </Step>

  <Step title="Database Lookup">
    Sendook queries the database for an API key matching the provided token
  </Step>

  <Step title="Organization Validation">
    The organization associated with the API key is verified and loaded
  </Step>

  <Step title="Request Authorization">
    The organization object is attached to the request for authorization checks
  </Step>
</Steps>

From `~/workspace/source/api/controllers/PassportController.ts:29-48`:

```typescript theme={null}
export const passportApiKeyStrategy = new BearerStrategy(
  async (token, done) => {
    try {
      const apiKey = await getApiKeyByKey(token);
      if (!apiKey) {
        return done(null, false);
      }
      const organization = await getOrganizationById(
        apiKey.organizationId.toString()
      );
      if (!organization) {
        return done(null, false);
      }
      return done(null, {
        ...(organization?.toJSON()),
        apiKey,
      });
    } catch (err) {
      return done(err, null);
    }
  }
);
```

## Managing API Keys

### List API Keys

Retrieve all API keys for your organization:

```bash theme={null}
curl https://api.sendook.com/v1/api_keys \
  -H "Authorization: Bearer your_api_key"
```

### Get Specific API Key

```bash theme={null}
curl https://api.sendook.com/v1/api_keys/{apiKeyId} \
  -H "Authorization: Bearer your_api_key"
```

### Delete API Key

Revoke an API key when it's no longer needed:

```bash theme={null}
curl -X DELETE https://api.sendook.com/v1/api_keys/{apiKeyId} \
  -H "Authorization: Bearer your_api_key"
```

<Warning>
  Deleting an API key immediately revokes access. Any requests using that key will fail with a `401 Unauthorized` error.
</Warning>

## Authentication Errors

### 401 Unauthorized

Returned when authentication fails:

```json theme={null}
{
  "error": "Unauthorized"
}
```

**Common causes:**

* Missing `Authorization` header
* Invalid or expired API key
* API key format is incorrect
* API key has been deleted or deactivated

### Example Error Response

```bash theme={null}
curl https://api.sendook.com/v1/inboxes
# Missing Authorization header
```

**Response:**

```http theme={null}
HTTP/1.1 401 Unauthorized
Content-Type: application/json

{
  "error": "Unauthorized"
}
```

## Security Best Practices

<AccordionGroup>
  <Accordion title="Store API keys securely">
    * Never commit API keys to version control
    * Use environment variables or secret management services
    * Rotate keys periodically for enhanced security
  </Accordion>

  <Accordion title="Use separate keys per environment">
    Create different API keys for development, staging, and production environments. This allows you to:

    * Isolate environments
    * Revoke keys without affecting other environments
    * Track usage per environment
  </Accordion>

  <Accordion title="Minimize key exposure">
    * Only share API keys with team members who need them
    * Use service-specific keys when possible
    * Delete unused or compromised keys immediately
  </Accordion>

  <Accordion title="Monitor API key usage">
    * Regularly review API logs in your dashboard
    * Set up alerts for unusual activity
    * Track which keys are being used and where
  </Accordion>
</AccordionGroup>

## Environment Variables

Store your API key as an environment variable:

<CodeGroup>
  ```bash .env theme={null}
  SENDOOK_API_KEY=sk_live_your_api_key_here
  ```

  ```javascript Node.js theme={null}
  const client = new Sendook(process.env.SENDOOK_API_KEY);
  ```

  ```python Python theme={null}
  import os
  from sendook import Sendook

  client = Sendook(os.environ['SENDOOK_API_KEY'])
  ```
</CodeGroup>

<Tip>
  For self-hosted installations, Bun automatically loads `.env` files. No additional dotenv package is needed.
</Tip>

## Rate Limiting and Authentication

Authenticated requests are subject to rate limiting. See the [API Overview](/api/overview#rate-limits) for details on rate limits.

Rate limits are tracked per organization, not per API key. Multiple API keys for the same organization share the same rate limit pool.

## Testing Authentication

Test your API key with a simple health check:

```bash theme={null}
curl https://api.sendook.com/v1/api_keys \
  -H "Authorization: Bearer your_api_key"
```

If authentication succeeds, you'll receive a list of your API keys. If it fails, you'll receive a `401 Unauthorized` response.

## Next Steps

<CardGroup cols={2}>
  <Card title="Create an Inbox" icon="inbox" href="/api/inboxes">
    Start by creating your first inbox
  </Card>

  <Card title="Send a Message" icon="paper-plane" href="/api/messages">
    Send your first email via the API
  </Card>

  <Card title="Set Up Webhooks" icon="webhook" href="/api/webhooks">
    Receive incoming email notifications
  </Card>

  <Card title="Node.js SDK" icon="node-js" href="/sdk/installation">
    Use the official SDK for easier integration
  </Card>
</CardGroup>
