API Keys
Every HANA integration uses API keys scoped to your organization and environment. Keys follow a predictable format so you can identify them quickly in logs:
hana_sk_live_... → Production key
hana_sk_test_... → Sandbox key
Never embed API keys in client-side code, mobile apps, or version control. Use environment variables or a secrets manager.
Key Permissions
Keys are scoped to one of three permission levels:
Scope Can Do Use Case full_accessAll operations Server-to-server integrations engagements_onlyCreate/read engagements, receive webhooks Limited integrations read_onlyRead engagements, patients, metrics Dashboards, reporting
Creating Keys
Keys are provisioned during partner onboarding. To manage keys:
# List active keys
GET /v1/auth/keys
# Rotate a key (old key remains valid for 24 hours)
POST /v1/auth/keys/{key_id}/rotate
Response:
{
"id" : "key_xyz789" ,
"prefix" : "hana_sk_live_" ,
"scope" : "full_access" ,
"created_at" : "2026-02-07T14:30:00Z" ,
"expires_at" : null ,
"last_used_at" : "2026-02-07T14:28:00Z"
}
Key Rotation
HANA supports zero-downtime key rotation. When you rotate a key:
A new key is issued immediately
The old key continues working for 24 hours
After 24 hours, the old key is automatically revoked
This gives your team time to update all services without disruption.
Request Authentication
Include your API key in the Authorization header on every request:
curl -X POST https://api.hana.health/v1/engagements \
-H "Authorization: Bearer hana_sk_live_abc123..." \
-H "Content-Type: application/json" \
-d '{ ... }'
import { HanaClient } from '@hana-health/sdk' ;
const hana = new HanaClient ({
apiKey: process . env . HANA_API_KEY ,
environment: 'production' ,
region: 'eu'
});
// SDK handles authentication automatically
const engagement = await hana . engagements . create ({ ... });
Webhook Verification
All outbound webhooks from HANA are signed with HMAC-SHA256 using your webhook secret. Always verify the signature before processing events.
Verification Flow
HANA computes HMAC-SHA256(webhook_secret, raw_request_body)
The signature is sent in the X-Hana-Signature header
Your server recomputes the HMAC and compares
const crypto = require ( 'crypto' );
function verifyHanaWebhook ( rawBody , signature , secret ) {
const expected = crypto
. createHmac ( 'sha256' , secret )
. update ( rawBody )
. digest ( 'hex' );
return crypto . timingSafeEqual (
Buffer . from ( `sha256= ${ expected } ` ),
Buffer . from ( signature )
);
}
// Express middleware
app . post ( '/webhooks/hana' , express . raw ({ type: 'application/json' }), ( req , res ) => {
const sig = req . headers [ 'x-hana-signature' ];
if ( ! verifyHanaWebhook ( req . body , sig , process . env . HANA_WEBHOOK_SECRET )) {
return res . status ( 401 ). send ( 'Invalid signature' );
}
const event = JSON . parse ( req . body );
// Process event...
res . status ( 200 ). send ( 'ok' );
});
Always use timing-safe comparison functions to prevent timing attacks. Never use == for signature comparison.
Organization & Environment Isolation
Each organization gets fully isolated environments:
Organization: "Acme Health"
├── Production
│ ├── API Key: hana_sk_live_...
│ ├── Webhook Secret: whsec_live_...
│ └── Data: Production patients & engagements
└── Sandbox
├── API Key: hana_sk_test_...
├── Webhook Secret: whsec_test_...
└── Data: Test patients only (no real calls)
Data never crosses environment boundaries. Sandbox keys cannot access production data.
IP Allowlisting (Optional)
For organizations with strict network policies, restrict API access to specific IP ranges:
POST /v1/auth/ip-allowlist
{
"allowed_cidrs" : [
"203.0.113.0/24" ,
"198.51.100.0/24"
]
}
When enabled, requests from non-allowlisted IPs receive 403 Forbidden.
Next: Webhooks Detailed guide to receiving and processing HANA events.