# Nöbetçi Eczane (SBX-ECZ)

More than 30,000 pharmacies (on-duty and regular) across 81 provinces and ~960 districts, with on-duty status and shift windows plus nearest-to-point search — refreshed up to three times a day.

Version: v1.0

## Authentication

Send your API key on every request, either as a Bearer token or as the `apikey` query parameter:

```
Authorization: Bearer <YOUR_API_KEY>
https://api.servicebox.io/v1/pharmacy/...?apikey=<YOUR_API_KEY>
```

Get a key: sign up at https://servicebox.io/en/signup and create one on the dashboard. An agent can sign up itself with `POST https://api.servicebox.io/v1/accounts` and `{"email": "...", "apis": ["pharmacy"]}`: the owner of the mailbox approves by email and the agent collects a short-lived key by polling the returned `poll_url`.

## Base URL

`https://api.servicebox.io`

## Endpoints

### GET /v1/pharmacy/cities

**List cities**

All 81 provinces with pharmacy and on-duty counts, sorted by pharmacy count descending. A city's `id` is its name, which is what `city=` accepts. Not paged: the whole list in one answer.

**Credits:** free (0 credits per call)

No parameters.

**Example**

```bash
curl "https://api.servicebox.io/v1/pharmacy/cities" \
  -H "Authorization: Bearer $SBX_API_KEY"
```

### GET /v1/pharmacy/districts

**List districts**

Districts (roughly 960 nationwide) with pharmacy and on-duty counts, optionally filtered to one city. A district's `id` is its name; `cityId` is its city's. Not paged: the whole list in one answer.

**Credits:** free (0 credits per call)

**Parameters**

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `city` | query | string | no | Restrict to districts of this city (case- and accent-insensitive). Omit to list all districts nationwide. |

**Example**

```bash
curl "https://api.servicebox.io/v1/pharmacy/districts" \
  -H "Authorization: Bearer $SBX_API_KEY"
```

### GET /v1/pharmacy/pharmacies

**Search pharmacies**

All pharmacies (on-duty and regular) matching the given filters.

**Credits:** 1 per call

**Parameters**

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `city` | query | string | no | Filter by city name (case- and accent-insensitive). Up to 120 characters. |
| `district` | query | string | no | Filter by district name (case- and accent-insensitive). Up to 120 characters. |
| `name` | query | string | no | Turkish-aware substring match on pharmacy name. Up to 120 characters. `q` is an alias for this parameter. |
| `q` | query | string | no | Alias for `name`. |
| `duty` | query | boolean | no | Filter to on-duty (`true`) or off-duty (`false`) pharmacies. Omit to return both. |
| `activelyOnDuty` | query | boolean | no | `true` = duty shift active now (Europe/Istanbul, start inclusive, end exclusive); `false` = not active now. Such answers carry `Cache-Control: no-store`, no `ETag`, and are never answered `304`. `false` does not mean closed. |
| `sort` | query | string (`id`, `name`, `city`) | no | Sort order for the result set. |
| `limit` | query | integer | no | Maximum number of items on this page. |
| `cursor` | query | string | no | Opaque; the `next_cursor` of the previous page. Keep every other parameter unchanged, or the call is a 400. |

**Example**

```bash
curl "https://api.servicebox.io/v1/pharmacy/pharmacies" \
  -H "Authorization: Bearer $SBX_API_KEY"
```

### GET /v1/pharmacy/pharmacies/nearby

**Find nearby pharmacies**

Pharmacies within a radius of a coordinate, nearest first and annotated with `distanceKm`. Pages through at most the 500 nearest: at 500 `next_cursor` is null.

**Credits:** 2 per call

**Parameters**

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `lat` | query | number | yes | Latitude of the search center (WGS84). |
| `lon` | query | number | yes | Longitude of the search center (WGS84). |
| `radiusKm` | query | number | no | Search radius in kilometers. |
| `city` | query | string | no | Filter by city name (case- and accent-insensitive). Up to 120 characters. |
| `district` | query | string | no | Filter by district name (case- and accent-insensitive). Up to 120 characters. |
| `name` | query | string | no | Turkish-aware substring match on pharmacy name. Up to 120 characters. `q` is an alias for this parameter. |
| `q` | query | string | no | Alias for `name`. |
| `duty` | query | boolean | no | Filter to on-duty (`true`) or off-duty (`false`) pharmacies. Omit to return both. |
| `activelyOnDuty` | query | boolean | no | `true` = duty shift active now (Europe/Istanbul, start inclusive, end exclusive); `false` = not active now. Such answers carry `Cache-Control: no-store`, no `ETag`, and are never answered `304`. `false` does not mean closed. |
| `limit` | query | integer | no | Maximum number of items on this page. |
| `cursor` | query | string | no | Opaque; the `next_cursor` of the previous page. Keep every other parameter unchanged, or the call is a 400. |

**Example**

```bash
curl "https://api.servicebox.io/v1/pharmacy/pharmacies/nearby?lat=0&lon=0" \
  -H "Authorization: Bearer $SBX_API_KEY"
```

### GET /v1/pharmacy/pharmacies/on-duty

**List on-duty pharmacies**

Pharmacies currently on duty, sorted by city. Always returns on-duty pharmacies only — the shared `duty` filter does not apply here.

**Credits:** 1 per call

**Parameters**

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `city` | query | string | no | Filter by city name (case- and accent-insensitive). Up to 120 characters. |
| `district` | query | string | no | Filter by district name (case- and accent-insensitive). Up to 120 characters. |
| `name` | query | string | no | Turkish-aware substring match on pharmacy name. Up to 120 characters. `q` is an alias for this parameter. |
| `q` | query | string | no | Alias for `name`. |
| `activelyOnDuty` | query | boolean | no | `true` = duty shift active now (Europe/Istanbul, start inclusive, end exclusive); `false` = not active now. Such answers carry `Cache-Control: no-store`, no `ETag`, and are never answered `304`. `false` does not mean closed. |
| `limit` | query | integer | no | Maximum number of items on this page. |
| `cursor` | query | string | no | Opaque; the `next_cursor` of the previous page. Keep every other parameter unchanged, or the call is a 400. |

**Example**

```bash
curl "https://api.servicebox.io/v1/pharmacy/pharmacies/on-duty" \
  -H "Authorization: Bearer $SBX_API_KEY"
```

### GET /v1/pharmacy/pharmacies/{id}

**Get a pharmacy by id**

A single pharmacy by its numeric id.

**Credits:** 1 per call

**Parameters**

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | integer | yes | Positive integer pharmacy id. |

**Example**

```bash
curl "https://api.servicebox.io/v1/pharmacy/pharmacies/1" \
  -H "Authorization: Bearer $SBX_API_KEY"
```

## Errors

Errors are RFC 9457 `application/problem+json` bodies with a machine-readable `type`.

- `401` — the key is missing, unknown, expired or revoked.
- `402` — not enough credits: the body carries `credits_required` and `upgrade_url` (https://servicebox.io/en/pricing).
- `403` — the key is not allowed to call this API.
- `429` — rate limited: wait `retry_after` seconds (also sent as the `Retry-After` header); `upgrade_url` points to a larger plan.

## Links

- OpenAPI document: https://api.servicebox.io/v1/pharmacy/openapi.json
- Pricing: https://servicebox.io/en/pricing?api=SBX-ECZ
- API page: https://servicebox.io/en/apis/pharmacy
