Recipes

Zapier recipe

Receive Cortex triggers as a Zap. Catch Hook trigger + Code (JavaScript) step for HMAC verification + an action step that hits one of Zapier's 7,000+ app integrations + a Webhooks step to trigger.complete.

Why Zapier

  • Reach — 7,000+ pre-built app integrations downstream.
  • No infra required; runs entirely in Zapier's cloud.
  • Good fit when you want triggers to feed into many SaaS tools at once.

Zap shape

  1. Trigger: “Webhooks by Zapier” → “Catch Raw Hook” (raw matters — we need the unparsed body for signature verification).
  2. Code step: JavaScript — verify HMAC, parse the trigger (snippet below).
  3. Action step(s): Slack send, Gmail send, Twilio SMS, anything Zapier supports.
  4. Final step: “Webhooks by Zapier” → “POST” to /v1/triggers/{trigger_id}/complete.

Code step — verify the signature

javascriptZapier Code by Zapier (JavaScript)
// Inputs:
//   inputData.rawBody       — the raw POST body from Catch Raw Hook
//   inputData.signature     — value of "X-Cortex-Signature" header
//   inputData.timestamp     — value of "X-Cortex-Timestamp" header
//   inputData.webhookSecret — your stored webhook secret

const crypto = require('crypto');
const FIVE_MIN = 5 * 60 * 1000;

const sig = (inputData.signature || '').replace(/^sha256=/, '');
const ts  = inputData.timestamp || '';

const tsMs = Date.parse(ts);
if (Number.isNaN(tsMs) || Math.abs(Date.now() - tsMs) > FIVE_MIN) {
  throw new Error('stale_or_bad_timestamp');
}

const expected = crypto
  .createHmac('sha256', inputData.webhookSecret)
  .update(ts + '.' + inputData.rawBody, 'utf8')
  .digest('hex');

const a = Buffer.from(expected, 'hex');
const b = Buffer.from(sig, 'hex');
if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) {
  throw new Error('signature_invalid');
}

const trigger = JSON.parse(inputData.rawBody);
output = {
  trigger_id:    trigger.trigger_id,
  action_class:  trigger.action_class,
  mode:          trigger.mode,
  body:          trigger.payload?.body || '',
  counterparty:  trigger.counterparty?.display_name || '',
};

Final step — trigger.complete

Use the Webhooks by Zapier “POST” action with:

  • URL: https://mcp.cortex.jakeselby.com/v1/triggers/{{trigger_id}}/complete
  • Payload type: JSON
  • Headers: Authorization: Bearer YOUR_TOKEN, Idempotency-Key: cb_{{trigger_id}}
  • Data: outcome=executed, external_ref={{previous_step_id}}, executed_at={{zap_meta_human_now}}