Webhooks: Stripe, Polar, Clerk

Billing and auth events reach Mara through the webhooks you already have. Each connector gets a per-tenant URL, verifies the provider's signature, and dedupes on the provider's event id, so redeliveries are safe. Setup is two pasted values: Mara's URL into the provider, the provider's signing secret into Mara.

Your per-tenant URLs and the secret fields live in Settings under Integrations. The raw markdown version of this page is at hiremara.com/docs/webhooks.md. For product events from your own code, see the Events API.

What journeys can trigger on

Provider events are normalized into eight lifecycle moments. Journeys trigger on these, not on raw provider payloads:

Mara event typeMeaning
subscription-startedA new subscription begins.
trial-convertedA trial becomes a paying subscription.
subscription-upgradedPlan or quantity changed upward.
subscription-canceledSubscription canceled or revoked.
payment-failedA renewal payment failed (dunning territory).
payment-recoveredA previously failing payment went through.
refund-issuedA charge was refunded.
purchaseA one-time purchase, not tied to a subscription.

Anything else the provider sends returns 200 with "status": "ignored". It is fine, and simplest, to send everything.

Custom fields you attach as provider metadata (Stripe subscription or checkout metadata, Polar order or customer metadata, Clerk public metadata) are projected onto the contact as attributes, with the same sanitization as the Events API: flat scalars only, secret-looking keys dropped, capped at 50 keys.

Stripe

Endpoint:

POST https://hiremara.com/api/webhooks/stripe/{tenantId}

Setup:

  1. In the Stripe dashboard, open Developers, then Webhooks, and add a destination with your per-tenant URL from Mara's settings page.
  2. Select these events (or send all): customer.subscription.created, customer.subscription.updated, customer.subscription.deleted, invoice.payment_failed, invoice.payment_succeeded, charge.refunded, checkout.session.completed.
  3. Copy the signing secret (whsec_...) and paste it into Settings, Integrations, Billing, Stripe.

How Stripe events map:

Stripe eventBecomes
customer.subscription.createdsubscription-started
customer.subscription.updatedtrial-converted when status goes trialing to active; subscription-upgraded when the plan or items changed; otherwise ignored.
customer.subscription.deletedsubscription-canceled
invoice.payment_failedpayment-failed
invoice.payment_succeededpayment-recovered, only when it recovers a failing invoice. First-attempt successes are ignored.
charge.refundedrefund-issued
checkout.session.completedpurchase, only for mode=payment (one-time). Subscription checkouts are already covered above.

Requests are verified with the stripe-signature header against your pasted secret. Wrong or missing signature returns 401; a tenant with no secret configured returns 412.

Polar

Endpoint:

POST https://hiremara.com/api/webhooks/polar/{tenantId}

Setup:

  1. In Polar, open your organization settings, then Webhooks, and add an endpoint with your per-tenant URL.
  2. Select the subscription and order events (or send all).
  3. Copy the signing secret and paste it into Settings, Integrations, Billing, Polar.

How Polar events map:

Polar eventBecomes
subscription.createdsubscription-started
subscription.activetrial-converted
subscription.upgradedsubscription-upgraded
subscription.canceled, subscription.revokedsubscription-canceled
subscription.past_duepayment-failed
subscription.recoveredpayment-recovered
order.refundedrefund-issued
order.paidpurchase, only for orders not tied to a subscription. Renewal cycles are ignored.

Signatures follow the Standard Webhooks spec (webhook-id, webhook-timestamp, webhook-signature headers).

Clerk

Endpoint:

POST https://hiremara.com/api/webhooks/clerk/{tenantId}

Setup:

  1. In the Clerk dashboard, open Webhooks and add an endpoint with your per-tenant URL.
  2. Subscribe to user.created, user.updated, and user.deleted.
  3. Copy the Svix signing secret and paste it into Settings, Integrations, Clerk.

What each event does: user.created creates the contact and records a user.created event, which can fire your welcome journey (map it as the signup event on the settings row). user.updated refreshes the contact's email and name. user.deleted records a deactivation signal. Mara projects the email, username, avatar URL, and public metadata; private and unsafe metadata are never read.

Optional backfill: paste a Clerk Backend API key on the same settings row and Mara imports your existing users as contacts, so journeys do not start from an empty list.

Verify it is flowing

After setup, trigger a test event (most providers have a "send test event" button) and check the ingestion health strip in Settings, Integrations: it shows per-connector contact counts and last activity. Or ask Mara in chat.