Skip to content
API v1 preview — endpoints and fields may change before general availability.

Zapier

How do I call BetterJobs and receive its webhooks in Zapier?

View .md

BetterJobs has no native Zapier app. You use two built-in apps:

  • Webhooks by Zapier to call the API and to catch events.
  • Code by Zapier to check the event signature.
  1. Add an action step: Webhooks by Zapier → Custom Request.

  2. Set:

    Field Value
    Method POST
    URL https://api.betterjobs.cc/v1/jobs/search
    Headers Authorization = Bearer bj_live_..., BetterJobs-Version = 2026-10-01, Content-Type = application/json
  3. Paste the Data field:

    {
    "filters": {
    "company_domain_or": ["acme-robotics.example"],
    "title_or": ["Head of RevOps", "Revenue Operations"],
    "posted_within_days": 30
    },
    "waterfall": {
    "strategy": "cheapest_first",
    "max_credits": 5
    },
    "limit": 5
    }

    Replace acme-robotics.example (a fictional domain) with a field mapped from the trigger, for example a company domain from your CRM.

  4. Test the step. Zapier parses the JSON response into fields.

Zapier flattens the data array: each job field becomes a list, such as all titles joined. For one job per row, keep limit small and use the first value. For one action per job, add Looping by Zapier on the job id list.

Map metadata.credits_charged into a log column so you can see what each run cost. A run with no matching jobs returns data: [] and costs 0 credits.

Zapier is a poor fit for paging through hundreds of jobs. For large pulls, use an async search with webhook_url set to a Zapier catch hook, or use n8n or code.

BetterJobs POSTs one event per request and signs it with the BetterJobs-Signature header (t=<unix>,v1=<hex>). v1 is the HMAC-SHA256 of <t>.<raw body> with your endpoint secret. Check it before the Zap acts.

  1. Create a Zap with the trigger Webhooks by Zapier → Catch Raw Hook. Use Raw, not the plain Catch Hook: the signature covers the exact body bytes, and the plain trigger parses them first.
  2. Copy the webhook URL. Use it as webhook_url in POST /v1/watches or POST /v1/searches.
  3. Send a test event. POST /v1/webhooks/replay re-sends an existing event to its endpoint.
  4. In the test data, find the raw body field and the BetterJobs-Signature header field.

Zapier responds 200 as soon as it catches the request, which meets BetterJobs’ 10-second deadline.

Add Code by Zapier → Run Python (or Run JavaScript). Set the Input Data:

Key Value
raw_body The raw body field from the trigger
signature The BetterJobs-Signature header field from the trigger
secret Your endpoint secret

The secret lives in the step’s input field, not in the code.

import hashlib
import hmac
import json
import time
TOLERANCE_SECONDS = 300
parts = dict(p.split("=", 1) for p in input_data["signature"].split(","))
signed = f'{parts["t"]}.{input_data["raw_body"]}'.encode()
expected = hmac.new(input_data["secret"].encode(), signed, hashlib.sha256).hexdigest()
fresh = abs(time.time() - int(parts["t"])) <= TOLERANCE_SECONDS
valid = fresh and hmac.compare_digest(expected, parts["v1"])
event = json.loads(input_data["raw_body"]) if valid else {}
output = {
"valid": valid,
"type": event.get("type"),
"event_id": event.get("id"),
"job_id": event.get("data", {}).get("job", {}).get("id"),
}
  1. Add Filter by Zapier: only continue if valid is true.
  2. Add Paths by Zapier on type:
    • job.opened: start outbound. It is the only event that should.
    • job.reposted: update the record. Never re-trigger outbound.
    • job.closed: stop sequences tied to job_id.

Return more fields from the Code step if a later step needs them. The full payload of each event type is in the event catalog.

If a delivery does not get a 2xx within 10 seconds, BetterJobs retries for 24 hours with backoff. After that, replay any event with POST /v1/webhooks/replay. Replays are free. See Webhooks.