For patient-authorized SMART apps and practice-authorized population access, read the SMART on FHIR guide. Complete record downloads use the EHI export format.
ChartVoyant for developers
Build on the chart.
ChartVoyant exposes a tenant-scoped REST API over the same contract layer the product itself runs on, and an MCP server so an AI agent can work the chart with the same key. Lab feeds, imaging networks, population-health platforms, a practice's own internal tools — if your system needs to read or write a chart, it does it with an API key over HTTPS.
Who this is for
The API exists so a practice's data can move where the practice needs it to — without anyone screen-scraping a chart or emailing a spreadsheet.
Lab & imaging feeds
Deliver results into the ordering provider's chart instead of a fax queue, and read back the orders that produced them.
Network & population analytics
A clinically integrated network pulling quality measures, utilization, and roster data across its member practices.
A practice's own tools
Internal dashboards, an intake site, a reporting job — anything a practice or its IT vendor wants to build against its own data.
Migration & sync
Moving records in from a prior system, or keeping a downstream registry current on a schedule.
Two ways in
Start in the sandbox — it takes an email and no paperwork. Production is where real charts live, so it carries real obligations.
Build against synthetic data
https://demo.chartvoyant.com/api/v1
- Your own key, issued to anyone who asks. Not shared with other developers.
- Full read and write, so you can actually exercise the integration you're building.
- Entirely synthetic patients on a separate stack. No PHI, no BAA, no signature.
- The MCP server at
/api/v1/mcptakes the same key, so you can try an AI agent on synthetic charts first. - Accept the Sandbox Terms in your request email. That's the whole gate.
Connect to a live practice
https://chartvoyant.com/api/v1
- Bound to one practice, at an access level and expiry set when it's issued.
- The same key works at the MCP endpoint,
/api/v1/mcp. - The practice has to confirm the request. It's their data, not ours to hand out.
- A signed API Use Agreement on file before the key is issued.
- A business associate agreement between you and the practice.
How an API key works
One credential format, everywhere. A key is a bearer token you send over TLS — there is no OAuth dance and no refresh cycle to implement.
Anatomy of a ChartVoyant key. The prefix identifies which key you are; the secret proves you hold it.
- One key, one practice — always. The key is the tenant. There is no cross-office key, no account switching, and no header you can send to reach a different practice's data. A key that could straddle two offices would be a way around every other control in the system, so it doesn't exist.
- The prefix is public; the secret is not. Quote the prefix in a support email so we can find your key. Never send the full token to anyone, including us.
- Two access levels.
read_onlypermits safe methods only — aPOST,PUT,PATCHorDELETEis refused with a 403 that says so.fullpermits reads and writes. Ask for the lower one unless you genuinely write. The one place a read-only key mayPOSTis the MCP endpoint, where every call is a POST: there it can call the read tools, and the write tools are refused. - Keys expire on purpose. Every key is issued with an expiry — 90 days by default. Expiry is a feature, not an obstacle: it bounds the damage of a credential nobody remembers issuing. Ask for a longer term if your integration needs one.
- Revocation is immediate. A revoked key stops authenticating on the next request. There is no grace period and no soft-delete window.
- Every request is logged to the key. Method, route, status, source IP, correlation ID and duration — including refusals, which are the interesting rows. We don't log your query strings, request bodies or response payloads into that trail; PHI access belongs in the practice's audit log, and that's where it goes.
Quickstart
Send the key as a bearer token. That's the entire authentication story.
Request
# Sandbox — synthetic patients, safe to poke at curl https://demo.chartvoyant.com/api/v1/patients?limit=5 \ -H "Authorization: Bearer $CHARTVOYANT_API_KEY" \ -H "X-Purpose: operations"
Response
{
"data": [
{
"id": "0f2c…",
"mrn": "MRN-100482",
"name": { "family": "Alvarez", "given": ["Marisol"] },
"birthDate": "1974-03-11"
}
],
"page": { "limit": 5, "offset": 0, "hasMore": true }
}
Headers
| Header | Required | What it does |
|---|---|---|
| Authorization | Yes | Bearer cvk_… — your full key. Sent on every request; there is no session to establish first. |
| X-Purpose | No | Purpose-of-use recorded on the practice's audit event for this request. Defaults to operations. Set it honestly — it's what an auditor reads. |
| Content-Type | On writes | application/json. |
Server-side only
A ChartVoyant key belongs on a server you control. Never ship one in a browser bundle, a mobile app, a desktop client, or anything else a user can open — a key in client-side code is a key in public, and it carries the access level of the practice it's bound to.
New Live October 7, 2026
The MCP server: an AI agent on the chart
ChartVoyant runs a Model Context Protocol server. Point Claude Code, or any MCP client that can send a header, at it with your API key, and the agent can look up patients, read the chart, work the schedule and the inbox — bound to the same office, at the same access level, on the same audit trail as every other call.
| Environment | MCP endpoint |
|---|---|
| Sandbox — synthetic patients | https://demo.chartvoyant.com/api/v1/mcp |
| Production — a live practice | https://chartvoyant.com/api/v1/mcp |
- The same key, the same rules. Send
Authorization: Bearer cvk_…on every request. There is no OAuth flow, no session and nothing to refresh, and the agent sees only the one office the key is bound to. - The access level decides the tools. A read-only key gets the read tools only. A full-access key adds booking, rescheduling and cancelling visits, the waitlist, and inbox tasks. A read-only key that tries a write gets a refusal that says so.
- Every call is on the record. Each tool call writes an event to the practice's audit log under your key, and the key's activity trail names the method and the tool. Arguments and results stay out of both.
- Streamable HTTP, stateless. One JSON-RPC message per POST, answered with one JSON response. MCP 2026-07-28, plus 2025-11-25, 2025-06-18 and 2025-03-26 for clients that still open with
initialize. The rate limits below apply as they do to the REST API.
Connect a client
Claude Code
claude mcp add --transport http chartvoyant https://demo.chartvoyant.com/api/v1/mcp \ --header "Authorization: Bearer $CHARTVOYANT_API_KEY"
A config file (Claude Code's .mcp.json; other clients take the same url and headers)
{
"mcpServers": {
"chartvoyant": {
"type": "http",
"url": "https://demo.chartvoyant.com/api/v1/mcp",
"headers": { "Authorization": "Bearer ${CHARTVOYANT_API_KEY}" }
}
}
}
Any HTTP client
# List the tools this key can call
curl https://demo.chartvoyant.com/api/v1/mcp \
-H "Authorization: Bearer $CHARTVOYANT_API_KEY" \
-H "Content-Type: application/json" \
-H "MCP-Protocol-Version: 2025-11-25" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
Tools
| Who gets it | Tools |
|---|---|
| Every key | get_practice_contextsearch_patientsget_patient_overviewget_patient_chartget_observationslist_patient_notesread_noteget_procedure_planget_patient_action_noteget_schedulefind_free_slotslist_waitlistlist_casesget_caseget_fax_inboxlist_patient_orderslist_outbound_faxessearch_facilitiesget_patient_billingget_patient_billing_detaillist_claimsget_claimget_claim_ledgerget_billing_worklistlist_prior_authsget_prior_authlist_directorysearch_terminologyPractice context and today's date, patients and the chart, notes, vitals and labs, the procedure plan, the schedule and open slots, the waitlist, inbox tasks and the fax inbox, orders and outbound faxes, billing, claims and prior authorizations, the staff directory and code lookups. |
| Full-access keys add | book_appointmentreschedule_appointmentcancel_appointmentadd_to_waitlistcreate_patient_caseupdate_caselink_case_to_patientlog_action_noteScheduling and inbox work. Booking checks double-booking, closures and the practice's booking rules first, and reports a conflict instead of booking over it. |
| Never over MCP | Chart entries, notes, signatures, prescriptions and orders; faxes and patient messages; eligibility and claim-status checks; claims, payments and statements.A person does those in ChartVoyant. That is what keeps clinical decisions with a clinician. |
Before you connect a production key
The model sees the chart. MCP hands chart data to the AI model behind your client. With a production key that data is PHI, so the model provider has to be covered: a BAA with that provider that covers the specific product, plan and features you use — MCP, connector and tool traffic included, which some providers' healthcare plans exclude, so get it in writing — terms that keep the data out of training, and the practice's written approval. A consumer chat account is never covered. Until all three are in place, build on the sandbox.
The risk is yours, and it's in writing. A production key used with any AI agent needs version 1.1 of the API Use Agreement. Its §10 sets these conditions, and §§17–20 put the agent, its model provider and the data they receive on you: ChartVoyant's liability is limited, you indemnify ChartVoyant and the practice, and you carry cyber and errors-and-omissions insurance.
The key stays in your own client's configuration. An MCP client you run yourself, on a computer your organization manages or on your server, is somewhere you control. One key per person, kept in an environment variable or the system's credential store — never in a config file you share, sync or commit, never in an MCP client other people use, and never pasted into the chat itself. Protect or turn off the client's transcripts and telemetry; they hold chart data too.
Times are practice-local. Have the agent call get_practice_context first. A timestamp such as 2026-10-08T09:00:00.000Z means 9:00 AM at the practice — the Z does not mean UTC. Money is in integer cents.
Limits and errors
Rate limits
Budgets sit far above normal integration traffic — they exist to stop a runaway loop, not to meter you. Two windows apply at once: a per-second burst and a per-minute sustained rate, counted per key and again across the whole practice.
| Scope | Burst | Sustained |
|---|---|---|
| Per key | 150 requests / second | 3,600 requests / minute |
| Per practice (all keys and staff sessions combined) | 400 requests / second | 12,000 requests / minute |
Over budget returns 429 with a Retry-After header. Honor it and back off — hammering a 429 is grounds for revocation. If you need a bulk window for a migration or a nightly extract, tell us in advance rather than discovering the ceiling in production.
Need a higher limit? Email info@chartvoyant.com with the integration, the traffic it sends and the peak rate you need, and we'll raise the limit. There's no fee for a higher limit.
Status codes
| Code | Meaning |
|---|---|
| 400 | The request was malformed or failed validation. The message says what. |
| 401 | The key is unknown, revoked, expired, or the secret is wrong. We deliberately don't say which — an error that distinguishes those is a key-enumeration oracle. Check the token you sent. |
| 403 | Your key is valid but this is not allowed: a read-only key attempting a write, or any key touching a forbidden path. Unlike a 401, this one tells you which wall you hit, so you don't retry forever. |
| 404 | No such record in the practice this key is bound to. A record that exists at another office is a 404 here, not a 403. |
| 429 | Rate limited. Back off for Retry-After seconds. |
| 5xx | Our problem. Retry with backoff, and send us the correlation ID if it persists. |
Error shape
Every error is the same envelope. Log the correlationId — it's the single fastest way for us to find your request, and it joins your call to the practice's audit trail.
{
"error": {
"code": "forbidden",
"message": "This API key is read-only; POST is not permitted",
"correlationId": "01J8ZC…"
}
}
What a key can never reach
These refusals are structural, not configurable. No access level unlocks them, and asking us nicely won't either — they're the privilege-escalation ladders, and a machine credential that could climb one isn't a machine credential.
Probing them isn't subtle, either. A refused request is a row in your key's activity trail with the reason attached, and a key that keeps knocking on those doors gets a phone call before it gets a second chance.
API key usage policy
These terms apply to every key we issue. For production keys they're the substance of the API Use Agreement you sign; for sandbox keys the shorter Sandbox Terms below apply.
- One key per integration. Never shared.
A key identifies a system, not a company. Two integrations get two keys, so one can be revoked without breaking the other and the activity trail means something. Don't pass your key to a subcontractor, a sister product, or another practice.
- Server-side only, with one exception.
Keys live on infrastructure you control. Not in browser JavaScript, not in a mobile or desktop app you ship, not in a CLI you distribute — anywhere an end user could extract it. The one exception is an MCP client run by the person the key was issued to, on a computer your organization manages; item 14 sets the rules.
- Store it like a database password.
A secrets manager or an encrypted store. Not in source control, not in a container image, not in a CI log, not in a screenshot, not pasted into a support ticket or a chat window — and not into an AI assistant's transcript, which is a persisted copy of your credential in someone else's system.
- Request the least access that does the job.
Read-only unless you write. If your integration writes to two endpoints and reads twenty, say so — we'd rather scope the key correctly than issue a broad one and hope.
- Minimum necessary.
Pull the records and fields the integration actually needs. A nightly full-table sweep to support a feature that touches fifty patients is not minimum necessary, and it's the pattern that turns a small breach into a large one.
- Don't build a shadow chart.
Cache what you need to do the job, for as long as the job takes. Standing up a permanent parallel copy of a practice's clinical record needs that practice's explicit written agreement — the API is an interface to their chart, not a license to replicate it.
- No secondary use.
Data reached with a ChartVoyant key is used to deliver the service the practice asked for. Not to train models, not to build a data product, not for research, not to enrich a marketing profile, and never sold or brokered — unless the practice has authorized that specific use in writing.
- Commercial products share profits.
If the API powers something you sell, thirty-five percent of the profits from it go to Geach Technologies, LLC, on the terms set in the API Use Agreement — including that the rate and terms can change on notice. If a profit share shapes whether your product works as a business, read that section before you build on us.
- Respect the rate limits.
Honor
429andRetry-Afterwith real backoff. Schedule bulk work off-hours and tell us before a migration or a large backfill. - Rotate on a schedule, and on turnover.
Ask for a new key before the current one expires, and whenever someone who had access to it leaves. Old key gets revoked; there's no reason to run two.
- Report exposure immediately.
A key in a public repo, a leaked log, a compromised host, a laptop gone missing — email info@chartvoyant.com with the key prefix and what happened. We revoke first and sort it out after. Telling us early is not the thing that gets a key pulled permanently; not telling us is.
- Keep your contact current.
We need a real technical contact who answers email. Expiry notices, incident notices, and breaking-change notices go there.
- Access can be revoked at any time.
ChartVoyant may suspend or revoke a key at any time, for any reason, without notice — a security incident, use outside these terms, or a request from the practice it's bound to are the common ones, but the right isn't limited to them. The practice can likewise revoke its own keys whenever it wants and doesn't owe you an explanation — it's their data. Build with that in mind.
- AI agents are your risk, not ours.
An MCP client hands what it reads to its AI model, so with a production key the model provider needs a BAA that covers the exact product and features you use — MCP, connector and tool traffic included, which some providers exclude even on healthcare plans — and no training on the data. Consumer accounts never qualify. One key per person or per agent, a managed computer for any client that holds a key, a person supervising the agent, and no clinical decisions made by it. The agent, its model provider and the data once ChartVoyant returns it are your responsibility, and ChartVoyant takes no liability for them. Production use needs version 1.1 of the API Use Agreement.
PHI, BAAs, and the paperwork
A production key returns protected health information. That is the point of it, and it's why the production path has gates the sandbox doesn't.
The practice is the covered entity. ChartVoyant is its business associate. When you integrate against a practice's data you become a business associate too, and you need a BAA with that practice before we issue a key. We'll ask you to confirm one is in place; we don't sign it for them.
The signed API Use Agreement comes to us. It's the policy above, as terms, with a signature block. Print it, sign it, and email it back — we keep it on file against the key in our admin console, so there's a record of who agreed to what, for which integration, on which date.
AI agents need version 1.1. If an agent will use a production key, the agreement asks you to name the agent and its model provider and to confirm the provider's BAA covers that use, and it puts the risk of the agent on you. If you signed version 1.0, sign 1.1 before you connect an agent.
Everything is audited on the practice's side. A key-authenticated read of a chart writes an audit event in that practice's own trail, tied to your key by correlation ID. The practice can see what your integration looked at. Build as though they're watching, because they can.
TLS only. Plain HTTP isn't served. Data is hosted in the United States.
How to get a key
Every request is read by a person. There's no self-serve signup, and that's deliberate — we'd rather know who's holding a credential to a medical record.
Sandbox — usually same day
- Email us
Send info@chartvoyant.com your company or project, what you're building, a technical contact, and a line accepting the Sandbox Terms below.
- We issue your key
Your own key, bound to the shared sandbox office, with read and write on synthetic patients. It arrives by email to the technical contact you named.
- Start building
Point at
https://demo.chartvoyant.com/api/v1and go. Ask for a fresh key whenever this one expires.
Production — a few days, mostly paperwork
- Tell us what you're connecting
Email info@chartvoyant.com with the practice, the integration, the data it needs, whether it writes, and a technical contact.
- The practice confirms
We check with the office that they asked for this. If you're the practice, that step is already done.
- Sign the API Use Agreement
Print the agreement, sign it, email the scan back. We file it against the key. Confirm your BAA with the practice is in place at the same time, and if an AI agent will use the key, name it and its model provider on the agreement.
- We issue the key
Bound to that one office, at the access level you asked for, with an expiry. Delivered to the named technical contact — never posted in a ticket or a chat.
- Verify, then go live
Make a call, confirm it lands in the key's activity trail, and you're connected. We watch the first days of a new integration more closely than the rest.
You'll hear back from a person
Usually within two business days. If you don't, email again — occasionally a request with an attachment gets filtered, and we'd rather get two than none.
Sandbox terms
Short, because the sandbox has no real patients in it. Accept these in your request email and you're done — no signature, no BAA.
- The sandbox contains synthetic data only. Never send real patient information to it — not a real name, not a real MRN, not a real date of birth, and not through an AI agent connected to it either. If you need to test with real data, you need a production key.
- Your sandbox key is yours. Don't publish it, share it, or commit it. Points 1 through 3 and 8 through 11 of the usage policy apply to it as written, and so do point 14's rules for the computer, the key and the agent. Point 14's BAA rule doesn't, because the sandbox holds no real patients.
- The sandbox is a development environment. It may be reset, reseeded, or taken down without notice, and it is not covered by any uptime commitment. Don't run anything you care about against it.
- Don't load-test it or use it to probe for vulnerabilities. If you find a security issue, we want to hear about it — email info@chartvoyant.com rather than digging further.
- Sandbox access is a courtesy, offered with no warranty and revocable at any time.
- Moving to production means the full API Use Agreement, a sponsoring practice, and a BAA. Nothing about your sandbox key carries over.
On the roadmap
Not built yet — listed so you can tell us if one of these is what you actually need. Saying so moves it up.
FHIR R4 facade
A standards-shaped read surface over the same data, for systems that already speak FHIR and would rather not learn our resource shapes.
MCP sign-in with OAuth
The MCP server is live and takes an API key. Next: an OAuth sign-in, so apps that only add servers through OAuth can connect without anyone handling a raw key.
Webhooks
Push instead of poll — a callback when a result posts, an appointment moves, or a note is signed.
Questions we get
Can I get a production key without a practice?
No. Every key is bound to one office, and that office has to want the integration. If you're building something practices would use and don't have one yet, take a sandbox key — it's the same API, and it's how you'd demo to them anyway.
What happens when my key expires?
It stops authenticating and every call returns 401. We email the technical contact on file before that happens, so keep it current. Ask for a replacement any time — we'd rather rotate you early than have an integration go dark at 2am.
Can I see what my key has been doing?
Ask us and we'll pull it. Every key-authenticated request is recorded with its method, route, status, source IP and duration, and the practice can see the same trail in their console. If your call count looks wrong to you, it'll look wrong to us in the same view.
Can I connect Claude, or another AI agent?
Yes — that is what the MCP server is for. Add https://demo.chartvoyant.com/api/v1/mcp to any MCP client that can send an Authorization header, with your key as the bearer token. The agent gets the tools your key's access level allows, and every call is audited under the key. Before a production key goes anywhere near a model, read what has to be in place first: a BAA with the model provider that covers MCP traffic (some don't), and version 1.1 of the API Use Agreement, which puts the risk of the agent on you.
Is there an OpenAPI spec?
Yes — an OpenAPI 3.1 description of the contract layer, which we'll send along with your key. It's the same document the product is built against, so it doesn't drift from reality.
Do you charge for API access?
Sandbox access is free, and nothing is metered per call. Production access for a practice's own operations is handled within that practice's subscription. A commercial product built on the API pays a profit share — 35% of profits to Geach Technologies, LLC, on the terms in the API Use Agreement — so price that in before you commit to a business model.
I found a security problem. Who do I tell?
Email info@chartvoyant.com with what you found and how to reproduce it. Please don't test it against a live practice, and please give us a chance to fix it before publishing. We'll acknowledge and keep you posted.
Start in the sandbox
Synthetic patients, read and write, your own key. One email and no paperwork — the fastest way to find out whether this API fits what you're building.