title: Website Webhook Integration description: How to receive approved DailyLife content on your website. public: true reviewed: 02092026
Website Webhook Integration
DailyLife can send approved content to your website using a signed webhook.
This page covers:
- payload format
- signature verification
- delivery behaviour
- troubleshooting
When Deliveries Happen
DailyLife sends a webhook after a manager approves content for publication.
Supported event values:
gallery.publishedevents.publishedcareers.publishedcontent.retracted
Request Details
- Method:
POST - Content type:
application/json - Signature header:
X-DailyLife-Signature
The signature header uses this format:
sha256=<hex_digest>
Payload Format
{
"delivery_id": "22222222-2222-2222-2222-222222222222",
"event": "gallery.published",
"version": "1.1",
"timestamp": "2026-08-23T18:10:00Z",
"org_id": "00000000-0000-0000-0000-000000000000",
"site": {
"id": "33333333-3333-3333-3333-333333333333",
"name": "Wild Acres Care Home"
},
"attempt": 1,
"post": {
"id": "11111111-1111-1111-1111-111111111111",
"title": "Afternoon activity update",
"body": "A short update ready for publication.",
"category": "activities",
"tags": ["activities", "community"],
"images": [
{
"path": "media/path/example.jpg",
"url": "https://.../media/path/example.jpg?token=...",
"expires_in": 86400
}
],
"approved_at": "2026-08-23T18:09:30Z"
}
}
Notes:
delivery_ididentifies this delivery. It stays the same across every retry of the same delivery and differs for a fresh one, so it is the value to deduplicate on. It is also sent as anX-DailyLife-Deliveryheader, so you can discard a duplicate before parsing the body.eventidentifies the content stream.versionis1.1. Version1.0sent image paths with nourland nodelivery_id, and did not name the site.sitenames which location the post came from, or isnullfor content that is not tied to one. A group with several locations on one website needs this to file the post correctly.attemptis 1 on the first try and increases on each retry.timestampis the delivery generation time in UTC.
Images
Each entry in post.images carries a ready-to-use url alongside its path.
- The
urlis temporary.expires_inis the number of seconds it remains valid from the moment the delivery was generated, currently 24 hours. - Download and store each image when you receive it. Do not save the
urland serve it to your visitors: it will stop working, and it is not intended to be a public address. pathis a stable identifier for the same image across deliveries, which is useful if you want to avoid downloading a picture you already hold.- If an image cannot be prepared it is omitted rather than sent as a broken link, so an incomplete post is visible as one.
Retraction Payload
A content.retracted delivery has a different, deliberately minimal shape. There is nothing to display, only something to remove:
{
"delivery_id": "44444444-4444-4444-4444-444444444444",
"event": "content.retracted",
"version": "1.1",
"timestamp": "2026-09-02T09:00:00Z",
"org_id": "00000000-0000-0000-0000-000000000000",
"attempt": 1,
"content": {
"table": "gallery",
"id": "11111111-1111-1111-1111-111111111111"
}
}
Notes:
content.idmatches thepost.idfrom the original*.publisheddelivery for the same piece of content. Use it to find and remove what you stored.- There is no
postobject, no images and no signature verification difference: sign and verify a retraction the same way as any other delivery. - A retraction carries no title, body or images. There is nothing new to disclose, only an instruction to remove what you already hold.
- DailyLife does not verify that your website has actually removed the content. A
2xxresponse means you accepted the notice, the same as for a publish. What you do with it is your own implementation.
Signature Verification
You must verify the signature against the raw request body before processing the payload.
Verification steps:
- Read the raw body as bytes/text without reformatting.
- Compute
HMAC-SHA256(raw_body, your_shared_secret). - Compare your computed value with the value in
X-DailyLife-Signature. - Reject the request if values do not match.
Pseudocode:
rawBody = readRawBody(request)
header = request.headers["X-DailyLife-Signature"] // e.g. "sha256=abc123..."
received = header.removePrefix("sha256=")
computed = HMAC_SHA256_HEX(sharedSecret, rawBody)
if !timingSafeEqual(received, computed):
return 401
payload = parseJson(rawBody)
process(payload)
return 200
Retry Behaviour
If your endpoint does not return a success response, DailyLife retries:
- Attempt 1: immediate
- Attempt 2: +5 minutes
- Attempt 3: +15 minutes
After the third failed attempt, the delivery is marked as failed and is not retried again.
Content That Is Never Sent
Some approved content is deliberately not delivered.
Before every send, including every retry, DailyLife re-checks that everyone identified in a gallery post still has valid permission to appear in published material. If that permission has been withdrawn or has lapsed since the post was approved, the delivery is stopped and the post is returned to the care home's review queue.
Your endpoint receives nothing in that case. There is no request to respond to, and nothing has gone wrong at your end.
Content That Is Withdrawn After Publication
Unlike the case above, this applies to content your website has already received. A care home can retract a live post at any time, either because a manager decided to or because permission that was granted when the post went out has since been withdrawn. Either way you receive a content.retracted delivery naming the content to remove. See Retraction Payload above.
Response Expectations
Return:
2xxwhen you have accepted and processed the payload4xxif the request is invalid (for example, signature mismatch)5xxif your service is temporarily unavailable
Idempotency
Deliveries can arrive more than once: a retry follows any response that was not a success, including a success your server produced but could not return.
Store the delivery_id of everything you process and ignore a repeat. Do not deduplicate on post.id alone, because the same post being approved again after an edit is a genuinely new delivery that you should process.
Troubleshooting
- Signature mismatch: check that you verify the raw body and correct shared secret.
- Duplicate content: add idempotency checks using payload identifiers.
- Missing content: ensure your endpoint returns
2xxonly after successful processing. - Images that will not load: the
urlis temporary. Download the file when the delivery arrives and serve your own copy. - A post that never arrived at all: it may have been stopped because permission to publish somebody in it was withdrawn. The care home can see this in DailyLife.