Webhooks allow your application to stay informed with what’s happening on Fullscript. You can subscribe to events and be notified when they happen. Let’s say one of your clinics updates a patient or creates a treatment plan; webhooks allow you to know about those events and take action if needed.
You can register a single webhook URL through the API Dashboard and subscribe to multiple event types.
When the event occurs—say a treatment plan is created, a patient is updated, or a clinic key is revoked, etc.—Fullscript creates an Event. This Event contains all the relevant information about what just happened. It includes the event's type (ex: treatment_plan.created) and any relevant data to that event.
Once the event is created, Fullscript will send out a payload with the event data via an HTTP POST request to the webhook url that you defined in your account. Note that we only send events to a single endpoint per environment.
Webhooks are configured through the API Dashboard. For each environment that you have setup, you can enter a URL to receive events. This should be a dedicated URL on your server that is setup to receive webhook notifications.
All urls need to use HTTPS. We will validate that your connection is secure and HIPAA compliant before sending any webhook data. For this to work, your server needs to be setup to support HTTPS with a valid certificate.
To acknowledge that you received a webhook notification, your endpoint needs to respond with either a 200 or 201 HTTP status code. Any response codes outside of this range will tell us that the webhook has not been received and will be treated as a failure.
Your endpoint's body must also respond with your challenge token (available in the API Dashboard). This is a security measure to ensure that you own the url in question and it hasn't been hijacked. A successful response could look something like this:
HTTP 200 OK
Content-type: application/json
{ "challenge": "your-secret-challenge-token" }
We will attempt to deliver your webhooks up to 6 times with exponential back off. Webhooks cannot manually be retried, however you can make a query to the events endpoint to reconcile data in case of any missed events.
We will attempt to send event deliveries in order, however that is not a guarantee. We will also attempt to deliver webhooks within 30 minutes from when the event was created. In most cases however, this should be close to instantaneous.
The webhook deliveries endpoint has all the information you need to check how many times we’ve attempted to deliver an event, what the response received was, the status code, and other relevant information.
We set aggressive time-outs for webhook deliveries. If you have to do a bunch of complex logic with the event data, or need to make network requests, it’s possible that the delivery attempt will time-out before we receive a 2xx HTTP status code. To mitigate this, you may want to respond immediately with a 2xx HTTP status code, and then perform your complex logic afterwards.
Each event payload comes with both a clinic_id and an integration_id (if relevant). The clinic key is the unique identifier for the clinic. Any clinic events (patient, practitioner, treatment plan, etc.) will be scoped to that clinic through the clinic_id.
Because it's possible for clinics to have multiple integrations enabled, the exact same events will be sent for each integration that a clinic has enabled with you. To mitigate unwanted duplication of events, the integration has to be activated before any webhook events will be sent. This means that it’s been used as least once with a valid X-FS-Clinic-Key and the key has not been revoked. The integration_id allows you to scope events to the relevant integration that is enabled.
Both the clinic_id and integration_id can be retrieved through the API at the clinic endpoint.
In some circumstances we will disable your endpoint and stop trying to deliver events to it. This can happen when: we receive a 410 HTTP status code or if the delivery attempts are consistently failing for more than 24 hours. In that case your webhook endpoint may be disabled and we will no longer send events to that url.
Re-enabling a disabled webhook can be done through the API Dashboard once you have resolved the issues.
You can see the status (both failed and successful delivery attempts) through the webhook deliveries endpoint.
Webhook events follow the same logic as our versioning scheme in the API and it respects the patch_version that you’re on.
Fullscript-Signature headerFullscript sends a header in the webhook request that can be used in conjunction with your Webhook Secret Key to verify the payload. Here is an example of the header:
Fullscript-Signature: t=1591826856,v1=0c262932b0ac6b4952e2fe24fdf419313984a66f6f442e0b8ec4cb87f2a107ad
This represents the format: t=<timestamp>,v1=<signature>
The signature is generated using a hash-based message authentication code (HMAC) with SHA-256.
This hash is generated using 3 things:
timestamprequest_body (The POST message's JSON payload string)Webhook Secret KeyThe timestamp and request_body are combined to create the payload provided to the hash function. The Webhook Secret Key is used as the key.
The same hash can be computed and compared to the signature to verify the request.
timestamp and signature from the header.payload by combining the timestamp and request_body with a single .Example: payload = '1591826856.{"event":{...<more_json>}}'
Webhook Secret Key as the key. Use the payload string as the message.signature.Note: The timestamp is generated directly before we send the payload. It is included in the hash payload in order to help prevent replay attacks. We recommend using this to verify the age of a request with a reasonable tolerance. 5 minutes is usually a good default.
This endpoint lists all webhook_deliveries from the last 30 days.
attempted_atstring
Filter by attempted_at date. The date must be formatted as follows yyyy-mm-dd.
attempted_at date is less than. <yyyy-mm-dd.attempted_at date is greater than. >yyyy-mm-dd.attempted_at date is within a range. yyyy-mm-dd..yyyy-mm-dd.event_idstring
Filter webhook deliveries by event_id.
successfully_deliveredstring
Filter webhook deliveries by whether they have been successfully delivered or not. Accepts a string of true or false
sort_bystring
Accepts one of the following arguments: event_id attempted_at.
order_bystring
Ordering defaults to ASC and can take an argument of ASC or DESC.
curl "https://api-us-snd.fullscript.io/api/webhooks/deliveries" \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer XXXXXXXXXXXXXXXXXXXX'