# Services

The Services offered by the Organization and the ServiceVariants that can be booked.

## List the Organization's Services

`GET /v1/services`

**Required API scopes:** `services.read`

## Parameters

- `is_bookable_online` (query, `boolean`) - Only return Services that patients can book online.
- `limit` (query, `integer`) - The maximum number of items to return. Defaults to `25`; the maximum is `100`.
- `starting_after` (query, `string`) - Return items after this resource ID. You cannot use this with `cursor`.
- `cursor` (query, `string`) - The `next_cursor` value from the previous page. You cannot use this with `starting_after`.

## Response `200`

Paginated list of `Service` objects.

- `any`

### Example

```json
{
  "object": "list",
  "data": [
    {
      "id": "5e6f7081-92a3-4bcd-8ef0-123456789abc",
      "object": "service",
      "created_at": "2026-01-01T09:00:00Z",
      "description": "An initial consultation at the Harley Street Clinic.",
      "duration_minutes": 30,
      "is_bookable_online": true,
      "name": "Initial consultation",
      "service_variants": [
        {
          "id": "6f708192-a3b4-4cde-9f01-23456789abcd",
          "clinician_id": "2b3c4d5e-6f70-489a-9bcd-ef0123456789",
          "currency": "GBP",
          "description": "An initial consultation at the Harley Street Clinic.",
          "links": {
            "clinician": "https://api.carebit.co/v1/clinicians/2b3c4d5e-6f70-489a-9bcd-ef0123456789",
            "location": "https://api.carebit.co/v1/locations/3c4d5e6f-7081-49ab-acde-f0123456789a"
          },
          "location_id": "3c4d5e6f-7081-49ab-acde-f0123456789a",
          "net_price": 1,
          "permits_remote_bookings": true
        }
      ],
      "tax_rate": {
        "id": "211b60c7-ec1b-41b4-8a29-e855209bc694",
        "description": "An initial consultation at the Harley Street Clinic.",
        "percentage": 20,
        "title": "VAT"
      },
      "updated_at": "2026-01-01T09:00:00Z"
    }
  ],
  "has_more": false,
  "next_cursor": "eyJzdGFydF90aW1lIjoiMjAyNi0wMS0wMVQwOTowMDowMFoifQ",
  "url": "/v1/services"
}
```

## Response `400`

A filter or pagination parameter is invalid.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `401`

The access token is missing, invalid, expired, or revoked.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `403`

The access token lacks the required scope, or the project is disabled.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `429`

Too many requests. Retry after the delay indicated by `Retry-After`.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Code samples

```bash
curl -X GET "https://api.carebit.co/v1/services" \
  -H "Authorization: Bearer $CAREBIT_ACCESS_TOKEN"
```

```javascript
const response = await fetch("https://api.carebit.co/v1/services", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.CAREBIT_ACCESS_TOKEN}`,
  },
});

if (!response.ok) {
  throw new Error(`Carebit API error: ${response.status}`);
}

const data = await response.json();
```

```python
import os
import requests

response = requests.get(
    "https://api.carebit.co/v1/services",
    headers={
        "Authorization": f"Bearer {os.environ['CAREBIT_ACCESS_TOKEN']}",
    }
)
response.raise_for_status()
data = response.json()
```

```ruby
require "httparty"

response = HTTParty.get(
  "https://api.carebit.co/v1/services",
  headers: {
    "Authorization" => "Bearer #{ENV.fetch("CAREBIT_ACCESS_TOKEN")}"
  }
)
raise "Carebit API error: #{response.code}" unless response.success?
data = response.parsed_response
```

```php
<?php

$client = new GuzzleHttp\Client();

