Skip to main content

Webhooks & automation

InTransparency events in any tool

Five HMAC-SHA256-signed events, delivered to your HTTPS endpoint. Works today with Zapier, Make, n8n or any custom receiver.

Available events

match.created

A talent search you ran returned this candidate: one event for each candidate in the results. The candidate is identified only by a pseudonym and a first name with an initial, never a surname or an email.

Goes to the webhook subscriptions of the recruiter who ran the search

data: { matchId, candidateId, candidatePseudonym, candidateName, matchScore, decisionLabel, jobId, url }

credential.issued

A signed credential (W3C Verifiable Credential) was issued for a project, a completed internship or a professor's endorsement.

Goes to the student's own webhook subscriptions

data: { credentialId, credentialType, issuerName, issuedAt }

credential.revoked

A credential issued earlier was revoked; the event carries the reason.

Goes to the student's own webhook subscriptions

data: { credentialId, credentialType, revokedAt, reason }

stage.completed

The company tutor submitted the final evaluation of an internship.

Goes to the student's own webhook subscriptions

data: { stageExperienceId, placementId, companyName, completedAt }

exchange.completed

The host university marked an exchange as completed.

Goes to the student's own webhook subscriptions

data: { exchangeEnrollmentId, completedAt }

  1. 1. Create the subscription

    You need an API key (free, from your workspace). The subscription accepts any HTTPS URL — including a Zapier Catch Hook or a Make Custom Webhook.

    Shell

    # The key needs the agent:webhook scope (agent:write covers it too).
    # Tick "Webhooks" when you create it at /developers/keys.
    curl -X POST https://www.in-transparency.com/api/agents/webhooks \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "url": "https://hooks.zapier.com/hooks/catch/123456/abcdef/",
        "events": ["match.created"]
      }'
    
    # Response. The secret is shown exactly once, so store it now:
    # {
    #   "id": "cmh4p2x7k0002s8v3",
    #   "url": "https://hooks.zapier.com/hooks/catch/123456/abcdef/",
    #   "events": ["match.created"],
    #   "active": true,
    #   "createdAt": "2026-05-03T14:20:51.000Z",
    #   "secret": "3f8a…64 hex characters…c1",
    #   "message": "Store the secret — we use HMAC-SHA256 to sign every delivery…"
    # }
  2. 2. Receive deliveries

    Each event arrives as a JSON POST, and we wait up to 5 seconds for an answer. Today a delivery is attempted once — an error status or a timeout is not retried — so reply with a 2xx straight away and do the work afterwards. To skip duplicates, key on event plus eventId; X-InTransparency-Delivery names the single delivery.

    HTTP

    POST <your-url>
    Content-Type: application/json
    User-Agent: InTransparency-Webhook/1.0
    X-InTransparency-Signature: sha256=<hex HMAC-SHA256 of the raw body>
    X-InTransparency-Delivery: <delivery id>
    
    {
      "event": "match.created",
      "eventId": "cmh3x9q2a0001k7w4",
      "occurredAt": "2026-05-03T14:22:08.000Z",
      "data": {
        "matchId": "cmh3x9q2a0001k7w4",
        "candidateId": "cmh1k7w4n0007p2r9",
        "candidatePseudonym": "stu_4f2a91c0b6e54d12",
        "candidateName": "Giulia M.",
        "matchScore": 89,
        "decisionLabel": "STRONG_MATCH",
        "jobId": "cmh2b8r1v0003x5q1",
        "url": "https://www.in-transparency.com/en/matches/cmh3x9q2a0001k7w4/why"
      }
    }
  3. 3. Verify the signature

    Every delivery is signed with the subscription secret. Verify before trusting the payload (on Zapier/Make you may skip verification as long as the hook URL stays secret).

    Node.js

    // Node.js — check the signature before trusting the payload.
    // rawBody is the body exactly as it arrived (a Buffer or a string):
    // parsing and re-serialising it changes the bytes, and the HMAC with them.
    import crypto from 'crypto'
    
    function isValid(rawBody, signatureHeader, secret) {
      const expected = 'sha256=' +
        crypto.createHmac('sha256', secret).update(rawBody).digest('hex')
      const received = Buffer.from(signatureHeader || '')
      // timingSafeEqual throws when the lengths differ, so compare them first.
      return received.length === expected.length &&
        crypto.timingSafeEqual(received, Buffer.from(expected))
    }

No-code tool recipes

  • Zapier

    Webhooks by Zapier

    1. New Zap → "Webhooks by Zapier" trigger → Catch Hook
    2. Copy the hook URL
    3. Register it as a subscription (step 1 above)
    4. Wire actions: Slack, Sheets, CRM…
  • Make

    Custom webhook

    1. New scenario → "Webhooks" module → Custom webhook
    2. Copy the generated URL
    3. Register it as a subscription
    4. Make learns the payload shape on the first event
  • n8n

    Webhook node

    1. Add a "Webhook" node (POST)
    2. Use the node's production URL
    3. Register it as a subscription
    4. Verify the HMAC in a Function node

Need an API key?

API keys and subscription management are included in every plan. Reach out and we'll enable access.