Skip to main content

Overview

Webhooks allow you to receive HTTP notifications when events occur in your Polar account, such as completed checkouts, new subscriptions, or updated orders.

The Webhook Endpoint Object

id
string
required
Unique identifier
url
string
required
Webhook URL to receive events
secret
string
required
Secret for verifying webhook signatures
events
array
required
Array of event types to receive
organization_id
string
required
Organization ID
created_at
string
required
Creation timestamp

List Webhook Endpoints

cURL
curl -X GET "https://api.polar.sh/v1/webhooks/endpoints" \
  -H "Authorization: Bearer polar_pat_..."

Query Parameters

organization_id
string
Filter by organization

Get Webhook Endpoint

cURL
curl -X GET "https://api.polar.sh/v1/webhooks/endpoints/{id}" \
  -H "Authorization: Bearer polar_pat_..."

Path Parameters

id
string
required
Webhook endpoint ID

Create Webhook Endpoint

cURL
curl -X POST "https://api.polar.sh/v1/webhooks/endpoints" \
  -H "Authorization: Bearer polar_pat_..." \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/webhooks/polar",
    "events": [
      "checkout.confirmed",
      "subscription.created",
      "order.created"
    ],
    "organization_id": "org_123"
  }'

Request Body

url
string
required
HTTPS URL to receive webhook events
events
array
required
Event types to subscribe to
organization_id
string
Organization ID (required unless using org token)

Response

Returns the webhook endpoint object including the secret for signature verification.

Update Webhook Endpoint

cURL
curl -X PATCH "https://api.polar.sh/v1/webhooks/endpoints/{id}" \
  -H "Authorization: Bearer polar_pat_..." \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
      "checkout.confirmed",
      "subscription.created",
      "subscription.updated",
      "order.created"
    ]
  }'

Path Parameters

id
string
required
Webhook endpoint ID

Request Body

url
string
Update webhook URL
events
array
Update subscribed events

Delete Webhook Endpoint

cURL
curl -X DELETE "https://api.polar.sh/v1/webhooks/endpoints/{id}" \
  -H "Authorization: Bearer polar_pat_..."

Path Parameters

id
string
required
Webhook endpoint ID

List Deliveries

cURL
curl -X GET "https://api.polar.sh/v1/webhooks/endpoints/{id}/deliveries" \
  -H "Authorization: Bearer polar_pat_..."
View delivery history for a webhook endpoint.

Path Parameters

id
string
required
Webhook endpoint ID

Query Parameters

succeeded
boolean
Filter by delivery status
start_timestamp
string
Filter deliveries after this timestamp
end_timestamp
string
Filter deliveries before this timestamp

Redeliver Webhook

cURL
curl -X POST "https://api.polar.sh/v1/webhooks/deliveries/{id}/redeliver" \
  -H "Authorization: Bearer polar_pat_..."
Retry a failed webhook delivery.

Path Parameters

id
string
required
Delivery ID

Event Types

Checkout Events

checkout.created
A new checkout session was created
checkout.updated
A checkout session was updated
checkout.confirmed
A checkout was confirmed and payment succeeded

Order Events

order.created
A new order was created
order.updated
An order was updated

Subscription Events

subscription.created
A new subscription was created
subscription.updated
A subscription was updated
subscription.canceled
A subscription was canceled
subscription.revoked
A subscription was revoked

Customer Events

customer.created
A new customer was created
customer.updated
A customer was updated

Benefit Events

benefit_grant.created
A benefit was granted to a customer
benefit_grant.revoked
A benefit was revoked from a customer

Webhook Payload

All webhooks include:
{
  "type": "checkout.confirmed",
  "data": {
    // Event-specific data
  },
  "timestamp": "2024-01-15T10:30:00Z",
  "id": "evt_123"
}

Signature Verification

Verify webhook authenticity using the Polar-Signature header:
import hmac
import hashlib

def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(signature, expected)
import crypto from 'crypto';

function verifyWebhook(
  payload: string,
  signature: string,
  secret: string
): boolean {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

Examples

Create Webhook for All Events

curl -X POST "https://api.polar.sh/v1/webhooks/endpoints" \
  -H "Authorization: Bearer polar_pat_..." \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://myapp.com/webhooks/polar",
    "events": [
      "checkout.confirmed",
      "order.created",
      "subscription.created",
      "subscription.updated",
      "subscription.canceled",
      "customer.created"
    ],
    "organization_id": "org_xyz"
  }'

Handle Webhook in Express.js

app.post('/webhooks/polar', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['polar-signature'] as string;
  const payload = req.body;
  
  if (!verifyWebhook(payload.toString(), signature, WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  
  const event = JSON.parse(payload.toString());
  
  switch (event.type) {
    case 'checkout.confirmed':
      // Handle confirmed checkout
      break;
    case 'subscription.created':
      // Handle new subscription
      break;
  }
  
  res.sendStatus(200);
});

Build docs developers (and LLMs) love