This explains how you can use the webhook to keep your surrounding systems up to date.
Save time and increase data quality by automating updates to any other system β a simple way to import and keep people synchronized between your organization in Huma and your other systems or services.
The formats can be subject to change.
Supported features
- Employee profile events π
- Specific event for changing email used for login to a profile π
- Automated updates when users are added or removed
Whenever a user is created or deleted in Huma, a message is automatically sent to the url registered. - Automatically receive real-time updates when a profile is changed in Huma
Changes made in the supported profile fields (listed below) will be automatically sent as updates to the url registered. - Export current state of user profiles, including Custom Fields
To initialise state for the system connecting by webhook, exporting will send updates for each employee with all current field values.
- Team & Location events π
- Team & Location updates
Updates are sent for the creation, update, or deletion of a Team or Location.
- Membership changes
Receive events whenever users are added to, or removed from a Team or Location
- Team & Location updates
- Absence events π
- Automated updates when absences are registered or removed
Whenever a new absence is registered, or an existing one is removed, a message is automatically sent to the url registered - Receive real-time updates when an absence entry is reviewed, or otherwise edited
Most commonly, a message will be sent when an absence request is accepted or rejected, but changing the requested dates, editing the explanatory note, or any other change will also cause a message to be sent.
- Automated updates when absences are registered or removed
Can I use webhooks for service "X"?
It is very common to have a "middle service" between the webhook and third party, that re-writes the format of the message so it is tailored to the receiver. Some of our customers let their IT-department make their own service to receive webhooks and send the message onwards to one or several of their systems, transformed to a format that those systems understand. Other customers outsource this to "middle service"-suppliers. For a general example, please check out this article.
How to use the webhook
To access Integrations under System settings you'll need a System role with permissions to do Organization-wide settings. Read more here
To get started, go to System settings/Integrations/Webhooks and click connect, simply provide an url which can receive the requests the webhook will send. You can also register a client secret and/or an access token.
Both Access Token and Client Secret are optional to use. They offer two different ways for the receiver to confirm that the sender is their actual Huma account. Whether this is necessary is up to you to decide.
-
If the client secret is set, each request will include a header [huma-hmac-sha256] with a hash of the json body, signed with the secret to verify the message.
-
If the access token is set, each request will include it as a standard bearer token.
Changing a profile's main email, the topic will be:
-
user-email-update
Because the profile email is used for logging in to the service, there are extra steps when changing it, and the webhook event is sent as its own topic.
βΉοΈ Note: a profile can have a private email address, which is treated as a normal field, since it does not affect authentication. Any changes to it will be sent in a users-update
topic, see profile update event, and supported fields, below.
For profile data, the topic will be one of:
-
users-create
-
users-update
-
users-delete
-
users-export
For Team & Location events, the topic will be one of:
-
groups-create
-
groups-update
-
groups-delete
-
groups-export
-
groups-add-members
-
groups-remove-members
For absence data, the topic will be one of:
-
absence-create
-
absence-update
-
absence-delete
-
absence-export
Be aware, if a request is not handled within 1 second, it will time out, so it may be useful to persist received data and respond, then do any further work to the data in a separate process
Profile email change event π
These events include a single object [user], which identifies the affected user. This object contains:
-
id
- Always present
- A unique identifier for the user
- This value will remain unchanged over the userβs lifetime.
- Value is a standard 128-bit UUID (see rfc4122)
-
oldEmail
- Always present
- The email that previously identified the profile
- Value is a string, validated to be an email address
-
newEmail
- Always present
- The email that identifies the profile from now on
-
- Value is a string, validated to be an email address
-
employmentId
- Present if set, absent if the user does not have one
- A unique identifier at the point where the request is sent: no two users can have the same employment ID
- Note that a userβs employment ID can be changed, or removed, by a user with the appropriate permission, so a user is not guaranteed to have the same value in later requests.
- Value is a string, no restriction other than uniqueness within the organization
Example:
{
"topic": "user-email-update",
"user": {
"id": "d96434d7-9506-4d5f-a969-7d1eea8bc3d6",
"oldEmail": "jesper@godmat.no",
"newEmail": "jesper.blom@godmat.no",
"employmentId": "1"
}
}
Profile events π
All request bodies also include a [users] array, which contains an object for each affected user. These objects will always contain:
-
id
- Always present
- A unique identifier for the user
- This value will remain unchanged over the userβs lifetime.
- Value is a standard 128-bit UUID (see rfc4122)
-
email
- Always present
- A unique identifier at the point where the request is sent: no two users can have the same email
- Note that a userβs email can be changed by a user with the appropriate permission (see , so a user is not guaranteed to have the same value in later requests.
- Value is a string, validated to be an email address
-
employmentId
- Present if set, absent if the user does not have one
- A unique identifier at the point where the request is sent: no two users can have the same employment ID
- Note that a userβs employment ID can be changed, or removed, by a user with the appropriate permission, so a user is not guaranteed to have the same value in later requests.
- Value is a string, no restriction other than uniqueness within the organization
-
status
- Always present
-
either ACTIVE or INACTIVE
Create
A user or users being created in your Huma account is sent as a [POST] request, with full profile objects for the created users in the [users] array.
For example:
{
"topic": "users-create",
"users": [
{
"id": "09d41e51-0963-4763-933b-8c9df093d653",
"status": "ACTIVE",
"givenName": "Ida",
"preferredName": null,
"familyName": "Fossdal",
"email": "ida.fossdal@godmat.no",
"privateEmail": null,
"phone": "+47 955 55 167",
"address": {
"line1": "Fossvegen 82",
"line2": null,
"postalCode": "1823",
"city": "Bergen",
"country": "NO"
},
"birthDate": "1993-07-29",
"nationality": null,
"dietaryRequirements": null,
"funfacts": null,
"interests": null,
"bankAccount": {
"type": "national",
"number": "12345678903",
"country": ""
},
"gender": "Female",
"civilStatus": null,
"employmentId": "1",
"firstDayOfWork": "2001-09-14",
"employmentStartDate": "2001-09-14",
"lastDayOfWork": null,
"employmentEndDate": null,
"terminationNoticeDate": null,
"terminationDate": null,,
"employmentType": "Permanent",
"employmentPercentage": 100
"jobTitle": "CEO",
"jobDescription": "Make the decisions",
"identifications": null,
"salary": {
"periodUnit": "yearly",
"amount": 950000,
"currency": "NOK",
"note": null
},
"supervisor": null
},
{
"id": "d96434d7-9506-4d5f-a969-7d1eea8bc3d6",
"givenName": "Jesper",
"preferredName": null,
"familyName": "Blom",
"email": "jesper.blom@godmat.no",
"privateEmail": null,
"phone": "+46 7555512",
"address": {
"line1": null,
"line2": null,
"postalCode": "520 43",
"city": "Stockholm",
"country": "SE"
},
"birthDate": "1989-09-08",
"nationality": null,
"dietaryRequirements": null,
"funfacts": null,
"interests": null,
"bankAccount": null,
"gender": "Male",
"employmentId": "31",
"employmentStartDate": "2019-01-01",
"firstDayOfWork": "2019-01-01",
"lastDayOfWork": null,
"employmentEndDate": null,
"terminationNoticeDate": null,
"terminationDate": null,,
"employmentType": "Permanent",
"employmentPercentage": 100
"jobTitle": null,
"jobDescription": null,
"identifications": null,
"salary": {
"periodUnit": "yearly",
"amount": 700000,
"currency": "SEK",
"note": null
},
"supervisor":{
"id": "09d41e51-0963-4763-933b-8c9df093d653",
"email": "ida.fossdal@godmat.no"
}
}
]
}
Delete
A user or users being deleted in your Huma account is sent as a [DELETE] request, with the [users] object(s) containing only identifiers.
For example:
{
"topic": "users-delete",
"users": [
{
"id": "d96434d7-9506-4d5f-a969-7d1eea8bc3d6",
"email": "jesper.blom@godmat.no",
"employmentId": "1",
"status": "INACTIVE"
}
]
}
Update π
A regular update is sent as a [PATCH] request, with the [users] object(s) containing only identifiers and the actually changed field(s).
For example, an employee changing their bank details to use IBAN:
{
"users": [
{
"id": "d96434d7-9506-4d5f-a969-7d1eea8bc3d6",
"email": "jesper.blom@godmat.no",
"employmentId": "31",
"status": "INACTIVE",
"bankAccount": {
"type": "international",
"iban": "FR7630006000011234567890189",
"bic": "AGRIFRPP"
}
}
],
"topic": "users-update"
}
Export π
An export is sent as one or more POST request(s), each detailing the full state of all fields supported by the webhook for all users, including empty values for fields that have not been set. Each request details up to 50 profiles, so if your organization has more than 50 users, the export will be sent as multiple requests. E.g. an export from an organizations with 132 users would receive three requests, the first two with 50 user objects each, followed by a final request with 32 user objects.
For example:
{
"topic": "users-export",
"users": [
{
"id": "c2c8d497-352a-4c21-bf7c-aefbaec37717",
"status": "ACTIVE",
"givenName": "Patrick",
"preferredName": null,
"familyName": "Remen",
"email": "patrick.remen@godmat.no",
"privateEmail": null,
"phone": "+46 7455564",
"address": {
"line1": null,
"line2": null,
"postalCode": "464 95",
"city": "Stockholm",
"country": "SE"
},
"birthDate": "1987-02-13",
"nationality": null,
"dietaryRequirements": null,
"funfacts": null,
"interests": null,
"bankAccount": null,
"gender": "Male",
"civilStatus": null,
"employmentId": "30",
"firstDayOfWork": "2012-03-13",
"employmentStartDate": "2012-03-13",
"lastDayOfWork": null,
"employmentEndDate": null,
"terminationNoticeDate": null,
"terminationDate": null,
"employmentType": "Permanent",
"employmentPercentage": 100,
"jobTitle": null,
"jobDescription": null,
"identifications": null,
"salary": {
"periodUnit": "yearly",
"amount": 550000,
"currency": "NOK",
"note": null
},
"supervisor":{
"id": "09d41e51-0963-4763-933b-8c9df093d653",
"email": "ida.fossdal@godmat.no"
}
},
{
"id": "12b87a11-7b5a-4c77-bef2-f46522d99e1c",
"givenName": "Laila",
"preferredName": null,
"familyName": "StΓΈa",
"email": "laila.stoa@godmat.no",
"privateEmail": null,
"phone": "+47 455 53 217",
"address": {
"line1": "Kleivbakken 21",
"line2": null,
"postalCode": "2412",
"city": "Bergen",
"country": "NO"
},
"birthDate": "1981-08-04",
"nationality": null,
"dietaryRequirements": null,
"funfacts": null,
"interests": null,
"bankAccount": {
"type": "national",
"number": "12345678902",
"country": "NO"
},
"gender": "Female",
"employmentId": "2",
"employmentStartDate": "1999-05-18",
"firstDayOfWork": "1999-05-18",
"lastDayOfWork": null,
"employmentEndDate": null,
"terminationNoticeDate": null,
"terminationDate": null,
"employmentType": "Permanent",
"employmentPercentage": 60,
"jobTitle": null,
"jobDescription": null,
"identifications": null,
"salary": {
"periodUnit": "yearly",
"amount": 500000,
"currency": "NOK",
"note": null
},
"supervisor":{
"id": "09d41e51-0963-4763-933b-8c9df093d653",
"email": "ida.fossdal@godmat.no"
}
},
{
"id": "d96434d7-9506-4d5f-a969-7d1eea8bc3d6",
"status": "ACTIVE",
"givenName": "Jesper",
"preferredName": null,
"familyName": "Blom",
"email": "jesper.blom@godmat.no",
"privateEmail": null,
"phone": "+46 7555512",
"address": {
"line1": null,
"line2": null,
"postalCode": "520 43",
"city": "Stockholm",
"country": "SE"
},
"birthDate": "1989-09-08",
"nationality": null,
"dietaryRequirements": null,
"funfacts": null,
"interests": null,
"bankAccount": {
"type": "international",
"iban": "FR7630006000011234567890189",
"bic": "AGRIFRPP"
},
"gender": "Male",
"civilStatus": null,
"employmentId": "31",
"firstDayOfWork": "2019-01-01",
"employmentStartDate": "2019-01-01",
"lastDayOfWork": null,
"employmentEndDate": null,
"terminationNoticeDate": null,
"terminationDate": null,
"employmentType": "Permanent",
"employmentPercentage": 100,
"jobTitle": null,
"jobDescription": null,
"identifications": null,
"salary": {
"periodUnit": "yearly",
"amount": 700000,
"currency": "SEK",
"note": null
},
"supervisor":{
"id": "09d41e51-0963-4763-933b-8c9df093d653",
"email": "ida.fossdal@godmat.no"
}
}
]
}
Supported fields π
These are the profile fields that the webhook will send updates about:
Field | JSON key |
Email address | email β note that changes to a profile's main email is sent as a user-email-update event |
Status | status |
Given name | givenName |
Family name | familyName |
Preferred name | preferredName |
Phone number | phone |
Private email | privateEmail |
Address | address |
Date of birth | birthDate |
Nationality | nationality |
Dietary restrictions | dietaryRequirements |
Fun facts | funfacts |
Interests | interests βeither null or an array of strings |
Bank account number |
bankAccount β either null or an object. The object contains the fields type, and two other fields, depending on the value of type. If type is national, the other two fields are number, and country. If type is international, the other two fields are iban and bic.
|
Gender | gender |
Civil status | civilStatus |
Employment ID | employmentId |
Employment start date | employmentStartDate |
Probation end date | probationEndDate |
First day of work | firstDayOfWork |
Termination notice date | terminationNoticeDate |
Last day of work | lastDayOfWork |
Employment end date | employmentEndDate |
Employment type |
employmentType β either null, if not set, or one of:
|
Employment percentage | employmentPercentage |
Job title | jobTitle |
Job description | jobDescription |
Identifications |
identifications β either null or an array of identification objects. Each identification object contains the fields id, type, country, and value.
|
Salary |
salary β an object containing the fields, periodUnit, amount, currency, and optionally note.
|
Supervisor |
supervisor β either null or an object containing the fields id and email.
|
Custom fields π
Any custom fields your organization has defined will be included in update events when the custom field is the one being updated. They will also all be included in export events.
If an event includes any custom fields, the user profile object(s) will contain a field custom
, which is an object with the the custom fields as keys and corresponding values. If the custom value is unset, it will be included as a null
.
As an example, for an organization that has defined two custom fields: Shirt size and License plate. An export for a user with the value "XL" for "Shirt size" and "License plate" not set, would include the following:
"custom": {
"shirtSize": "XL",
"licensePlate": null
}
See custom fields for more detail on how field name is determined, and the kinds of values custom fields can contain.
Absence events π
All absence event request bodies include an [absence] array, which contains an object for each affected absence entry. Each entry object will always contain all supported information for the entry.
Create
Absence entries being registered in your Huma account are sent as [POST] requests.
For example:
{
"topic": "absence-create",
"absence": [
{
"id": "45be6bce-88f5-4f67-a6de-cbd84df21e1e",
"status": "pending",
"type": {
"name": "vacation"
},
"user": {
"id": "c2c8d497-352a-4c21-bf7c-aefbaec37717",
"email": "patrick.remen@godmat.no"
},
"startDate": "2022-10-24",
"endDate": "2022-10-28",
"workRelated": false,
"note": null,
"comment": null,
"reviewedAt": null,
"reviewedBy": null,
"registeredAt": "2022-10-04T11:57:13.819Z",
"registeredBy": {
"id": "c2c8d497-352a-4c21-bf7c-aefbaec37717",
"email": "patrick.remen@godmat.no"
}
}
]
}
Update
Absence entries being updated in your Huma account β whether itβs a reviewer changing the status, edit by a requesting employee, or changes made by a manager on behalf of an employee β are sent as [PATCH] requests.
For example:
{
"topic": "absence-update",
"absence": [
{
"id": "e9b5a57f-2f36-462e-aed2-19c6aa990fce",
"status": "approved",
"type": {
"name": "vacation"
},
"user": {
"id": "c2c8d497-352a-4c21-bf7c-aefbaec37717",
"email": "patrick.remen@godmat.no"
},
"startDate": "2022-10-10",
"endDate": "2022-10-14",
"workRelated": false,
"note": null,
"comment": null,
"reviewedAt": "2022-10-05T11:57:13.819Z",
"reviewedBy": {
"id": "d96434d7-9506-4d5f-a969-7d1eea8bc3d6",
"email": "jesper.blom@godmat.no",
},
"registeredAt": "2022-10-04T11:51:08.962Z",
"registeredBy": {
"id": "c2c8d497-352a-4c21-bf7c-aefbaec37717",
"email": "patrick.remen@godmat.no"
}
}
]
}
Delete
Absence entries being deleted in your Huma account are sent as [DELETE] requests. The absence objects only contain identifiers.
For example:
{
"topic": "absence-delete",
"absence": [
{
"id": "e9b5a57f-2f36-462e-aed2-19c6aa990fce"
}
]
}
Supported fields π
These are the absence fields that the webhook will send updates about:
Field | JSON key |
The entry's ID | id |
Status | status - one of pending , approved , or rejected |
Type |
|
User | user - an object containing the fields id and email , for the user the entry is in regard to |
Start date | startDate |
End date | endDate |
grade | grade - a decimal number, where , 1.0 is 100% absence, 0.5 is 50%, etc. |
Work related | workRelated |
Notes added when the entry was registered | note |
Comment added when the entry was reviewed | comment |
The time of the entry's last review | reviewedAt |
The entry's reviewer | reviewedBy - an object containing the fields id and email , for the last user who reviewed the entry |
The time of the entry's registration | registeredAt |
The user who registered the entry | registeredBy - an object containing the fields id and email , for the user who registered the entry |
Team & Location events π
All Team or Location event request bodies include a [groups] array, which contains an object for each affected Team or Location. Each group object will always contain a unique and unchanging [id] field, the group [name], and the group [type], which will be either [team] or [location].
Create
When a Team or Location is created, you will receive a [POST] request:
{
"topic": "groups-create",
"groups":
[
{
"id": "<group ID>",
"name": "<group name>",
"type": "<team/location>",
"description": "<optional group description>",
"links": [
"<link name>\n<link url>"
],
"address": {
"line1": "Example street 57",
"line2": "<optional second line>",
"postalCode": "9999",
"city": "Demo city",
"country": "Theoretia"
},
"members": [
{
"id": "<user ID>",
"email": "<user email>"
}
]
}
]
}
Update
When the details of a Team or Location are changed, you will receive a [PUT] request:
{
"topic": "groups-update",
"groups":
[
{
"id": "<group ID>",
"name": "<group name>",
"type": "<team/location>",
"description": "<optional group description>",
"links": [
"<link name>\n<link url>"
],
"address": {
"line1": "Example street 57",
"line2": "<optional second line>",
"postalCode": "9999",
"city": "Demo city",
"country": "Theoretia"
},
"members": [
{
"id": "<user ID>",
"email": "<user email>"
}
]
}
]
}
Delete
When a Team or Location is deleted, you will receive a [DELETE] request:
{
"topic": "groups-delete",
"groups":
[
{
"id": "<group ID>",
"name": "<group name>",
"type": "<team/location>",
"description": "<optional group description>",
"links": [
"<link name>\n<link url>"
],
"address": {
"line1": "Example street 57",
"line2": "<optional second line>",
"postalCode": "9999",
"city": "Demo city",
"country": "Theoretia"
},
"members": [
{
"id": "<user ID>",
"email": "<user email>"
}
]
}
]
}
Add members
When new members are added to a Team or Location, you will receive a [PUT] request:
{
"topic": "groups-add-members",
"groups": [
{
"id": "<group ID>",
"name": "<group name>",
"type": "<team/location>",
"members-added": [
{
"id": "<user ID>",
"email": "<user email>"
}
]
}
]
}
Remove members
When members of a Team or Location are removed, you will receive a [PUT] request:
{
"topic": "groups-remove-members",
"groups": [
{
"id": "<group ID>",
"name": "<group name>",
"type": "<team/location>",
"members-removed": [
{
"id": "<user ID>",
"email": "<user email>"
}
]
}
]
}
Security & compliance
By connecting with webhooks, you authorize Huma to access your webhooks account as described in our Terms of Service under Third-Party Platforms.
The webhook and other integrations require a Business or Enterprise subscription