Starting with webhooks

Webhooks allow external services to be notified when certain events happen. When the specified events happen, we’ll send a POST request to each of the URLs you provide.

Setting up a webhook

Go to Settings -> Webhooks -> Add new webhook.

You will see 4 fields:

  • Name - name your webhook so you can find it later
  • Payload URL - it's the URL of the server that will receive the webhook POST requests.
  • Secret - you can add a string to use as a secret key, this is optional.
  • Topics - events that you would like to be notified of happening; you can choose multiple.

Once all fields are filled you are ready to go! Save your new webhook and try it out.


Secrets in webhooks are random strings or tokens used for authentication and security purposes. When setting up a webhook, you can optionally add a secret key, which is then shared between PeopleForce and your server or application. This secret key is used to sign requests sent from the webhook provider to the recipient, ensuring that only legitimate requests are accepted. It adds an extra layer of security by preventing unauthorized access or tampering with webhook payloads.

If you define a secret key, the webhook will include an additional header x-peopleforce-signature. This signature helps verify the origin of the webhook. Without knowledge of the secret key, it's impossible for someone else to send events via webhook and generate a matching x-peopleforce-signature.

To verify the signature, follow these rules:

• The signature is computed using HMAC-SHA256, combining your webhook's secret key with the payload's contents.
• The computed hash should be a hexadecimal digest.
• The signature format in the headers starts with sha256=.
• Use a constant time string comparison to compare the generated hash with the one in the X-PeopleForce-Signature header to prevent timings attack.
• Treat the payload as UTF-8 encoded text during this process.

Code examples:


def verify_signature(payload_body, signature_header)
  secret_key = ENV['WEBHOOK_SECRET']
  computed_signature = 'sha256=' + OpenSSL::HMAC.hexdigest('sha256'), secret_key, payload_body)
  unless Rack::Utils.secure_compare(computed_signature, signature_header)
    return halt 500, "Signatures didn't match!"


import hmac
import hashlib
import os

def verify_signature(payload_body, signature_header):
    secret_token = os.getenv('WEBHOOK_SECRET')
    if not signature_header:
        raise HTTPException(status_code=403, detail="Missing signature header!")

    hash_object ='utf-8'), msg=payload_body.encode('utf-8'), digestmod=hashlib.sha256)
    expected_signature = 'sha256=' + hash_object.hexdigest()

    if not hmac.compare_digest(expected_signature, signature_header):
        raise HTTPException(status_code=403, detail="Signatures did not match!")

Testing webhook

When the event will be triggered PeopleForce will deliver the JSON payload directly as the body of the POST request.
You can give it a try of your webhook by using (WARNING: external link. Please be mindful of your data).

Add your unique URL as Payload URL into your webhook in PeopleForce.
Then go and trigger the selected event (topic), for example, if you want to know about new employees created - create one.
Check the request you received. For the new employee created it would look very similar to this:

  "action": "employee_create",
  "data": {
    "id": 130333,
    "attributes": {
      "employee_number": "PF124593",
      "hired_on": "2022-09-12",
      "probation_ends_on": "2022-12-12",
      "first_name": "John",
      "last_name": "Doe",
      "email": "[email protected]",
      "personal_email": null,
      "gender": "male",
      "mobile_number": "",
      "work_phone_number": "",
      "date_of_birth": "1978-08-31",
      "termination_effective_date": null,
      "termination_comment": null,
      "avatar_url": null
    "reporting_to": {
      "id": 5844,
      "full_name": "Ross Kate",
      "email": "[email protected]"
    "employment_type": {
      "id": 1899,
      "name": "Full-Time"
    "position": {
      "id": 11943,
      "name": "Senior Developer"
    "department": {
      "id": 5094,
      "name": "IT"
    "division": {
      "id": 1819,
      "name": "Europe"
    "location": null,
    "custom_fields": {
      "2692d87e-c388-49ea-b903-616bc1557746": {
        "name": "T-shirt size",
        "value": "M",
        "group": "Personal"
    "meta": {
      "created_at": "2022-09-05T18:33:55.130+03:00",
      "updated_at": "2022-09-05T18:33:55.526+03:00"

Webhook execution history

Want to make sure your webhook was sent?
Go to Settings -> Webhooks -> and click on your webhook name.
It will open your history of webhook execution.
Clicking on the name of the delivery you can view the raw data that was sent.


Did something go wrong? Maybe you did not receive your webhook or received not what you expected?

  1. Check your Payload URL, make sure it's correct, and that server that will be receiving webhook supports webhooks.
  2. Check the history of your webhook runs. If the webhook was delivered repeat step 1 and proceed to step 3.

200 Success

Webhook was delivered

404 Not Found

The resource could not be found. Please check that your request is referring to an existing object.

500 Internal Server Error

There was a problem with our server. Try again later or contact support to learn more.

  1. Check your recipient server to be up and running and not to have any issues.

If neither of these helps feel free to contact us