Send Cursor Origin webhook events straight into Axiom. One serverless function, zero dependencies. Deploy your own copy for free — your data never touches anyone else's infrastructure.
- In Axiom: create a dataset (e.g.
origin) and an API token with ingest permission for it. - Click the deploy button above and set:
AXIOM_TOKEN— the Axiom API tokenAXIOM_DATASET— the dataset nameAXIOM_URL— optional, defaults tohttps://api.axiom.co(set for EU region)
- Open
https://<your-deployment>.vercel.app— the setup page checks your config live and shows your webhook URL. - In Origin app settings, set your app's webhook URL to:
https://<your-deployment>.vercel.app/api/webhook - Subscribe to the events you want. They land in your dataset within seconds.
Each delivery is verified (Ed25519 signature against Origin's JWKS, 5-minute timestamp window) and flattened to:
{
"_time": "<event.eventTime>",
"type": "pull_request.merged",
"eventId": "evt_01...",
"deliveryId": "whd_01...",
"appId": "app_01...",
"installationId": "i_01...",
"payload": { ... }
}Failed Axiom ingests return 5xx so Origin redelivers (up to 6 retries). Deliveries are at-least-once — dedup on deliveryId in queries if exactness matters.
Field paths below are verified against real Origin events. pull_request.merged events carry both createdAt and mergedAt, so cycle time needs no joins:
['origin']
| where type == 'pull_request.merged'
| extend cycle_min = datetime_diff('minute',
todatetime(['payload.pullRequest.mergedAt']),
todatetime(['payload.pullRequest.createdAt']))
| summarize avg(cycle_min) by bin_auto(_time)Push activity by author:
['origin']
| where type == 'repository.pushed'
| summarize count() by author = tostring(['payload.pusher.user.email']), bin_auto(_time)npm test