<!-- Carebit docs: Testing your integration -->

# Testing your integration

Test with example data before connecting an integration to real
clinical data. Never use a real patient's details, and never paste API
credentials or patient information into third-party request inspectors.

## Test safely

Integrations use the production API at `https://api.carebit.co`.
Use a dedicated example patient and take care not to trigger real messages,
billing, or clinical automations while testing.

## Create or find an example patient

The public API can create a Patient with `POST /v1/patients` and the
`patients.create` scope. Before creating another record, use
`GET /v1/patients` with the `patients.read` scope to look for an existing
example Patient by exact first name, last name, and date of birth:

<!-- code-tabs -->

### cURL

```bash
curl "https://api.carebit.co/v1/patients?first_name=Example%20API&last_name=Patient&date_of_birth=1970-01-01" \
  -H "Authorization: Bearer $CAREBIT_ACCESS_TOKEN"
```

### JavaScript

```javascript
const params = new URLSearchParams({
  first_name: "Example API",
  last_name: "Patient",
  date_of_birth: "1970-01-01",
});
const response = await fetch(`https://api.carebit.co/v1/patients?${params}`, {
  headers: {
    Authorization: `Bearer ${process.env.CAREBIT_ACCESS_TOKEN}`,
  },
});
const patients = await response.json();
```

### Python

```python
import os
import requests

response = requests.get(
    "https://api.carebit.co/v1/patients",
    headers={
        "Authorization": f"Bearer {os.environ['CAREBIT_ACCESS_TOKEN']}",
    },
    params={
        "first_name": "Example API",
        "last_name": "Patient",
        "date_of_birth": "1970-01-01",
    },
)
patients = response.json()
```

### Ruby

```ruby
require "httparty"

response = HTTParty.get(
  "https://api.carebit.co/v1/patients",
  headers: {
    "Authorization" => "Bearer #{ENV.fetch("CAREBIT_ACCESS_TOKEN")}"
  },
  query: {
    first_name: "Example API",
    last_name: "Patient",
    date_of_birth: "1970-01-01"
  }
)
patients = response.parsed_response
```

### PHP

```php
$client = new GuzzleHttp\Client();

$response = $client->get("https://api.carebit.co/v1/patients", [
    "headers" => [
        "Authorization" => "Bearer " . getenv("CAREBIT_ACCESS_TOKEN"),
    ],
    "query" => [
        "first_name" => "Example API",
        "last_name" => "Patient",
        "date_of_birth" => "1970-01-01",
    ],
]);
$patients = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR);
```

<!-- /code-tabs -->

If your StaffMember account has only the Developer role, it cannot open the
Patients area. Create the example Patient through the API with a project that
has `patients.create`, or ask an Admin or another StaffMember with patient
access to create it in Carebit.

New Carebit organizations normally include a patient named **Mr Example
Patient**. Open **Patients** and search for that name before creating another
record. Check its contact details before triggering any communication because
the onboarding record may use an email address belonging to your organization.

If you need a separate record:

1. In Carebit, open **Patients** and select **New patient**.
2. Enter an unmistakably fabricated first and last name, such as `Example API`
   and `Patient`.
3. Enter a fabricated date of birth, such as 1 January 1970, and select a sex.
4. Leave email address, telephone numbers, NHS number, address, and other
   optional fields empty unless the behavior under test requires them.
5. Select **Save**.
6. If Carebit asks for a payment method because of the organization's billing
   settings, select **Skip** rather than entering real payment details.

After saving, Carebit opens the patient profile. The UUID at the end of the
browser URL and the `id` returned by `GET /v1/patients` are the `patient_id` to
use in API requests. The example patient is a real record inside your Carebit
organization, so API writes against it can still run configured automations.
Review the organization's messaging, billing, and automation settings before
testing.

## Prepare a webhook receiver

Your receiver must be available at the HTTPS URL configured on the webhook
endpoint. It should:

- preserve the raw request bytes for signature verification;
- verify the `Carebit-Signature` header before trusting the body;
- log the `Carebit-Delivery-Id` and `Carebit-Event-Id`; and
- return a `2XX` response within 20 seconds.

See [Webhook setup](/guides/webhook-setup) and
[Webhook signatures](/guides/webhook-signatures) before sending an event.

## Send a test webhook event

The project must be active, and the endpoint must be enabled and subscribed to
at least one event type.

1. In Carebit, open **Settings > Developer platform > Projects**.
2. Open the project and its **Webhook endpoints** section.
3. Open an enabled endpoint, then select **Send test event**.
4. Choose an event type. The list contains only event types to which that
   endpoint is currently subscribed.
5. Review the payload preview and select **Send test event**.

Carebit queues the payload only for the selected endpoint through the same
delivery and retry pipeline used by live webhooks. The dashboard then opens
the project's **Events** tab and filters it to the new event. Delivery attempts
are recorded asynchronously, so they may take a few moments to appear.

The event ID and `created_at` value are generated when you send the event.
The remaining preview values are sent as shown. Test payloads:

- contain deterministic, fabricated resource UUIDs;
- use names such as `Test Patient` and `Dr Ada Lovelace`;
- use reserved `example.invalid` email addresses;
- set `livemode` to `false`; and
- use the normal retry schedule after a failed attempt, but do not affect the
  endpoint's failure streak or automatic disablement.

The resources represented by a test payload do not exist in your
organization. A test webhook validates delivery, signature handling, and
payload parsing, but it cannot be followed by an API request for the
fabricated resource.

## Test a complete workflow

Use the dashboard's test event first to validate webhook transport. To test a
complete workflow with queryable data, perform an API action against your
example patient, such as creating or updating a Booking, and receive the real
webhook generated by that action.

Before doing so, confirm that:

- the project has the resource scopes required by the API operation;
- the endpoint is enabled and subscribed to the expected event;
- any messages, invoices, or automations triggered by the action are safe; and
- your receiver treats repeated deliveries as idempotent.

Use the API request ID, event ID, and delivery ID to correlate both sides of
the workflow. See [Support diagnostics](/guides/support-diagnostics) for the
details to retain.
