For healthtech developers
Onboard onto Graft
The payer connecting layer: check, document, submit, track through one JSON API. Graft maps FHIR, CDS Hooks, and payer protocols to a stable contract. This page is the path from zero to a working integration.
Your path
Same sequence in sandbox and Inferno. Only payer_id and session context change.
01
Sign in
Magic link opens a dashboard session.
02
Create sandbox key
Copy grft_sandbox_* once.
03
Try it out
Hit graft_sandbox from /try.
04
Wire your app
Same four calls from your backend.
05
Optional
Webhooks, update/cancel, Inferno.
06
Ship
Field reference lives in /docs.
Get access
- Sign in at usegraft.dev with a magic link (or
POST /auth/login). - Open /dashboard and create a sandbox key. Copy the
grft_sandbox_*value; it is shown once. - Export it in your shell:
export GRAFT_KEY=grft_sandbox_xxxxxxxxxxxxxxxxxxxxxxxxBase URL: https://api.usegraft.dev/v1. Header: Authorization: Bearer $GRAFT_KEY. Sandbox keys reach graft_sandbox and inferno. Live keys (grft_live_*) cannot call those payers.
What you can test
Two payers, one developer flow. Response shapes stay the same.
| IG | Graft call | graft_sandbox | inferno |
|---|---|---|---|
| CRD | POST /check | Simulated determination + check_id | Real CDS Hooks against CRD Client suite |
| DTR | GET /requirements | Generic questionnaire (simulated) | Live questionnaire package from Inferno |
| PAS | POST /submit · /auths/{id}/update|cancel · GET /status/{id} | Magic member_ids drive decisions + webhooks | Real Claim/$submit, update, cancel, notifications |
Sandbox outcomes are steered by magic member_id values. Full list: /docs#sandbox.
Inputs & where they come from
Values come from your EHR, eligibility, Inferno UI, or a prior Graft response.
- GRAFT_KEY header
- Sandbox API key from /dashboard after magic-link sign-in. Prefix grft_sandbox_. Shown once.
- payer_id body
- From GET /coverage. Start with graft_sandbox; use inferno for ONC suite traffic.
- member.* body
- From your EHR / eligibility response. Sandbox magic member_ids steer outcomes (see /docs#sandbox).
- service.* body
- From the clinical order: CPT/HCPCS, ICD-10 list, service date, optional place of service.
- provider.npi body
- Rendering provider NPI (Luhn-valid). Generate a test one at /docs#create-npi.
- check_id from response
- Returned by POST /check. Thread into requirements and submit.
- answers[] from questionnaire
- Built from GET /requirements items. Echo each link_id with the matching value_* field.
- Idempotency-Key header
- Any unique string you generate (UUID). Required on every POST /submit.
- auth_id from response
- Returned by POST /submit. Use with status, update, cancel, and chain.
- payer_context.*_session_id Inferno only
- Copied from the Inferno suite URL after you start a session. Register JWKS first.
How to use
Four core calls. Graft runs CRD / DTR / PAS inside them. Schemas and curl: /docs. Live sandbox: /try.
1 · POST /check
Ask if prior auth is required. Read
auth_required, keepcheck_id. details2 · GET /requirements
If auth is required, pull questionnaire
items[]and collect answers in your UI. details3 · POST /submit
File the PA with
check_id+answers. You generateIdempotency-Key(UUID). Keepauth_id. details4 · GET /status/{auth_id}
Poll Graft's decision and
history. Optional: register a webhook for push events. detailsOptional · update / cancel / chain
After submit, amend or cancel under
/auths. Each returns a newauth_id. Lineage:GET /auths/{id}/chain. details
Starter body for sandbox check (also on /try):
check.json (graft_sandbox)json
{
"payer_id": "graft_sandbox",
"hook": "sign",
"member": {
"first_name": "Ada",
"last_name": "Lovelace",
"member_id": "GRAFT-APPROVE-NOW",
"dob": "1985-12-10"
},
"service": {
"cpt": "72148",
"icd10": ["M54.16"],
"service_date": "2026-09-01",
"place_of_service": "11"
},
"provider": {
"npi": "1669613154"
}
}Inferno
Use payer_id: "inferno" for real ONC suite HTTP. Same Graft endpoints; pass session ids in payer_context. JWKS and field notes: /docs#inferno.
1. Start suite sessions
Open each suite, start a session, copy the alphanumeric id from the URL (segment after the suite name). Leave the target group RUNNING (waiting) before calling Graft.
- CRD
- https://inferno.healthit.gov/test-kits/davinci-crd
payer_context.crd_session_id· Graft:POST /check - DTR
- https://inferno.healthit.gov/test-kits/davinci-dtr
payer_context.dtr_session_id· Graft:GET /requirements - PAS
- https://inferno.healthit.gov/test-kits/davinci-pas
payer_context.pas_session_id· Graft:POST /submit · /auths/{id}/update|cancel
2. Register Graft JWKS
In each Inferno session's Client Registration, paste:
curl https://api.usegraft.dev/v1/inferno/jwks.json3. Call Graft with payer_id=inferno
Sample Inferno check bodyjson
{
"payer_id": "inferno",
"hook": "sign",
"payer_context": {
"crd_session_id": "Cd34Ef56",
"pas_session_id": "Ab12Cd34",
"dtr_session_id": "Ef56Gh78"
},
"member": {
"first_name": "Ada",
"last_name": "Lovelace",
"member_id": "W265689448",
"dob": "1985-12-10"
},
"service": {
"cpt": "72148",
"icd10": ["M54.5"],
"service_date": "2026-09-01",
"place_of_service": "11"
},
"provider": {
"npi": "1669613154"
}
}Then GET /requirements, POST /submit, GET /status/{id}, optional update/cancel under /auths. Stored payer_context on the check is reused unless you override it.
Webhooks
Register once; Graft POSTs signed events when decisions land. Store the whsec_* secret (returned once). Verify Graft-Signature before trusting a delivery. Verify snippet and event catalog: /docs#webhooks.
curl https://api.usegraft.dev/v1/webhook_endpoints \
--request POST \
--header "Authorization: Bearer $GRAFT_KEY" \
--header "Content-Type: application/json" \
--data '{
"url": "https://yourapp.example.com/webhooks/graft",
"subscribed_events": ["auth.approved", "auth.denied", "auth.modified", "auth.cancelled"]
}'Next steps
- Field-level reference: /docs
- Keys and analytics: /dashboard
- Test NPI generator: /docs#create-npi
- Payer discovery: GET /coverage