Skip to content
VakanssiDocs
VakanssiDocs
Get Vakanssi
esc

Integrations

Send Vakanssi's hiring events to Slack, Microsoft Teams, Zapier, Make, or your own service, with endpoints, the event catalog, automatic retries, a delivery log, and signature verification.

On this page(6)

Pro feature

Integrations Pro feature, requires a Vakanssi Pro license is part of Vakanssi Pro and runs while the Integrations module is switched on under Hiring, then Tools, then Features (see Managing features). Without it, the Integrations tab does not appear; the free plugin has no Integrations tab at all.

A webhook is a message your site sends to another service’s web address the moment something happens, with no polling and no copy-paste.

Vakanssi can send its hiring events to Slack, to Microsoft Teams, or to any webhook receiver: a Zapier Zap or a Make scenario (which can then update a spreadsheet, a CRM, or almost anything else), or a service your own team built. You choose where events go by adding endpoints on the Integrations tab.

Hiring, then Settings, then Integrations. Endpoints on top, the delivery log below.

Adding an endpoint

  1. Click Hiring in the left sidebar, then click Settings and open the Integrations tab.
  2. Click Add endpoint, or a Quick start preset (New applications, Stage changes, or Interviews to Slack) to open the form with the type and events already filled in.
  3. Fill in the form (fields below) and click Save endpoint. It appears in the Endpoints table.
  4. Click Send test on its row to confirm the connection. Vakanssi sends a sample “Application received” payload (a fake candidate named Jane Sample, marked as a test) and reports the result.

The endpoint form:

FieldWhat it does
LabelA name for your own reference, shown in the Endpoints table.
TypeWebhook (signed JSON) for Zapier, Make, or your own service; Slack (incoming webhook) for a Slack channel; Microsoft Teams (incoming webhook) for a Teams channel.
URLWhere events are delivered. Vakanssi shows a short tip for each type on how to get the URL. It must be a public http or https address: a local or private-network one (such as localhost, a .local name, or 10.0.0.5) is refused, and the endpoint is not saved.
EventsOne checkbox per hiring event (catalog below). Only the events you tick are delivered to this endpoint.
ActiveOn by default. Uncheck to pause deliveries to this endpoint without deleting it.
Signing secretGenerated automatically for a new endpoint and shown when you edit it. Used to sign webhook payloads (see Verifying webhook signatures). A “Regenerate secret on save” checkbox issues a new one.

Each row in the Endpoints table has Edit, Send test, and Delete actions. To save and test in one step, use Save & send test on the form.

The events

EventLabel in the formFires when
application.createdApplication receivedSomeone submits an application to one of your jobs.
application.stage_changedCandidate moved stageAn application moves to a different hiring stage.
application.hiredCandidate hiredAn application is moved to a Won (hired) stage.
application.rejectedCandidate rejectedAn application is moved to a Lost (rejected) stage.
application.assignedCandidate assignedAn application is assigned to a team member.
interview.scheduledInterview scheduledAn interview is scheduled, or a candidate self-books a time.
interview.canceledInterview canceledA scheduled interview is canceled.
evaluation.savedScorecard submittedA reviewer saves a scorecard.
candidate.sourcedCandidate sourcedA candidate is added manually on the Candidates screen.
note.addedNote addedA team member posts an internal note on a candidate.

Payloads are deliberately lean about personal data: the candidate appears as name and email only.

note.added carries who wrote the note and who it @mentions. With Collaboration Pro feature, requires a Vakanssi Pro license mentions on the note, the Slack and Teams line names both, for example “Avery mentioned Riley on Ava Johnson (Product Designer)”; a note with no mentions keeps the plain “Note added on…” wording.

The signed JSON payload always carries author and a mentions array (empty when there are none), plus a short note_excerpt of the note text.

Slack and Teams endpoints

A Slack or Teams endpoint posts one short, readable line to your channel per event, for example “New application: Ava Johnson applied for Product Designer”. You do not deal with any JSON.

To set one up, create an incoming webhook for the channel in Slack or Teams (each app has a feature for this that gives you a URL), then add a Vakanssi endpoint of the matching type and paste that URL. Vakanssi checks that the URL looks right for the type you picked and warns you if it does not.

