Introduction
This is the documentation for the Truepill UK Pharmacy API. This API allows you to digitally integrate with the Truepill Pharmacy in the UK. You can place Orders on behalf of your users that will be prescribed, processed & fulfilled by our Prescribing & Pharmacy teams.
Partnering with Truepill in the UK
If you are currently operating / considering starting a business that could benefit from integration with our digital pharmacy services please get in touch at https://truepill.co.uk/contact.
Technical notes
Security
All API requests are securely transmitted using the TLS 1.2 protocol. All data is encrypted in transit & at rest in the database systems.
JSON API
Our API adheres to the JSON:API 1.0 specification, as detailed here.
JSON:API is a specification for how a client should request that resources be fetched or modified, and how a server should respond to those requests.
Important note: JSON:API requires the use of the JSON:API media type (application/vnd.api+json) for exchanging data.
Content-Type: application/vnd.api+json
For more information on some of the benefits of JSON API have a look at this blog post: https://nordicapis.com/the-benefits-of-using-json-api/
Getting Started
Before you begin
Before you can access the Pharmacy API you will need some credentials. These are issued to you when you sign up to work with Truepill and must be kept secure at all times.
Once you have obtained your credentials, which are issued in the form of a pair of keys referred to as a Client ID & Client Secret, you may proceed to the Accessing the API section below.
If you are not yet registered with us please see the information in Partnering with Truepill in the UK
Sandbox Environment
We provide a "sandbox" environment so that you can test your integrations before using the production systems. This is currently provided free of charge & any API requests made to the system will not incur billing costs.
The sandbox environment is kept up-to-date with the latest live version of the Pharmacy API.
The URL for the sandbox environment is: https://sandbox.truepill.co.uk
We provide different types of test products to help you onboard quickly with the sandbox environment.
Product ID | Type |
---|---|
2021-GBP-A1-TESTPOM-63-TESTPOM63 | POM |
2021-GBP-A1-TESTP-1-TESTP1 | P |
2021-GBP-A1-TESTGSL-1-TESTGSL1 | GSL |
Accessing the API
To access the API an Authorization HTTP Header is required for all endpoints.
The Pharmacy API Authentication is OpenID Connect compatible which means that it is OAuth 2.0 compliant.
For now we support the Client Credentials authentication flow. For more details on what that means have a look at this information from Auth0.
Continue reading to see how this looks in practice.
Obtaining an initial Token
Tokens are obtained from the Truepill Auth server which can be found at https://auth.truepill.co.uk/
.
curl --request POST \
--url https://auth.truepill.co.uk/auth/realms/pharmacy/protocol/openid-connect/token \
--data 'grant_type=client_credentials' \
--data 'client_id=YourClientId'\
--data 'client_secret=your-client-secret-string' \
--data 'response_type=code'
const response = await fetch(
'https://auth.truepill.co.uk/auth/realms/pharmacy/protocol/openid-connect/token',
{
method: 'POST',
headers: { 'content-type': 'application/x-www-form-urlencoded' },
body: 'grant_type=client_credentials'
+ '&client_id=<YOUR_CLIENT_ID>'
+ '&client_secret=<YOUR_CLIENT_SECRET>'
+ '&response_type=code'
}
);
return response.json();
Successful responses look like this:
{
"access_token": "eyJ...TEfg",
"expires_in": 36000,
"refresh_expires_in": 1800,
"refresh_token": "\"eyJhb...gwuF56ahx5uMlE8neo\"",
"token_type": "bearer",
"not-before-policy": 0,
"session_state": "c8ea91e6-f9c6-44c3-b685-c14f6f62b63d",
"scope": "acceptable scopes"
}
The important part of this is the access_token
property.
The Access Token is what you submit with each of your API requests as a Bearer Token in an Authentication header.
Making an API request
You should now have an Access Token from the previous step. You can now make an authenticated request to the Pharmacy API.
To submit your access token with a request it must be included in the Authorization
header in the Bearer Token format.
Example header: Authorization: Bearer <Your Access Token>
You should then be able to successfully make a request to an endpoint, e.g. POST /orders
.
Errors
Our API uses the following error codes. Click here to read more about JSON:API errors.
Error Code | Meaning |
---|---|
400 | Bad Request - Your request is invalid. |
401 | Unauthorized - We cannot identify you. Please acquire a new Access Token using the Authentication workflow. |
403 | Forbidden - You cannot access this resource. |
404 | Not Found - The specified resource could not be found. |
500 | Internal Server Error - We had a problem with our server. Try again later. |
Orders
Creating an order is the first step to providing medication to your customers. You simply need to provide us with a few key bits of information and we can handle the rest for you.
The first step is to place an order via the API. The same create order endpoint can be used to place a single one time order or a Repeat Order. The single one time order is a one off order while the repeat order can be automatically fullfiled for customers needing a repeat prescription e.g. every month for the next 5 months.
Depending on the type of order, it may need to be prescribed by one of our prescribing team or reviewed by our pharmacy.
If there is a medical reason the order cannot proceed it will be REJECTED
at this stage.
If the order is approved it is sent to our pharmacy and marked as READY_FOR_DISPATCH
.
This is where our pharmacists will find and package the correct medication for the concerned order.
Once an order is handed to a shipping carrier it is marked as DISPATCHED
.
This completes the order lifecycle.
Note: We are looking to add shipping carrier tracking integration in the future.
Classes of Medication
There are three classes of medication under the Medicines Act 1968, and each one has a slightly altered workflow.
- General Sale List medicines (GSL).
- Pharmacy medicines (P).
- Prescription Only Medicines (POM).
POM (Prescription Only Medication) Orders
This type of medication requires a prescriber to read over any necessary consultation notes and prescribe it.
The prescriber can approve or reject an order. The approval creates a prescription which can be signed.
Once approved the prescription is awaiting dispensing where it can then be fulfilled.
P (Pharmacy Medication)
Much like POM medication this requires consultation notes to be checked over however instead of a prescriber a pharmacist is able to approve/reject orders.
GSL (General Sales List)
These medications can be obtained without a pharmacist or prescriber and can be attached to any order with other medications.
To read in more detail about medication classifications, you can look here
You can stay up to date with order status updates by making use of webhooks.
Create an Order
curl --request POST \
--url https://pharmacy.truepill.co.uk/api/orders \
-H "Authorization: Bearer eyJ...TEfg" \
-H "Content-Type: application/vnd.api+json" \
--data '{
"data": {
"type": "order",
"attributes": {
"prescriptionId": "prescriptionId",
"shippingAddress": {
"name": "The Royal Family",
"line1": "Buckingham Palace",
"postcode": "SW1A 1AA"
},
"repeatPrescription": {
"repeat": 3,
"interval": "week",
"frequency": 4
},
"consultation": [
{
"question": "Do you have any existing medical conditions?",
"answer": "No"
}
],
"patient": {
"sex": "female",
"telephone": "07111111111",
"dob": "2011-10-05",
"email": "jane@foo.com",
"firstName": "Jane",
"lastName": "Doe",
"genderIdentity": "female",
"preferredPronouns": "She/Her",
"preferredName": "Ms Doe"
},
"items": [{
"id": "2020-GBP-A1-FRCON-63-MCGY3075",
"quantity": 3
}]
}
}
}'
return fetch('https://pharmacy.truepill.co.uk/api/orders', {
method: 'POST',
headers: {
'Content-Type': 'application/vnd.api+json',
'Authorization': 'Bearer eyJ...TEfg',
},
body: {
"data": {
"type": "order",
"attributes": {
"prescriptionId": "prescriptionId",
"upstreamId": "BHA1634",
"shippingAddress": {
"name": "The Royal Family",
"line1": "Buckingham Palace",
"postcode": "SW1A 1AA"
},
"repeatPrescription": {
"repeat": 3,
"interval": "week",
"frequency": 4
},
"consultation": [
{
"question": "Do you have any existing medical conditions?",
"answer": "No"
}
],
"patient": {
"sex": "female",
"telephone": "07111111111",
"dob": "1998-10-05",
"email": "jane@foo.com",
"firstName": "Jane",
"lastName": "Doe",
"genderIdentity": "female",
"preferredPronouns": "She/Her",
"preferredName": "Ms Doe"
},
"items": [{
"id": "2020-GBP-A1-FRCON-63-MCGY3075",
"quantity": 3
}]
}
}
}
});
POST https://pharmacy.truepill.co.uk/api/orders
Field | Type | Required | Notes |
---|---|---|---|
upstreamId | String | No | An optional identifier that identifies the Order record in your system. This could be a reference from a 3rd party system or your own internal Order number. |
Can be helpful for customer-services cases. | |||
prescriptionId | String | No | Optional parameter - if you have uploaded your own prescription then use the returned prescriptionId to create your order and bypass our in house prescription service. |
shippingAddress | Address | Yes | If no name is provided in shippingAddress, the combination of firstName and lastName from patient will be used. |
repeatPrescription | Repeat Prescription | No | Can only be included for prescription (POM) orders. Repeats are not supported for GSL and P medications. |
consultation | Consultation | Yes | |
patient | Patient | Yes | |
items | Items | Yes |
Shipping Address
Field Name | Type | Example | Required |
---|---|---|---|
name | String | The Royal Family |
No |
line1 | String | Buckingham Palace |
Yes |
line2 | String | Room 12 |
No |
city | String | London |
No |
region | String | London |
No |
postcode | String | SW1A 1AA |
Yes |
Repeat Prescription
Object included on order that will lead to the creation of a repeat prescription. The interval and frequency at which repeat orders will be created must be specified (for instance, frequency
of 3 and interval
of "week"
to specify a repeat order every 3 weeks). The number of repeats which will follow the original order must also be included.
Repeat orders that are generated in future will need to be manually approved before dispatch. Any repeats that are auto-created will expire after 7 days if not approved.
Field Name | Type | Example | Required |
---|---|---|---|
repeat | Number | 3 | Yes |
interval | String | day , week or month |
Yes |
frequency | Number | 4 | Yes |
Consultation
Array of answers with their attached questions. The consultations are important for pharmacists and prescribers understand whether the medication selected is right for the customer.
Field Name | Type | Example | Required |
---|---|---|---|
question | string | "Do you have any existing medical conditions?" | Yes |
answer | string | No | No |
Patient
Field Name | Type | Example | Required |
---|---|---|---|
firstName | String | john |
Yes |
lastName | String | smith |
Yes |
sex | String | male , female or intersex |
Yes |
dob | String | 2011-10-05 : yyyy-mm-dd format |
Yes |
String | john.smith@example.com |
Yes | |
telephone | String | 07500555555 |
Yes |
genderIdentity | String | Non Binary |
No |
preferredPronouns | String | They/Them |
No |
preferredName | String | Jon |
No |
Items
Array of items with their attached ids and quantities.
Field Name | Type | Example | Required |
---|---|---|---|
id | String | 2020-GBP-A1-FRCON-63-MCGY3075 |
Yes |
quantity | Number | 3 | Yes |
Responses
This is an example response:
{
"data": {
"type": "order",
"id": "ord_31232",
"attributes": {
"upstreamId": "BHA1634",
"status": "READY_FOR_PRESCRIBER",
"shippingAddress": {
"name": "The Royal Family",
"line1": "Buckingham Palace",
"postcode": "SW1A 1AA"
},
"repeatPrescription": {
"repeat": 3,
"interval": "week",
"frequency": 4
},
"createdAt": "2011-10-05T14:48:00.000Z",
"items": [{
"id": "2020-GBP-A1-FRCON-63-MCGY3075",
"quantity": 3,
"productType": "medication",
"medicationType": "POM"
}]
}
}
}
Status Code | Meaning |
---|---|
200 | Your order has successfully been created |
400 | The order was invalid and could not be created. Usually this is a simple validation error and you will get a detailed error object explaining what is missing. In some cases it may be because the patient data clashed with existing patient data, and could neither be merged nor stored separately. In this case you will get the error "Conflict found with existing data." |
Get an Order
curl --request GET \
--url https://pharmacy.truepill.co.uk/api/orders/:orderId/ \
-H "Authorization: Bearer eyJ...TEfg" \
-H "Content-Type: application/vnd.api+json"
return fetch('https://pharmacy.truepill.co.uk/api/orders/:orderId', {
headers: {
'Content-Type': 'application/vnd.api+json',
'Authorization': 'Bearer eyJ...TEfg',
}
});
GET https://pharmacy.truepill.co.uk/api/orders/:orderId/
You can retrieve an individual order with its current status and full order information.
Responses
This is an example response:
{
"data": {
"type": "order",
"id": "ord_31232",
"attributes": {
"upstreamId": "BHA1634",
"status": "READY_FOR_PRESCRIBER",
"shippingAddress": {
"name": "The Royal Family",
"line1": "Buckingham Palace",
"postcode": "SW1A 1AA"
},
"shippingInformation": {
"trackingUrl": "http://some-link.com/test",
"carrier": "ROYAL_MAIL",
"trackingId": "test"
},
"createdAt": '2011-10-05T14:48:00.000Z',
"reviewerDetails": { // A reviewer can either be a Pharmacist or a Prescriber
"name": "Jane",
"registrationId": "823739",
"registrationBody": 'GPhC',
"reviewedAt": null // Only populated when it has been approved (P/POM)
},
"items": [{
"id": "2020-GBP-A1-FRCON-63-MCGY3075",
"quantity": 3,
"type": "pom"
}]
}
}
}
This is an example for a dispatched order including the resolved object:
{
"data": {
"type": "order",
"id": "ord_31232",
"attributes": {
"status": "DISPATCHED",
"shippingAddress": {
"name": "The Royal Family",
"line1": "Buckingham Palace",
"postcode": "SW1A 1AA"
},
"createdAt": "2011-10-05T14:48:00.000Z",
"resolution": {
"type": "DISPATCHED",
"resolvedAt": "2011-10-06T08:01:00.000Z"
},
"items": [{
"id": "2020-GBP-A1-FRCON-63-MCGY3075",
"quantity": 3,
"type": "pom"
}]
}
}
}
Status Code | Meaning |
---|---|
200 | Successfully retrieved order |
Response properties
Property | Type |
---|---|
upstreamId | String |
status | String of Status |
shippingAddress | Address |
createdAt | DateTime* |
reviewerDetails | Reviewer |
reviewedAt | DateTime* (Only populated when it has been approved (P/POM) |
items | Array of Items |
resolution | Resolution |
shippingInformation | ShippingInformation |
*Datetimes are all ISO 9801 with timezone
Reviewer
A reviewer can either be a Pharmacist or a Prescriber.
Field Name | Type |
---|---|
name | String |
registrationId | String |
registrationBody | String |
Items
An array of items.
Field Name | Type |
---|---|
id | String |
quantity | number |
Resolution
A resolved order may be "Cancelled", "Rejected" or "Dispatched". In all these cases a resolution object is included.
Field Name | Type | Description |
---|---|---|
type | String | The final status of the order (Cancelled, Rejected, Dispatched) |
resolvedAt | DateTime* | The timestamp when order was resolved |
reason | String | Conditional field for additional information (when Cancelled/Rejected) |
name | String | The full name of individual that resolved the order (when Rejected) |
registrationBody | String | The professional body the named individual is registered with (when Rejected) |
registrationId | String | Id of the individual at their professional body (when Rejected) |
Cancel an Order
curl --request POST \
--url https://pharmacy.truepill.co.uk/api/orders/:orderId/cancel \
-H "Authorization: Bearer eyJ...TEfg" \
-H "Content-Type: application/vnd.api+json"
return fetch('https://pharmacy.truepill.co.uk/api/orders/:orderId/cancel', {
method: 'POST'
headers: {
'Content-Type': 'application/vnd.api+json',
'Authorization': 'Bearer eyJ...TEfg',
}
});
POST https://pharmacy.truepill.co.uk/api/orders/:orderId/cancel
All successful requests will trigger an event to be sent to all subscribed webhooks. Click here to find out about our webhooks. Orders can only be cancelled in certain statuses, to see the applicable statuses, please click here.
Responses
This is an example response:
{
"data": {
"type": "order",
"id": "ord_31232",
"attributes": {
"status": "CANCELLED",
"shippingAddress": {
"name": "The Royal Family",
"line1": "Buckingham Palace",
"postcode": "SW1A 1AA"
},
"createdAt": "2011-10-05T14:48:00.000Z",
"resolution": {
"resolvedAt": "2020-04-20T09:00:00Z",
"type": "CANCELLED",
"reason": "By request"
},
"items": [{
"id": "2020-GBP-A1-FRCON-63-MCGY3075",
"quantity": 3,
"type": "pom"
}]
}
}
}
Status Code | Meaning | Resolution |
---|---|---|
200 | Successful | The order has been successfully cancelled. |
Uploading Prescriptions
curl --request POST \
--url https://pharmacy.truepill.co.uk/api/prescriptions \
-H "Authorization: Bearer eyJ...TEfg" \
-H "Content-Type: multipart/form-data" \
--form 'file=@"path/to/file.pdf"'
--form 'data="{
\"prescriber\": {
\"email\": \"name@domain.com\",
\"name\": \"Name\",
\"registrationId\": \"registrationId\",
\"registrationBody\": \"GPHC\"
},
\"requestedItems\": [
{
\"productId\": \"productId\",
\"instructions\": \"instructions go here\"
}
]
}"'
const formdata = new FormData();
formdata.append("file", fileInput.files[0], "file.pdf");
formdata.append("data", `{
"prescriber": {
"email": "name@domain.com",
"name": "Your Name",
"registrationId": "registration ID",
"registrationBody": "GPHC"
},
"requestedItems": [
{
"productId": "productID go here",
"instructions": "instructions go here"
}
]
}`);
return fetch('https://pharmacy.truepill.co.uk/api/prescriptions', {
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data',
'Authorization': 'Bearer eyJ...TEfg',
},
body: formdata
});
POST https://pharmacy.truepill.co.uk/api/prescriptions
We provide our own in house prescription generation and signing service using our own team of prescribers. However, should you wish to use your own documents you can upload a root certificate digitally signed (ie. Docusign) prescription pdf to this endpoint.
We will be unable to verify any document that is not signed in this way. This endpoint returns a prescriptionId
which can then be included on the request body when Creating an Order. When creating an order, use this prescriptionId in the request payload
in order to link your prescription to your order and bypass our prescribing step. If an order is created without a prescriptionId then the system will assume that you need a prescription creating for the order and one will be generated by our prescribing team.
NOTE: This endpoint has a content-type of multipart/form-data
and takes both a file & JSON request payload.
Field | Type | Required |
---|---|---|
prescriber | Prescriber | Yes |
requestedItems | Requested Item | Yes |
Prescriber
Object required in the request payload included in uploading a prescription.
Field | Type | Required | Notes |
---|---|---|---|
String | Yes | Must be in typical email format of name@domain. | |
name | String | Yes | |
registrationId | String | Yes | |
registrationBody | String | Yes | One of either GMC or GPHC . |
Requested Item
Array of objects required in the request payload included in uploading a prescription. Must not be empty and must match the products later requested on the order.
Field | Type | Required |
---|---|---|
productId | String | Yes |
instructions | String | Yes |
Responses
This is an example response:
{
"data": {
"type": "prescription",
"attributes": {
"prescriptionId": "pxn_6262a032e62eb00f75df538c"
},
"relationships": {},
}
}
Status Code | Meaning |
---|---|
200 | Your prescription has successfully been uploaded and stored |
400 | The prescription pdf or request payload was invalid and the prescription could not be uploaded.. Usually this is a simple validation error and you will get a detailed error object explaining what is missing. |
Update shipping information
This endpoint is for internal use only. Our dispatchers/cs team update the shipment information and when that is successful it triggers an ORDER_UPDATED webhook. Click here to find out about our webhooks.
Shipping Information
Field Name | Type | Example |
---|---|---|
trackingUrl | String | http://some-link.com/trackingId |
trackingId | String | trakingId |
carrier | String | ROYAL_MAIL , DX or DPD |
Statuses
Status | Meaning | Event Triggered | Cancellable |
---|---|---|---|
AWAITING_APPROVAL | Waiting for an auto-generated repeat order to be approved | ❌ | ✅ |
READY_FOR_PRESCRIBER | Waiting for a prescriber to be assigned | ❌ | ✅ |
READY_FOR_REVIEW | Waiting for a pharmacist to be assigned | ❌ | ✅ |
PRESCRIBING | Currently being reviewed by a prescriber | ❌ | ✅ |
REVIEWING | Currently being reviewed by a pharmacist | ❌ | ✅ |
READY_FOR_DISPENSING | Order has been approved and is ready to be dispensed | ✅ | ✅ |
READY_FOR_DISPATCH | Order has been dispensed and is ready to be dispatched | ✅ | ✅ |
DISPATCHING | Currently being handled by a dispatcher | ❌ | ❌ |
DISPATCHED | Order has been dispatched | ✅ | ❌ |
REJECTED | Order was rejected by Truepill | ✅ | ❌ |
CANCELLED | Order has been cancelled | ✅ | ❌ |
Webhooks
When an order status changes, you might want to send an email update to your customer, or update some status on your server.
In order to see when an order status changes you can enrol a webhook address with us, and we will POST
event updates back to you, signed
with a secret key.
Create a new Webhook
curl --request POST \
--url https://pharmacy.truepill.co.uk/api/webhooks \
-H "Authorization: Bearer eyJ...TEfg" \
--data '
{
"data": {
"type": "webhook",
"attributes": {
"url": "https://mysite.com/callbacks/notify-orders"
}
}
}'
return fetch('https://pharmacy.truepill.co.uk/api/webhooks', {
method: 'POST',
headers: {
'Content-Type': 'application/vnd.api+json',
'Authorization': 'Bearer eyJ...TEfg',
},
body: {
"data": {
"type": "webhook",
"attributes": {
"url": "https://mysite.com/callbacks/notify-orders"
}
}
}
});
Successful responses look like:
{
"data": {
"type": "webhook",
"id": "hook_72392e4a608e",
"attributes": {
"secret": "4f4505a8-0907-43e8-bd1d-8470a8a347bd",
"url": "https://mysite.com/callbacks/notify-orders"
}
}
}
POST https://pharmacy.truepill.co.uk/api/webhooks
Content-Type: application/vnd.api+json
Once created, you must save your signing-secret, which you can use to verify that events came directly from TruePill.
HTTP Request
Parameters
Field | Type | Example | Required |
---|---|---|---|
url | string | https://www.managed-client.com/api/webhooks/orders | Yes |
Responses
Status Code | Meaning |
---|---|
200 | Created |
View All Webhooks
This endpoint allows you to view all of your companies webhooks.
GET https://pharmacy.truepill.co.uk/api/webhooks
curl --request GET \
--url https://pharmacy.truepill.co.uk/api/webhooks \
-H "Authorization: Bearer eyJ...TEfg" \
return fetch('https://pharmacy.truepill.co.uk/api/webhooks', {
headers: {
'Content-Type': 'application/vnd.api+json',
'Authorization': 'Bearer eyJ...TEfg',
}
});
The above request will create a response that looks like this:
{
"data": [
{
"type": "webhook",
"id": "hook_2e414da9d950",
"attributes": {
"secret": "5c10b4d8-7813-4a42-b6bd-f13dcde947cd",
"url": "https://test.com/test"
}
},
{
"type": "webhook",
"id": "hook_72392e4a608e",
"attributes": {
"secret": "4f4505a8-0907-36dh-bd1d-8470a8a347ed",
"url": "https://test.com/status"
}
}
]
}
Responses
Status Code | Meaning |
---|---|
200 | Ok |
Delete a Webhook
If you not longer require a webhook you can use this endpoint to delete it.
DELETE https://pharmacy.truepill.co.uk/api/webhooks/:webhook_id
curl --request DELETE \
--url https://pharmacy.truepill.co.uk/api/webhooks/:webhook_id \
-H "Authorization: Bearer eyJ...TEfg" \
return fetch('https://pharmacy.truepill.co.uk/api/webhooks', {
method: 'DELETE',
headers: {
'Content-Type': 'application/vnd.api+json',
'Authorization': 'Bearer eyJ...TEfg',
}
});
Responses
Status Code | Meaning |
---|---|
204 | Deleted the webhook |
Events
When an Order Status changes an Event will be sent to your registered Webhooks. Only certain statuses will trigger an event.
Signing
An example JWS would look like this:
eyJhbGciOiJIUzUxMiJ9.eyJldmVudCI6Ik9SREVSX1VQREFURUQiLCJyZXNvdXJjZSI6eyJpZCI6Im9yZF8xMjM0IiwidHlwZSI6Im9yZGVyIiwibGluayI6Imh0dHBzOi8vcGhhcm1hY3kudHJ1ZXBpbGwuY28udWsvYXBpL29yZGVycy9vcmRfMTIzNCJ9fQ.Ayd3GADKtyng3jop9gUl8HN3L5nHdvFw_s7qSQRCuR-gQkAb0Da1kIZlHKuyyXElY0FwNK9H_mRR2-XO3l6nng
You can use
node-jws
to quickly verify and decode JWS payloads.
import jws from 'jws';
// ...
const { header, payload } = jws.decode(data);
if (!jws.verify(data, header.alg, storedSecret)) {
throw new Error('Request did not come from Truepill');
}
const event = JSON.parse(payload);
Events will be sent to your webhook addresses in JWS format. This includes a JSON payload and a signature. The signature uses a 512-bit HMAC algorithm, and the key is the secret
returned when you created the webhook. The node-jws
package can be used to easily verify the signature and decode the JSON string.
The decoded JSON payload will be the following format:
Event Fields
An example of the JSON payload:
{
"event": "ORDER_UPDATED",
"resource": {
"id": "ord_1234",
"type" : "order",
"link": "https://pharmacy.truepill.co.uk/api/orders/ord_1234"
}
}
An example of the JSON payload when a repeat order is automatically generated:
{
"event": "REPEAT_ORDER_CREATED",
"resource": {
"id": "ord_1234",
"type" : "order",
"link": "https://pharmacy.truepill.co.uk/api/orders/ord_1234",
"endpoints": [
"approve": {
"href": "https://pharmacy.truepill.co.uk/api/orders/repeat/:orderId/approve",
"rel": "approve",
"method": "POST"
},
"cancel": {
"href": "https://pharmacy.truepill.co.uk/api/orders/repeat/:originalOrderId/cancel",
"rel": "cancel",
"method": "POST"
}
]
}
}
Property | Meaning | Type |
---|---|---|
resource.type | The resource type | String |
resource.id | The ID of the resource | String |
resource.link | The url at which the resource can be viewed | String |
event | The type of Event that occurred | String |
endpoints | A list of endpoints made available as a result of the fired event | Array |
endpoints.href | The endpoint URL | String |
endpoints.rel | The endpoint relationship | String |
endpoints.method | The endpoint method | String |