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

# Authentication

> Secure your API requests with API key authentication

## Overview

The Operahealth API uses API key authentication. All requests must include a valid API key in the `Authorization` header using the Bearer scheme.

```http theme={null}
Authorization: Bearer opera_live_a1b2c3d4e5f6...
```

## API Key Format

API keys follow a specific format based on environment:

| Environment | Example                      |
| ----------- | ---------------------------- |
| Production  | `opera_live_a1b2c3d4e5f6...` |
| Development | `opera_demo_a1b2c3d4e5f6...` |

## Managing API Keys

API keys are managed through your Operahealth dashboard at **Settings** → **API Keys**.

### Creating a Key

<Steps>
  <Step title="Log in to your dashboard">
    Navigate to your Operahealth dashboard and log in with your credentials.
  </Step>

  <Step title="Go to API Keys">Navigate to **Settings** → **API Keys**.</Step>

  <Step title="Create a new key">
    Click **Create API Key** and give it a descriptive name (e.g., "Production
    Integration" or "Development Integration").
  </Step>

  <Step title="Copy and store securely">
    Copy the key immediately — it won't be shown again. Store it securely in an
    environment variable or secrets manager.
  </Step>
</Steps>

<Warning>
  Store your API key securely. Once created, the full key cannot be retrieved
  again. If you lose it, you'll need to create a new one.
</Warning>

### Revoking a Key

Keys can be revoked instantly from the dashboard. Once revoked, any requests using that key will immediately return `401 Unauthorized`.

## Security Best Practices

<AccordionGroup>
  <Accordion title="Keep API keys secret" icon="lock">
    * Never commit keys to version control - Never expose keys in client-side
      code - Use environment variables or a secrets manager
  </Accordion>

  <Accordion title="Use HTTPS only" icon="shield">
    API keys must only be transmitted over secure HTTPS connections. The API
    will reject non-HTTPS requests.
  </Accordion>

  <Accordion title="Rotate keys regularly" icon="rotate">
    Periodically revoke old keys and create new ones, especially if team members
    leave or keys may have been exposed.
  </Accordion>

  <Accordion title="One key per integration" icon="diagram-project">
    Use separate keys for different integrations. This makes it easier to track
    usage and revoke access for specific integrations without affecting others.
  </Accordion>
</AccordionGroup>

## Example Request

<Tabs>
  <Tab title="Production">
    <CodeGroup>
      ```typescript TypeScript theme={null}
      const response = await fetch(
        "https://api.prod.operahealth.ai/api/v1/patients",
        {
          method: "POST",
          headers: {
            Authorization: "Bearer opera_live_your_api_key_here",
            "Content-Type": "application/json",
          },
          body: JSON.stringify({
            firstName: "John",
            lastName: "Doe",
            phoneNumber: "+61412345678",
            email: "john@example.com",
          }),
        }
      );
      ```

      ```python Python theme={null}
      import requests

      response = requests.post(
          'https://api.prod.operahealth.ai/api/v1/patients',
          headers={
              'Authorization': 'Bearer opera_live_your_api_key_here',
              'Content-Type': 'application/json',
          },
          json={
              'firstName': 'John',
              'lastName': 'Doe',
              'phoneNumber': '+61412345678',
              'email': 'john@example.com',
          },
      )
      ```

      ```bash cURL theme={null}
      curl -X POST https://api.prod.operahealth.ai/api/v1/patients \
        -H "Authorization: Bearer opera_live_your_api_key_here" \
        -H "Content-Type: application/json" \
        -d '{"firstName": "John", "lastName": "Doe", "phoneNumber": "+61412345678", "email": "john@example.com"}'
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Development">
    <CodeGroup>
      ```typescript TypeScript theme={null}
      const response = await fetch(
        "https://api.demo.operahealth.ai/api/v1/patients",
        {
          method: "POST",
          headers: {
            Authorization: "Bearer opera_demo_your_api_key_here",
            "Content-Type": "application/json",
          },
          body: JSON.stringify({
            firstName: "John",
            lastName: "Doe",
            phoneNumber: "+61412345678",
            email: "john@example.com",
          }),
        }
      );
      ```

      ```python Python theme={null}
      import requests

      response = requests.post(
          'https://api.demo.operahealth.ai/api/v1/patients',
          headers={
              'Authorization': 'Bearer opera_demo_your_api_key_here',
              'Content-Type': 'application/json',
          },
          json={
              'firstName': 'John',
              'lastName': 'Doe',
              'phoneNumber': '+61412345678',
              'email': 'john@example.com',
          },
      )
      ```

      ```bash cURL theme={null}
      curl -X POST https://api.demo.operahealth.ai/api/v1/patients \
        -H "Authorization: Bearer opera_demo_your_api_key_here" \
        -H "Content-Type: application/json" \
        -d '{"firstName": "John", "lastName": "Doe", "phoneNumber": "+61412345678", "email": "john@example.com"}'
      ```
    </CodeGroup>
  </Tab>
</Tabs>

## Authentication Errors

| Status | Error                    | Description                                  |
| ------ | ------------------------ | -------------------------------------------- |
| `401`  | Missing API key          | No `Authorization` header provided           |
| `401`  | Invalid API key          | Key format is incorrect or key doesn't exist |
| `401`  | Revoked API key          | Key has been revoked in the dashboard        |
| `403`  | Insufficient permissions | Key lacks required permissions (future)      |

```json Example 401 Response theme={null}
{
  "type": "about:blank",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Missing or invalid API key",
  "instance": null
}
```
