> ## 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.

# Search API

> Search across all collections in the Dzaleka Online Services platform

## GET /api/search

Search across multiple collections including services, events, resources, news, photos, jobs, and documentation.

### Query Parameters

<ParamField query="q" type="string" required>
  Search query string (minimum 2 characters)
</ParamField>

<ParamField query="collections" type="string">
  Comma-separated list of collections to search.

  Default: `services,events,resources,news,photos,jobs,docs`

  Available collections:

  * `services`
  * `events`
  * `resources`
  * `news`
  * `photos`
  * `jobs`
  * `docs`
</ParamField>

<ParamField query="limit" type="number">
  Maximum number of results per collection

  Default: `10`
</ParamField>

### Response Format

<ResponseField name="status" type="string" required>
  Status of the API response ("success" or "error")
</ResponseField>

<ResponseField name="query" type="string" required>
  The original search query
</ResponseField>

<ResponseField name="totalResults" type="number" required>
  Total number of results across all collections
</ResponseField>

<ResponseField name="results" type="object" required>
  Search results organized by collection

  Each collection key (e.g., "services", "events") contains an array of result objects:

  <ResponseField name="slug" type="string">
    Unique identifier/slug for the item
  </ResponseField>

  <ResponseField name="title" type="string">
    Item title or name
  </ResponseField>

  <ResponseField name="description" type="string">
    Item description
  </ResponseField>

  <ResponseField name="category" type="string">
    Item category
  </ResponseField>

  <ResponseField name="collection" type="string">
    Collection name
  </ResponseField>

  <ResponseField name="url" type="string">
    Relative URL to the item
  </ResponseField>

  <ResponseField name="image" type="string">
    URL to item image or logo
  </ResponseField>

  <ResponseField name="featured" type="boolean">
    Whether the item is featured
  </ResponseField>
</ResponseField>

<ResponseField name="cached" type="boolean">
  Whether the results were served from cache
</ResponseField>

<ResponseField name="cacheAge" type="number">
  Age of cached results in milliseconds (only present if `cached: true`)
</ResponseField>

### Caching

Search results are cached for 5 minutes to improve performance. Cache headers are included in responses:

* `X-Cache`: "HIT" (cached) or "MISS" (fresh query)
* `Cache-Control`: `public, max-age=300` (5 minutes)

### Error Responses

<ResponseField name="status" type="string">
  "error"
</ResponseField>

<ResponseField name="message" type="string">
  Error message description
</ResponseField>

<ResponseField name="error" type="string">
  Detailed error information
</ResponseField>

**Status Codes:**

* `200` - Success
* `400` - Bad request (query too short or invalid)
* `429` - Rate limit exceeded (60 requests per minute)
* `500` - Internal server error

### Rate Limiting

All API endpoints are rate-limited to 60 requests per minute per IP address. Rate limit headers are included in responses:

* `X-RateLimit-Limit`: Maximum requests per window
* `X-RateLimit-Remaining`: Remaining requests in current window
* `X-RateLimit-Reset`: Timestamp when the rate limit resets
* `Retry-After`: Seconds to wait before retrying (only on 429 responses)

### Example Request

Search all collections:

```bash theme={null}
curl -X GET "https://services.dzaleka.com/api/search?q=education" \
  -H "Content-Type: application/json"
```

Search specific collections:

```bash theme={null}
curl -X GET "https://services.dzaleka.com/api/search?q=technology&collections=services,jobs&limit=5" \
  -H "Content-Type: application/json"
```

### Example Response

```json theme={null}
{
  "status": "success",
  "query": "education",
  "totalResults": 3,
  "results": {
    "services": [
      {
        "slug": "BloomBox",
        "title": "BloomBox Design Labs",
        "description": "BloomBox Design Labs is dedicated to the application of sustainable design strategies, materials, and energy to advancing access to high quality education.",
        "category": "Education",
        "collection": "services",
        "url": "/services/BloomBox",
        "image": "https://static.wixstatic.com/media/bd2625_69e11c70797246ccba3425b1b8bcd771%7Emv2.png/v1/fill/w_192%2Ch_192%2Clg_1%2Cusm_0.66_1.00_0.01/bd2625_69e11c70797246ccba3425b1b8bcd771%7Emv2.png",
        "featured": true
      }
    ],
    "jobs": [
      {
        "slug": "Content-Curator-and-Editor",
        "title": "Content Curator & Editor",
        "description": "Join Dzaleka Digital Heritage as a Content Curator & Editor to help shape and refine the digital narratives that showcase the stories of Dzaleka's community.",
        "category": "business",
        "collection": "jobs",
        "url": "/jobs/Content-Curator-and-Editor",
        "image": null,
        "featured": true
      }
    ],
    "resources": [
      {
        "slug": "Banking-services-in-Dzaleka-Refugee-Camp",
        "title": "Banking services in Dzaleka Refugee Camp",
        "description": "New Finance Bank opened its branch of service in Dzaleka Refugee Camp on 12 April 2018.",
        "category": "Situation Reports / Updates",
        "collection": "resources",
        "url": "/resources/Banking-services-in-Dzaleka-Refugee-Camp",
        "image": null,
        "featured": false
      }
    ]
  },
  "cached": false
}
```

### Example Cached Response

```json theme={null}
{
  "status": "success",
  "query": "education",
  "totalResults": 3,
  "results": {
    "services": [...]
  },
  "cached": true,
  "cacheAge": 125430
}
```

## Implementation Details

The Search API implementation includes:

* **Query Parsing**: Searches across common fields (title, name, description, category, tags) - `src/pages/api/search.ts:154`
* **Result Caching**: 5-minute TTL with max 100 cached queries - `src/pages/api/search.ts:14`
* **Cache Key Generation**: Based on query + collections + limit - `src/pages/api/search.ts:24`
* **Automatic Cleanup**: Expired cache entries removed every 10 minutes - `src/pages/api/search.ts:81`

Source code: `src/pages/api/search.ts:92`
