How to register your own ModMed FHIR app
Register a Bulk FHIR app with ModMed and connect it to Tenklo
This guide covers the one-time setup for ModMed's Certified FHIR API Bulk FHIR flow. You do this once for your whole application — every connection you create afterward (one per practice) reuses the same Client ID and key.
Bulk FHIR authenticates your application, not an individual end user — there's no OAuth redirect or login screen, and no client secret. ModMed verifies a JWT that Tenklo signs on your behalf (private_key_jwt), checking it against a public key you publish yourself. Tenklo signs with ES384, the algorithm ModMed confirms for this flow, so the private key you generate and give Tenklo must be an EC (P-384) key.
Register a Bulk FHIR app with ModMed
Go to Become a ModMed Certified FHIR API Vendor and click Register Now. When you configure your app, choose the Bulk FHIR app type — it gives practice-level access without per-user authentication.
Generate an EC (P-384) key pair:
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-384 -out privatekey.pem
openssl pkey -in privatekey.pem -pubout -out publickey.pemprivatekey.pem must start with -----BEGIN PRIVATE KEY----- (PKCS#8). Tenklo can't read a key that starts with -----BEGIN EC PRIVATE KEY-----, which is what openssl ecparam -genkey produces. To convert one, run openssl pkcs8 -topk8 -nocrypt -in old-key.pem -out privatekey.pem.
Keep privatekey.pem secret — you'll paste its contents into Tenklo in a later step. Never commit it to source control or share it outside Tenklo.
Host a JWKS file with your public key
Convert your public key to JWK format and publish it as a JWKS document at a stable, publicly reachable URL you control (e.g. https://your-domain.com/.well-known/modmed-jwks.json). Assign a unique kid (key ID) to the key entry — you'll need this exact value in Tenklo.
To get the x and y values, run:
node -e 'console.log(require("crypto").createPublicKey(require("fs").readFileSync("publickey.pem")).export({ format: "jwk" }))'Then add alg, use, and kid to build the JWKS document:
{
"keys": [
{
"kty": "EC",
"crv": "P-384",
"alg": "ES384",
"use": "sig",
"kid": "<your-key-id>",
"x": "<x-coordinate>",
"y": "<y-coordinate>"
}
]
}Register your JWKS URL with ModMed
In your app's configuration, register the JWKS URL from the previous step. Note the Client ID ModMed assigns your app and the system/*.rs scopes it's approved for — you'll need both for the next step, along with the kid you chose.
Enter your credentials in Tenklo
- In Tenklo, go to Integrations → your ModMed (FHIR) integration → Settings tab.
- Enter:
- Client ID — from the previous step
- Key ID — the
kidfrom your JWKS entry - Private Key — the full contents of
privatekey.pem, the EC (P-384) private key you generated in step 2. Tenklo signs withES384, so this must be a P-384 EC key — an RSA or P-256 key won't work. - Scope — the space-separated
system/*.rsscopes your app was approved for (e.g.system/Patient.rs system/Observation.rs). ModMed requires scope on every Bulk FHIR token request.
Each field saves as soon as you leave it. Every connection you create under this integration reuses these values automatically — you won't be asked for them again per practice.
Follow the connect guide to create a connection for your first practice.
For more details, see ModMed Certified FHIR API — Authentication.