Developers

Webhooks

Receive events as they happen and verify their signature.

Webhooks POST a JSON event to your URL when something happens to your company's trees. Create endpoints in the Platform dashboard at Settings > Webhooks or through the API (webhooks:manage).

These are the outgoing webhooks of the Platform to your systems. The Platform itself receives its data from the WoodYouCare Foundation; every Foundation event that touches your company becomes one of the events below.

Events

The events follow the lifecycle of an allocation. Every payload is documented under Webhook events in the reference.

TypeSent when
allocation.createdTrees were pledged to your company (the Foundation registered a donation)
allocation.plantedThe planting behind an allocation was done; the dossier has a date, polygon and species
allocation.monitoredA first monitoring measurement was recorded for the planting of an allocation
allocation.updatedThe number of trees of an allocation changed, for example after a refund; data.previous holds the old value
planting.updatedThe proof dossier of a planting was extended: photos, species, notes or another monitoring measurement
verification.publishedA verification statement was published for a project of yours
recipient.createdA recipient was created through the API, in the dashboard, by a gift code or by the Foundation
recipient.claimedA person claimed one of your gift codes and became a recipient
certificate.createdA certificate was generated or regenerated

Payload

{
  "id": "whevt_01K...",
  "object": "event",
  "type": "allocation.planted",
  "created": "2026-10-01T12:00:00Z",
  "livemode": true,
  "data": {
    "object": { "id": "alloc_01K...", "object": "allocation", "status": "planted", "trees": 250 }
  }
}

data.object is the same object the matching GET endpoint returns. Personal data of recipients is only included when the endpoint was set up to receive it.

Verify the signature

Every request carries a WoodYouCare-Signature header:

WoodYouCare-Signature: t=1790000000,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd

Compute an HMAC-SHA256 of {t}.{raw request body} with your endpoint's signing secret and compare it with v1. Reject requests where t is more than five minutes old.

import crypto from 'node:crypto';

export function verify(rawBody, header, secret) {
  const parts = Object.fromEntries(header.split(',').map((part) => part.split('=')));
  const expected = crypto.createHmac('sha256', secret).update(`${parts.t}.${rawBody}`).digest('hex');
  const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;

  return fresh && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}

Delivery

  • Answer with any 2xx status within 10 seconds. Do the real work afterwards, for example on a queue.
  • Failed deliveries are retried for about a day with increasing delays.
  • An endpoint that keeps failing for three days is switched off; its owners get an email.
  • The same event can arrive more than once. Store id and skip events you already processed.
  • Redirects are not followed, and endpoints must be public HTTPS URLs.
  • Missed something? GET /v2/events lists the last 30 days with delivery status, and POST /v2/events/{id}/redeliver sends one again.

On this page