⌘K

Webhook & Event Catalog

Partner lifecycle, pipeline, ingest, identity, FHIR subscription, and specialty events — with payload schemas and signature verification requirements.

Delivery requirements

  • HTTPS endpoint responding within 5 seconds with HTTP 2xx
  • Verify X-Apex-Signature HMAC-SHA256 signature
  • Event type in X-Apex-Event-Type header
  • Idempotent processing — retries use exponential backoff (max 72h)
Configure webhooks guide

Register webhook endpoint

Partner-signed HTTPS endpoints receive TEFCA exchange events. Requires sign-in and cms.partner.write scope on your OAuth client.

Event subscriptions

Your endpoints

Loading…

Webhook delivery log

Sign in to view delivery attempts and send a test.ping event to registered endpoints.

No deliveries logged yet.

Signature verification (HMAC-SHA256)

Signed payload format: {timestamp}.{raw JSON body}. Signature header value: sha256={hex}. Reject requests older than 300 seconds.

HeaderRequiredDescription
X-Apex-SignatureYesHMAC-SHA256 hex digest prefixed with sha256=
X-Apex-Event-TypeYesDot-notation event type (e.g. pipeline.sync.completed)
X-Apex-Delivery-IdYesUnique delivery ID — use for idempotent processing
X-Apex-TimestampYesUnix epoch seconds when the event was dispatched
Content-TypeYesapplication/json
User-AgentNoApex-Webhook/1.0 (+https://developers.parkerapex.com/webhooks)

Node.js

bash
import crypto from 'crypto';

const SIGNATURE_HEADER = 'X"text-cyan-300">-Apex-Signature';
const TIMESTAMP_HEADER = 'X"text-cyan-300">-Apex-Timestamp';
const TOLERANCE_SEC = 300;

"text">-amber-300 font">-semibold">export function verifyApexWebhook(rawBody: Buffer, headers: Record<string, string>, secret: string): boolean {
  const signature = headers[SIGNATURE_HEADER.toLowerCase()] ?? headers[SIGNATURE_HEADER];
  const timestamp = headers[TIMESTAMP_HEADER.toLowerCase()] ?? headers[TIMESTAMP_HEADER];
  if (!signature?.startsWith('sha256=') || !timestamp) return false;

  const ts = parseInt(timestamp, 10);
  if (Math.abs(Date.now() / 1000 - ts) > TOLERANCE_SEC) return false;

  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${timestamp}.${rawBody.toString('utf8')}`)
    .digest('hex');

  const received = signature.slice('sha256='.length);
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received));
}

Python

bash
import hmac
import hashlib
import time

SIGNATURE_HEADER = "X">-Apex-Signature"
TIMESTAMP_HEADER = "X">-Apex-Timestamp"
TOLERANCE_SEC = 300

def verify_apex_webhook(raw_body: bytes, headers: dict, secret: str) -> bool:
    signature = headers.get(SIGNATURE_HEADER) or headers.get(SIGNATURE_HEADER.lower())
    timestamp = headers.get(TIMESTAMP_HEADER) or headers.get(TIMESTAMP_HEADER.lower())
    if not signature or not signature.startswith("sha256=") or not timestamp:
        return False

    ts = int(timestamp)
    if abs(time.time() - ts) > TOLERANCE_SEC:
        return False

    signed_payload = f"{timestamp}.{raw_body.decode('utf-8')}".encode("utf-8")
    expected = hmac.new(secret.encode(), signed_payload, hashlib.sha256).hexdigest()
    received = signature.removeprefix("sha256=")
    return hmac.compare_digest(expected, received)

Retry schedule (max 72h)

  • Attempt 1: 1 minute
  • Attempt 2: 5 minutes
  • Attempt 3: 30 minutes
  • Attempt 4: 2 hours
  • Attempt 5: 6 hours
  • Attempt 6: 24 hours

Idempotency

Store processed delivery IDs (X-Apex-Delivery-Id) for at least 72 hours. Retries reuse the same delivery ID — return HTTP 2xx only after durable processing.

X-Apex-Delivery-Id

Certification checklist
pipeline.sync.completedPipeline

Pipeline Sync Completed

FHIR or batch sync job finished successfully.

X-Apex-SignatureX-Apex-Event-TypeX-Apex-Delivery-Id
json
{
  -300">"event": -300">"pipeline.sync.completed",
  -300">"job_id": -300">"job_abc123",
  -300">"partner_gpid": -300">"CMS-00000001",
  -300">"resource_types": [
    "Patient",
    "Observation"
  ],
  -300">"records_processed": 1240,
  -300">"completed_at": -300">"2026-06-13T20:00:00Z"
}
pipeline.sync.failedPipeline

Pipeline Sync Failed

Sync job failed after retries.

X-Apex-SignatureX-Apex-Event-Type
json
{
  -300">"event": -300">"pipeline.sync.failed",
  -300">"job_id": -300">"job_abc123",
  -300">"error_code": -300">"VALIDATION_ERROR",
  -300">"message": -300">"Bundle entry 14 failed FHIR validation",
  -300">"failed_at": -300">"2026-06-13T20:01:00Z"
}
ingest.completeBeacon / Ingest

Ingest Complete

Document or FHIR bundle ingest normalized and stored.

X-Apex-SignatureX-Apex-Event-Type
json
{
  -300">"event": -300">"ingest.complete",
  -300">"document_id": -300">"doc_xyz789",
  -300">"gpid": -300">"APX-1A2B3C4D",
  -300">"match_status": -300">"deterministic_match",
  -300">"lake_resource_id": -300">"Patient/abc"
}
ingest.rejectedBeacon / Ingest

Ingest Rejected

Ingest rejected — virus scan, validation, or policy failure.

X-Apex-SignatureX-Apex-Event-Type
json
{
  -300">"event": -300">"ingest.rejected",
  -300">"document_id": -300">"doc_xyz789",
  -300">"reason": -300">"MALWARE_DETECTED",
  -300">"rejected_at": -300">"2026-06-13T19:55:00Z"
}
identity.matchIdentity / GPID

Identity Match Resolved

GPID match or merge completed for a subject.

X-Apex-SignatureX-Apex-Event-Type
json
{
  -300">"event": -300">"identity.match",
  -300">"gpid": -300">"APX-1A2B3C4D",
  -300">"match_type": -300">"DETERMINISTIC",
  -300">"identity_status": -300">"ACTIVE",
  -300">"subject_gpid": -300">"APX-1A2B3C4D"
}
identity.mergeIdentity / GPID

Identity Merge

Two GPID records merged into golden record.

X-Apex-SignatureX-Apex-Event-Type
json
{
  -300">"event": -300">"identity.merge",
  -300">"survivor_gpid": -300">"APX-1A2B3C4D",
  -300">"merged_gpids": [
    "APX-OLD001"
  ],
  -300">"merged_at": -300">"2026-06-13T18:00:00Z"
}
prime.ingest.persistedPrime Wearables

Prime Ingest Persisted

Wearable telemetry normalized to FHIR Observations.

X-Apex-SignatureX-Apex-Event-Type
json
{
  -300">"event": -300">"prime.ingest.persisted",
  -300">"ingestion_id": -300">"ing_def456",
  -300">"observation_count": 4,
  -300">"athlete_gpid": -300">"APX-1A2B3C4D",
  -300">"source": -300">"oura"
}
prime.readiness.alertPrime Wearables

Prime Readiness Alert

Readiness flag triggered from biometric thresholds.

X-Apex-SignatureX-Apex-Event-Type
json
{
  -300">"event": -300">"prime.readiness.alert",
  -300">"flag": -300">"recovery_low",
  -300">"severity": -300">"warning",
  -300">"athlete_gpid": -300">"APX-1A2B3C4D",
  -300">"metric": -300">"hrv_rmssd",
  -300">"value": 28.5
}
fhir.subscription.notificationFHIR

FHIR Subscription Notification

R4 Subscription resource triggered — payload is FHIR Bundle.

X-Apex-SignatureX-Apex-Event-TypeContent-Type: application/fhir+json
json
{
  -300">"resourceType": -300">"Bundle",
  -300">"type": -300">"history",
  -300">"entry": [
    {
      -300">"resource": {
        -300">"resourceType": -300">"Observation",
        -300">"id": -300">"obs-1"
      }
    }
  ]
}
claim.adjudicatedVelocity RCM

Claim Adjudicated

Payer claim response received and linked to Claim resource.

X-Apex-SignatureX-Apex-Event-Type
json
{
  -300">"event": -300">"claim.adjudicated",
  -300">"claim_id": -300">"clm_001",
  -300">"claim_response_id": -300">"CR-99201",
  -300">"status": -300">"active",
  -300">"payer": -300">"Aetna",
  -300">"paid_amount": 142.5
}
partner.token.revokedCMS / Partners

Partner Token Revoked

API key or OAuth client revoked — rotate credentials.

X-Apex-SignatureX-Apex-Event-Type
json
{
  -300">"event": -300">"partner.token.revoked",
  -300">"token_id": -300">"tok_abc",
  -300">"partner_gpid": -300">"CMS-00000001",
  -300">"revoked_at": -300">"2026-06-13T17:00:00Z",
  -300">"reason": -300">"admin_action"
}
sightline.prescription.fulfilledSightline

Vision Prescription Fulfilled

Optical order fulfilled — lenses/frames dispensed.

X-Apex-SignatureX-Apex-Event-Type
json
{
  -300">"event": -300">"sightline.prescription.fulfilled",
  -300">"vision_prescription_id": -300">"VP-001",
  -300">"patient_gpid": -300">"APX-1A2B3C4D",
  -300">"fulfillment_status": -300">"completed"
}
odonto.treatment_plan.updatedOdonto

Dental Treatment Plan Updated

CarePlan or treatment plan modified in Odonto EHR.

X-Apex-SignatureX-Apex-Event-Type
json
{
  -300">"event": -300">"odonto.treatment_plan.updated",
  -300">"care_plan_id": -300">"CP-001",
  -300">"patient_gpid": -300">"APX-1A2B3C4D",
  -300">"procedures_added": 2
}
tefca.exchange.completedTEFCA / KONZA

TEFCA Exchange Completed

Outbound or inbound XCPD/XCA exchange finished (success or empty result).

X-Apex-SignatureX-Apex-Event-TypeX-Apex-Delivery-Id
json
{
  -300">"event": -300">"tefca.exchange.completed",
  -300">"exchange_type": -300">"xcpd",
  -300">"direction": -300">"outbound",
  -300">"gpid": -300">"APX-1A2B3C4D",
  -300">"target_organization_oid": -300">"2.16.840.1.113883.3.2791.1",
  -300">"purpose_of_use": -300">"TREAT",
  -300">"success": -300">true
}
tefca.consent.deniedTEFCA / KONZA

TEFCA Consent Denied

Exchange blocked by patient consent or policy for the declared purpose of use.

X-Apex-SignatureX-Apex-Event-Type
json
{
  -300">"event": -300">"tefca.consent.denied",
  -300">"exchange_type": -300">"xca",
  -300">"gpid": -300">"APX-1A2B3C4D",
  -300">"purpose_of_use": -300">"TREAT",
  -300">"reason": -300">"Patient consent does not permit this disclosure"
}
velocity.claim.submittedVelocity / Stedi

Claim Submitted via Stedi

837P professional claim accepted by the Stedi clearinghouse.

X-Apex-SignatureX-Apex-Event-TypeX-Apex-Delivery-Id
json
{
  -300">"event": -300">"velocity.claim.submitted",
  -300">"claim_id": -300">"CLM-2026-00412",
  -300">"control_number": -300">"123456789",
  -300">"trading_partner_service_id": -300">"PAYER_ID",
  -300">"usage_indicator": -300">"T"
}
velocity.eligibility.completedVelocity / Stedi

Eligibility Check Completed

270/271 eligibility inquiry returned from Stedi.

X-Apex-SignatureX-Apex-Event-Type
json
{
  -300">"event": -300">"velocity.eligibility.completed",
  -300">"member_id": -300">"MBR001",
  -300">"active_coverage": -300">true,
  -300">"trading_partner_service_id": -300">"PAYER_ID"
}
test.pingSystem

Webhook Test Ping

Synthetic test delivery from the developer portal Test button.

X-Apex-SignatureX-Apex-Event-TypeX-Apex-Delivery-Id
json
{
  -300">"event": -300">"test.ping",
  -300">"message": -300">"Parker Apex webhook test delivery",
  -300">"webhook_id": 1
}