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

# Authentication

> Learn how to authenticate your API requests using API keys

## Authentication Method

The Gather API uses API Key authentication via a simple header. All requests must include your API key in the `x-api-key` header.

## Request Format

Include your API key in the `x-api-key` header:

```
x-api-key: your-api-key-here
```

<Callout type="info">
  The API key contains all necessary information including your organization and
  team context. You don't need to provide an organization ID separately.
</Callout>

## Legacy Basic auth (optional)

Humanly still accepts an older transport format for the **same Gather API key**:

```
Authorization: Basic base64(organizationId:apiKey)
```

Use **`x-api-key` for all new integrations.** This Basic format encodes your Gather `qapi_` key — it is **not** ATS or HRIS integration credentials. Connect uses a different Basic-auth model on legacy data routes; see [Platform authentication](/platform/authentication).

## Getting Your API Key

<Callout type="info">
  API credentials are created via Eucalyptus (internal admin tool). Contact your
  Qualifi administrator to obtain your API key.
</Callout>

### API Key Format

* **Format**: API keys are prefixed with `qapi_` followed by a secure random string
* **Example**: `qapi_abc123def456ghi789jkl012mno345pqr678stu901vwx234yz`
* **Scope**: API keys are scoped to your organization/team level
* **Permissions**: API keys inherit permissions from the organization/team they're associated with

## Example Requests

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl -X GET https://api.prod.qualifi.hr/qsi/gather/questions \
      -H "x-api-key: your-api-key-here"
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const apiKey = 'your-api-key-here';

    const response = await fetch('https://api.prod.qualifi.hr/qsi/gather/questions', {
      headers: {
        'x-api-key': apiKey
      }
    });

    const data = await response.json();
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import requests

    api_key = 'your-api-key-here'

    response = requests.get(
        'https://api.prod.qualifi.hr/qsi/gather/questions',
        headers={'x-api-key': api_key}
    )

    data = response.json()
    ```
  </Tab>

  <Tab title="Ruby">
    ```ruby theme={null}
    require 'net/http'

    api_key = 'your-api-key-here'

    uri = URI('https://api.prod.qualifi.hr/qsi/gather/questions')
    req = Net::HTTP::Get.new(uri)
    req['x-api-key'] = api_key

    response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
      http.request(req)
    end
    ```
  </Tab>
</Tabs>

## Authorization Scope

All resources are automatically scoped to your organization/team based on your API key:

* You can only access resources belonging to your organization
* API keys inherit permissions from the organization/team they're associated with
* Multiple API keys can be created per organization/team
* API keys can be rotated or revoked independently
* The organization and team context is automatically determined from your API key

## Error Responses

Invalid or missing API keys will result in a `401 Unauthorized` response:

```json theme={null}
{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid API key"
  },
  "meta": {
    "requestId": "uuid",
    "timestamp": "2024-01-01T00:00:00Z"
  }
}
```

Missing the `x-api-key` header will result in:

```json theme={null}
{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Missing authentication header",
    "details": {
      "expectedFormat": "x-api-key header"
    }
  },
  "meta": {
    "requestId": "uuid",
    "timestamp": "2024-01-01T00:00:00Z"
  }
}
```

## API Key Management

* **Multiple Keys**: Each organization/team can have multiple API keys
* **Key Rotation**: API keys can be rotated/revoked without affecting other keys
* **Read-Only Keys**: Support for read-only vs. read-write API keys (future enhancement)
* **Team-Specific Keys**: API keys can be scoped to specific teams within an organization

<Callout type="warning">
  Keep your API keys secure. Never commit them to version control or expose them
  in client-side code. Store them as environment variables or in secure
  credential management systems.
</Callout>

## Best Practices

1. **Environment Variables**: Store API keys in environment variables

   ```bash theme={null}
   export GATHER_API_KEY="qapi_your-key-here"
   ```

2. **Secure Storage**: Use secret management tools (AWS Secrets Manager, HashiCorp Vault, etc.) in production

3. **Key Rotation**: Rotate API keys periodically for security

4. **Separate Keys**: Use different keys for different environments (production, staging)

5. **Monitor Usage**: Regularly review API key usage and revoke unused keys

<Callout type="info">
  For credential management operations (create, list, revoke), contact your
  Qualifi administrator or use the Eucalyptus admin tool.
</Callout>

## Next Steps

<CardGroup cols={2}>
  <Card title="Quick Start" icon="rocket" href="/getting-started/quickstart">
    Make your first authenticated API request
  </Card>

  <Card title="Rate Limits" icon="gauge" href="/getting-started/rate-limits">
    Understand API rate limits and throttling
  </Card>
</CardGroup>
