Webhooks
Subscribe to real-time events from the Jobiflow platform
Webhooks
Webhooks let you receive real-time HTTP notifications when events occur in your Jobiflow account — for example, when a new application arrives or an applicant's status changes.
Registering a Webhook
POST /public/v1/webhooks
X-API-Key: <your_key>
Content-Type: application/json
{
"url": "https://yourapp.example.com/webhooks/jobiflow",
"events": ["application.created", "application.status_changed"],
"secret": "my_webhook_signing_secret"
}The secret field is optional but strongly recommended — it is used to sign each delivery so your endpoint can verify authenticity.
Supported Events
| Event | Description |
|---|---|
application.created | A new application was submitted (internal or external) |
application.status_changed | An application's status was updated |
application.rejected | An applicant was moved to the Rejected stage |
application.selected | An applicant was marked as Selected |
job_listing.created | A new job listing was created |
job_listing.published | A job listing was published and made public |
job_listing.closed | A job listing was closed |
job_listing.archived | A job listing was archived |
candidate.imported | A candidate was imported into the company pipeline |
Webhook Payload
Every delivery is a POST request with a JSON body:
{
"id": "evt_01HYZ1234ABCDE",
"event": "application.created",
"timestamp": "2026-05-17T12:34:56Z",
"companyId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"data": {
"id": "a1b2c3d4-...",
"jobListingId": "f9e8d7c6-...",
"status": "ACTIVE",
"source": "EXTERNAL",
"appliedAt": "2026-05-17T12:34:55Z",
"candidate": {
"id": "00000000-...",
"firstName": "Jane",
"lastName": "Doe",
"email": "jane@example.com"
}
}
}Verifying Signatures
When a secret is configured, Jobiflow signs each delivery with HMAC-SHA256 and includes the signature in the X-Jobiflow-Signature-256 header:
X-Jobiflow-Signature-256: sha256=<hex_digest>Verify it in your endpoint to reject forged requests:
import { createHmac, timingSafeEqual } from 'node:crypto';
function verifyWebhook(rawBody: string, secret: string, header: string): boolean {
const expected = 'sha256=' + createHmac('sha256', secret).update(rawBody).digest('hex');
return timingSafeEqual(Buffer.from(expected), Buffer.from(header));
}Always use timingSafeEqual (or your language's equivalent) when comparing signatures to prevent timing attacks.
Retries & Delivery Guarantees
- Jobiflow expects a 2xx response from your endpoint within 10 seconds.
- If the endpoint returns a non-2xx or times out, delivery is retried with exponential back-off: immediately, +1 min, +5 min, +30 min, +2 h, +8 h (6 attempts total).
- After all retries are exhausted, the delivery is marked as failed. Check your webhook logs in the dashboard.
- Events are delivered at least once — your endpoint should be idempotent (use the
idfield to deduplicate).
Testing a Webhook
Send a test ping to verify your endpoint is configured correctly:
POST /public/v1/webhooks/{id}/test
X-API-Key: <your_key>The response contains the HTTP status code and body returned by your endpoint.
Managing Webhooks
| Action | Endpoint |
|---|---|
| List all subscriptions | GET /public/v1/webhooks |
| Create a subscription | POST /public/v1/webhooks |
| Update URL / events / active state | PATCH /public/v1/webhooks/{id} |
| Delete a subscription | DELETE /public/v1/webhooks/{id} |
| Send a test ping | POST /public/v1/webhooks/{id}/test |