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

# Authentication

> Authenticate with the Znift API using API keys.

## Overview

All API requests require authentication via an API key. Every request must include your key in a header.

## Creating an API key

1. Log in to [znift.com](https://znift.com)
2. Navigate to **Profile** > **API Keys**
3. Click **Create API Key**
4. Enter a descriptive name (e.g., "Claude Agent", "CLI Tool")
5. Copy the key immediately

<Warning>
  The full API key is only shown once during creation. If you lose it, revoke the key and create a new one.
</Warning>

## Using the API key

Include your key in one of these headers:

<Tabs>
  <Tab title="x-api-key (recommended)">
    ```bash theme={null}
    curl https://znift.com/api/v1/tasks?date=2026-04-04 \
      -H "x-api-key: znift_YOUR_KEY"
    ```
  </Tab>

  <Tab title="Authorization Bearer">
    ```bash theme={null}
    curl https://znift.com/api/v1/tasks?date=2026-04-04 \
      -H "Authorization: Bearer znift_YOUR_KEY"
    ```
  </Tab>
</Tabs>

## Key format

All Znift API keys are prefixed with `znift_`. This makes them easy to identify in logs, environment variables, and secret scanners.

```
znift_abc123def456...
```

## Rate limits

The API enforces a rate limit of **300 requests per minute** per API key. Rate limiting is tracked per key, not per user.

When you exceed the limit, requests are rejected until the window resets. Plan your agent workflows accordingly — a typical daily briefing flow (dashboard + a few toggles) uses under 10 requests.

## Error responses

All errors follow the same format:

```json theme={null}
{
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable description"
  }
}
```

### Error codes

| Status | Code                | When                                                  |
| ------ | ------------------- | ----------------------------------------------------- |
| 401    | `MISSING_API_KEY`   | No API key header provided                            |
| 401    | `INVALID_API_KEY`   | Key is invalid, expired, or revoked                   |
| 400    | `VALIDATION_ERROR`  | Request body or query params failed validation        |
| 404    | `NOT_FOUND`         | Task or resource doesn't exist, or you don't own it   |
| 400    | `INVALID_OPERATION` | Invalid action (e.g., deleting a non-archived task)   |
| 429    | `RATE_LIMITED`      | Rate limit exceeded (300 requests/minute per API key) |
| 500    | `INTERNAL_ERROR`    | Unexpected server error                               |

## Security best practices

<AccordionGroup>
  <Accordion title="Never expose keys in client-side code">
    API keys should only be used in server-side code, CLI tools, or AI agent configurations. Never embed them in frontend JavaScript, mobile apps, or public repositories.
  </Accordion>

  <Accordion title="Use environment variables">
    Store your API key in an environment variable rather than hardcoding it:

    ```bash theme={null}
    export ZNIFT_API_KEY="znift_YOUR_KEY"
    ```

    ```bash theme={null}
    curl -H "x-api-key: $ZNIFT_API_KEY" ...
    ```
  </Accordion>

  <Accordion title="Use separate keys for each integration">
    Create a dedicated API key for each tool or agent. This way you can revoke access to one integration without affecting others.
  </Accordion>

  <Accordion title="Rotate keys if compromised">
    If a key is accidentally exposed, immediately revoke it in Profile > API Keys and create a new one.
  </Accordion>
</AccordionGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Getting 401 but my key looks correct">
    Check that you're sending the key in the right header. The API checks `x-api-key` first, then `Authorization: Bearer`. Make sure there are no extra spaces or newlines in the key value.
  </Accordion>

  <Accordion title="Getting 400 on every request">
    This usually means the request body or query parameters are invalid, not the API key. Check that dates are in strict `YYYY-MM-DD` format (e.g., `2026-04-04`, not `2026-4-4`) and required fields like `text` are present.
  </Accordion>

  <Accordion title="Key was working but suddenly stopped">
    The key may have been revoked by another team member, or it may have expired if an expiration was set during creation. Create a new key in Profile > API Keys.
  </Accordion>
</AccordionGroup>
