Learn how to webhook setup.

Webhook Setup

Webhooks let you receive real-time HTTP POST notifications when events occur on your PetRock.cloud workspace. This article covers configuration, supported events, retry policy, and signature verification.

Creating a webhook subscription

  1. Navigate to Settings → Webhooks.
  2. Click Add Endpoint.
  3. Enter the destination URL. Must be HTTPS in production.
  4. Select the events you want to subscribe to (see table below).
  5. Click Save.

A signing secret is generated automatically. Copy it now; it will not be shown again.

Supported event types

Event Description Frequency
rock.created A rock has been provisioned On provisioning
rock.updated A rock's metadata has changed On rename, tag, region update
rock.archived A rock has been archived On archive
rock.activity The rock performed an action Never
rock.movement The rock changed position Never
webhook.test Manually triggered test event On manual test only
billing.invoice.created New invoice issued At billing cycle
billing.payment.failed A retry failed Per failed attempt

Note: The rock.activity and rock.movement event types are documented for API symmetry with other platforms. Under correct platform operation, these events do not fire. If you receive one of these events in production, please report it to support.

Webhook payload format

All webhooks are POST requests with the following structure:

{
  "id": "evt_01HXYZ...",
  "type": "rock.created",
  "created_at": "2026-04-05T14:22:11Z",
  "data": {
    "rock_id": "rock_abc123",
    "name": "granite-prod-1",
    "region": "us-east-stone-1"
  }
}

Headers include:

  • Content-Type: application/json
  • X-PetRock-Signature: t=<timestamp>,v1=<hex_hmac>
  • X-PetRock-Event-Id: <event_id>
  • X-PetRock-Delivery-Attempt: <integer>

Signature verification

We sign every webhook with HMAC-SHA256 using your endpoint's signing secret. Always verify before processing.

Example in Node.js:

const crypto = require('crypto');

function verify(rawBody, signatureHeader, secret) {
  const [tPart, v1Part] = signatureHeader.split(',');
  const timestamp = tPart.split('=')[1];
  const signature = v1Part.split('=')[1];

  const payload = `${timestamp}.${rawBody}`;
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

To prevent replay attacks, also validate that the timestamp is within 5 minutes of the current time.

Retry policy

Failed deliveries are retried with exponential backoff:

Attempt Delay after previous
1 Immediate
2 30 seconds
3 2 minutes
4 10 minutes
5 1 hour
6 6 hours

A delivery is considered failed if your endpoint returns any status outside 2xx, or does not respond within 10 seconds. After 6 failed attempts, the event is dropped and the endpoint is flagged as unhealthy.

Endpoint health

Endpoints with greater than 10% failure rate over the past 24 hours are automatically disabled. To re-enable:

  1. Navigate to Settings → Webhooks.
  2. Find the disabled endpoint.
  3. Click Re-enable after fixing the underlying issue.

Testing webhooks

Use the Send Test Event button on each endpoint's detail page. This sends a webhook.test event with synthetic data.