How delivery works

  • Applicants are shielded from a slow or down receiver. Events are queued during the request and sent only after the page has finished responding. On most hosts (anywhere PHP can hand the response back to the browser first) an applicant never waits on a delivery at all, and each delivery gets five seconds.
  • On hosts that cannot hand the response back early (mod_php), each delivery is capped at two seconds instead, so a dead endpoint can delay the response only briefly. A delivery that misses that window is picked up by the automatic retry.
  • Big batches are not dropped. Since v0.35.2, when one request queues more deliveries than it can send in time (a bulk move of hundreds of candidates, say), the rest wait in the log as “Queued to send” and the retry task delivers them within a few minutes.
  • Automatic retries. A delivery that gets no response, a 429, or a 5xx error is tried up to four times in all, waiting 5 minutes, then 30 minutes, then 3 hours. A background task checks every 5 minutes; you do not have to do anything. Other errors, such as a 404, are not retried.
  • Turning off an endpoint, or unticking one of its events, cancels its pending retries. The next retry, automatic or by hand, checks the endpoint again first: if it is now switched off or no longer subscribed to that event, Vakanssi abandons the send instead of firing it, and the log shows why.
  • Send test and Resend. Send test on any endpoint delivers a sample payload immediately and reports the result. In the log, a delivery that failed or is waiting on a retry has a Resend link to try it again by hand right away.

The Recent deliveries log

Below the Endpoints table, Recent deliveries lists the latest delivery attempts, successes and failures alike, tests included. Each row shows when it happened, the event, the destination URL, how many tries it took, and the result: “OK” with the response code, “Failed” with the code and error, “Retry scheduled” or “Queued to send” with the time it goes out, or “Sending, no result yet”.

You can filter the log by endpoint. Entries are kept for 30 days, after which a daily task trims older rows.

How long a delivery's candidate data is kept

The event payload behind a delivery carries candidate data such as name and email. A delivery that succeeds, or that is abandoned because you switched off its endpoint or unsubscribed its event, has its payload cleared at once, keeping just the event, status, and response code.

Since v0.35.2, a delivery that failed for good keeps its payload for a day, long enough to fix the receiving end and click Resend, then the daily retention sweep clears it. After that the row shows no Resend link. A delivery still waiting on a retry a week later is given up on and cleared the same way.

If the candidate is erased or anonymised by the automatic retention purge while a delivery still holds their payload, their name and email are wiped from it immediately, and nothing empty is ever sent in its place. See Privacy & GDPR.

Verifying webhook signatures

For whoever builds the receiver

This section is for the developer building the receiving service. Zapier, Make, Slack, and Teams users can skip it. For the webhook-related filters, see Hooks.

Every Webhook-type delivery (not Slack or Teams) is a JSON POST with these headers:

HeaderContents
Content-Typeapplication/json
X-Vakanssi-EventThe event key, for example application.created.
X-Vakanssi-Signaturesha256= followed by the HMAC-SHA256 of the raw request body, keyed with the endpoint’s signing secret.
X-Vakanssi-DeliveryThe ID of this delivery. Since v0.33.40 it stays the same on every retry of the same event, so a receiver can drop duplicates.

To confirm a request really came from your site, recompute the signature over the raw body (before any parsing) and compare in constant time:

$secret    = 'your-endpoint-signing-secret';
$body      = file_get_contents( 'php://input' );
$signature = $_SERVER['HTTP_X_VAKANSSI_SIGNATURE'] ?? '';
$expected  = 'sha256=' . hash_hmac( 'sha256', $body, $secret );

if ( ! hash_equals( $expected, $signature ) ) {
    http_response_code( 403 );
    exit( 'Invalid signature' );
}

$payload = json_decode( $body, true );
// Trusted: handle the event.

Reject anything that fails the check. If you regenerate an endpoint’s secret, update the receiver at the same time.

The job title, stage, interview title and location, staff names, and note excerpt in the payload arrive as plain text, not HTML entities, so escape them yourself before putting them into HTML. The candidate’s name is the exception: it is sent as stored, since it comes from the public application form.