Pagination & Limits
Pagination
List endpoints are page-based. Pass page as a query parameter; it defaults to 1.
curl 'https://api.blueprint.ai/v2/clinicians/{clinicianId}/clients?page=2' \
-H 'Access-Token: YOUR_ACCESS_TOKEN' \
-H 'X-API-Key: YOUR_API_KEY'Every paginated response has the same envelope:
{
"data": [
{ "id": "00000000-0000-0000-0000-000000000000", "firstName": "Jordan", "lastName": "Reyes" }
],
"meta": {
"totalItems": 42,
"totalPages": 5,
"itemsPerPage": 10,
"currentPage": 2
}
}Page size is fixed at 10 and cannot be changed. There is no limit, pageSize, or per_page
parameter. Iterate until currentPage === totalPages:
async function listAllClients(clinicianId) {
const all = []
let page = 1, totalPages = 1
do {
const res = await fetch(
`${BASE}/clinicians/${clinicianId}/clients?page=${page}`,
{ headers }
)
const { data, meta } = await res.json()
all.push(...data)
totalPages = meta.totalPages
page += 1
} while (page <= totalPages)
return all
}Paginated endpoints
GET /organizations · GET /organizations/{organizationId}/clinics ·
GET /organizations/{organizationId}/programs · GET /clinics/{clinicId}/clinicians ·
GET /clinics/{clinicId}/clients · GET /clinics/{clinicId}/assessments ·
GET /clinicians/{clinicianId}/clients · GET /clinicians/{clinicianId}/magic-edit ·
GET /clients/{clientId}/sessions · GET /clients/{clientId}/programs
Filtering
Two list endpoints accept filters alongside page. All filters are optional and combine with AND.
GET /clinics/{clinicId}/clients and GET /clinicians/{clinicianId}/clients:
| Parameter | Notes |
|---|---|
externalId | Your own identifier. The recommended way to find a client you created. |
firstName, lastName | Exact match |
name | Free-text search across first and last name |
email, phoneNumber | Exact match |
dateOfBirth | ISO 8601 date |
status | awaiting_invite, active, archived, declined, invite_sent, pending, unknown |
clinicianId | Clinic-scoped endpoint only |
GET /clinics/{clinicId}/clinicians: id, firstName, lastName, email, externalId
GET /clinics/{clinicId}/assessments: defaultOnly
Filtering by externalId is the intended way to reconcile your records with Blueprint's — see
Concepts.
Rate limits
The Partner API enforces rate, burst, and daily quota limits. See
Rate Limiting & Throttling for the default usage plan and
guidance for handling throttled requests.
Idempotency
Idempotency keys are not supported. There is no Idempotency-Key header, so a retried POST
may create a duplicate resource.
Practical guidance:
- Creates are not safe to blind-retry. If a create times out, search before retrying — use
?externalId=for clients and clinicians. SettingexternalIdon everything you create makes this
possible; without it you have no way to detect the duplicate. POST /clients/{clientId}/secondary-cliniciansis safe to retry. It skips clinicians who are
already assigned.PATCHandDELETEare naturally idempotent.
Webhook deduplication
Webhook delivery is at-least-once, so you can receive the same event more than once, and the
payload carries no delivery ID to dedupe on. Use the natural key from the payload instead:
| Event group | Suggested dedupe key |
|---|---|
| Progress note events | eventType + progressNoteId |
transcript_ready, session_transcript_error, mdm_elements_identified | eventType + sessionId |
assessment_completed | eventType + each assessmentScores[].id |
Make your handler idempotent on that key. See
Listening to Webhooks.
Field limits and validation rules
| Field | Rule |
|---|---|
phoneNumber | Must include a + calling code, e.g. +15555550123. Without it the request fails with 400 phoneNumber should include calling code. |
userInstructions (magic edit) | Maximum 5000 characters. Whitespace is trimmed. |
dateOfBirth | ISO 8601 date string |
fileUrl (create session) | Must be a valid absolute URL. See API Only Integrations. |
externalId | Free-form string. Expected to be unique within a clinical organization; not enforced. |
Updated 28 days ago