$response = $client->get("https://api.carebit.co/v1/services", [
    "headers" => [
      "Authorization" => "Bearer " . getenv("CAREBIT_ACCESS_TOKEN"),
    ]
]);
$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR);
```


## Get a Service

`GET /v1/services/:id`

**Required API scopes:** `services.read`

## Parameters

- `id` (path, `string`) (required)

## Response `200`

The requested `Service`.

- `object`
  - `created_at` (`string`) - format: `date-time`; An ISO 8601 timestamp in UTC, with a `Z` suffix. For example, `2026-07-01T09:00:00Z`.
  - `description` (`string | null`) - The description of the service shown to staff members and patients.
  - `duration_minutes` (`integer | null`) - The scheduled duration of the service, in minutes.
  - `id` (`string`) - format: `uuid`; The resource's unique identifier, formatted as an RFC 4122 version 4 UUID.
  - `is_bookable_online` (`boolean`) - Whether patients can book this service online in the Patient Portal.
  - `name` (`string`) - The display name of the service.
  - `object` (`any`) - Discriminator value emitted at `object`.
  - `service_variants` (`array`) - The bookable variants of this service.
    - `items` (`object`)
      - `clinician_id` (`string | null`) - format: `uuid`; The identifier of the clinician assigned to this service variant, when the variant is clinician-specific.
      - `currency` (`string | null`) - The ISO 4217 currency code used for this service variant. Must be one of `chf`, `eur`, `gbp`, or `usd`.
      - `description` (`string | null`) - The description of this service variant.
      - `id` (`string`) - format: `uuid`; The resource's unique identifier, formatted as an RFC 4122 version 4 UUID.
      - `links` (`object`) - URLs to related resources.
        - `clinician` (`string | null`) - format: `uri`; The full URL of a related resource.
        - `location` (`string | null`) - format: `uri`; The full URL of a related resource.
      - `location_id` (`string | null`) - format: `uuid`; The identifier of the location assigned to this service variant, when the variant is location-specific.
      - `net_price` (`integer | null`) - The net price of this service variant, before tax, in the currency's minor units.
      - `permits_remote_bookings` (`boolean`) - Whether this service variant can be used for remote bookings.
  - `tax_rate` (`any`) - The tax rate applied to this service. Null when no tax rate is set.
  - `updated_at` (`string`) - format: `date-time`; An ISO 8601 timestamp in UTC, with a `Z` suffix. For example, `2026-07-01T09:00:00Z`.

### Example

```json
{
  "id": "5e6f7081-92a3-4bcd-8ef0-123456789abc",
  "object": "service",
  "created_at": "2026-01-01T09:00:00Z",
  "description": "An initial consultation at the Harley Street Clinic.",
  "duration_minutes": 30,
  "is_bookable_online": true,
  "name": "Initial consultation",
  "service_variants": [
    {
      "id": "6f708192-a3b4-4cde-9f01-23456789abcd",
      "clinician_id": "2b3c4d5e-6f70-489a-9bcd-ef0123456789",
      "currency": "GBP",
      "description": "An initial consultation at the Harley Street Clinic.",
      "links": {
        "clinician": "https://api.carebit.co/v1/clinicians/2b3c4d5e-6f70-489a-9bcd-ef0123456789",
        "location": "https://api.carebit.co/v1/locations/3c4d5e6f-7081-49ab-acde-f0123456789a"
      },
      "location_id": "3c4d5e6f-7081-49ab-acde-f0123456789a",
      "net_price": 1,
      "permits_remote_bookings": true
    }
  ],
  "tax_rate": {
    "id": "211b60c7-ec1b-41b4-8a29-e855209bc694",
    "description": "An initial consultation at the Harley Street Clinic.",
    "percentage": 20,
    "title": "VAT"
  },
  "updated_at": "2026-01-01T09:00:00Z"
}
```

## Response `401`

The access token is missing, invalid, expired, or revoked.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `403`

The access token lacks the required scope, or the project is disabled.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `404`

Error response.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Response `429`

Too many requests. Retry after the delay indicated by `Retry-After`.

- `object`
  - `error` (`object`) - The structured details that describe why the request failed.
    - `code` (`string`) - The machine-readable error code.
    - `errors` (`array | null`) - Additional errors from a failed validation.
      - `items` (`object`)
        - `code` (`string`) - The machine-readable code for this validation error.
        - `message` (`string`) - A message that explains this validation error.
        - `param` (`string | null`) - The name of the parameter that caused this validation error, when known.
    - `message` (`string`) - A message that explains the error and how to resolve it.
    - `param` (`string | null`) - The name of the parameter that caused the error, when known.
    - `type` (`string`) - enum: `authentication_error`, `permission_error`, `invalid_request_error`, `rate_limit_error`, `api_error`; The high-level category of the error.

### Example

```json
{
  "error": {
    "code": "resource_missing",
    "errors": [
      {
        "code": "resource_missing",
        "message": "The requested resource was not found.",
        "param": "patient_id"
      }
    ],
    "message": "The requested resource was not found.",
    "param": "patient_id",
    "type": "authentication_error"
  }
}
```

## Code samples

```bash
curl -X GET "https://api.carebit.co/v1/services/8f14e45f-ea7d-4b6f-9c2a-1d3e5f7a9b0c" \
  -H "Authorization: Bearer $CAREBIT_ACCESS_TOKEN"
```

```javascript
const response = await fetch("https://api.carebit.co/v1/services/8f14e45f-ea7d-4b6f-9c2a-1d3e5f7a9b0c", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.CAREBIT_ACCESS_TOKEN}`,
  },
});

if (!response.ok) {
  throw new Error(`Carebit API error: ${response.status}`);
}

const data = await response.json();
```

```python
import os
import requests

response = requests.get(
    "https://api.carebit.co/v1/services/8f14e45f-ea7d-4b6f-9c2a-1d3e5f7a9b0c",
    headers={
        "Authorization": f"Bearer {os.environ['CAREBIT_ACCESS_TOKEN']}",
    }
)
response.raise_for_status()
data = response.json()
```

```ruby
require "httparty"

response = HTTParty.get(
  "https://api.carebit.co/v1/services/8f14e45f-ea7d-4b6f-9c2a-1d3e5f7a9b0c",
  headers: {
    "Authorization" => "Bearer #{ENV.fetch("CAREBIT_ACCESS_TOKEN")}"
  }
)
raise "Carebit API error: #{response.code}" unless response.success?
data = response.parsed_response
```

```php
<?php

$client = new GuzzleHttp\Client();

$response = $client->get("https://api.carebit.co/v1/services/8f14e45f-ea7d-4b6f-9c2a-1d3e5f7a9b0c", [
    "headers" => [
      "Authorization" => "Bearer " . getenv("CAREBIT_ACCESS_TOKEN"),
    ]
]);
$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR);
```

