Glossary & Reference
This page is the canonical reference for terms, identifiers, statuses, and webhook events used across every Stealth Health partner integration. Each tier guide links here rather than duplicating these tables.
ID Prefixes
All partner-facing identifiers carry a stable prefix so you can route them in your own systems without parsing.
| Prefix | Object | Issued by |
|---|---|---|
ptr_ | Partner | Stealth Health (at onboarding) |
sk_live_ / sk_test_ | API key (production / sandbox) | Stealth Health |
whsec_ | Webhook signing secret | Stealth Health |
ref_ | Referral | Stealth Health (POST /partner/referrals) |
ptn_ | Patient profile | Stealth Health (after enrollment) |
pres_ | Prescriber (clinical-tier registry) | Stealth Health (POST /partner/prescribers) |
appt_ | Appointment | Stealth Health |
appt_partner_ | Partner-submitted appointment | Stealth Health (POST /partner/prescriptions) |
PRX- | Partner-submitted prescription (rx_id) | Stealth Health |
evt_ | Webhook event | Stealth Health |
Partners are encouraged to set their own partner_reference on every create call. We treat it as the idempotency key and echo it back on every webhook so your downstream joins are stable.
Authentication headers
| Header | Purpose | Required on |
|---|---|---|
X-Partner-ID | Identifies the partner (public, safe to log). | All /partner/* calls. |
X-Api-Key | Authenticates the request (secret). Compared in constant time against SHA-256(api_key_hash). | All /partner/* calls. |
X-Access-Tier | Must be clinical for clinical-tier endpoints. Referral-tier keys hitting clinical endpoints are rejected with 403 CLINICAL_ACCESS_REQUIRED. | Clinical-tier endpoints. |
Key rotation supports a dual-hash window: the old key remains valid until previous_key_expires_at (default 7 days) so partners can deploy the new key with zero downtime.
Webhook signature header
Every outbound webhook delivery includes:
X-Stealth-Signature: sha256=<hex-digest>
The digest is HMAC-SHA256(webhook_secret, raw_request_body). Verify on every request, against the raw body bytes, using a constant-time comparison. A reference implementation lives in Clinical Tier § 16.2.
Delivery contract:
- Stealth Health expects a
2xxresponse within 10 seconds. - Failed deliveries are retried with backoff
[30s, 5m, 30m, 2h, 12h](max 6 attempts) and persisted in our internalpartner_eventscollection for replay. - Each event has a unique
event_id; treat it as the idempotency key.
Webhook event catalog
Referral-tier events
Available on all tiers. Delivered to the URL configured in partner_configs.webhook_url.
| Event | Trigger | Payload extension |
|---|---|---|
referral.enrolled | Patient completes intake form | product_category |
referral.pending_review | Intake submitted for doctor review | — |
referral.approved | Doctor approves prescription | — |
referral.denied | Doctor denies prescription | denial_category (medical_contraindication, incomplete_information, not_a_candidate, ...) |
referral.payment_due | Payment required from patient | amount_cents, currency |
referral.payment_complete | Patient payment received | amount_cents, currency |
referral.awaiting_shipment | Prescription sent to pharmacy | — |
referral.shipped | Order shipped by pharmacy | carrier, estimated_delivery |
referral.in_transit | Carrier scan | carrier |
referral.out_for_delivery | Shipment out for delivery | carrier |
referral.delivered | Shipment delivered | carrier, delivered_at |
referral.delivery_exception | Delivery issue (failed attempt etc.) | carrier, exception_type |
referral.cancelled | Referral cancelled | cancelled_by (partner or patient) |
referral.expired | Enrollment URL expired without completion | — |
Clinical-tier events
Sent only to clinical-tier partners. PHI-bearing payloads.
| Event | Trigger | Payload extension |
|---|---|---|
patient.created | Patient profile created after enrollment | patient (full profile) |
patient.updated | Patient updates their profile | patient (changed fields) |
appointment.intake_completed | Intake questionnaire submitted | appointment_id, intake_summary |
appointment.prescription_signed | Prescription signed by doctor | appointment_id, prescription (full detail) |
transaction.succeeded | Payment successfully processed | transaction (full detail) |
transaction.refunded | Payment refunded | transaction, refund_amount_cents, reason |
prescription.received | Partner-submitted Rx accepted by POST /partner/prescriptions | appointment_id, prescription_id, rx_id, prescriber_id, medications[] |
prescription.rejected | Partner-submitted Rx rejected after async re-validation (reserved) | error_code, error_message |
Prescriber-Partner events
| Event | Trigger | Payload extension |
|---|---|---|
appointment.submitted | Appointment created and queued for review | appointment_id, patient_id, status, estimated_review_hours |
appointment.in_review | Physician has opened the case | appointment_id |
appointment.prescription_signed | Physician approved and signed a prescription | appointment_id, prescription, prescriber |
appointment.denied | Physician denied the case | appointment_id, denial_category, denial_reason |
prescription.routed | Prescription sent to pharmacy (when we route) | appointment_id, pharmacy_name, pharmacy_npi |
prescription.filled | Pharmacy confirmed fill and shipped | appointment_id, tracking |
Status lifecycles
Referral status
Appointment status (clinical / prescriber-partner)
doctor_reviewed is also the entry state for partner-submitted prescriptions (the appointment is created already in this state by POST /partner/prescriptions).
Common error codes
The complete per-endpoint error catalog lives in each tier guide. The codes below appear across multiple endpoints.
| Code | HTTP | Meaning |
|---|---|---|
MISSING_CREDENTIALS | 401 | X-Partner-ID or X-Api-Key header missing. |
INVALID_CREDENTIALS | 401 | Partner not found, inactive, or key hash mismatch. |
CLINICAL_ACCESS_REQUIRED | 403 | Endpoint requires clinical-tier access but a referral-tier key was used. |
RATE_LIMIT_EXCEEDED | 429 | Per-minute rate limit hit. Honor Retry-After. |
INVALID_BODY | 400 | Request body failed schema validation. details contains specifics. |
INTERNAL_ERROR | 500 | Unexpected server error. Safe to retry with exponential backoff. |
Rate limits
| Environment | Limit (per partner, per minute) |
|---|---|
Production (api.stealth.health) | 300 |
Sandbox (sandbox.stealth.health) | 60 |
429 responses include standard Retry-After, X-RateLimit-Remaining, and X-RateLimit-Reset headers.
Environments
| Environment | Base URL | Notes |
|---|---|---|
| Production | https://api.stealth.health | Real PHI. Requires production API key (sk_live_*). |
| Sandbox | https://sandbox.stealth.health | Synthetic data only. Requires sandbox key (sk_test_*). Functionally identical surface. |