/actions

get

Get html head snippet (typically an include of a stylesheet) used to style the html for a strip of buttons.

The app building the page that embeds the buttons must insert the results of this API call in its head section.

All APIs beneath here are operating on behalf of the logged in candidate.

get

Get an array which is a rollup of all applicable candidate-facing actions from all apps. SoT.

get

Get an array which is a rollup of all applicable candidate-facing actions from all apps. SoT.

get

Get the html for the strip of buttons, ready to plug into a job details page as viewed by the candidate. SoT.

The app building the page that embeds this strip must in its head section pull in style sheet, javascript, etc. as obtained via a call to GET /actions/byCandidate/headHtml.

get

Get a single, named action from a single app. Non-SoT.

The producing app might customise the button/control(s), or choose not display it at all e.g.;

  • for an apply button, display that a partial (draft) registration is already underway
  • gray the register button out if candidate logged in and already registered

Security considerations: If the producing app attaches the incoming relayPage paramater to the button's link, then it should protect itelf from Open Redirection attacks as described at https://www.owasp.org/index.php/Testing_for_Client_Side_URL_Redirect_(OTG-CLIENT-004).

One approach would be by:

  • attaching an additional digital signature to the link based on the link's other values, including the relayPage
  • verifying when the candidate follows the link that the relayPage has not been tampered with

Another approach would be not putting the relayPage in the link at all, but instead storing it and putting a key into the link.

The commonly used approach of whitelisting is not useful as there is no common repository of all of the valid domains in use by all apps that a tenant may have installed and that may include this action.

The default type of the action is 'button'. If the type 'image' is used then the 'imageUri' property is used to specify the location of the image.

get

Get an array which is a rollup of all applicable candidate-facing actions from all apps. SoT.

get

Get the html for the strip of buttons, ready to plug into a job details page as viewed by the candidate. SoT.

The app building the page that embeds this strip must in its head section pull in style sheet, javascript, etc. as obtained via a call to GET /actions/byCandidate/headHtml.

get

Get a single, named action from a single app. Non-SoT.

The producing app might customise the button/control(s), or choose not display it at all e.g.;

  • for an apply button, display that a partial (draft) registration is already underway
  • gray the register button out if candidate logged in and already registered

Security considerations: If the producing app attaches the incoming relayPage paramater to the button's link, then it should protect itelf from Open Redirection attacks as described at https://www.owasp.org/index.php/Testing_for_Client_Side_URL_Redirect_(OTG-CLIENT-004).

One approach would be by:

  • attaching an additional digital signature to the link based on the link's other values, including the relayPage
  • verifying when the candidate follows the link that the relayPage has not been tampered with

Another approach would be not putting the relayPage in the link at all, but instead storing it and putting a key into the link.

The commonly used approach of whitelisting is not useful as there is no common repository of all of the valid domains in use by all apps that a tenant may have installed and that may include this action.

The default type of the action is 'button'. If the type 'image' is used then the 'imageUri' property is used to specify the location of the image.

get

Get the html for the strip of buttons, ready to plug into a job details page as viewed by the candidate. SoT.

The app building the page that embeds this strip must in its head section pull in style sheet, javascript, etc. as obtained via a call to GET /actions/byCandidate/headHtml.

get

Get a single, named action from a single app. Non-SoT.

The producing app might customise the button/control(s), or choose not display it at all e.g.;

  • for an apply button, display that a partial (draft) registration is already underway
  • gray the register button out if candidate logged in and already registered

Security considerations: If the producing app attaches the incoming relayPage paramater to the button's link, then it should protect itelf from Open Redirection attacks as described at https://www.owasp.org/index.php/Testing_for_Client_Side_URL_Redirect_(OTG-CLIENT-004).

One approach would be by:

  • attaching an additional digital signature to the link based on the link's other values, including the relayPage
  • verifying when the candidate follows the link that the relayPage has not been tampered with

Another approach would be not putting the relayPage in the link at all, but instead storing it and putting a key into the link.

The commonly used approach of whitelisting is not useful as there is no common repository of all of the valid domains in use by all apps that a tenant may have installed and that may include this action.

The default type of the action is 'button'. If the type 'image' is used then the 'imageUri' property is used to specify the location of the image.

get

Get an array which is a rollup of all applicable candidate-facing actions from all apps. SoT.

get

Get an array which is a rollup of all applicable candidate-facing actions from all apps. SoT.

get

Get an array which is a rollup of all applicable candidate-facing actions from all apps. SoT.

get

Get the html for the strip of buttons, ready to plug into a job details page as viewed by the candidate. SoT.

The app building the page that embeds this strip must in its head section pull in style sheet, javascript, etc. as obtained via a call to GET /actions/byCandidate/headHtml.

get

Get a single, named action from a single app. Non-SoT.

The producing app might customise the button/control(s), or choose not display it at all e.g.;

  • for an apply button, display that a partial (draft) registration is already underway
  • gray the register button out if candidate logged in and already registered

Security considerations: If the producing app attaches the incoming relayPage paramater to the button's link, then it should protect itelf from Open Redirection attacks as described at https://www.owasp.org/index.php/Testing_for_Client_Side_URL_Redirect_(OTG-CLIENT-004).

One approach would be by:

  • attaching an additional digital signature to the link based on the link's other values, including the relayPage
  • verifying when the candidate follows the link that the relayPage has not been tampered with

Another approach would be not putting the relayPage in the link at all, but instead storing it and putting a key into the link.

The commonly used approach of whitelisting is not useful as there is no common repository of all of the valid domains in use by all apps that a tenant may have installed and that may include this action.

The default type of the action is 'button'. If the type 'image' is used then the 'imageUri' property is used to specify the location of the image.

get

Get an array which is a rollup of all applicable candidate-facing actions from all apps. SoT.

get

Get the html for the strip of buttons, ready to plug into a job details page as viewed by the candidate. SoT.

The app building the page that embeds this strip must in its head section pull in style sheet, javascript, etc. as obtained via a call to GET /actions/byCandidate/headHtml.

get

Get a single, named action from a single app. Non-SoT.

The producing app might customise the button/control(s), or choose not display it at all e.g.;

  • for an apply button, display that a partial (draft) registration is already underway
  • gray the register button out if candidate logged in and already registered

Security considerations: If the producing app attaches the incoming relayPage paramater to the button's link, then it should protect itelf from Open Redirection attacks as described at https://www.owasp.org/index.php/Testing_for_Client_Side_URL_Redirect_(OTG-CLIENT-004).

One approach would be by:

  • attaching an additional digital signature to the link based on the link's other values, including the relayPage
  • verifying when the candidate follows the link that the relayPage has not been tampered with

Another approach would be not putting the relayPage in the link at all, but instead storing it and putting a key into the link.

The commonly used approach of whitelisting is not useful as there is no common repository of all of the valid domains in use by all apps that a tenant may have installed and that may include this action.

The default type of the action is 'button'. If the type 'image' is used then the 'imageUri' property is used to specify the location of the image.

get

Get the html for the strip of buttons, ready to plug into a job details page as viewed by the candidate. SoT.

The app building the page that embeds this strip must in its head section pull in style sheet, javascript, etc. as obtained via a call to GET /actions/byCandidate/headHtml.

get

Get a single, named action from a single app. Non-SoT.

The producing app might customise the button/control(s), or choose not display it at all e.g.;

  • for an apply button, display that a partial (draft) registration is already underway
  • gray the register button out if candidate logged in and already registered

Security considerations: If the producing app attaches the incoming relayPage paramater to the button's link, then it should protect itelf from Open Redirection attacks as described at https://www.owasp.org/index.php/Testing_for_Client_Side_URL_Redirect_(OTG-CLIENT-004).

One approach would be by:

  • attaching an additional digital signature to the link based on the link's other values, including the relayPage
  • verifying when the candidate follows the link that the relayPage has not been tampered with

Another approach would be not putting the relayPage in the link at all, but instead storing it and putting a key into the link.

The commonly used approach of whitelisting is not useful as there is no common repository of all of the valid domains in use by all apps that a tenant may have installed and that may include this action.

The default type of the action is 'button'. If the type 'image' is used then the 'imageUri' property is used to specify the location of the image.

General actions seen by candidates are typically embedded in page headers, e.g. "register", "share this entire site", etc.

get

Get an array which is a rollup of all possible candidate-facing actions from all apps. SoT.

get

