Skip to main content
/

Webhooks

Webhooks allow AlchemOS Positive to push real-time event notifications to your application instead of requiring you to poll the API.


Supported events

Event Triggered when
emission.created New emission entry created
emission.updated Emission entry edited
emission.approved Entry moved to Approved state
emission.locked Entry locked (reporting period closed)
report.generated Report generation job completed
offset.purchased Credit purchase order confirmed
offset.retired Registry confirms a retirement
certificate.issued Certificate approved and issued
certificate.revoked Certificate revoked
target.milestone.achieved Milestone year passed; target met
target.milestone.missed Milestone year passed; target missed
user.invited New team member invited
user.deactivated Team member deactivated

Creating a webhook endpoint

  1. Go to Settings → Webhooks → Add Endpoint
  2. Enter your endpoint URL (must be HTTPS)
  3. Select the events to subscribe to
  4. Optionally add a description
  5. Click Save

AlchemOS Positive will send a test ping event immediately to confirm reachability.


Creating a webhook via API

POST /api/v1/settings/webhooks
{
  "url": "https://yourapp.com/webhooks/alchemos",
  "events": ["emission.approved", "certificate.issued", "offset.retired"],
  "description": "ERP integration listener"
}

Response (201)

{
  "data": {
    "id": "wh_abc123",
    "url": "https://yourapp.com/webhooks/alchemos",
    "signingSecret": "whsec_xxxxxxxxxxxxxxxxxxxx",
    "events": ["emission.approved", "certificate.issued", "offset.retired"],
    "status": "active"
  }
}

Save the signingSecret — it is shown only once and is used to verify webhook authenticity.


Webhook payload structure

{
  "id": "evt_xyz789",
  "type": "emission.approved",
  "createdAt": "2024-11-01T09:05:00Z",
  "organisationId": "org_001",
  "data": {
    "id": "em_abc123",
    "scope": 1,
    "tco2e": 0.273,
    "state": "approved"
  }
}

The data object mirrors the corresponding REST API response for that resource type.


Verifying webhook signatures

Every webhook request includes an Alchemos-Signature header. Verify it to ensure the request came from AlchemOS Positive and was not tampered with.

Alchemos-Signature: t=1730000000,v1=abc123def456...

Verification algorithm

  1. Extract t (timestamp) and v1 (signature) from the header
  2. Construct the signed payload: {t}.{raw_request_body}
  3. Compute HMAC-SHA256 using your signingSecret
  4. Compare the result to v1

TypeScript example

import crypto from 'crypto';

function verifyWebhook(payload: string, header: string, secret: string): boolean {
  const parts = Object.fromEntries(header.split(',').map(p => p.split('=')));
  const signedPayload = `${parts.t}.${payload}`;
  const expected = crypto
    .createHmac('sha256', secret)
    .update(signedPayload)
    .digest('hex');
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}

Reject requests where:

  • Signature verification fails
  • The t timestamp is more than 5 minutes in the past (replay attack protection)

Retries and delivery guarantees

AlchemOS Positive delivers webhooks at least once. If your endpoint returns a non-2xx response or times out (10-second timeout), retries occur:

Attempt Delay
1st retry 30 seconds
2nd retry 5 minutes
3rd retry 30 minutes
4th retry 2 hours
5th retry 8 hours

After 5 failed retries, the event is marked failed and no further retries occur. Review failed events in Settings → Webhooks → → Delivery Log.


Testing webhooks

Use Settings → Webhooks → → Send Test Event to send a sample payload for any event type. Useful for testing your receiver locally.

For local development, use a tunnel tool such as ngrok or Cloudflare Tunnel to expose your local server.


Managing webhooks

Endpoint Description
GET /api/v1/settings/webhooks List all endpoints
GET /api/v1/settings/webhooks/{id} Get endpoint details
PATCH /api/v1/settings/webhooks/{id} Update URL or events
DELETE /api/v1/settings/webhooks/{id} Delete endpoint
GET /api/v1/settings/webhooks/{id}/deliveries List delivery history
POST /api/v1/settings/webhooks/{id}/test Send test event

Was this page helpful?