API Only Integrations
You provide the entire user interface and use no Blueprint UI components. This gives you complete
control of the experience, and it means you implement device access, audio capture, user feedback,
error handling, and upload reliability yourself.
Blueprint still needs clinician and client records so documentation attaches to the right chart.
Your backend creates those, then makes each recording available for Blueprint to fetch.
Before choosing this method, be clear about what you are taking on: microphone permissions across
browsers, device selection, level metering, connection loss and resume, and reliable upload of long
recordings are all handled by Blueprint's embedded UI. See
Design Your Integration.
How audio gets to Blueprint
There is no upload endpoint. You do not POST audio bytes to Blueprint.
Instead you host the recording at a URL and give Blueprint that URL when you create the session.
Blueprint fetches the file and processes it asynchronously.
Your app records audio
→ you store it somewhere Blueprint can reach (e.g. S3 with a presigned URL)
→ POST /v2/clients/{clientId}/sessions with fileUrl
→ Blueprint downloads and processes it
→ webhook when the note is ready
The flow
1. Store your credentials. clientId, clientSecret, and apiKey, in your backend's secret
manager.
2. Authenticate. POST /v2/partners/authenticate for a server-to-server access token, valid one
hour.
3. Create organization, clinic, clinician, and client records mirroring your own, linked with
externalId. See Quickstart.
4. Capture audio in your application.
5. Make it fetchable and create the session:
curl -X POST https://api.blueprint.ai/v2/clients/{clientId}/sessions \
-H 'Content-Type: application/json' \
-H 'Access-Token: YOUR_ACCESS_TOKEN' \
-H 'X-API-Key: YOUR_API_KEY' \
-d '{
"fileUrl": "https://files.example.com/sessions/abc123.mp3?signature=...",
"setting": "telehealth",
"noteType": "soap",
"treatmentApproach": "cbt",
"sessionExternalId": "appt-99031"
}'Returns 201 with the session, including progressNoteIds.
6. Receive a webhook when documentation is ready, and fetch the artifact.
Request fields
| Field | Required | Notes |
|---|---|---|
fileUrl | yes | Absolute URL Blueprint will fetch the audio from |
setting | yes | in-person or telehealth |
noteType | yes | e.g. soap, dap, birp. Call GET /v2/organizations/{organizationId}/progress-note-types for what is available. |
treatmentApproach | no | A single value, e.g. cbt |
sessionExternalId | no | Your appointment ID. Echoed back in webhook payloads. |
preferences | no | Note generation preferences for this session |
usingHeadphones | no | Accepted, but not currently applied by this endpoint |
Three behaviors worth knowing before you build against it:
- The clinician is derived from the client, not chosen by you. This endpoint uses the first
clinician associated with the client. If a client has secondary clinicians, you cannot direct the
session to a specific one. Model one primary clinician per client if attribution matters. - Only the singular
treatmentApproachis accepted here.GETresponses return a plural
treatmentApproachesand mark the singular form deprecated, but session creation accepts the
singular form only. Pass one value. usingHeadphonesis accepted and ignored on this endpoint. It is meaningful in the embedded UI,
where Blueprint controls capture.
Requirements for fileUrl
fileUrlBlueprint fetches this URL server-side, asynchronously, after you create the session.
- It must be an absolute URL. Relative paths and
file://are rejected with 400. - It must be reachable by Blueprint's servers at fetch time — which is after your request returns,
not during it. A URL that has already expired by then will fail. - Presigned URLs (S3, GCS, Azure) are the usual approach. Give them a generous expiry.
Confirm the specifics with your Blueprint representative before you build. Maximum file size,
accepted audio formats, how long the URL must remain valid, whether authenticated (non-presigned)
URLs are supported, and the retry behavior on a failed fetch are not yet documented here. If you are
planning an API Only integration, ask about these first — they affect how you store recordings.
Knowing whether it worked
Session creation returning 201 means Blueprint accepted the request, not that the audio was
fetched or processed. Processing happens afterward.
Watch for these events:
| Event | Meaning |
|---|---|
transcript_ready | Audio was fetched and transcribed. payload.transcriptUrl has the transcript. |
progress_note_generated | The note is ready at payload.progressNoteUrl. |
session_transcript_error | Transcription failed. payload.error has the reason. |
session_transcript_error is the channel to watch for a failed or unusable fetch. Log
payload.error — it is your main diagnostic for audio problems.
If you would rather poll, GET /v2/sessions/{sessionId}/progress-note returns isLoading: true while
the note is still generating. Webhooks are more reliable and much cheaper. See
Listening to Webhooks.
What else the API gives you
Because you own the UI, these become your responsibility to expose:
- Organization and clinic lookup by ID:
GET /v2/organizations/{organizationId}and
GET /v2/clinics/{clinicId}— resolve a stored UUID without paging the list endpoint - Note types available to an organization:
GET /v2/organizations/{organizationId}/progress-note-types - Per-clinician note preferences:
GET/POST /v2/clinicians/{clinicianId}/note-preferences - Editing a note section by section:
PATCH /v2/progress-notes/{progressNoteId} - Magic edit with natural-language instructions (up to 5000 characters):
POST /v2/progress-notes/{progressNoteId}/magic-edit - Regenerate in a different format:
POST /v2/progress-notes/{progressNoteId}/regenerate - Transcript, summary, and MDM elements per session
- Assessments — assign, administer, or submit answers collected in your own UI
Note that once a note is finalized it is locked, and patch, magic-edit, and regenerate all return
403. See Errors.
Next
- Quickstart — the full sequence in
curl - Webhook Events Reference — all seven events and their payloads
- Errors — including how to tell "not ready" from "not available"
Updated 28 days ago
