Table of Contents

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