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

# Authentication & CORS

> Learn how to authenticate and configure requests to the Dzaleka API

## Authentication

The Dzaleka Online Services API is currently a **public API** and does not require authentication keys or tokens.

<Info>
  All endpoints are publicly accessible without API keys. Rate limiting is applied based on IP address.
</Info>

### Future Authentication

While the API is currently public, future versions may introduce optional API keys for:

* Higher rate limits
* Access to advanced features
* Usage analytics
* Priority support

<Note>
  Any future authentication changes will be announced with ample notice and backward compatibility.
</Note>

## CORS Configuration

The API is configured to accept requests from any origin, making it easy to use in web applications.

### CORS Headers

All API responses include the following CORS headers from `src/utils/api-utils.ts:4-10`:

```http theme={null}
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type
Content-Type: application/json
```

### What This Means

<AccordionGroup>
  <Accordion title="Access-Control-Allow-Origin: *">
    Requests are accepted from **any domain**. You can call the API from:

    * Frontend JavaScript applications
    * Mobile apps
    * Server-side applications
    * Command-line tools
  </Accordion>

  <Accordion title="Access-Control-Allow-Methods">
    The API supports three HTTP methods:

    * `GET` - Fetch data from collections
    * `POST` - Fetch data with additional options
    * `OPTIONS` - CORS preflight requests
  </Accordion>

  <Accordion title="Access-Control-Allow-Headers">
    Only the `Content-Type` header is required for POST requests with JSON payloads.
  </Accordion>
</AccordionGroup>

## Required Headers

### GET Requests

No special headers required:

```bash theme={null}
curl https://services.dzaleka.com/api/services
```

### POST Requests

Include `Content-Type: application/json` when sending JSON data:

```bash theme={null}
curl -X POST https://services.dzaleka.com/api/services \
  -H "Content-Type: application/json" \
  -d '{"options": {"includeMetadata": true}}'
```

### OPTIONS Requests

OPTIONS requests are handled automatically by browsers for CORS preflight. The server responds with a `204 No Content` status and appropriate CORS headers.

```bash theme={null}
curl -X OPTIONS https://services.dzaleka.com/api/services \
  -H "Access-Control-Request-Method: POST" \
  -H "Access-Control-Request-Headers: Content-Type"
```

Response:

```http theme={null}
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type
```

## Client IP Detection

For rate limiting purposes, the API detects your client IP from various headers to support different proxy configurations (see `src/utils/api-utils.ts:24-29`):

1. `x-forwarded-for` (standard proxy header)
2. `x-real-ip` (nginx)
3. `cf-connecting-ip` (Cloudflare)
4. Direct connection IP

<Warning>
  If you're behind a proxy or CDN, ensure these headers are properly configured to avoid shared rate limits.
</Warning>

## Usage Examples

### JavaScript (Fetch API)

```javascript theme={null}
// GET request
fetch('https://services.dzaleka.com/api/services')
  .then(response => response.json())
  .then(data => {
    console.log('Services:', data.data.services);
  })
  .catch(error => console.error('Error:', error));

// POST request with options
fetch('https://dzaleka.com/api/services', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    options: {
      includeMetadata: true,
      includeStats: true
    }
  })
})
  .then(response => response.json())
  .then(data => {
    console.log('Services:', data.data.services);
    console.log('Metadata:', data.metadata);
  });
```

### JavaScript (Axios)

```javascript theme={null}
import axios from 'axios';

// GET request
const getServices = async () => {
  try {
    const response = await axios.get('https://services.dzaleka.com/api/services');
    console.log('Services:', response.data.data.services);
  } catch (error) {
    console.error('Error:', error.response?.data || error.message);
  }
};

// POST request
const getServicesWithMetadata = async () => {
  try {
    const response = await axios.post('https://services.dzaleka.com/api/services', {
      options: {
        includeMetadata: true,
        includeStats: true
      }
    });
    console.log('Services:', response.data.data.services);
    console.log('Stats:', response.data.stats);
  } catch (error) {
    console.error('Error:', error.response?.data || error.message);
  }
};
```

### Python (requests)

```python theme={null}
import requests

# GET request
response = requests.get('https://services.dzaleka.com/api/services')
if response.status_code == 200:
    data = response.json()
    print(f"Found {data['count']} services")
    print(data['data']['services'])
else:
    print(f"Error: {response.status_code}")
    print(response.json())

# POST request with options
response = requests.post(
    'https://dzaleka.com/api/services',
    json={
        'options': {
            'includeMetadata': True,
            'includeStats': True
        }
    },
    headers={'Content-Type': 'application/json'}
)

if response.status_code == 200:
    data = response.json()
    print(f"Export date: {data['metadata']['exportDate']}")
    print(f"Total items: {data['stats']['totalItems']}")
```

### cURL

```bash theme={null}
# GET request
curl -X GET https://services.dzaleka.com/api/services

# POST request with JSON payload
curl -X POST https://services.dzaleka.com/api/services \
  -H "Content-Type: application/json" \
  -d '{
    "options": {
      "includeMetadata": true,
      "includeStats": true
    }
  }'

# Search with query parameters
curl -X GET "https://services.dzaleka.com/api/search?q=education&limit=10"
```

## CORS in Different Environments

### Browser Applications

Browsers automatically handle CORS preflight requests. No special configuration needed:

```javascript theme={null}
// This works in any browser
fetch('https://services.dzaleka.com/api/services')
  .then(response => response.json())
  .then(data => console.log(data));
```

### Node.js Applications

Node.js doesn't enforce CORS, so requests work without additional configuration:

```javascript theme={null}
import fetch from 'node-fetch';

const response = await fetch('https://services.dzaleka.com/api/services');
const data = await response.json();
```

### Mobile Applications

Mobile apps (React Native, Flutter, etc.) typically don't have CORS restrictions:

```javascript theme={null}
// React Native
fetch('https://services.dzaleka.com/api/services')
  .then(response => response.json())
  .then(data => console.log(data));
```

## Security Considerations

<Warning>
  While the API is public, please respect fair usage policies and rate limits.
</Warning>

### Best Practices

1. **Don't abuse the open CORS policy** - Use the API responsibly
2. **Implement client-side rate limiting** - Don't wait for 429 errors
3. **Cache responses** - Reduce unnecessary API calls
4. **Handle errors gracefully** - Always check response status
5. **Monitor your usage** - Track API calls in your application

## Troubleshooting

### Common CORS Issues

<AccordionGroup>
  <Accordion title="CORS Error in Browser Console">
    If you see CORS errors despite the permissive configuration:

    * Ensure you're using HTTPS in production
    * Check that your request method is GET, POST, or OPTIONS
    * Verify the Content-Type header is set correctly for POST requests
  </Accordion>

  <Accordion title="Preflight Request Failing">
    OPTIONS requests should return 204. If failing:

    * Check network connectivity
    * Verify the endpoint URL is correct
    * Ensure no proxy is blocking OPTIONS requests
  </Accordion>

  <Accordion title="Rate Limit on Shared IP">
    If multiple users share an IP:

    * Rate limits apply per IP address
    * Consider implementing request queuing
    * Contact support for enterprise solutions (future)
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card icon="code" href="/api/overview" title="API Overview">
    Learn about available endpoints and response formats
  </Card>

  <Card icon="gauge" href="/api/rate-limits" title="Rate Limits">
    Understand rate limiting and best practices
  </Card>
</CardGroup>
