# List treatments

`GET https://app.pozyskajpacjenta.pl/api/v1/services` · operationId `listServices` · since 1.1.0 · tag Entities

The clinic's published treatments, in the clinic's order. Responses are private to the key: `Cache-Control: private, max-age=60`, so cache them on your side for up to a minute.

## Request

Authorization: `Bearer <the clinic's key>`.

### cURL

```bash
curl "https://app.pozyskajpacjenta.pl/api/v1/services" \
  -H "Authorization: Bearer $PP_API_KEY"
```

### TypeScript

```ts
import { PozyskajPacjentaClient } from "@pozyskajpacjenta/sdk";

const client = new PozyskajPacjentaClient({
  apiKey: process.env.PP_API_KEY ?? "",
  baseUrl: "https://app.pozyskajpacjenta.pl",
});

const { services } = await client.listServices();
```

### PHP

```php
<?php
$response = wp_remote_get(
    'https://app.pozyskajpacjenta.pl/api/v1/services',
    array(
        'headers' => array( 'Authorization' => 'Bearer ' . getenv( 'PP_API_KEY' ) ),
        'timeout' => 10,
    )
);
if ( is_wp_error( $response ) ) {
    error_log( $response->get_error_message() );
    return;
}
$status = wp_remote_retrieve_response_code( $response );
$data   = json_decode( wp_remote_retrieve_body( $response ), true );
```

## Response

### 200: Published treatments.

- `services` (`ServiceSummary[]`, required): The treatments.
  - `id` (`string`, required): Treatment id.
  - `slug` (`string`, required): Slug from the treatment's address.
  - `path` (`string`, required): Path on the clinic's site, e.g. /zabiegi/implanty.
  - `name` (`string`, required): Treatment name.
  - `category` (`string | null`): Category the clinic groups the treatment under; null when none.
  - `shortDesc` (`string | null`): One-sentence description for lists; null when empty.
  - `priceFromLabel` (`string | null`): Price label, e.g. od 290 zł; null when the clinic shows no price.
  - `durationLabel` (`string | null`): Duration label, e.g. zabieg 60 min; null when empty.
  - `bookingServiceId` (`string | null`, required, since 1.3.0): Id of the active booking service this treatment is booked as: an entry of GET /booking/catalog and the `service` parameter of /booking/slots. null when the treatment is not linked to booking or the linked service is inactive.

Example (Published treatments (trimmed to two)):

```json
{
  "services": [
    {
      "id": "svc_konsultacja",
      "slug": "konsultacja-stomatologiczna",
      "name": "Konsultacja stomatologiczna",
      "category": "Diagnostyka",
      "shortDesc": "Przegląd jamy ustnej, diagnoza i plan leczenia z wyceną na piśmie, punkt startowy każdego leczenia.",
      "priceFromLabel": "200 zł",
      "durationLabel": "wizyta 30 min",
      "bookingServiceId": "bsvc_konsultacja",
      "path": "/zabiegi/konsultacja-stomatologiczna"
    },
    {
      "id": "svc_impl",
      "slug": "konsultacja-implantologiczna",
      "name": "Konsultacja implantologiczna z tomografią 3D",
      "category": "Implantologia",
      "shortDesc": "Tomografia CBCT, ocena warunków kostnych i kompletny plan odbudowy implantologicznej na jednej wizycie.",
      "priceFromLabel": "350 zł",
      "durationLabel": "wizyta 45 min",
      "bookingServiceId": "bsvc_impl",
      "path": "/zabiegi/konsultacja-implantologiczna"
    }
  ]
}
```

## Errors

| Status | code | When |
| --- | --- | --- |
| 401 |  | No Authorization header |
| 401 |  | Unknown or rotated key |
| 429 |  | Over 120 requests in this minute |

401 (No Authorization header):

```json
{
  "error": "missing Authorization: Bearer <klucz z panelu Ustawienia>"
}
```

401 (Unknown or rotated key):

```json
{
  "error": "invalid key"
}
```

429 (Over 120 requests in this minute):

```json
{
  "error": "przekroczono limit 120 zapytań/min"
}
```

## Rate limit

- 120 requests per minute per key, shared by every endpoint.

## SDK method

`client.listServices(): Promise<{ services: ServiceSummary[] }>`
