Quickstart
This walks the full path from credentials to a generated progress note. It uses the sandbox
environment and curl; every call maps directly onto the API Reference.
You will need the clientId, clientSecret, and apiKey Blueprint provisioned for you. If you do
not have them, contact your Blueprint representative.
Set up your shell:
export BP_BASE='https://api.staging.blueprint.ai/v2'
export BP_API_KEY='your-api-key'
export BP_CLIENT_ID='your-client-id'
export BP_CLIENT_SECRET='your-client-secret'Note the
/v2in the base URL — it is part of the path, not a header. See
Environments & Base URLs.
1. Authenticate your backend
curl -sS -X POST "$BP_BASE/partners/authenticate" \
-H 'Content-Type: application/json' \
-H "X-API-Key: $BP_API_KEY" \
-d "{\"clientId\":\"$BP_CLIENT_ID\",\"clientSecret\":\"$BP_CLIENT_SECRET\"}"{
"accessToken": "very-long-alphanumeric-string",
"expiresIn": 3600,
"tokenType": "Bearer"
}Save it. This token lasts an hour and goes on every subsequent call as Access-Token:
export BP_TOKEN='very-long-alphanumeric-string'Confirm it works:
curl -sS "$BP_BASE/partners" \
-H "Access-Token: $BP_TOKEN" -H "X-API-Key: $BP_API_KEY"{ "id": "00000000-0000-0000-0000-000000000000", "callbackUrl": null }callbackUrl is where webhooks will be delivered. It is null until you set it in step 6.
2. Create an organization and a clinic
An organization is a customer of yours — a practice or group. A clinic is a location within
it. Every organization needs at least one clinic; if a practice has no locations to model, create
one clinic that mirrors the organization. See Concepts.
curl -sS -X POST "$BP_BASE/organizations" \
-H 'Content-Type: application/json' \
-H "Access-Token: $BP_TOKEN" -H "X-API-Key: $BP_API_KEY" \
-d '{"name":"Evergreen Behavioral Health","externalId":"org-8842"}'Returns 201:
{
"id": "11111111-1111-1111-1111-111111111111",
"name": "Evergreen Behavioral Health",
"externalId": "org-8842"
}export BP_ORG='11111111-1111-1111-1111-111111111111'
curl -sS -X POST "$BP_BASE/organizations/$BP_ORG/clinics" \
-H 'Content-Type: application/json' \
-H "Access-Token: $BP_TOKEN" -H "X-API-Key: $BP_API_KEY" \
-d '{"name":"Evergreen — Downtown","externalId":"clinic-1"}'Returns 201:
{
"id": "22222222-2222-2222-2222-222222222222",
"name": "Evergreen — Downtown",
"externalId": "clinic-1"
}Set
externalIdon everything you create. It is your own identifier — a row ID or MRN — and it
is how you reconcile your records with Blueprint's later. Because the API has no idempotency keys,
externalIdis also the only reliable way to detect a duplicate after a failed retry. See
Pagination & Limits.
3. Create a clinician
export BP_CLINIC='22222222-2222-2222-2222-222222222222'
curl -sS -X POST "$BP_BASE/clinics/$BP_CLINIC/clinicians" \
-H 'Content-Type: application/json' \
-H "Access-Token: $BP_TOKEN" -H "X-API-Key: $BP_API_KEY" \
-d '{
"firstName": "Dana",
"lastName": "Okonkwo",
"email": "[email protected]",
"externalId": "user-5501"
}'Returns 201:
{
"id": "33333333-3333-3333-3333-333333333333",
"firstName": "Dana",
"lastName": "Okonkwo",
"email": "[email protected]",
"externalId": "user-5501",
"clinicId": "22222222-2222-2222-2222-222222222222"
}Creating a clinician whose email already exists returns 409. Search first with
GET /clinics/{clinicId}/clinicians?email=... if you are not sure.
4. Create a client
Clients belong to a clinician.
export BP_CLINICIAN='33333333-3333-3333-3333-333333333333'
curl -sS -X POST "$BP_BASE/clinicians/$BP_CLINICIAN/clients" \
-H 'Content-Type: application/json' \
-H "Access-Token: $BP_TOKEN" -H "X-API-Key: $BP_API_KEY" \
-d '{
"firstName": "Jordan",
"lastName": "Reyes",
"dateOfBirth": "1991-04-17",
"pronouns": "they/them/theirs",
"email": "[email protected]",
"phoneNumber": "+15555550123",
"externalId": "mrn-77120"
}'Returns 201 with a ClientDTO.
phoneNumbermust include a+calling code.5555550123is rejected with 400
phoneNumber should include calling code.Send+15555550123. Omit the field entirely if you do
not have a normalized number.
Find them again later without storing Blueprint's ID:
curl -sS "$BP_BASE/clinicians/$BP_CLINICIAN/clients?externalId=mrn-77120" \
-H "Access-Token: $BP_TOKEN" -H "X-API-Key: $BP_API_KEY"5. Get a note
From here the path depends on who captures the audio.
Option A — Blueprint captures the audio (widget)
Mint a clinician token and hand it to the embedded UI:
curl -sS -X POST "$BP_BASE/clinicians/$BP_CLINICIAN/authenticate" \
-H "Access-Token: $BP_TOKEN" -H "X-API-Key: $BP_API_KEY"No request body. Returns:
{
"AccessToken": "very-long-alphanumeric-string",
"IdToken": "very-long-alphanumeric-string",
"RefreshToken": "very-long-alphanumeric-string",
"ExpiresIn": 600
}Return that object to your frontend unchanged — the field names are PascalCase and the widget
depends on them. Then:
<script>
window.blueprintSettings = {
containerId: 'blueprint-container',
isMinifiedView: true
}
</script>
<script src="https://embed.staging.blueprint.ai/index.min.js"></script>
<div id="blueprint-container"></div>
<script>
Blueprint.authenticate(clinicianTokens)
Blueprint.selectClient('CLIENT_ID_FROM_STEP_4')
Blueprint.onNoteGenerated(async ({ sessionId }) => {
const note = await myBackend.fetchProgressNote(sessionId)
insertIntoChart(note)
})
</script>window.blueprintSettings must be assigned before the script tag. See
Customizing the Experience and
Controlling the UI.
Option B — You capture the audio (API only)
Host the recording at a URL Blueprint can fetch, then create a session:
curl -sS -X POST "$BP_BASE/clients/$BP_CLIENT/sessions" \
-H 'Content-Type: application/json' \
-H "Access-Token: $BP_TOKEN" -H "X-API-Key: $BP_API_KEY" \
-d '{
"fileUrl": "https://files.example.com/sessions/abc123.mp3",
"setting": "telehealth",
"noteType": "soap",
"sessionExternalId": "appt-99031"
}'Returns 201 with the session, including progressNoteIds. Blueprint downloads the audio and
generates the note asynchronously. See API Only Integrations for the
constraints on fileUrl.
6. Receive the note
Register a callback URL once:
curl -sS -X PATCH "$BP_BASE/partners/$BP_PARTNER_ID" \
-H 'Content-Type: application/json' \
-H "Access-Token: $BP_TOKEN" -H "X-API-Key: $BP_API_KEY" \
-d '{"callbackUrl":"https://your-app.example.com/blueprint/webhooks"}'When the note is ready you receive:
{
"eventType": "progress_note_generated",
"timeStamp": "2026-07-29T18:04:11.522Z",
"payload": {
"progressNoteId": "44444444-4444-4444-4444-444444444444",
"sessionId": "55555555-5555-5555-5555-555555555555",
"sessionExternalId": "appt-99031",
"clientId": "...",
"clinicianId": "...",
"clinicId": "...",
"organizationId": "...",
"progressNoteUrl": "https://api.staging.blueprint.ai/v2/sessions/555.../progress-note"
}
}Verify the X-Blueprint-Signature header before trusting it, then GET the progressNoteUrl with
your normal headers:
{
"id": "44444444-4444-4444-4444-444444444444",
"sessionId": "55555555-5555-5555-5555-555555555555",
"isLoading": false,
"note": [
{ "key": "subjective", "title": "Subjective", "content": "Client reported feeling overwhelmed by..." },
{ "key": "objective", "title": "Objective", "content": "Therapist guided client through..." },
{ "key": "assessment", "title": "Assessment", "content": "Client is experiencing..." },
{ "key": "plan", "title": "Plan", "content": "Client will continue to..." }
],
"template": {
"noteType": "soap",
"sessionType": "individual",
"title": "SOAP",
"sections": [
{ "key": "subjective", "title": "Subjective" },
{ "key": "objective", "title": "Objective" },
{ "key": "assessment", "title": "Assessment" },
{ "key": "plan", "title": "Plan" }
]
}
}note is an ordered array of sections rather than a keyed object, so you can render an unknown note
type without knowing its sections in advance. Use template.sections for the expected section list
and note[].content for the text.
Signature verification is the one step you must not skip — see
Listening to Webhooks for a correct implementation.
Where to go next
- Design Your Integration — choosing between UI, UI + API, and API only
- Authentication — token lifetimes and refresh behavior
- Errors — what each status code means
- Webhook Events Reference — all seven event types
Updated about 1 month ago