Your app should produce this API to return an array with an element for every different button that your app might ever provide (i.e., the superset of all of your app's possible buttons).

Typically this will be called by a coordinating app at significant times, such as after the tenant is rebooted, or after your app has signalled a change to its buttons by calling the deltaPings API. That coordinating app can then present all possible buttons to some administrator, who can then flip some config switches to dictate which buttons should be shown in different situations.

For example, the customer might want to only show a "refer a friend" button for their sales jobs, not their call center jobs.

This API is for all possible buttons - at runtime, a different API will be called on your app to ask for actual details (color, label, disabled, etc.) of each actual button. For example, your app might declare with this API that it produces a "share" button, but then at runtime it might decide not to show the "share" button if it sees that the logged in candidate has exceeded some quota for sharing.

Non-SoT.

post

Alert any app that cares that the set of actions produced by this app has changed. Non-SoT.

Job-level actions seen by candidates are typically embedded in job details pages, e.g. "apply", "share this job", etc.

get

Get an array which is a rollup of all possible candidate-facing actions from all apps. SoT.

get

Your app should produce this API to return an array with an element for every different button that your app might ever provide (i.e., the superset of all of your app's possible buttons).

Typically this will be called by a coordinating app at significant times, such as after the tenant is rebooted, or after your app has signalled a change to its buttons by calling the deltaPings API. That coordinating app can then present all possible buttons to some administrator, who can then flip some config switches to dictate which buttons should be shown in different situations.

For example, the customer might want to only show a "refer a friend" button for their sales jobs, not their call center jobs.

This API is for all possible buttons - at runtime, a different API will be called on your app to ask for actual details (color, label, disabled, etc.) of each actual button. For example, your app might declare with this API that it produces a "share" button, but then at runtime it might decide not to show the "share" button if it sees that the logged in candidate has exceeded some quota for sharing.

Non-SoT.

The setup page uses uiMode to understand whether the user is at a point in the UI where they are:

  • view: viewing setup details
  • edit: editing setup details

In all cases the app should apply its own security to decide whether the user is actually allowed to view/edit, this value is just a hint to make the setup page work smoothly in conjunction with the "edit mode" as set in the containing UI.

true if the setup page is setting up details for internal candidates, or false for externals

setup page for default values, that will affect all jobs (unless overridden at workflow level or on the job itself)

get

API to get a link to a page hosted by your app that the user can use to to set up defaults or values for this action (button).

For example if your app is an employee referral program app, and the button is "refer to a friend", then the setup page, when attaching the button to a job, could be used to set the referral amount.

Communicating from your setup page back to the container

When the user drags your button (e.g. in switchgear) onto a job, they will see your setup page, iframed within the page.

Your setup page should display a UI to capture any data you need from the user, and also the OK and Cancel buttons.

Once the user has provided enough data in your page, then you can light up your OK button. When the user clicks OK, you signal to the container like this:

Window.parent.postMessage({"action": "closePanel", "verb": "ok"});

If they clicked cancel in your page, then pass "cancel" instead as the verb.

Once you signal OK, the "attach button" operation will be completed. If you signal cancel, the operation will be cancelled and the button won't be attached.

Setting default values

For actions relating to jobs like this, a setup page can also be used to set defaults (at either the global or workflow level).

This API is non-SoT, on-behalf (principal == user).

setup page for default values that will affect all jobs of the given workflow, unless overridden on the job itself

get

API to get a link to a page hosted by your app that the user can use to to set up defaults or values for this action (button).

For example if your app is an employee referral program app, and the button is "refer to a friend", then the setup page, when attaching the button to a job, could be used to set the referral amount.

Communicating from your setup page back to the container

When the user drags your button (e.g. in switchgear) onto a job, they will see your setup page, iframed within the page.

Your setup page should display a UI to capture any data you need from the user, and also the OK and Cancel buttons.

Once the user has provided enough data in your page, then you can light up your OK button. When the user clicks OK, you signal to the container like this:

Window.parent.postMessage({"action": "closePanel", "verb": "ok"});

If they clicked cancel in your page, then pass "cancel" instead as the verb.

Once you signal OK, the "attach button" operation will be completed. If you signal cancel, the operation will be cancelled and the button won't be attached.

Setting default values

For actions relating to jobs like this, a setup page can also be used to set defaults (at either the global or workflow level).

This API is non-SoT, on-behalf (principal == user).

setup page for values that affect only this job

get

API to get a link to a page hosted by your app that the user can use to to set up defaults or values for this action (button).

For example if your app is an employee referral program app, and the button is "refer to a friend", then the setup page, when attaching the button to a job, could be used to set the referral amount.

Communicating from your setup page back to the container

When the user drags your button (e.g. in switchgear) onto a job, they will see your setup page, iframed within the page.

Your setup page should display a UI to capture any data you need from the user, and also the OK and Cancel buttons.

Once the user has provided enough data in your page, then you can light up your OK button. When the user clicks OK, you signal to the container like this:

Window.parent.postMessage({"action": "closePanel", "verb": "ok"});

If they clicked cancel in your page, then pass "cancel" instead as the verb.

Once you signal OK, the "attach button" operation will be completed. If you signal cancel, the operation will be cancelled and the button won't be attached.

Setting default values

For actions relating to jobs like this, a setup page can also be used to set defaults (at either the global or workflow level).

This API is non-SoT, on-behalf (principal == user).

post

Alert any app that cares that the set of actions produced by this app has changed. Non-SoT.

get

Get an array which is a rollup of all possible candidate-facing actions from all apps. SoT.

get

Your app should produce this API to return an array with an element for every different button that your app might ever provide (i.e., the superset of all of your app's possible buttons).

Typically this will be called by a coordinating app at significant times, such as after the tenant is rebooted, or after your app has signalled a change to its buttons by calling the deltaPings API. That coordinating app can then present all possible buttons to some administrator, who can then flip some config switches to dictate which buttons should be shown in different situations.

For example, the customer might want to only show a "refer a friend" button for their sales jobs, not their call center jobs.

This API is for all possible buttons - at runtime, a different API will be called on your app to ask for actual details (color, label, disabled, etc.) of each actual button. For example, your app might declare with this API that it produces a "share" button, but then at runtime it might decide not to show the "share" button if it sees that the logged in candidate has exceeded some quota for sharing.

Non-SoT.

post

Alert any app that cares that the set of actions produced by this app has changed. Non-SoT.

/advertisements

post

Produced by a Job Board App to post a new advertisement to that Job Board. Non-SoT.

get

Produced by a Job Board App to allow the Job Board Hub to fetch the advertisement details. Non-SoT.

patch

Produced by a Job Board App to allow the Job Board Hub to update or expire an advertisement. Non-SoT.

post

Produced by a Job Board App to allow the Job Board Hub to post through IDs of advertisements to find out the status of the specified advertisements. Non-SoT.

/applications

get

This API is used to fetch or query details of 1 to 100 job applications in a single call.

You should call this API either:

  • passing the "applications" parameter, to fetch a specific, known set of applications; OR
  • passing some combination of "bucket", "job", "candidate", "since" and "minID" to query an unknown number of applications, filtered to your requirements

In the second case, the total number of results may exceed the maximum (100) per API call, so you will need to paginate the results as follows (results are ordered by since asc, application ID asc):

  • first, call the API passing only your filters (i.e., not the since or minID parameters)
  • if you get back exactly 100 applications, call the API again, but this time setting since and minID paramaters to the values from the last application in the previous response
  • repeat the above until less than 100 results are returned (indicating you've fetched the final application)

SinceDate is the datelastUpdated for the application.

post

The main ping for any changes to a job application. Noisy, i.e. other apps need to store previous state to work out what has actually changed.

Non-SoT.

The id of the application's new bucket

post

Consumed by something like an ATS when an application has changed its bucket. Noise-free, i.e. when fired we know the application has changed bucket.

Non-SoT.

post

A non-SoT API for pings about applications, but which is only sent to the application that sourced the application (i.e., that owns the campaign tracker attached to the application).

all items held on an application

get

Get values and (in some scenarios) metadata, for all items

get

Get value and (in some scenarios), metadata for a specific item

Metadata for items held on the candidate

get

Get metadata for all items

get

Get metadata for a specific item

get

Get a sanitised and basic set of information for a job application, which the consumer is entitled to by virtue of sourcing the application (i.e., owning the campaign tracker attached to the application).

A view is a curated package of information about an application and its job, candidate, etc.

The tenant controls what data appears in a view. This allows them to e.g. only share the minimum amount of data with an app. For example, an onboarding app might need details of the applicant's salary, whereas a survey app might only need to know their email address.

These "at" APIs provide access to applications based on the phase of the recruitment process that they are in now, or have ever been in. An application's phase is determined by its bucket (every bucket is linked to a single phase). In these descriptions:

  • "entering a phase" means that an application has transitioned into a bucket of that phase, from a bucket of some other phase (or from initial creation) - i.e. moving between buckets of the same phase has no effect on these APIs
  • "exiting a phase" means that an application has transitioned out of a bucket of this phase into a bucket of some other phase.
get

The 'now' APIs return all applications:

  • that are currently in this phase; AND
  • (if since is specified), that most recently entered this phase after the given date; AND
  • (if minID is specified), that have id > minID

A maximum of 100 applications will be returned by a single call to the API. If this maximum number is returned, the client should fetch again, specifying both sinceDate and minID, as there may be more results.

Results are ordered by sinceDate asc, applicationId asc.

sinceDate in this case is the date the application most recently entered the phase.

post

A request containing a view will be sent for the 'now' case to all listeners whenever an application;

  • enters the phase

An empty request will be sent whenever an application;

  • exits the phase

Non-SoT.

get

The 'ever' APIs return all applications:

  • that have ever been in this phase; AND
  • (if since is specified), that first entered this phase after the given date; AND
  • (if minID is specified), that have id > minID

A maximum of 100 applications will be returned by a single call to the API. If this maximum number is returned, the client should fetch again, specifying both sinceDate and minID, as there may be more results.

Results are ordered by sinceDate asc, applicationId asc.

sinceDate in this case is the date the application first entered the phase.

post

A request containing a view will be sent for the "ever" case to all listeners;

  • the first time (only) that an application enters the phase

Non-SoT.

get

The 'now' APIs return all applications:

  • that are currently in this phase; AND
  • (if since is specified), that most recently entered this phase after the given date; AND
  • (if minID is specified), that have id > minID

A maximum of 100 applications will be returned by a single call to the API. If this maximum number is returned, the client should fetch again, specifying both sinceDate and minID, as there may be more results.

Results are ordered by sinceDate asc, applicationId asc.

sinceDate in this case is the date the application most recently entered the phase.

post

A request containing a view will be sent for the 'now' case to all listeners whenever an application;

  • enters the phase

An empty request will be sent whenever an application;

  • exits the phase

Non-SoT.

get

The 'ever' APIs return all applications:

  • that have ever been in this phase; AND
  • (if since is specified), that first entered this phase after the given date; AND
  • (if minID is specified), that have id > minID

A maximum of 100 applications will be returned by a single call to the API. If this maximum number is returned, the client should fetch again, specifying both sinceDate and minID, as there may be more results.

Results are ordered by sinceDate asc, applicationId asc.

sinceDate in this case is the date the application first entered the phase.

post

A request containing a view will be sent for the "ever" case to all listeners;

  • the first time (only) that an application enters the phase

Non-SoT.

get

The 'now' APIs return all applications:

  • that are currently in this phase; AND
  • (if since is specified), that most recently entered this phase after the given date; AND
  • (if minID is specified), that have id > minID

A maximum of 100 applications will be returned by a single call to the API. If this maximum number is returned, the client should fetch again, specifying both sinceDate and minID, as there may be more results.

Results are ordered by sinceDate asc, applicationId asc.

sinceDate in this case is the date the application most recently entered the phase.

post

A request containing a view will be sent for the 'now' case to all listeners whenever an application;

  • enters the phase

An empty request will be sent whenever an application;

  • exits the phase

Non-SoT.

get

The 'ever' APIs return all applications:

  • that have ever been in this phase; AND
  • (if since is specified), that first entered this phase after the given date; AND
  • (if minID is specified), that have id > minID

A maximum of 100 applications will be returned by a single call to the API. If this maximum number is returned, the client should fetch again, specifying both sinceDate and minID, as there may be more results.

Results are ordered by sinceDate asc, applicationId asc.

sinceDate in this case is the date the application first entered the phase.

post

A request containing a view will be sent for the "ever" case to all listeners;

  • the first time (only) that an application enters the phase

Non-SoT.

get

The 'now' APIs return all applications:

  • that are currently in this phase; AND
  • (if since is specified), that most recently entered this phase after the given date; AND
  • (if minID is specified), that have id > minID

A maximum of 100 applications will be returned by a single call to the API. If this maximum number is returned, the client should fetch again, specifying both sinceDate and minID, as there may be more results.

Results are ordered by sinceDate asc, applicationId asc.

sinceDate in this case is the date the application most recently entered the phase.

post

A request containing a view will be sent for the 'now' case to all listeners whenever an application;

  • enters the phase

An empty request will be sent whenever an application;

  • exits the phase

Non-SoT.

get

The 'ever' APIs return all applications:

  • that have ever been in this phase; AND
  • (if since is specified), that first entered this phase after the given date; AND
  • (if minID is specified), that have id > minID

A maximum of 100 applications will be returned by a single call to the API. If this maximum number is returned, the client should fetch again, specifying both sinceDate and minID, as there may be more results.

Results are ordered by sinceDate asc, applicationId asc.

sinceDate in this case is the date the application first entered the phase.

post

A request containing a view will be sent for the "ever" case to all listeners;

  • the first time (only) that an application enters the phase

Non-SoT.

get

The 'now' APIs return all applications:

  • that are currently in this phase; AND
  • (if since is specified), that most recently entered this phase after the given date; AND
  • (if minID is specified), that have id > minID

A maximum of 100 applications will be returned by a single call to the API. If this maximum number is returned, the client should fetch again, specifying both sinceDate and minID, as there may be more results.

Results are ordered by sinceDate asc, applicationId asc.

sinceDate in this case is the date the application most recently entered the phase.

post

A request containing a view will be sent for the 'now' case to all listeners whenever an application;

  • enters the phase

An empty request will be sent whenever an application;

  • exits the phase

Non-SoT.

get

The 'ever' APIs return all applications:

  • that have ever been in this phase; AND
  • (if since is specified), that first entered this phase after the given date; AND
  • (if minID is specified), that have id > minID

A maximum of 100 applications will be returned by a single call to the API. If this maximum number is returned, the client should fetch again, specifying both sinceDate and minID, as there may be more results.

Results are ordered by sinceDate asc, applicationId asc.

sinceDate in this case is the date the application first entered the phase.

post

A request containing a view will be sent for the "ever" case to all listeners;

  • the first time (only) that an application enters the phase

Non-SoT.

get

The 'now' APIs return all applications:

  • that are currently in this phase; AND
  • (if since is specified), that most recently entered this phase after the given date; AND
  • (if minID is specified), that have id > minID

A maximum of 100 applications will be returned by a single call to the API. If this maximum number is returned, the client should fetch again, specifying both sinceDate and minID, as there may be more results.

Results are ordered by sinceDate asc, applicationId asc.

sinceDate in this case is the date the application most recently entered the phase.

post

A request containing a view will be sent for the 'now' case to all listeners whenever an application;

  • enters the phase

An empty request will be sent whenever an application;

  • exits the phase

Non-SoT.

get

The 'ever' APIs return all applications:

  • that have ever been in this phase; AND
  • (if since is specified), that first entered this phase after the given date; AND
  • (if minID is specified), that have id > minID

A maximum of 100 applications will be returned by a single call to the API. If this maximum number is returned, the client should fetch again, specifying both sinceDate and minID, as there may be more results.

Results are ordered by sinceDate asc, applicationId asc.

sinceDate in this case is the date the application first entered the phase.

post

A request containing a view will be sent for the "ever" case to all listeners;

  • the first time (only) that an application enters the phase

Non-SoT.

get

The 'now' APIs return all applications:

  • that are currently in this phase; AND
  • (if since is specified), that most recently entered this phase after the given date; AND
  • (if minID is specified), that have id > minID

A maximum of 100 applications will be returned by a single call to the API. If this maximum number is returned, the client should fetch again, specifying both sinceDate and minID, as there may be more results.

Results are ordered by sinceDate asc, applicationId asc.

sinceDate in this case is the date the application most recently entered the phase.

post

A request containing a view will be sent for the 'now' case to all listeners whenever an application;

  • enters the phase

An empty request will be sent whenever an application;

  • exits the phase

Non-SoT.

get

The 'ever' APIs return all applications:

  • that have ever been in this phase; AND
  • (if since is specified), that first entered this phase after the given date; AND
  • (if minID is specified), that have id > minID

A maximum of 100 applications will be returned by a single call to the API. If this maximum number is returned, the client should fetch again, specifying both sinceDate and minID, as there may be more results.

Results are ordered by sinceDate asc, applicationId asc.

sinceDate in this case is the date the application first entered the phase.

post

A request containing a view will be sent for the "ever" case to all listeners;

  • the first time (only) that an application enters the phase

Non-SoT.

get

The 'now' APIs return all applications:

  • that are currently in this phase; AND
  • (if since is specified), that most recently entered this phase after the given date; AND
  • (if minID is specified), that have id > minID

A maximum of 100 applications will be returned by a single call to the API. If this maximum number is returned, the client should fetch again, specifying both sinceDate and minID, as there may be more results.

Results are ordered by sinceDate asc, applicationId asc.

sinceDate in this case is the date the application most recently entered the phase.

post

A request containing a view will be sent for the 'now' case to all listeners whenever an application;

  • enters the phase

An empty request will be sent whenever an application;

  • exits the phase

Non-SoT.

get

The 'ever' APIs return all applications:

  • that have ever been in this phase; AND
  • (if since is specified), that first entered this phase after the given date; AND
  • (if minID is specified), that have id > minID

A maximum of 100 applications will be returned by a single call to the API. If this maximum number is returned, the client should fetch again, specifying both sinceDate and minID, as there may be more results.

Results are ordered by sinceDate asc, applicationId asc.

sinceDate in this case is the date the application first entered the phase.

post

A request containing a view will be sent for the "ever" case to all listeners;

  • the first time (only) that an application enters the phase

Non-SoT.

get

The 'now' APIs return all applications:

  • that are currently in this phase; AND
  • (if since is specified), that most recently entered this phase after the given date; AND
  • (if minID is specified), that have id > minID

A maximum of 100 applications will be returned by a single call to the API. If this maximum number is returned, the client should fetch again, specifying both sinceDate and minID, as there may be more results.

Results are ordered by sinceDate asc, applicationId asc.

sinceDate in this case is the date the application most recently entered the phase.

post

A request containing a view will be sent for the 'now' case to all listeners whenever an application;

  • enters the phase

An empty request will be sent whenever an application;

  • exits the phase

Non-SoT.

get

The 'ever' APIs return all applications:

  • that have ever been in this phase; AND
  • (if since is specified), that first entered this phase after the given date; AND
  • (if minID is specified), that have id > minID

A maximum of 100 applications will be returned by a single call to the API. If this maximum number is returned, the client should fetch again, specifying both sinceDate and minID, as there may be more results.

Results are ordered by sinceDate asc, applicationId asc.

sinceDate in this case is the date the application first entered the phase.

post

A request containing a view will be sent for the "ever" case to all listeners;

  • the first time (only) that an application enters the phase

Non-SoT.

get

The 'now' APIs return all applications:

  • that are currently in this phase; AND
  • (if since is specified), that most recently entered this phase after the given date; AND
  • (if minID is specified), that have id > minID

A maximum of 100 applications will be returned by a single call to the API. If this maximum number is returned, the client should fetch again, specifying both sinceDate and minID, as there may be more results.

Results are ordered by sinceDate asc, applicationId asc.

sinceDate in this case is the date the application most recently entered the phase.

post

A request containing a view will be sent for the 'now' case to all listeners whenever an application;

  • enters the phase

An empty request will be sent whenever an application;

  • exits the phase

Non-SoT.

get

The 'ever' APIs return all applications:

  • that have ever been in this phase; AND
  • (if since is specified), that first entered this phase after the given date; AND
  • (if minID is specified), that have id > minID

A maximum of 100 applications will be returned by a single call to the API. If this maximum number is returned, the client should fetch again, specifying both sinceDate and minID, as there may be more results.

Results are ordered by sinceDate asc, applicationId asc.

sinceDate in this case is the date the application first entered the phase.

post

A request containing a view will be sent for the "ever" case to all listeners;

  • the first time (only) that an application enters the phase

Non-SoT.

post

Ask the view holding app to create a view instance of the given view type for this application. The response includes the key of the newly created view instance.

get

Get the previously created view instance.

get

Get a list of all available view types (i.e. pre-defined sets of information about an application)

/appStatus

get

Produced by apps to inform the storefront app of this app's:

  • landing page, i.e where should the user go to do on clicking "open" on the app - e.g. clicking a job board app might go to the front page of the job board
  • setup required status, i.e. whether the app is degraded or unusable due to some missing setup
  • setup page, i.e. where should the user go to adjust the app's setup

Probably only consumed by storefront apps.

SoT: non-SoT (each app has their own landing page).

When the app is generating the setup page url, the relayPage parameter indicates where the user should be redirected to after completing the setup (i.e. typically the app details page witin the storefront).

/assessments

These APIs are on behalf, allowing the identity of the user raising the assessment to be available to the hub.

get

Get the html for the strip of assessments (not started, underway or complete), ready to plug in next to a job applicant.

SoT.

The app building the page that embeds this strip must in its head section pull in style sheet, javascript, etc. as obtained via a call to GET /assessments/strips/headHtml.

get

Get html head snippet (typically an include of a stylesheet) used to style the html for the assessments strip.

The app building the page (e.g. applicant list) that embeds assessment strips must insert the results of this API call in its head section.

The head HTML API pulls in a function initializeSearchWidget() that the ATS can call, passing a single object with these fields:

  • String tenant
  • Number bucket
  • HTMLElement sortWidget (an empty DOM element that the hub will put the sort control widget in)
  • Number currentSort (indicates the assessment type currently being sorted on, so the sort control can render itself)
  • Boolean currentSortAsc (is the current sort asc or desc?)
  • Number job (the job the ATS is displaying applicants for)
  • Function callback (callback function that the hub will use to notify the ATS when a sort is requested). The callback takes params:
    • Number assessmentType (to sort by)
    • Boolean sortAsc (whether to sort asc or desc)
post

An app such as an ATS calls this on an app such as the assessment hub to convert a set of application IDs into a sorted set.

If there are no assessments the result is 200 with an empty array.

get

get details of this assessment, reflecting changes made by the app and/or the tenant.

post

Tenant creates (or reuses) an assessment of the given type, for the given job application, for example upon a candidate applying and being screened in.

SoT. Typically implemented by the assessment hub.

There is no request body. The response contains the assessment ID.

post

Tenant creates (or reuses) an assessment of the given type, for the given job application, for a logged in user, who will appear in the raisers section of the assessment. This is an on-behalf version of the similar API (without /me).

SoT. Typically implemented by the assessment hub.

There is no request body. The response contains the assessment ID.

get

Returns a list of assessment progress information for an individual Application ID SoT. Typically implemented by the assessment hub.

get

get details of this assessment, reflecting changes made by the app and/or the tenant.

patch

Consumed by the assessment app to update an existing assessment using JSON Merge Patch semantics (https://tools.ietf.org/html/rfc7396). Apps may set most details and some statuses for an assessment, but cannot alter the on hold flag.

patch

Consumed by the assessment hub, as a result of some tenant action, to update an existing assessment using JSON Merge Patch semantics (https://tools.ietf.org/html/rfc7396). The tenant cannot alter many details of an assessment other than to change the status.

post

Alerts listeners to a change to an assessment caused by the tenant

get

Returns a list of assessment progress information for a given Job ID SoT. Typically implemented by the assessment hub.

post

An app such as the assessment hub calls this on the assessment app that owns these assessments, to have them sorted.

post

Creates (or reuses) and starts an assessment of the given type, for the given job application, for the given raiser. SoT. Typically implemented by the assessment hub.

/assessmentTypes

get

Get the list of all assessment types produced by all assessment apps.

SoT.

get

This API is deprecated in favour of the key field returned by GET /assessments/byID/{} and will shortly be removed.

Get details of a single assessment type, by ID. The response is an array containing a single type. Typically used by the assessment hub's UI when rendering details about assessments about to be created, or that already exist.

Even when an assessment type has been deleted (i.e., is no longer passed by the assessment app) it will still be returned by this API, but with activeFlag set to false.

SoT.

get

Get the list of assessment types produced by an assessment app.

Non-SoT.

get

Get the url for the assessment type's launcher UI. The UI may adapt itself based on job and/or candidate, e.g. to ask less of internal candidates. Or it could ignore the application ID and just present its generic UI.

post

This API is deprecated in favour of POST /assessmentTypes/forApp/deltaPings/1 and will shortly be removed.

Consumed by an assessment app to alert any interested parties that the list of assessment types produced by the app has changed.

Non-SoT (there may be many listeners).

post

Consumed by an assessment app to alert any interested parties that the list of assessment types produced by the app has changed.

SoT.

get

Get the list of assessment types that are visible to this user, for applicants for this job and in this bucket. This can be used e.g. to populate a sorting widget - in it the user could click on a sortable assessment type to sort the applicants.

/buckets

get
get
post

The main ping for any changes to a bucket. Noisy, i.e. other apps need to store previous state to work out what has actually changed.

Non-SoT.

/candidates

Candidates are people who are in the tenant's talent world, perhaps stored in their ATS. Maybe they applied for an opening, registered in the database, were imported from some other system, etc.

post

This API has the same behaviour as POST /candidates/me, except that the call is not on behalf.

post

This API has the same behaviour as POST /candidates/me/unvalidated, except that the call is not on behalf.

All APIs beneath here are operating on behalf of the logged in candidate.

get

Get the signed in candidate's details

post

Overview

These "apply APIs" are used by an apply app to create or update a candidate in the ATS (depending on whether one exists with a matching email), and optionally create a job application.

There are 4 versions of the apply APIs:

  • POST /candidates
  • POST /candidates/unvalidated
  • POST /candidates/me
  • POST /candidates/me/unvalidated

The /me (on behalf) versions of these APIs are strongly preferred for security and the best candidate experience. They require that the candidate is signed in via SSO.

The non-/unvalidated versions of these APIs are also preferred whenever possible. The /unvalidated versions should be used only if its not possible to answer all of the customer's mandatory questions.

Preparing to call the APIs

Before calling this API, the apply app will usually make an API call to fetch the edit spec (i.e. details of the application form) from the ATS.

The apply app uses this to build up an application form and show it to the candidate.

Once the candidate has completed the application form, the apply app uses one of these apply APIs to push the candidate data and job applications into the ATS.

Update semantics

When updating, merge patch semantics are used (https://tools.ietf.org/html/rfc7386). For example;

  • if resume is present in the request, it will be set
  • if present and null, any existing resume will be cleared
  • if not present, any existing resume will be left unchanged

Internal candidates

The API calls can set or update the candidate's internalFlag (i.e. indicating they are an employee).

The /me versions of the APIs do this by checking for the "internal" role in the incoming SAML assertion. If present, the candidate will be set to have internalFlag = true. If not present, false. The internal flag should not be present in API the request - a 400 error will be thrown if it is.

For the non-/me versions of the APIs, the ATS should just examine the candidate's internal flag in the request.

  • if present and true then the candidate is set to internalFlag == true
  • if present and true then the candidate is set to internalFlag == false
  • if not present, then when creating, the internalFLag will be set to false, and when updating no change will be made

Fields duplicated in the vcard

Within the person object, some fields - e,g, email, first name, last name - are duplicated, i.e. they appear both as a first class field, and also within the vcard. In the API request, either can be used to set the underlying value;

  • The underlying value will be set to whichever is not null
  • If both are null, the underlying value will be set to null
  • If both are not null and they clash, a 400 error will be thrown

Category values

When the API request contains the categories object, and there is a category present (e.g. Location), then the the candidate will be updated to exactly match the category values.

Any categories not passed in will not be changed on the candidate.

Checking eligibility to apply

When the API request includes an job application, the ATS should check that the job is active, AND that one of the following is true;

  • if the job is "open to externals", that the candidate is external
  • if the job is "open to internals", that the candidate is internal
  • if neither, that a tracker chain was passed in that has a campaign tracker for this job and with correctly matching access code

If the job is not active or none of the above are true, then the API will return 400 and no changes will be made.

File checks

The ATS must run all uploaded files through OWASP security tests:

  • extension matches actual file type
  • virus check
  • etc.

Validation

The ATS (app producing the API) must not blindly apply the incoming data. Instead it must itself first generate an editSpec for the candidate, and then check that the incoming data is a subset of what the editSpec allows/requires. This prevents attacks where e.g. the apply app tries to write to a random item. This checking must happen in both the normal and the /unvalidated forms of the APIs.

The ATS must also check that the apply app has passed the resume (if mandatory) and any mandatory data items. The /unvalidated versions of the APIs don't perform these mandatory checks.

post

This API has the same behaviour as POST /candidates/me, except that mandatory items may be missing.

get

This API is deprecated in favour of GET /candidates/me and will shortly be removed.

Get general information about the candidate including notifications (subscribe y/n)

get

Get the uri of the home page, a landing page where a logged in candidate can see anything they should know about or should do, e.g. the status of their job application, assessments they still haven't completed, etc. Often produced by an ATS.

Details of a relayPage can be passed in when the home page was reached as part of some activity. e.g. candidate applies for job and after submission is redirected to the home page, e.g. so they can complete any auto-started assessments. Passing the relayPage of the job (where they clicked Apply) causes navigation link "Back to Creative Director" to be displayed at the top of the candidate home page.

SoT. There is only one home page to send the candidate to.

This API is deprecated in favour of GET /candidates/me and will shortly be removed.

The ID of the candidate.

get

Get the ID (database primary key) of ourselves (the currently logged in principal, who must be of principal type 'candidate').

get

This API is deprecated in favour of GET /candidates/me and will shortly be removed.

Get candidate contact details, in the form described by rfc7095

get

This API is deprecated in favour of GET /candidates/me and will shortly be removed.

Get metadata about the candidate's resume (size, filename, etc.)

get

get the document as a stream, i.e. binary document, using the appropriate mime type

get

get an html version of the candidate's resume

A separate delta ping from the main candidate one, since managing the html version may be done delayed by a downstream app. Probably only useful as non-SoT.

post
get

This API is deprecated in favour of GET /candidates/me and will shortly be removed.

Get the categories for this candidate

post

Perform a normalized merge of the candidate's category values with the passed in values, and return the result. The candidate is not altered. We use a POST to allow passing a request body.

By normalizing we mean that:

  • any folder or leaf must be included (explicitly or implicitly) only once
  • the minimum possible number of folders and leaves should be included

e.g. given an example tree like this:

/a
  /b
    /d
    /e
  /c
    /f
/g
  /h
  /i

The following are correctly normalized:

/a
/b,/f
/a,/h

The following are not:

/b,/c (since /a would be more minimal)
/a,/b (since /a already implies /b)
/d,/e (since /b would be more minimal) 
/f (since /c would be more minimal) 
get

The tracker (if any) that was passed in when this candidate last applied for a job (i.e. a call to POST /candidates was made with a job specified). When a candidate applies for multiple jobs over time, this helps understand what last drew them to the site.

get
get

a tracker, as passed in to the edit

get

This API is deprecated in favour of GET /candidates/me and will shortly be removed.

Get candidate contact details, in the form described by rfc7095

get

This API is deprecated in favour of GET /candidates/me and will shortly be removed.

Get metadata about the candidate's resume (size, filename, etc.)

get

get the document as a stream, i.e. binary document, using the appropriate mime type

all application-scoped items held for when a candidate applies to a job

get

Get values and (in some scenarios) metadata, for all items

all items held on a candidate

get

Get values and (in some scenarios) metadata, for all items

get

Get value and (in some scenarios), metadata for a specific item

Metadata for items held on the candidate

get

Get metadata for all items

get

Get metadata for a specific item

get

get the document as a stream, i.e. binary document, using the appropriate mime type

get

Get the candidate's stars against a specific job, perhaps inherited from the jobs's master or some talent pool

The main ping for any changes to a candidate, other than the html resume, which has its own delta ping. Only produced as non-SoT.

post
post

Search candidates, returning recruiter-facing details. The method is a POST solely because the size and number of parameters might get too large for a GET. withResume - if present, only return candidates with (if true) or without (if false) an attached resume

get

Return recruiter-facing details for a specific candidate. e.g do not contact flag

/careerSites

Career sites are web portals showing jobs that exist inside the tenant, as opposed to job boards, which live outside the tenant.

get

A rollup of the details of all careers sites produced by all apps. SoT.

get

Descriptions of one or more careers sites hosted by a specific app. Non-SoT.

get

Get details for whichever career site which has been marked as the primary by the tenant. SoT.

The response is the same as for GET /careerSites, except that only the board which has been marked as the primary is included in the results.

/categories

Tenant-defined hierarchical structures used in talent management to categorize job openings, candidates and others. Includes details of inactivated nodes.

get

Fetch list of categories

post

Create a single category (without any values)

post

The main ping for any changes to the categories. Useful e.g. to replicate categories into a database without polling.

Non-SoT.

category ID

post

Update a single category, not including its values

delete

Delete a category, along with all of its values

post

Sent to alert any listening apps that a change has been made to this category or one or more of its values. The listeners then know to call GET /categories, GET /categories/byID/{}/values to get the latest data.

get

Get root values and the hierarchy of values beneath. Only available nodes are returned.

post

Create or update a single category value. The category value must not contain the values element.

Data integrity rules for category values

400 must be thrown if the consumer violates any of these:

  • No parent child loops can exist (e.g. setting the parent of a node to one of its own grandchildren would not be allowed)
  • Inactive values must always be at the root (no parent), and cannot have children (i.e. they must not be in a hierarchy)
  • The remappedTo field can only be set (non-null) at the same time a node is inactivated.
  • At the time that remappedTo is set, it must refer to an active node.
  • External ID (unless null) must be unique among all values in a single category (active or not), immutable and never reused.

When a node is inactivated, all apps must remove all references to it. e.g. when the tenant inactivates (deffectively deletes) the IT node, a careers site app would unhook and maybe delete its IT testimonials.

Example operations

This test data is used throughout.

[
  {
    "id": 10034,
    "externalID": "a100",
    "parent": null,
    "name": "Wellington",
    "available": false
  },
  {
    "id": 10032,
    "externalID": "a101",
    "parent": null,
    "name": "Auckland",
    "available": true,
    "values": [
      {
        "id": 10036,
        "externalID": "a104",
        "parent": 10032,
        "name": "North Shore",
        "available": true,
        "values": [
          {
            "id": 10037,
            "externalID": "a105",
            "parent": 10036,
            "name": "Takapuna",
            "available": true
          }
        ]
      }
    ]
  }
]

The request body for the atomic API (POST /categories/byID/{}/values) must only pass a single node.

This is a valid request to POST /categories/byID/{}/values, and will change the name as well as reparenting the node:

  {
    "id": 10037,
    "parent": 10032,
    "name": "Takapuna/Milford"
  }

Create vs update

The POST operation can create nodes, or can update them as identified by id or external id. There is no delete (just updating the available flag to false).

This request will create a new root node, also named Takapuna:

  {
    "name": "Takapuna"
  }

This will create a new node called Albany, also under the North Shore parent:

  {
    "name": "Albany",
    "parent": 10036
  }

id and external id

If id is present, then an exactly matching node must exist. If the request also includes external id, that must match too.

Either of these are a valid request to update the name of the Takapuna node:

POST /categories/byID/{}/values

  {
    "id": 10037,
    "name": "Takapuna/Milford"
  }
  {
    "id": 10037,
    "externalID": "a105",
    "name": "Takapuna/Milford"
  }

This would give an error, since external id does not match.

  {
    "id": 10037,
    "externalID": "a106",
    "name": "Takapuna/Milford"
  }

If only external id is present, then if that matches an existing node, that will be an update, otherwise it will be a create.

e.g. this is a valid request to update the name of the Takapuna node.

  {
    "externalID": "a105",
    "name": "Takapuna/Milford"
  }

This will create a new node named Takapuna (since there is no existing node a1055).

  {
    "externalID": "a1055",
    "name": "Takapuna/Milford"
  }

Available flag

The available flag indicates whether a node can be used going forward - e.g. setting a node to unavailable will prevent it being used for new jobs. However old jobs may still use the category value, even if it is unavailable (see remapping).

By default, available is set to true for new nodes, e.g. this request will create a new, available root node:

  {
    "name": "Singapore"
  }

Remapping nodes

When a node is made unavailable, it can be remapped at the same time. This is a hint to apps that anything attached to that node (e.g. jobs) should be transferred across to the remap node.

For example, this request retires the Takapuna location, and will cause Takapuna jobs to be transferred to North Shore:

  {
    "id": 10037,
    "available": false,
    "remappedTo": 1036
  }

The remappedTo field can only be set at the same time as the node itself is made unavailable (i.e. in the same request).

Race conditions

Wen doing a rapid series of atomic operations on category values, e.g. test scripts, apps should think carefully about race conditions in downstream apps that are replicating the category.

For example, your app:

  • makes node 100 unavailable, and at the same time remaps it to node 102
  • a downstream app learns about this via POST /categories/byID/{}/values/byID/{}/deltaPings
  • the downstream app starts transferring its attached objects from 100 to 102
  • in the meantime, your app has already made 102 inactive and remapped to e.g. 103.
get

get unavailable and remapped nodes, using a cursor model

post

Used to bulk upload or update all values for a single category for the tenant in one long-running operation.

This API could be used to upload categories from an HRMS into an ATS.

The data from each category in the request is applied using JSON Merge Patch semantics (https://tools.ietf.org/html/rfc7396).

The app producing the API should do something like this;

  • build up a "mapping table" that stores mappings from incoming nodes in the request to existing nodes (active or inactive) in the producer's database
    • if the request node has neither id nor external id then no mapping
    • if the request node has id, then map to the existing node with the same id (404 if not found)
      • if the request node also has external id
        • if the mapped node in the database has null external id, its external id will be updated
        • if the mapped node in the database has a different external id, throw a 400 error
    • if the request node has only external id
      • if an existing node in the database has same external id, map to that, else no mapping
    • in all cases, a node can only be mapped once, otherwise 400 error
  • now that mapping is complete, producer can do the CRUD work
    • any unmapped nodes in the request will be created
    • any mapped nodes where the database node is inactive will be made active
    • any mapped nodes in the database will be updated as required (e.g. to have new details, parent)
    • any unmapped and active nodes in the database will be inactivated

The producer's behaviour need not be atomic - the call might fail after only partially processing the values, leaving partial changes applied. In this case the upload could be re-run once the problem was resolved.

SoT.

the ID of a previously launched category values bulk upload

get

Get the status of a previously started upload operation. Normally the producer should keep results around for some time (i.e. weeks/months) after the upload has completed.

SoT.

post

Alert listeners that a previously started upload operation has completed. Normally the producer should keep results around for some time (i.e. weeks/months) after the upload has completed.

Non-SoT.

get

get a single category node, even if it is unavailable (i.e. unlike GET /categories/byID/{}/values)

post

Tell any app that cares that a category node has changed. The node's new state is sent in the request.

post

Tell apps that care that a category node is about to be changed. The node's new state is sent in the request.

Each producer can pass back a markdown document rendering to a user what would happen if this change went ahead. e.g. "10 jobs would be deleted - click here to learn more.

get

Ask any apps that care about category nodes what information they are holding relating to this node.

Each producer can pass back a markdown document rendering to a user, e.g. an ATS might say "_10_ jobs, 287 candidates"

/editSpecs

Overview

The "editspec APIs" allow an apply app to ask the ATS for details of the data the candidate can/must provide - e.g. the job application form when applying for a job.

An editSpec can specify for example;

  • whether a resume can be provided, and whether it is mandatory
  • a message to be displayed to the candidate
  • a set of user-defined fields for the candidate
  • a set of user-defined fields that the candidate can/must provide that are specific to the job being applied for

Later, once the apply app has presented this application form to the candidate, and they have completed it, the apply app can push the candidate and job application(s) and related data into the ATS via POST /candidates.

Versions of the API

There are 4 versions of the editSpecs APIs:

  • POST /editSpecs/fetches/register/me
  • POST /editSpecs/fetches/apply/{job}/me
  • POST /editSpecs/fetches/register/anonymous
  • POST /editSpecs/fetches/apply/{job}/anonymous

The register versions of the API are for use when the app intends to create or update the candidate, without job applications.

The apply versions are for use when the app intends to also create job applications.

The /me (on behalf) versions of these APIs are strongly preferred for security and the best candidate experience. They require that the candidate is signed in via SSO. With the /me APIs, the application form that a candidate sees can be customised for who they are. e.g. an internal candidate might be asked "have you told your manager you're applying for other positions?".

The non-/me versions can be used when no candidate is signed in. This could be e.g.:

  • because the apply app does not use SSO (batch, import, email gateway etc.)
  • to deal with first time visitors to the career site who click "apply" (we may want to show them what the apply experience could be like, without making them sign in at this stage).

The intent - category values

The apply app can use an intent to send category values that hint to the ATS what sort of candidate is about to register, so it can serve up a sensible register form.

e.g. an employer runs a recruitment campaign to drive pilots to their careers site. These potential employees land on a pilot-specific landing page, featuring a button "Sign up for pilot careers". When the potential pilot clicks on the button, they will see the register form within the apply app.

That register form should be customised for pilots - e.g., welcome content for pilots, ask for details of their flight hours on different types of aircraft, etc.

When it calls the editSpecs API, the apply app makes this happen by passing an intent like this saying "give me the registration form for pilot";

Expertise->Pilot

At another example customer, a supermarket opening a new store buys some Facebook advertising in the region. The ads drive candidates to a specific landing page. When the candidate clicks to join, the apply app passes an intent like this to the editSpecs API:

Location->Lincoln Nebraska Expertise->Retail

Using this intent, the ATS can now customise the register form - e.g.

  • pre-set the location to Lincoln
  • display content related to Lincoln, Nebraska
  • display tax-, employment-related or EEO questions specific to Lincoln, Nebraska, and also to Retail roles

Intents are mainly useful for the register APIs. When passed to the apply APIs, the ATS can use both the job being applied for, and the intent, to customise the application form.

The tracker

If the apply app has access to a tracker, it should pass it into the editSpec API (and later, the apply API).

The tracker can allow the ATS to customise the form. For example when the a candidate was referred via the new employee referral program, the employer can ask additional/less questions.

Accessing the editSpec for invisible jobs

When the job is not visible to the candidate (e.g. internal only jobs), the editSpecs API call will fail.

The exception is when a tracker chain is passed to the API that contains the job access code.

Usually trackers like this are created by the employer to allow only selected candidates to apply, e.g. allowing only selected employees to apply for a job in a redundancy situation, allowing a late candidate to apply after the job even once it has been closed.

An apply app could also create a tracker like this in order to access the application form for a job which is not visible.

Always produced as SoT.

The methods are POST solely because parameters may get too long for a GET.

post
post
post
post

/global

resources which are global/singletons

get

Return true if the IP passed in falls within one of the ranges known to be internal. Apps can use this to make educated guesses about whether to display, for example, buttons like "employee referral" on jobs, depending on whether the user is on the internal network/VPN. Note apps should use this only as an indication, and should require the candidate to actually log in and thus be proven an internal before unlocking any actual internal behaviour (e.g. allowing the referral to be made).

get

Get a fragment of HTML with a script tag that pulls in the "current" jquery library, so that it is available to any javascript running anywhere in the page. Any page that injects (other than via iframe) HTML from other apps must include this, so that the injected apps can use it. When, from time to time, the jquery version is updated, all apps therefore receive the update at once.

get

Get the url of the terms and conditions that a candidate must accept before creating an account. Any apps that allow candidates to create accounts (such as apply apps) must require the candidate to agree to these.

/items

This API is deprecated in favour of GET /candidates/me and will shortly be removed.

Candidate-visible items held on the candidate themselves, e.g. their own answers when applying for jobs

get

Get values and (in some scenarios) metadata, for all items

/jobBoards

Job boards are external sites that a tenant may post their jobs to, as opposed to career sites, which are web portals showing jobs that exist inside the tenant.

get

A rollup of the details of all job boards produced by all apps. SoT.

get

Descriptions of a single job board hosted by a specific app. Non-SoT.

get

Get an installed job board's own status as held in the hub, e.g. its setup error message. SoT.

patch

Update an installed job board's own status as held in the hub, e.g. its setup error message. SoT.

Using JSON Merge Patch semantics (https://tools.ietf.org/html/rfc7396).

Job board--defined hierarchical structures used in talent management to categorize job openings, candidates and others.

get

Fetch list of categories

post

Create a single category (without any values)

get

Get root values and the hierarchy of values beneath. Only available nodes are returned.

post

Consumer can pass in a set of categories (the tenant's, e.g. for a job) and then get back a set of job-board specific categories and values that are a mapping from the request.

SoT, produced by a mapping app.

/jobs

These APIs manage position openings (aka vacancies, job openings, etc.) and job templates.

Job descriptions are formatted using a safe subset of markdown, with individual lines demarcated with \n.

Currently, "safe subset" simply means that angle brackets (< or >) are not allowed. Note that this prevents the markdown blockquote syntax from being used in a job description. The safe subset rules may be relaxed in the future.

get

The GET /jobs APIs return those jobs that:

  • match the relevant API, e.g. all jobs, or just jobs currently available to external candidates
  • if a categoryFilter is specified, that match the filter
  • if keywords are specified, that match the keywords
  • if one of the filter date parameters (e.g. gtPublishDate) is specified, that have that date (a) not null and (b) < or > given date
  • if ltID or gtID is specified, that have id < or > ID

When no filter date is specified, results are ordered by job ID asc (if ltID is specified, by job ID desc)

When a filter date (i.e., gtXDate or ltXDate) is specified, results are ordered by that date (asc or desc), and then by job ID asc or desc as above.

A maximum of [limit] jobs will be returned by a single call to the API. If this maximum number is returned, the client should fetch again, this time filtering by the ID and date from the last fetched job, as there may be more results.

post

Create a job, using the same content type as for updating (JSON Merge Patch semantics (https://tools.ietf.org/html/rfc7396)).

The id field must not be present in the request body.

The server's instance of the newly created resource, including its id, is passed back in the response.

get

The GET /jobs APIs return those jobs that:

  • match the relevant API, e.g. all jobs, or just jobs currently available to external candidates
  • if a categoryFilter is specified, that match the filter
  • if keywords are specified, that match the keywords
  • if one of the filter date parameters (e.g. gtPublishDate) is specified, that have that date (a) not null and (b) < or > given date
  • if ltID or gtID is specified, that have id < or > ID

When no filter date is specified, results are ordered by job ID asc (if ltID is specified, by job ID desc)

When a filter date (i.e., gtXDate or ltXDate) is specified, results are ordered by that date (asc or desc), and then by job ID asc or desc as above.

A maximum of [limit] jobs will be returned by a single call to the API. If this maximum number is returned, the client should fetch again, this time filtering by the ID and date from the last fetched job, as there may be more results.

get

The GET /jobs/byID/{} APIs return details for a job that matches the relevant API, e.g. must be open.

post

This API is consumed by the ATS some time after changes have been made to a job that was or is open.

In response, the producer (e.g. a job aggregator) will typically re-pull just this specific job, or all jobs.

Non-SoT.

Resource indicating whether a candidate can apply or not for a given job. An ATS might prevent it if the candidate has already applied, the job might be closed, or there might be more complex rules.

get

Find out if the logged in candidate is allowed to apply for this job, and if not why not.

post

Used to bulk upload or update jobs for the tenant in one long-running operation.

This API is intended for use both for a UI in the producer app to maintain its own database (by consuming its own API), or alternatively for some other app acting as the master to regularly push its data down into the producer.

The data from each job in the request is applied using JSON Merge Patch semantics (https://tools.ietf.org/html/rfc7396). In particular, if the categories array is present, only those categories that are actually present in the request will be altered.

The APIs expect external ID to be immutable.

The app producing the API should do something like this;

  • build up a "mapping table" that stores mappings from incoming nodes in the request to existing nodes in the producer's database
    • if the request node has neither id nor external id then no mapping
    • if the request node has id, then map to the existing node with the same id (404 if not found)
      • if the request node also has external id
        • if the mapped node in the database has null external id, its external id will be updated
        • if the mapped node in the database has a different external id, throw a 400 error
    • if the request node has only external id
      • if an existing node in the database has same external id, map to that, else no mapping
    • in all cases, a node can only be mapped once, otherwise 400 error
  • now that mapping is complete, producer can do the CRUD work
    • any unmapped nodes in the request will be created/re-activated
    • any mapped nodes in the database will be updated if required (e.g. to have new details, active status)
    • if the allInclusive flag is set
      • any unmapped nodes in the database will be deleted or inactivated

The producer's behaviour need not be atomic - the call might fail after only partially processing the values, leaving partial changes applied. In this case the upload could be re-run once the problem was resolved.

SoT.

the ID of a previously launched jobs bulk upload

get

Get the status of a previously started upload operation. Normally the producer should keep results around for some time (i.e. weeks/months) after the upload has completed.

SoT.

post

Alert listeners that a previously started upload operation has completed. Normally the producer should keep results around for some time (i.e. weeks/months) after the upload has completed.

Non-SoT.

get

The GET /jobs APIs return those jobs that:

  • match the relevant API, e.g. all jobs, or just jobs currently available to external candidates
  • if a categoryFilter is specified, that match the filter
  • if keywords are specified, that match the keywords
  • if one of the filter date parameters (e.g. gtPublishDate) is specified, that have that date (a) not null and (b) < or > given date
  • if ltID or gtID is specified, that have id < or > ID

When no filter date is specified, results are ordered by job ID asc (if ltID is specified, by job ID desc)

When a filter date (i.e., gtXDate or ltXDate) is specified, results are ordered by that date (asc or desc), and then by job ID asc or desc as above.

A maximum of [limit] jobs will be returned by a single call to the API. If this maximum number is returned, the client should fetch again, this time filtering by the ID and date from the last fetched job, as there may be more results.

get

The GET /jobs/byID/{} APIs return details for a job that matches the relevant API, e.g. must be open.

post

This API is consumed by the ATS some time after changes have been made to a job that was or is publicly visible.

In response, the producer (e.g. a job aggregator) will typically re-pull just this specific job, or all jobs.

Non-SoT.

get

The GET /jobs APIs return those jobs that:

  • match the relevant API, e.g. all jobs, or just jobs currently available to external candidates
  • if a categoryFilter is specified, that match the filter
  • if keywords are specified, that match the keywords
  • if one of the filter date parameters (e.g. gtPublishDate) is specified, that have that date (a) not null and (b) < or > given date
  • if ltID or gtID is specified, that have id < or > ID

When no filter date is specified, results are ordered by job ID asc (if ltID is specified, by job ID desc)

When a filter date (i.e., gtXDate or ltXDate) is specified, results are ordered by that date (asc or desc), and then by job ID asc or desc as above.

A maximum of [limit] jobs will be returned by a single call to the API. If this maximum number is returned, the client should fetch again, this time filtering by the ID and date from the last fetched job, as there may be more results.

get

The GET /jobs/byID/{} APIs return details for a job that matches the relevant API, e.g. must be open.

post

Used to bulk upload or update jobs for the tenant in one long-running operation.

This API is intended for use both for a UI in the producer app to maintain its own database (by consuming its own API), or alternatively for some other app acting as the master to regularly push its data down into the producer.

The data from each job in the request is applied using JSON Merge Patch semantics (https://tools.ietf.org/html/rfc7396). In particular, if the categories array is present, only those categories that are actually present in the request will be altered.

The APIs expect external ID to be immutable.

The app producing the API should do something like this;

  • build up a "mapping table" that stores mappings from incoming nodes in the request to existing nodes in the producer's database
    • if the request node has neither id nor external id then no mapping
    • if the request node has id, then map to the existing node with the same id (404 if not found)
      • if the request node also has external id
        • if the mapped node in the database has null external id, its external id will be updated
        • if the mapped node in the database has a different external id, throw a 400 error
    • if the request node has only external id
      • if an existing node in the database has same external id, map to that, else no mapping
    • in all cases, a node can only be mapped once, otherwise 400 error
  • now that mapping is complete, producer can do the CRUD work
    • any unmapped nodes in the request will be created/re-activated
    • any mapped nodes in the database will be updated if required (e.g. to have new details, active status)
    • if the allInclusive flag is set
      • any unmapped nodes in the database will be deleted or inactivated

The producer's behaviour need not be atomic - the call might fail after only partially processing the values, leaving partial changes applied. In this case the upload could be re-run once the problem was resolved.

SoT.

the ID of a previously launched jobs bulk upload

get

Get the status of a previously started upload operation. Normally the producer should keep results around for some time (i.e. weeks/months) after the upload has completed.

SoT.

post

Alert listeners that a previously started upload operation has completed. Normally the producer should keep results around for some time (i.e. weeks/months) after the upload has completed.

Non-SoT.

Access to publicly visible jobs via XML feeds

get

An XML feed of publicly visible jobs, with full descriptions

get

An XML feed of publicly visible jobs, with abbreviated descriptions

get

The GET /jobs/byID/{} APIs return details for a job that matches the relevant API, e.g. must be open.

patch

Update a job using JSON Merge Patch semantics (https://tools.ietf.org/html/rfc7396). The id field must not be present in the request.

This API is deprecated in favour of GET /jobs/open/byID/{}/canApply and will shortly be removed.

Resource indicating whether a candidate can apply or not for a given job. An ATS might prevent it if the candidate has already applied, the job might be closed, or there might be more complex rules.

get

Find out if the logged in candidate is allowed to apply for this job, and if not why not.

get

This API is deprecated in favour of GET /jobs/byID/{} and will shortly be removed.

Metadata for all items relevant to jobs of this workflow, useful e.g. when creating new jobs

get

Get metadata for all items

get

Get metadata for a specific item

get

This API is deprecated in favour of GET /jobs/feeds/full or GET /jobs/feeds/brief and will shortly be removed.

Get details of the tenant's job feed (an XML-formatted feed of all public jobs)

/jobSets

jobAdSets are job advertisements intended for job boards, etc.

post

Non-SoT.

This API is deprecated in favour of POST /jobSets/uploads and will shortly be removed.

Used to bulk upload active job ads for a tenant to a remote job board. See also APIs to:

  • GET /jobSets/forBoard/{board}

The jobSet is assumed to be the definitive set of jobs for the given tenant, i.e. after the call is complete, if it all went OK, the jobs for this tenant at that board will match the jobSet exactly.

The behavior of the producer is something like:

  • for each job in the jobSet
  • .search for a matching (by code) job in the database, and with status == active
  • .if the job does not exist, create it (producer might also choose to re-open an old one)
  • .if the job already exists and has identical details, leave it
  • .if the job exists but has different details, update it
  • for each job that exists but was not found in the jobSet for the org, make it not active or delete it

Therefore, sending up an empty jobSet effectively deletes or inactivates all jobs for the tenant.

The producer may enforce that job codes are unique within a tenant's open jobs at the board.

The producer's behaviour is not required to be atomic - it is allowed the call could fail after only partially processing the job list, leaving partial changes applied.

post

Non-SoT.

Used to bulk upload active job ads for a tenant to a remote job board. See also APIs to:

  • GET /jobSets/forBoard/{board}

The jobAdSet represents what the caller wants the job ads for the given tenant to be - after the upload the jobs for this tenant at that board should match the jobAdSet exactly.

The app producing the API should do something like this:

  • for each job in the jobSet
  • .search for a matching (by code) job in the database, and with status == active
  • .if the job does not exist, create it (producer might also choose to re-open an old one)
  • .if the job already exists and has identical details, leave it
  • .if the job exists but has different details, update it
  • for each job that exists but was not found in the jobSet for the org, make it not active or delete it

Sending up an empty jobSet deletes or inactivates all jobs for the tenant.

The producer may enforce that job codes are unique within a tenant's open jobs at the board.

The producer's behaviour need not be atomic - the call might fail after only partially processing the job list, leaving partial changes applied.

the ID of a previously launched job set upload

get

Get the status of a previously started upload operation. Normally the producer should keep results around for some time (i.e. weeks/months) after the upload has completed.

SoT.

post

Alert listeners that a previously started upload operation has completed. Normally the producer should keep results around for some time (i.e. weeks/months) after the upload has completed.

Non-SoT.

the shortcode of the app that owns the board

the ID (an integer) of the board

get

SoT.

Get the job ad set for this board, typically from a mapper type app that tracks which jobs have been posted where.

/landingPage

get

deprecated - use GET /appStatus instead.

Produced by apps that want to allow a user viewing the storefront app to click on the app's icon and be offered a link to some page (probably) within the app. e.g. clicking a job board app might go to the front page of the job board.

Probably only consumed by storefront apps.

SoT: non-SoT (each app has their own landing page).

OAuth: client credentials only (if principal-specific behaviour is needed that might happen after SSO on the landing page itself)

These APIs are for the universal menu that many apps inject into their UI.

These are menued apps that get displayed to users (as opposed to e.g. candidates, though currently there's no universal menu for anyone but users)

get

Get html head snippet (typically an include of a stylesheet) used to style the html for the universal menu.

The app building the page that embeds the universal menu must insert the results of this API call in its head section.

All APIs beneath here are operating on behalf of the logged in user.

get

This API is called to ask an app whether it wants to be displayed in the universal menu for the given context (e.g. for a specific job)

The producing app should decide whether it has anything meaningful to display for this specific context, and if so it should return a link, which will be inected into the universal menu. For example, if the context is job 100, then an ATS app likely would inject the URL of its job details page for that job.

Apps should not inject themselves in a spammy way (i.e. when they have nothing relevant to this context). The user can always get to the app via the storefront, and will find the spammy behaviour annoying, so there is no need to do this.

Non-SoT.

get

Get the html to display the universal menu.

The app building the page that embeds the universal menu must in its head section pull in the corresponding style sheet, javascript, etc. as obtained via separate API call.

SoT.

/orgs

orgs have the same semantics as a category, but are internal only (not visible to candidates)

get

Get root values and the hierarchy of values beneath. Only available nodes are returned.

post

create or update a single category value. See notes for POST /categories/byID/{}/uploads. The category value must not contain the values element.

get

get unavailable and remapped nodes, using a cursor model

post

Used to bulk upload or update all values for a single category for the tenant in one long-running operation.

This API could be used to upload categories from an HRMS into an ATS.

The data from each category in the request is applied using JSON Merge Patch semantics (https://tools.ietf.org/html/rfc7396).

The app producing the API should do something like this;

  • build up a "mapping table" that stores mappings from incoming nodes in the request to existing nodes (active or inactive) in the producer's database
    • if the request node has neither id nor external id then no mapping
    • if the request node has id, then map to the existing node with the same id (404 if not found)
      • if the request node also has external id
        • if the mapped node in the database has null external id, its external id will be updated
        • if the mapped node in the database has a different external id, throw a 400 error
    • if the request node has only external id
      • if an existing node in the database has same external id, map to that, else no mapping
    • in all cases, a node can only be mapped once, otherwise 400 error
  • now that mapping is complete, producer can do the CRUD work
    • any unmapped nodes in the request will be created
    • any mapped nodes where the database node is inactive will be made active
    • any mapped nodes in the database will be updated as required (e.g. to have new details, parent)
    • any unmapped and active nodes in the database will be inactivated

The producer's behaviour need not be atomic - the call might fail after only partially processing the values, leaving partial changes applied. In this case the upload could be re-run once the problem was resolved.

SoT.

the ID of a previously launched category values bulk upload

get

Get the status of a previously started upload operation. Normally the producer should keep results around for some time (i.e. weeks/months) after the upload has completed.

SoT.

post

Alert listeners that a previously started upload operation has completed. Normally the producer should keep results around for some time (i.e. weeks/months) after the upload has completed.

Non-SoT.

get

get a single category value, even if it is unavailable (i.e. unlike GET /categories/byID/{}/values)

post

Tell any app that cares that a category value has changed

/panels

Panels shown to a user about a specific job

get

Get an array of all of the panels from all apps.

SoT.

get

Get a panel (purpose-specific small, ebeddable web page) from a single app.

If the panel changes its size, it can trigger a resize of the iframe in the containing via a postMessage call, passing the verb "resize" and the new width and height.

Non-SoT.

Panels shown to a candidate about themselves, i.e on a logged in home page

get

Get an array of all of the panels from all apps.

SoT.

get

Get a panel (purpose-specific small, ebeddable web page) from a single app.

If the panel changes its size, it can trigger a resize of the iframe in the containing via a postMessage call, passing the verb "resize" and the new width and height.

Non-SoT.

/postings

Postings to job boards for individual jobs

patch

Update data on the posting that is set by the app, rather than the hub. Currently this is only the preview link.

The posting must belong to the API consumer (i.e. the job board app).

SoT.

post

Alerts job board apps that a posting has been created, or the tenant- or app-supplied fields on the posting (i.e. not the preview link) have been updated. The entire posting object is passed in the API request.

Non-SoT.

/trackers

A tracker represents a single sourcing event (social sharing, automated job alert, etc.).

Trackers are organized into trees. The path from a single leaf to the trunk of the tree represents the chain of sourcing events, for example that led a candidate to apply. Each tracker can append meta information (e.g. the employee making an employee referral) to the chain.

Trackers can be passed by id into tracker-aware APIs such as POST /candidates.

The producers of APIs that create trackers must:

  • attach the consuming tenant and consuming app (from the incoming OAuth token) onto the tracker itself, so that later access to the tracker can be restricted to the app that created it
  • reuse rather than create trackers when one exists with identical:
    • details (e.g. for a session tracker, the user's IP)
    • consumer
    • parent tracker
post

Create a root tracker (one with no parent).

get

Get this tracker, its parent tracker, and so on to the root of the tree.

post

Create a tracker and attach to the specified parent.

/socialNetworks

get

Get the social networks that are enabled for this tenant

/time

get

Get the current time, in ISO8601 format. This API is only intended for basic app testing, and because of API latency, is unlikely to be of any practical use.

/workflows

get
get
post

The main ping for any changes to a workflow. Noisy, i.e. other apps need to store previous state to work out what has actually changed.

Non-SoT.

/users

Users in the system, who may be recruiters or managers.

get

The GET /users APIs return those users that:

  • match the relevant API, e.g. all users, or just currently active users.
  • if keywords are specified, that match the keywords
  • if one of the filter date parameters (e.g. gtLastUpdateDate) is specified, that have that date (a) not null and (b) < or > given date
  • if ltID or gtID is specified, that have id < or > ID

When no filter date is specified, results are ordered by job ID asc (if ltID is specified, by job ID desc)

When a filter date (i.e., gtXDate or ltXDate) is specified, results are ordered by that date (asc or desc), and then by job ID asc or desc as above.

A maximum of [limit] users will be returned by a single call to the API. If this maximum number is returned, the client should fetch again, this time filtering by the ID and date from the last fetched user, as there may be more results.

post

Create a user, using the same content type as for updating (JSON Merge Patch semantics (https://tools.ietf.org/html/rfc7396)).

The id field must not be present in the request body.

The server's instance of the newly created resource, including its id, is passed back in the response.

get

Get details for this user.

patch

Update a user using JSON Merge Patch semantics (https://tools.ietf.org/html/rfc7396). The id field must not be present in the request.

post

Used to bulk upload or update users for the tenant in one long-running operation.

This API is intended for use both for a UI in the producer app to maintain its own database (by consuming its own API), or alternatively for some other app acting as the master to regularly push its data down into the producer.

The data from each user in the request is applied using JSON Merge Patch semantics (https://tools.ietf.org/html/rfc7396).

The APIs expect external ID to be immutable.

The app producing the API should do something like this;

  • build up a "mapping table" that stores mappings from incoming nodes in the request to existing nodes in the producer's database
    • if the request node has neither id nor external id then no mapping
    • if the request node has id, then map to the existing node with the same id (404 if not found)
      • if the request node also has external id
        • if the mapped node in the database has null external id, its external id will be updated
        • if the mapped node in the database has a different external id, throw a 400 error
    • if the request node has only external id
      • if an existing node in the database has same external id, map to that, else no mapping
    • in all cases, a node can only be mapped once, otherwise 400 error
  • now that mapping is complete, producer can do the CRUD work
    • any unmapped nodes in the request will be created/re-activated
    • any mapped nodes in the database will be updated if required (e.g. to have new details, active status)
    • if the allInclusive flag is set
      • any unmapped nodes in the database will be deleted or inactivated

The producer's behaviour need not be atomic - the call might fail after only partially processing the values, leaving partial changes applied. In this case the upload could be re-run once the problem was resolved.

SoT.

the ID of a previously launched users bulk upload

get

Get the status of a previously started upload operation. Normally the producer should keep results around for some time (i.e. weeks/months) after the upload has completed.

SoT.

post

Alert listeners that a previously started upload operation has completed. Normally the producer should keep results around for some time (i.e. weeks/months) after the upload has completed.

Non-SoT.

get

The GET /users APIs return those users that:

  • match the relevant API, e.g. all users, or just currently active users.
  • if keywords are specified, that match the keywords
  • if one of the filter date parameters (e.g. gtLastUpdateDate) is specified, that have that date (a) not null and (b) < or > given date
  • if ltID or gtID is specified, that have id < or > ID

When no filter date is specified, results are ordered by job ID asc (if ltID is specified, by job ID desc)

When a filter date (i.e., gtXDate or ltXDate) is specified, results are ordered by that date (asc or desc), and then by job ID asc or desc as above.

A maximum of [limit] users will be returned by a single call to the API. If this maximum number is returned, the client should fetch again, this time filtering by the ID and date from the last fetched user, as there may be more results.

get

Get details for this user.

get

The GET /users APIs return those users that:

  • match the relevant API, e.g. all users, or just currently active users.
  • if keywords are specified, that match the keywords
  • if one of the filter date parameters (e.g. gtLastUpdateDate) is specified, that have that date (a) not null and (b) < or > given date
  • if ltID or gtID is specified, that have id < or > ID

When no filter date is specified, results are ordered by job ID asc (if ltID is specified, by job ID desc)

When a filter date (i.e., gtXDate or ltXDate) is specified, results are ordered by that date (asc or desc), and then by job ID asc or desc as above.

A maximum of [limit] users will be returned by a single call to the API. If this maximum number is returned, the client should fetch again, this time filtering by the ID and date from the last fetched user, as there may be more results.

get

Get details for this user.

get

The GET /users APIs return those users that:

  • match the relevant API, e.g. all users, or just currently active users.
  • if keywords are specified, that match the keywords
  • if one of the filter date parameters (e.g. gtLastUpdateDate) is specified, that have that date (a) not null and (b) < or > given date
  • if ltID or gtID is specified, that have id < or > ID

When no filter date is specified, results are ordered by job ID asc (if ltID is specified, by job ID desc)

When a filter date (i.e., gtXDate or ltXDate) is specified, results are ordered by that date (asc or desc), and then by job ID asc or desc as above.

A maximum of [limit] users will be returned by a single call to the API. If this maximum number is returned, the client should fetch again, this time filtering by the ID and date from the last fetched user, as there may be more results.

get

Get details for this user.