Webhooks allow you to build or set up TS Recruiting Apps which subscribe to certain events. When one of those events is triggered, we'll send a HTTP POST payload to the webhook's configured URL. Webhooks can be used to be notified about vacancies status changes, application progression, or candidate hiring.
By default, the mechanism to call peers to inform them of any change is triggered every 15 minutes but can be modified by the client.
Events Subscriptions
Registering
To register to an event you have to use the usual authentication process with the following parameters :
- grant_type : client_credential
- clientId
- clientSecret
Request
To subscribe to an event the request may contain the following informations :
- event : the type of the event, ex vacancy_status
- callbackUrl: the Url on which Recruiting may call the subscriber
- pingUrl (optional) : the Url on which Recruiting may call when a ping is requested (aims to do configuration check or health-check)
POST /api/system/v1/webhooks
Authorization: Bearer /* Oauth2 token */
{
"event": "event_type",
"callbackUrl": "https://example.com/api/talentsoft/v1/events",
"pingUrl": "https://example.com/api/talentsoft/v1/pingevents"
}
Response
{
"hookId": "zwx"
}
The hookId is the identifier of the registration and may be used to delete the subscription to an event.
Unregistering
Request
DELETE /api/system/v1/webhooks/{hookId}
Authorization: Bearer /* Oauth2 token */
Events
When subscribing to a webhook, you can choose which events you would like to receive payloads for. Only subscribing to the specific events you plan on handling is useful for limiting the number of HTTP requests to your server.
Each event corresponds to a certain set of actions that can happen on specific object.
Name | Description |
---|---|
vacancy_new | Triggered when a new vacancy is created |
vacancy_update | Triggered when a vacancy's content or status is modified |
vacancy_status | Triggered when the status of a vacancy changes to Validated, Published, Archived, ... |
vacancy_unpublished_internet | Triggered when a vacancy is unpublished from the Internet publication media |
vacancy_unpublished_mobility | Triggered when a vacancy is unpublished from the Mobility publication media |
application_event_new | Triggered when a new event is added to an application Contected, Assessment test sent, ... |
application_status | Triggered when the status of an application changes to Rejected, Hired, ... |
applicant_status | Triggered when the status of an applicant changes to Rejected, Hired, ... |
applicant_status_hiring | Triggered when the status of an applicant changes to Hired |
applicant_referralstatus | Triggered when the referral status of an applicant changes |
applicant_resume_update | Triggered when a resume attached to an applicant has been updated or added |
applicant_joboffer_new | Triggered when a jobOffer is emitted to an applicant |
applicant_new | Triggered when an applicant is created |
applicant_update | Triggered when an applicant's content or status is modified |
applicant_deleted | Triggered when an applicant has been deleted or when a request for deletion has been received |
employee_deleted | Triggered when an employee is deleted |
Ping call
When you create or setup a new webhook, you'll need to test or check if it works correctly. This API will help you to call your ping endpoint for the selected event with a static payload.
Request
POST /api/system/v1/webhooks/{hookId}/pings
Authorization: Bearer /* Oauth2 token */
Payloads
Each event type has a specific payload format with the relevant event information.
Delivery Headers
Header | Description |
---|---|
X-TS-REC-Event | Name of the event type that triggered the delivery |
X-TS-REC-TraceId | A GUID to identify the delivery |
X-TS-REC-ClientId | The client id of the current customer |
X-TS-REC-Expires | The time when the signature expires, specified as the number of seconds since the epoch (00:00:00 UTC on January 1, 1970). A request received after this time (according to the server) will be rejected. |
Event types
vacancy_new
Triggered when a new vacancy is created.
{
"event_type": "vacancy_new",
"event_date": "2019-04-25T11:30:06Z",
"reference": "2019-1234"
"uri": "/api/v1/vacancies/2019-1234"
}
vacancy_update
Triggered when a vacancy's content or status is modified.
{
"event_type": "vacancy_update",
"event_date": "2019-04-25T11:30:06Z",
"reference": "2019-1234",
"uri": "/api/v1/vacancies/2019-1234"
}
vacancy_status
Triggered when the status of a vacancy change to Validated, Published, Archived, ...
{
"event_type": "vacancy_status",
"event_date": "2019-04-25T11:30:06Z",
"reference": "2019-1234",
"statusId": "_TS_Validated",
"uri": "/api/v1/vacancies/2019-1234"
}
application_event_new
Triggered when a new event on application is created
{
"event_type": "application_event_new",
"event_date": "2019-04-25T11:30:06Z",
"applicationId": "TS_00000000-0000-0000-0000-000000000001",
"vacancyId": "TS_00000000-0000-0000-0000-000000000002",
"applicantId": "TS_00000000-0000-0000-0000-000000000003",
"applicationEventTypeId": "_TS_TestSent",
"uri": "/api/v1/candidates/TS_00000000-0000-0000-0000-000000000003/applications/TS_00000000-0000-0000-0000-000000000001/events"
}
application_status
{
"event_type": "application_status",
"event_date": "2019-04-25T11:30:06Z",
"applicationId": "TS_00000000-0000-0000-0000-000000000001",
"vacancyId": "TS_00000000-0000-0000-0000-000000000002",
"applicantId": "TS_00000000-0000-0000-0000-000000000003",
"applicationStatusId": "_TS_Rejected",
"uri": "/api/v1/candidates/TS_00000000-0000-0000-0000-000000000003/applications/TS_00000000-0000-0000-0000-000000000001"
}
applicant_status
Triggered when the status of an applicant is changed
{
"event_type": "applicant_status",
"event_date": "2019-04-25T11:30:06Z",
"applicantId": "TS_00000000-0000-0000-0000-000000000003",
"applicationStatusId": "_TS_InProcess",
"uri": "/api/v1/candidates/TS_00000000-0000-0000-0000-000000000003"
}
applicant_status_hiring
Triggered when the status of an applicant is set to hiring.
{
"event_type": "applicant_status_hiring",
"event_date": "2019-04-25T11:30:06Z",
"applicantId": "TS_00000000-0000-0000-0000-000000000000",
"applicationStatusId": "_TS_Hired",
"uri": "/api/v1/candidates/TS_00000000-0000-0000-0000-000000000000"
}
applicant_referralstatus
Triggered when
{
"event_type": "applicant_referralstatus",
"event_date": "2019-04-25T11:30:06Z",
"applicantId": "TS_00000000-0000-0000-0000-000000000000",
"referralStatusId": "_TS_Hired",
"uri": "/api/v1/applicants/TS_00000000-0000-0000-0000-000000000000"
}
applicant_new
Triggered when an applicant is created.
{
"event_type": "applicant_new",
"event_date": "2019-04-25T11:30:06Z",
"applicantId": "TS_00000000-0000-0000-0000-000000000000"
}
applicant_update
Triggered when an applicant's content or status is modified.
{
"event_type": "applicant_deleted",
"event_date": "2019-04-25T11:30:06Z",
"applicantId": "TS_00000000-0000-0000-0000-000000000000"
}
applicant_deleted
Triggered when an applicant have been deleted or when a request for deletion have been received.
{
"event_type": "applicant_deleted",
"event_date": "2019-04-25T11:30:06Z",
"applicantId": "TS_00000000-0000-0000-0000-000000000000"
}
applicant_resume_update
Triggered when a resume attached to an applicant have been updated or added.
{
"event_type": "applicant_resume_update",
"event_date": "2019-04-25T11:30:06Z",
"applicantId": "TS_00000000-0000-0000-0000-000000000001",
"fileId": "TS_00000000-0000-0000-0000-000000000002"
}
employee_deleted
Triggered when an employee is deleted.
{
"event_type": "employee_deleted",
"event_date": "2019-04-25T11:30:06Z",
"employeeId": "TS_00000000-0000-0000-0000-000000000000"
}
Signature
To authenticate who sent the request, we will use the signed request.
The request looks like the following :
POST /api/talentsoft/v1/notif?expires=1141889120&client_id=AKIAIOSFODNN7EXAMPLE&signature=vjbyPxybdZaNmGa%2ByT272YEAiv4%3D HTTP/1.1
Host: partner.com
X-TS-REC-Event: vacancy_status
X-TS-REC-TraceId: 00000000-0000-0000-0000-000000000000
Content-Type: application/json
Content-Length: 124
{
"event_type": "vacancy_status",
"reference": "2019-1234",
"previousStatus": "Draft",
"newStatus": "Validated",
"uri": "/api/v1/vacancies/2019-1234"
}
Query String parameter Name | Example Value | Description |
---|---|---|
client_id | AKIAIOSFODNN7EXAMPLE | Your TS client ID. Specifies the TS client secret key used to sign the request and, indirectly, the identity of the customer making the request. |
expires | 1141889120 | The time when the signature expires, specified as the number of seconds since the epoch (00:00:00 UTC on January 1, 1970). A request received after this time (according to the server) will be rejected. |
signature | vjbyPxybdZaNmGa%2ByT272YEAiv4%3D | The URL encoding of the Base64 encoding of the HMAC-SHA1 of StringToSign. |
The following pseudocode illustrate the construction of the signature.
Signature = Base64( HMAC-SHA1( YourClientSecretID, UTF-8-Encoding-Of( StringToSign ) ) )
StringToSign = HTTP-Verb + "\n"
+ Content-MD5 + "\n" + Content-Type + "\n" + Expires + "\n"
+ CanonicalizedTsRecHeaders
+ CanonicalizedResource;
CanonicalizedResource = <HTTP-Request-URI, from the protocol name up to the query string>
+ [ subresource, if present. For example "?client_id", or "?expires" ];
CanonicalizedTsRecHeaders = <described below>
Constructing the CanonicalizedResource element
Step | Description |
---|---|
1 | Start with an empty string (""). |
2 | Append the path part of the un-decoded HTTP Request-URI, including the query string except signature. |
Constructing the CanonicalizedTsRecHeaders element
Step | Description |
---|---|
1 | Convert each HTTP header name to lowercase. For example, 'X-TS-REC-Event' becomes 'x-ts-rec-event'. |
2 | Sort the collection of headers lexicographically by header name. |
3 | Combine header fields with the same name into one "header-name:comma-separated-value-list" pair as prescribed by RFC 2616, section 4.2, without any whitespace between values. For example, the two metadata headers 'x-ts-rec-meta-username: fred' and 'x-ts-rec-meta-username: barney' would be combined into the single header 'x-amz-meta-username: fred,barney'. |
4 | "Unfold" long headers that span multiple lines (as allowed by RFC 2616, section 4.2) by replacing the folding whitespace (including new-line) by a single space. |
5 | Trim any whitespace around the colon in the header. For example, the header 'x-ts-rec-meta-username: fred,barney' would become 'x-ts-rec-meta-username:fred,barney' |
6 | Finally, append a newline character (U+000A) to each canonicalized header in the resulting list. Construct the CanonicalizedResource element by concatenating all headers in this list into a single string. |
Positional versus Named HTTP Header StringToSign Elements
The first few header elements of StringToSign (Content-Type and Content-MD5) are positional in nature. StringToSign does not include the names of these headers, only their values from the request. In contrast, the 'x-ts-rec-' elements are named. Both the header names and the header values appear in StringToSign.
If a positional header called for in the definition of StringToSign is not present in your request (for example, Content-Type or Content-MD5 are optional for PUT requests and meaningless for GET requests), substitute the empty string ("") for that position.
StringToSign Example
Incoming Request example | StringToSign example |
---|---|
POST /api/talentsoft/v1/notif?expires=1141889120&client_id=AKIAIOSFODNN7EXAMPLE&signature=xxx HTTP/1.1 User-Agent: curl/7.15.5 Host: static.johnsmith.net:8080 Date: Tue, 27 Mar 2007 21:06:08 +0000 content-type: application/json Content-MD5: 4gJE4saaMU4BqNR0kLY+lw== X-TS-REC-Event: vacancy_status X-TS-REC-TraceId: 00000000-0000-0000-0000-000000000000 X-TS-REC-ClientId: AKIAIOSFODNN7EXAMPLE Content-Encoding: gzip Content-Length: 5913339 |
POST\n 4gJE4saaMU4BqNR0kLY+lw==\n application/json\n 1141889120\n x-ts-rec-clientid:AKIAIOSFODNN7EXAMPLE\n x-ts-rec-event:vacancy_status\n x-ts-rec-traceid:00000000-0000-0000-0000-000000000000\n /api/talentsoft/v1/notif?expires=1141889120&client_id=AKIAIOSFODNN7EXAMPLE |