AllClear Partner API Documentation
Which API should I use?
Act for one user at a time, on the OAuth token they grant. Self-serve, no keys.
Reach all your connections from your backend. Partner-signed tokens over mTLS. Available today through a partner agreement.
Compare them in detail
Who does it act for?
One user at a time
All of your connections
How do you call it?
MCP tools today; REST on the user’s token is coming
REST endpoints
What do you use to authenticate?
An OAuth token the user granted
A partner-signed token over mTLS
How do you get set up?
Self-serve: your app registers itself, no keys
A partner agreement, then a tenant set up with us: signing keys, source-IP ranges
What you can reach. “Coming” in the Connection API column means calling it with a user’s OAuth token. To reach document downloads and connection events today, use the Partner API.
Records
✓
✓
Document downloads
Coming
✓
Connection events
Coming
✓
Messaging
Coming
Coming
This page covers the Partner API. For the Connection API, see the developer docs.
Integration guide for the AllClear Partner APIs: real-time event notifications, patient data, and health record access. This is the canonical source; Confluence links here rather than duplicating content.
A machine-readable OpenAPI 3.1 spec for the request/response endpoints is in openapi.yaml.
Getting Started
All Partner APIs are served from a single base URL:
The integration follows one flow: you register a tenant with us (Configuration), we notify your endpoint when events occur (Events API), and you call back to fetch the full data (Patient API and Patient Records API). Every request you make to us carries a signed JWT (Authentication); production tenants must also use mTLS and call from allowlisted IPs (Security and mTLS).
Sandbox vs production
Production and sandbox are distinguished by your client ID, not by a separate host, both use the same base URL above.
A
sandbox-*client is for testing: it is unrestricted (no mTLS or source-IP requirements) and may connect with or without a client certificate.A
prod-*client is your live tenant: mTLS public-key pinning and the source-IP allowlist are enforced.
Build against your sandbox client first, then switch to your production client for go-live.
How a connection is created
Everything you receive is scoped to a connection: a link between one AllClear user and you (the relying party), authorized by that user. A connection is created in one of two ways:
The user connects to you. The user finds you in AllClear and authorizes the connection.
You invite the user. You send an invitation and the user accepts it.
The user’s consent at connection time determines which events we send you and which scopes you hold (for example whether record.added events and the Patient Records API are available, see records:read). A user can withdraw consent at any time, which disconnects the connection and stops further events.
Quickstart
The shortest path to a working end-to-end integration:
Configure your sandbox client. Submit your configuration (endpoint URL, mTLS/JWT public keys). We return your
sandbox-*client ID.Stand up your notification endpoint. Accept
POST, verify the notification JWT, durably store the notification, and only then return200within 5 seconds.Connect a test user to your sandbox client (see Testing in sandbox) so events are generated.
Receive a notification and, asynchronously, call
GET /events/{id}with a Client Access Token to fetch the full event.Follow the event. For a
connection.connectedwithrecords:read, list the patient’s records withGET /patients/{id}/recordsand download one viaGET /patients/{id}/records/{recordId}.Go live. Repeat against your
prod-*client, this time over mTLS from an allowlisted IP (Security and mTLS).
Testing in sandbox
Patient and Records APIs return mock data for any ID in sandbox, so you can develop against them without a real connection.
Events are real for sandbox: to exercise the notification flow, connect a test user to your sandbox client (the same way a connection is created in production, see How a connection is created). Connecting, updating, or disconnecting that user, and records arriving for them, generate the corresponding events. Only events can return
404in sandbox, if you request an event ID that was never issued.
Sandbox exposes no real data. Everything you receive in sandbox is synthetic. You will never see real PII, and no identifier in a sandbox payload maps back to a real patient. Real events are anonymized before they reach a sandbox client: the demographic fields are replaced with fixed placeholder values, and every real patient and record ID (including inside portal_link) is swapped for a synthetic one. The synthetic IDs are deterministic and easy to recognize:
Identifier
Sandbox value
Patient ID
00000000-0000-8000-face-000000000001
Record ID
00000000-0000-8000-f11e-0000000000NN (NN = 1-based record index)
Because they are fixed, do not treat a sandbox ID as unique per user; use sandbox only to validate your integration mechanics, not to model real data volumes.
Configuration
To start using the Partner APIs, provide your configuration details and cryptographic keys in a structured JSON format.
Required Parameters
General
Name
Type
Format
Required
Description
client_id
string
Max length: 256 chars
Always
Unique identifier for your tenant. Must start with prod- (production) or sandbox- (non-production).
Outbound, We Call You (Events API only)
Name
Type
Format
Required
Description
outbound.endpoints
array
—
Always
Publicly accessible HTTPS endpoints where we send event notifications.
outbound.endpoints[].url
string
uri, max length: 2048
Always
The HTTPS URL for event notifications.
Inbound, You Call Us
Name
Type
Format
Required
Description
inbound.jwt_sig_keys
object
JWKS
Always
Your JWT public keys in JWKS format. We use these to verify API requests you sign. RSA keys must be at least 3072 bits long.
inbound.allowed_cidrs
array
IPv4/IPv6 CIDRs
Production only
The CIDR ranges you send API requests from (a single host is /32 for IPv4, /128 for IPv6). We only accept requests from these ranges.
inbound.mtls_client_keys
array
base64 strings
Production only
Base64-encoded DER public key from your mTLS client certificate. Used for mutual TLS authentication. RSA keys must be at least 3072 bits long.
Public Keys
You need two distinct public keys:
Key
Required
Used For
mTLS Client Key
Production tenants
Authenticating your mTLS connections when you call our API.
JWT Signing Key
Always
Verifying JWTs you sign when making API requests.
Caution: Do NOT include private keys. Each key must be unique.
Generating Keys
Create a Private Key
Extract Your mTLS Client Certificate
Use this in inbound.mtls_client_keys.
Convert JWT Private Key to JWKS
Use this output in inbound.jwt_sig_keys.
Full Configuration Example
Once you have extracted all public keys, structure them as follows and send this payload to us:
With Events API
Without Events API
Checklist Before Submission
All keys are unique and correct:
mTLS Client Key ->
inbound.mtls_client_keysJWT Signing Key (JWKS) ->
inbound.jwt_sig_keys
All fields adhere to max length constraints:
client_id-> 256 charsoutbound.endpoints[].url-> 2048 chars
Public keys are in the correct format:
Base64 DER for the mTLS client key
JWKS for the JWT key
Send the JSON file via Slack or email to our integration team. We’ll verify and confirm or provide guidance.
Authentication
All API requests from partners to AllClear must be authenticated using a client-signed JWT bearer access token (Client Access Token), provided in the Authorization header.
Client Access Token Format
JWT Payload
A Client Access Token must include the following claims:
Field
Required
Type
Format
Description
htu
Yes
string
base64url (SHA-256)
Base64url-encoded SHA-256 hash of the full request URI you are about to call. Ensures the JWT is valid only for that specific URI.
htm
Yes
string
base64url (SHA-256)
Base64url-encoded SHA-256 hash of the HTTP method in uppercase (e.g., GET, POST). Ensures the JWT is valid only for that request method.
iss
Yes
string
Max length: 256 chars
Issuer: must be the client ID of the requesting partner (e.g., prod-acme).
aud
Yes
string
Fixed: "partner.healthbankone.com"
Audience: must always be "partner.healthbankone.com".
iat
Yes
integer
int64 (Unix timestamp)
“Issued at” timestamp in Unix time (seconds since epoch).
nbf
Yes
integer
int64 (Unix timestamp)
“Not before” timestamp. Minimum value: 5 min before iat. Ensure your system clock is synchronized.
exp
Yes
integer
int64 (Unix timestamp)
Expiration timestamp. Maximum value: 5 min after iat. Ensure your system clock is synchronized.
jti
Yes
string
uuid
Unique identifier for the JWT to prevent replay attacks.
Computing htu and htm
JWT Signature
The Client Access Token must be signed using RS256 (unless otherwise agreed). AllClear will verify the signature using the partner’s public key identified by the kid value in the token’s header.
JWT Header
Field
Type
Format
Description
typ
string
Fixed: "JWT"
Token type. Always "JWT".
kid
string
Max length: 255 chars
ID of the key used for signature verification. Must match a key in your JWKS.
Security and mTLS
Production tenants require additional security measures beyond JWT authentication. These requirements apply to requests you make to our APIs. Receiving event notifications from us carries no additional requirements (see the last section).
mTLS (Mutual TLS) with Public-Key Pinning
When making requests to our APIs, you must authenticate using mutual TLS (mTLS). Both the client and server present a certificate during the TLS handshake. Your client certificate does not need to be issued by a public or trusted Certificate Authority. A self-signed certificate is fine. What matters is the public key it carries: we accept your requests only if the certificate presents the public key you registered with us. See public-key pinning below.
We enforce public-key pinning as part of mTLS, we will only accept requests whose client certificate contains a public key associated with your client ID. We pin the public key itself, not the certificate, so a renewed certificate carrying the same key is accepted without any coordination.
Public-Key Pinning Mechanics (your mTLS client certificate)
You can renew or replace your client certificate at any time without coordination, as long as its public key remains the same.
To rotate your key (change the public key itself), you must send us the new public key first so we can pin it alongside the existing one for a seamless transition, after which the old key is removed.
Static IPs
We only accept requests from your predefined static IP addresses. Any request from an unknown IP will be rejected. Send us the IP address ranges your requests will originate from before your production tenant is enabled.
Event Notification Delivery (outbound)
When we deliver event notifications to your endpoint there are no additional requirements on your side:
We connect over standard TLS to the endpoint hostname you provide: your endpoint’s certificate is validated against trusted CAs and its hostname is verified. We do not pin your endpoint’s certificate key and do not require a static IP on your endpoint: managed certificates (for example AWS ACM or Let’s Encrypt) and dynamic-IP hosting (for example AWS API Gateway) are fine.
Each notification is a JWT signed by AllClear containing only an event ID and event type: no patient data. Verify its signature against our published key to confirm it genuinely came from us, then fetch the event through the Events API.
Events API
The Events API delivers real-time event notifications by sending HTTP POST requests to your endpoints when designated events occur, connections, updates, disconnections, and new health records.
Notification Flow
Notification received: Your public endpoint receives an HTTP POST containing only the event type and event ID.
Verify the notification: The notification is a signed JWT. Verify its signature and claims. A notification that fails verification is not from AllClear, reject it and do not process it.
Persist the notification to durable storage: Write the notification (its event type and event ID) to a queue or other persistent store. This is the step that makes the event recoverable, so it must succeed before you acknowledge. If it fails, do not acknowledge (see step 4).
Acknowledge with
200 OKwithin 5 seconds: Return200 OKonly once the notification is safely stored. The200confirms receipt, not that you have finished processing, and it stops our retries: if you acknowledge before the notification is durably stored and then lose it, we will not redeliver it. If you cannot store it, do not return200, let the delivery fail so we retry (see Retry Strategy).De-duplicate by event ID: We may deliver the same event more than once. Skip event IDs you have already stored or processed.
Request full event data (asynchronously): Working off your stored queue, send an authenticated
GET /events/{id}request with the event ID. AllClear responds with the full event payload as JSON.Process the event: Process according to your business logic. If your fetch or processing fails, retry on your side from the stored notification; the event is safe because you persisted it before acknowledging.
The order is persist, then acknowledge, then fetch and process asynchronously. Never fetch or process before you acknowledge, and never acknowledge before the notification is durably stored. The 5-second window is for the acknowledgement of a stored notification, not for processing.
Receiving Event Notifications
Your endpoint receives an HTTP POST with a signed JWT body:
Header
Value
Description
Content-Type
application/jwt
The request body is a JWT.
Notification JWT Format
Note: Event notifications contain only the event type and id. Full event data must be retrieved by calling GET /events/{id}.
Field
Type
Format
Description
type
string
Fixed: "event_notification"
Always "event_notification".
event.type
string
Max length: 255 chars
Event type, e.g., "connection.connected".
event.id
string
uuid
Unique identifier of the event. Use for de-duplication.
iss
string
Fixed: "partner.healthbankone.com"
Issuer. Always "partner.healthbankone.com".
aud
string
Max length: 255 chars
Intended recipient (your client ID).
iat
integer
int64 (Unix timestamp)
“Issued at” timestamp.
nbf
integer
int64 (Unix timestamp)
“Not before” timestamp.
exp
integer
int64 (Unix timestamp)
Expiration timestamp (5 minutes after iat).
jti
string
uuid
Unique JWT identifier for replay prevention.
Notification JWT Header
The JWT is signed using RS256 and can be verified using AllClear’s public key identified by kid.
Validating Event Notifications
Validate the JWT header:
algequals"RS256"(or a pre-agreed algorithm).kidis the identifier of AllClear’s signing key.
Verify the JWT signature using AllClear’s key identified by
kid.Validate the JWT metadata:
issis exactly"partner.healthbankone.com".audmatches your client ID.nbfis in the past (allow margin for clock skew).expis in the future (allow margin for clock skew).
Fetch our public signing keys from our JWKS endpoint and select the one whose kid matches the token header:
This endpoint is public: it is not subject to mTLS or source-IP restrictions, so your webhook receiver can fetch it from any host, including sandbox.
We recommend the jose library’s createRemoteJWKSet, which fetches and caches the key set across warm invocations and refreshes automatically when we rotate keys, so you should not store or cache our keys yourself:
If verification fails, do not process the notification: a notification that does not verify was not sent by AllClear. Do not fetch the event and do not acknowledge it as a genuine event.
Requesting Full Event Data
See Authentication for how to build the Client Access Token.
Example Response
Error Responses
Status
Description
401 Unauthorized
Invalid or missing Client Access Token (see Errors).
404 Not Found
No event with that ID for your client (in sandbox, also if the ID was never issued).
500 Internal Server Error
Unexpected server error.
See Errors for the response bodies.
Acknowledging Event Notifications
Respond with HTTP 200 OK within 5 seconds, but only after you have durably stored the notification. The acknowledgement confirms receipt only, it does not mean you have finished processing the event, and because it stops our retries the durable write is its precondition: verify the notification, write it (its event type and ID) to a queue or other persistent store, and only then return 200. Fetch the full event and process it asynchronously off that stored record (see Notification Flow). If you cannot store the notification, do not return 200, let the delivery fail so we retry.
The following scenarios constitute a delivery failure:
We cannot negotiate or validate your server’s SSL certificate.
Your domain resolves to a disallowed IP address range.
We receive any response other than HTTP 200 OK.
We wait longer than 5 seconds for a response.
Tip: The order is durable-store, then 200, then fetch and process on a background worker. Never fetch GET /events/{id} or run business logic before acknowledging, and never acknowledge before the notification is safely stored, so neither processing latency nor a crash mid-processing can cost you an event.
Retry Strategy
If a delivery fails, we retry up to 5 times total, with the delays growing between attempts: 30 seconds, then 1, 2, 4, and 8 minutes (about 15.5 minutes across all attempts). We may add jitter to prevent retry storms and throttle notifications during high failure rates.
Upon consistent failures, we may disable event delivery and will notify you ahead of time.
Event Ordering
We try to deliver related events in order, connection.connected before record.added for the same patient. Occasionally events may arrive out of order.
To maintain order on your side, persist events in order-preserving storage as you acknowledge them, and have your background worker process them in received order rather than concurrently. Because you acknowledge before processing, ordering is your responsibility once the event is persisted.
See Event Types for detailed payloads of each event.
Replay and Backfill
If you miss events (for example an outage on your side that outlasts our retry window), we can replay or backfill them. This is currently a manual process coordinated with our operations team: contact us with the affected connection and time range and we will re-deliver. Automated self-service replay is on the roadmap.
Because notifications may be redelivered, your handler must be idempotent: de-duplicate by event ID (see Notification Flow).
Event Types
Data Model
A Connection links you (the partner) to a Patient and carries the permissions that gate access; a Patient belongs to a User (one user can hold several patients). Connection events describe changes to the connection; record.added signals new Records.
Connection Events
Event
Description
connection.connected
A new connection between you and a patient is established.
connection.updated
Connection attributes (e.g., permissions) are updated.
connection.disconnected
The connection is fully terminated.
Record Events
Event
Description
record.added
New medical records are added for a connected patient.
connection.connected
Triggered when a new connection between you and a patient is established.
If records:read is not included in permissions, you will not have access to the patient’s records or receive record-related event notifications.
With records:read
Without records:read
Fields
Field
Type
Format
Description
type
string
Max length: 255 chars
connection.connected, a new connection has been established.
timestamp
string
date-time (ISO 8601, UTC)
When the event occurred. Example: "2025-01-24T10:30:00Z".
id
string
uuid
Unique identifier of the event.
patient.id
string
uuid
Unique identifier of the patient (only present when records:read is granted).
patient.first_name
string
Max length: 100 chars
Patient’s first name.
patient.last_name
string
Max length: 100 chars
Patient’s last name.
patient.gender
string
enum: ("Male", "Female", "Other")
Patient’s gender.
patient.date_of_birth
string
date (ISO 8601), pattern: "^\d{4}-\d{2}-\d{2}$"
Patient’s birthdate (YYYY-MM-DD).
patient.email
string
email, max length: 200 chars
Patient’s email address.
patient.mobile_phone
string
E.164, pattern: ^\+?[1-9]\d{1,14}$, max length: 16
Patient’s mobile phone number in E.164 format.
patient.address
object
—
Patient’s address containing street1, street2, city, state, and zip.
patient.address.street1
string
Max length: 200 chars
First line of the patient’s address.
patient.address.street2
string
Max length: 100 chars
Second line of the patient’s address (optional).
patient.address.city
string
Max length: 100 chars
City of residence.
patient.address.state
string
pattern: "^[A-Z]{2}$", max length: 2
U.S. state abbreviation (e.g., CA, NY).
patient.address.zip
string
pattern: "^\d{5}$", max length: 5
ZIP code (U.S. format).
permissions
array
Items: string (enum: records:read, records:add)
Permissions the user granted. records:read allows retrieving records via the Patient Records API. records:add is a consent scope for records being added to the patient’s account on their behalf; it is not backed by a partner write endpoint (records are added by third parties through AllClear, see Patient Records API). If records:read is not included, the partner will not have access to records or receive related notifications.
portal_link
string
uri, max length: 2048
Direct URL to view this connection in the partner portal (within healthbankone.com).
promo_code
string
Max length: 32 chars
Reference data from connection creation (optional, may be absent). Contains the promo code if one was used.
connection.updated
Same structure as connection.connected (with and without records:read), but type is "connection.updated".
This fires whenever connection attributes change, including permissions being added or removed. If records:read is removed you lose access to the patient’s records and stop receiving record-related event notifications; if it is added, access begins.
connection.disconnected
Triggered when a connection is fully terminated (by either the patient or the partner). You lose access to the patient’s records and stop receiving any event notifications about this patient.
Field
Type
Format
Description
type
string
Max length: 255 chars
connection.disconnected, the connection has been terminated.
string
date-time (ISO 8601, UTC)
When the event occurred. Example: "2025-01-24T10:30:00Z".
id
string
uuid
Unique identifier of the event.
patient_id
string
uuid
Unique identifier of the patient.
portal_link
string
uri, max length: 2048
Direct URL to view this connection in the partner portal.
promo_code
string
Max length: 32 chars
Reference data from connection creation (optional, may be absent).
record.added
Triggered when new medical records are added and available for a connected patient.
Field
Type
Format
Description
type
string
Max length: 255 chars
record.added, a new record has been added to the patient’s file.
timestamp
string
date-time (ISO 8601, UTC)
When the event occurred. Example: "2025-01-24T10:30:00Z".
id
string
uuid
Unique identifier of the event.
records
array
—
The new records.
records[].portal_link
string
uri, max length: 2048
Direct URL to view the record in the partner portal.
Patient API
The Patient API allows you to fetch demographic and insurance information about connected patients.
Request
See Authentication for how to build the Client Access Token.
Response
Field Descriptions
Patient
Field
Type
Format
Description
id
string
uuid
Unique identifier of the patient.
first_name
string
Max length: 100 chars
Patient’s first name.
last_name
string
Max length: 100 chars
Patient’s last name.
gender
string
enum: "Male", "Female", "Other"
Patient’s gender.
date_of_birth
string
date (ISO 8601), pattern: "^\d{4}-\d{2}-\d{2}$"
Patient’s birthdate in ISO 8601 format (YYYY-MM-DD).
email
string
email, max length: 200 chars
Patient’s email address.
mobile_phone
string
E.164, pattern: ^\+?[1-9]\d{1,14}$, max length: 16
Patient’s mobile phone number in E.164 format. Example: "+15551234567".
Address
Field
Type
Format
Description
address.street1
string
Max length: 200 chars
First line of the address.
address.street2
string
Max length: 100 chars
Second line of the address (optional).
address.city
string
Max length: 100 chars
City of residence.
address.state
string
pattern: "^[A-Z]{2}$", max length: 2
U.S. state abbreviation (e.g., CA, NY).
address.zip
string
pattern: "^\d{5}$", max length: 5
ZIP code (U.S. format).
Insurance
Both primary_insurance and secondary_insurance are optional: they may be absent from the response.
Field
Type
Format
Description
health_insurance_provider
string
Max length: 200 chars
Name of the insurance provider.
member_id_number
string
Max length: 100 chars
Member ID number.
group_number
string
Max length: 100 chars
Group number (optional, may be absent).
member_name
string
Max length: 200 chars
Name of the member on the plan.
insurance_plans
array
Items: string
List of insurance plan names.
Patient Records API
The Patient Records API allows you to list and download health records for connected patients.
This API is read-only for partners: there is no endpoint to add or upload records. Records are added to a patient’s account when third parties provide them to AllClear; when a new record becomes available for a connected patient (and you hold records:read), you are notified with a record.added event.
List All Records
See Authentication for how to build the Client Access Token.
Returns all of the patient’s records as a flat JSON array in a single response. There is no pagination and there are no query parameters. A patient with no records returns 200 with an empty array ([]).
Response
Field
Type
Format
Description
id
string
uuid
Unique identifier of the record. Use it to fetch the full record with download URL.
file_name
string
Max length: 100 chars
Name of the file.
file_type
string
enum
One of: ccda, image, pdf, dicom, zip, text, bin
Get a Specific Record
Response
Field
Type
Format
Description
id
string
uuid
Unique identifier of the record.
file_name
string
Max length: 100 chars
Name of the file.
file_type
string
enum
One of: ccda, image, pdf, dicom, zip, text, bin
download
object
—
Metadata for downloading the record.
download.url
string
Max length: 2048 chars
Pre-signed download URL. Already includes authorization: no extra auth needed, and no mTLS or source-IP restriction. Valid until download.expires_at (5 minutes).
download.expires_at
string
ISO 8601 datetime
When the download URL expires. Example: "2025-09-08T13:38:25.419Z".
Errors
Every error carries an HTTP status and a JSON body. There are two body shapes: authentication failures use a flat { status, message }, and all other errors use the standard error envelope below.
Authentication failures (401)
A request that fails authentication is rejected with HTTP 401 and a flat body:
The message states the specific reason. Common causes:
Cause
What to check
JWT invalid or expired
nbf/exp are within 5 minutes of iat; htu/htm match the exact request URL and method; signed RS256 by a key in your JWKS (the header kid matches).
mTLS key not recognized (production)
Your client certificate must present the public key you registered in inbound.mtls_client_keys. A self-signed certificate is fine; we pin the key, not the certificate.
Source IP not allowlisted (production)
The request must originate from a CIDR listed in inbound.allowed_cidrs.
Sandbox clients skip the mTLS and source-IP checks.
Error envelope (403, 404, and other errors)
All other errors return the standard envelope:
Field
Description
error.code
Machine-readable code, for example FORBIDDEN, NOT_FOUND.
error.message
Human-readable description.
error.requestId
Identifier for this request. Include it when contacting support.
error.correlationId
Present when the request crossed internal services; include it too if present.
error.details
Optional array with field-level specifics when applicable.
Status
code
When
403
FORBIDDEN
You are authenticated, but not permitted to access this resource (for example a patient or record outside your consent). message is "Access Denied".
404
NOT_FOUND
The event, patient, or record does not exist (or, in sandbox, the event ID was never issued).
There are currently no request rate limits on the Partner APIs; you will not receive 429. This may change in future, in which case it will be announced ahead of time and documented here.
Versioning and Deprecation
Additive changes are backward-compatible and ship without a version bump. We may add new fields to responses and new event
typevalues at any time. Build tolerantly: ignore fields you do not recognize, and ignore event types you do not handle rather than failing on them.Breaking changes are introduced as a new version and announced in advance. The previous version continues to work for a deprecation window of 6 months from the announcement, so you have time to migrate.
All changes are recorded in the Changelog and announced over Slack or email.
Onboarding and Support
We assign your client IDs. You do not choose them. On onboarding we issue a sandbox-* client ID and, for go-live, a prod-* client ID.
Configuration lifecycle:
You submit your configuration JSON (endpoint URL, public keys) to the integration team.
We validate it and provision your sandbox client.
You build and test against sandbox.
You submit your production configuration; we provision your prod client with mTLS and source-IP enforcement.
You go live.
To change configuration later (rotate keys, add or remove allowed_cidrs, change your endpoint URL), submit an updated JSON to the integration team, the same way. We do not expose a self-service configuration endpoint today.
Need Help?
If you run into any issues, we’ll treat it as our top priority. Message us on Slack or email, we’ll jump in quickly to keep you moving.
We love hearing from partners, and we treat every request as a chance to make your integration smoother.
Changelog
Release Date
Changes
2026-09-16
Clarified the notification flow: acknowledge receipt with 200 within 5 seconds, then fetch and process the event asynchronously. Reworked the errors section (401 {status,message}, error envelope for 403/404) and removed rate-limit references (none are configured). Documented that /.well-known/jwks.json is public. Added Quickstart, connection creation, sandbox testing, event replay/backfill, versioning/deprecation, and onboarding/support sections. Added a machine-readable openapi.yaml.
2026-09-15
Renamed inbound.allowed_ips to inbound.allowed_cidrs. Added the 3072-bit RSA minimum to the mTLS client-key field (the JWT signing-key field already stated it). Clarified that mTLS uses public-key pinning: a self-signed client certificate is accepted, and the certificate does not need to be issued by a trusted CA.
2025-09-17
Updated event data format (no longer wrapped into JWE+JWS). Clarified payload structure and order guarantees. Added Patient API and Patient Records API.
2025-04-29
Defined encrypted (JWE) and signed (JWS) event wrapping. Added a sequence diagram and restructured to follow flow steps. Added htu/htm example code.
2025-02-10
Changed phone number format to E.164. Removed timestamp from event notifications. Specified delivery semantics, order, and retry nuances.
2025-01-31
Initial version.