# Provider Information Updates API

:::note

This document is subject to frequent changes. Updates will be announced and version controlled.

:::

This document describes the two available methods for retrieving updated **location** and
**provider** records from Intelibly:

- `GET /api/changes?cursor=...`, an HTTP API
- Daily JSONL file uploads via **SFTP**

Both channels return the same structured data in a standardized format.

## HTTP API: retrieve updates

### Endpoint

```http
GET /api/changes?cursor=<timestamp>
```

The endpoint is global; the authenticated token determines which partner's data is accessible. You
do not need to specify a partner ID in the URL.

### Purpose

Fetches a chronologically ordered stream of all **location** and **provider** records that have
changed since the given timestamp (`cursor`). This is useful for partners who prefer to poll for
changes.

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `cursor` | string | No | ISO 8601 UTC timestamp. If omitted, the system returns changes since the last known sync. |

### Authentication

All API requests must be authenticated with **bearer token authentication**:

- Include an `Authorization` header in each request: `Authorization: Bearer <your_api_token>`
- API tokens are issued to each partner and should be kept secure.
- Requests without valid authentication receive a `401 Unauthorized` response.

### Response format

The API responds in **JSON Lines (JSONL)** format. Each line is a valid JSON object. There are two
types of entries:

- `location` entries
- `provider` entries

### Example response

```json
{"type":"location","location":{"id":101,"name":"CareSmile Dental","street":"123 Main St","city":"Dallas","state":"TX","zip":"75201","partners_internal_id":"LOC-2025-0001","updated_at":"2025-06-05T07:22:30Z","inserted_at":"2024-08-15T10:00:00Z"}}
{"type":"provider","provider":{"id":205,"name":"Dr. Alicia Rivera","npi_number":"1770954829","bio":"Specialist in cosmetic and restorative dentistry.","partners_internal_id":"PROV-311X","updated_at":"2025-06-05T07:23:45Z","inserted_at":"2024-11-01T14:30:00Z"}}
```

### Field descriptions

#### Location payload

| Field | Type | Description |
| --- | --- | --- |
| `id` | int | Intelibly internal system ID |
| `name` | string | Location name |
| `street` | string | Street address |
| `city` | string | City |
| `state` | string | State abbreviation |
| `zip` | string | ZIP code |
| `partners_internal_id` | string | Partner's internal identifier |
| `updated_at` | string | UTC timestamp of last modification |
| `inserted_at` | string | UTC timestamp of initial creation |

#### Provider payload

| Field | Type | Description |
| --- | --- | --- |
| `id` | int | Intelibly internal system ID |
| `name` | string | Full provider name |
| `npi_number` | string | National Provider Identifier |
| `bio` | string | Short professional biography |
| `partners_internal_id` | string | Partner's internal identifier |
| `updated_at` | string | UTC timestamp of last modification |
| `inserted_at` | string | UTC timestamp of initial creation |

### HTTP status codes

| Code | Meaning |
| --- | --- |
| `200` | Successful response |
| `400` | Invalid `cursor` format |
| `401` | Unauthorized (missing or invalid token) |
| `500` | Server error or processing issue |

## SFTP file delivery

### Overview

As an alternative to polling the API, Intelibly offers automatic daily uploads of change data to
your organization's configured **SFTP server**.

### Format

- Files are in **JSONL** format, identical in structure to the API response.
- Each line is either a `location` or `provider` object.

### Delivery details

| Feature | Value |
| --- | --- |
| File name pattern | `<partner_id>_updates_<timestamp>.jsonl` |
| Remote path | Configured based on the partner's requirements |
| File encoding | UTF-8 |
| Frequency | Daily |
| File contents | Only records updated since the last run |

### Example file contents

```json
{"type":"location","location":{"id":101,"name":"CareSmile Dental","street":"123 Main St","city":"Dallas","state":"TX","zip":"75201","partners_internal_id":"LOC-2025-0001","updated_at":"2025-06-05T07:22:30Z","inserted_at":"2024-08-15T10:00:00Z"}}
{"type":"location","location":{"id":102,"name":"BrightDental Clinic","street":"987 Oak Ave","city":"Plano","state":"TX","zip":"75024","partners_internal_id":"LOC-2025-0002","updated_at":"2025-06-05T07:22:59Z","inserted_at":"2024-12-12T09:00:00Z"}}
{"type":"provider","provider":{"id":205,"name":"Dr. Alicia Rivera","npi_number":"1770954829","bio":"Specialist in cosmetic and restorative dentistry.","partners_internal_id":"PROV-311X","updated_at":"2025-06-05T07:23:45Z","inserted_at":"2024-11-01T14:30:00Z"}}
```

### Security and integrity

- Files are transferred via secure SFTP with credential-based access.
- Files are removed from Intelibly's servers after successful delivery.
- Timestamp cursors are used to prevent duplicate deliveries.

### Authentication credentials

Each partner provides Intelibly with unique SFTP credentials:

- **Username**: provided by the partner's team
- **Password**: provided by the partner's team (or an SSH key, if preferred)

Credentials are required to access the SFTP server and exchange files.

## Tips for consumers

- When using the API, save the latest `updated_at` timestamp and use it as the next `cursor`.
- When using SFTP, assume the file contains only *new* changes since your last pull.
- Process each line independently; there is no need to parse the entire file into memory.
