Skip to main content

Screen Data API

Retrieve the data held on any form or table screen in Sense HR, such as Training or Job details, through a single endpoint. Because a screen can hold a large amount of data, requests run in the background: you submit a request, then poll a URL until the r

Install the Screen Data API from the Automate Hub first.

Base URL

https://api.automate.sensewp.com/package/http/endpoint/{your-endpoint-id}

You receive the full URL, including your unique endpoint ID, when your access is set up. Treat it as sensitive.

Authentication

Every submission must include an Authorization header whose value is your API key exactly as issued.

Authorization: your-api-key-here
  • The key is sent raw. Do not prefix it with Bearer.

  • The header name is case-insensitive (Authorization and authorization both work), but the key value must match exactly.

If an IP allow-list has been configured for your endpoint, requests must also come from a registered public IP address. If no allow-list is configured, requests are accepted from any source presenting a valid key. To register or change your approved IP addresses, contact your Sense HR representative.

A submission with a missing or incorrect API key, or from an unregistered IP address, still returns 202, but its retrieval URL returns 404 and no data.

You can send the same Authorization header on the retrieval request too. It is not required there, because the retrieval URL itself is the credential for that one result.

Making a request

Because a screen can return a large volume of data, this endpoint works in two steps, each with its own method:

Step

Method

URL

Returns

1. Submit

POST

your endpoint URL

202 and a Location header

2. Retrieve

GET

the URL from Location

202 while pending, 200 with data when ready

The methods are not interchangeable. The endpoint URL accepts POST only, and the retrieval URL accepts GET only.

Step 1: Submit the request

Send a POST to your endpoint URL with a JSON body and Content-Type: application/json.

The response is 202 Accepted with no data. What matters is the Location response header, which holds the path where your result will become available:

HTTP/1.1 202 Accepted Location: /package/http/endpoint/requests/TGfviR-lsV0YdRfk2-Z_IH-OBZ3z6U5E_2AWsPBExHujXI-DByCBm3eSDppQXC6D

The path is relative. Prefix it with the API host to get the URL to call:

https://api.automate.sensewp.com/package/http/endpoint/requests/TGfviR-…
  • Always read the URL from the Location header. Do not build it yourself or assume the token has a particular length or character set.

  • 202 is not a redirect, so HTTP clients do not follow Location automatically. curl -L, for example, will not follow it: you must send the second request yourself.

  • Each POST submits a new request and returns a new token, so retrying a submission after a network timeout queues a second job. Retry the retrieval, not the submission, or use X-Request-Id (see Polling for the result) to make a retried submission safe.

Step 2: Retrieve the result

Send a GET to the URL from the Location header. Keep requesting the same URL while it returns 202. When it returns 200, the body holds your data. There is no separate status call and no progress information: a 202 simply means "not yet".

Parameters

Parameters go in the JSON body of the Step 1 POST. They are not accepted on the retrieval GET, which returns whatever the submission asked for. Only screenName is required.

Parameter

Type

Default when omitted

Description

screenName

string

(required)

The name of the Sense HR screen to read, e.g. Training. Up to 100 characters.

listType

string

ACTIVE

Which employees to include. One of ACTIVE, LEAVERS or ACTIVE_AND_LEAVERS.

senseHrId

string or array of strings

(all employees)

Restrict the results to one or more employees, identified by their senseHrId.

screenName behaviour

  • Must match the name of a form, table or leaver screen in your Sense HR account, as it appears in Sense HR. Leading and trailing spaces are ignored.

  • If it is missing, empty or not one of those screens, the request is rejected with an error. See Error responses.

  • The parameter name is also accepted as ScreenName.

listType behaviour

  • Accepts ACTIVE, LEAVERS or ACTIVE_AND_LEAVERS.

  • Case-insensitive: active is treated the same as ACTIVE.

  • If omitted, empty or set to an unrecognised value, it defaults to ACTIVE.

senseHrId behaviour

  • If omitted, all employees matching the listType are returned.

  • If supplied, only the employees with those IDs are returned. Accepts a single ID string or an array of ID strings.

  • IDs that are not valid senseHrId values are ignored. If none of the supplied IDs are valid, the filter is treated as empty and all employees are returned.

Use the senseHrId values returned by the Employee Core Data API to reference employees consistently across endpoints.

Polling for the result

The retrieval URL answers with one of these statuses:

Status

Meaning

What to do

202

The result is not ready yet.

Wait, then request the same URL again.

200

The request has finished. The body holds your data, or an error object.

Stop polling and process the body. Check for error first.

404

The submission was rejected: missing or incorrect API key, or an unregistered IP address.

Stop. Fix the credentials and submit again.

410

The result is unknown or no longer available.

Stop. Submit a new request.

500

The request failed while it was being processed.

Stop. Submit a new request; if it keeps failing, contact support.

Treat any status other than 202 as final and stop polling.

Recommended polling behaviour

  • Wait 1–2 seconds before the first retrieval attempt.

  • Then retry every 2–5 seconds.

  • Apply an overall timeout and treat exceeding it as a failure, rather than polling indefinitely. A few minutes is a sensible starting point for a whole-company request.

  • Do not poll in a tight loop. Rapid repeated requests do not make the result arrive sooner.

Larger requests take longer to prepare. One employee on a small screen is typically ready almost immediately; every employee on a table screen with many rows takes longer.

How long results are kept

A result can be retrieved for 1 hour from submission. You can retrieve it more than once in that time. After that, the retrieval URL returns 410 and you need to submit again.

Retrying a submission safely (optional)

To make a submission safe to retry, send an X-Request-Id header with a unique value of your own (a GUID works well):

  • Sending the same X-Request-Id with the same body again, within the hour, does not start a new request. It returns the same Location (or the result, if it is ready).

  • Sending the same X-Request-Id with a different body returns 422 Unprocessable Entity.

  • Without the header, every submission is a new request.

Example requests

Step 1: submit a request for the Training screen. Note -X POST, and -i so the response headers are printed:

curl -i -X POST "https://api.automate.sensewp.com/package/http/endpoint/{your-endpoint-id}" \   -H "Authorization: your-api-key-here" \   -H "Content-Type: application/json" \   -d '{ "screenName": "Training" }'
HTTP/1.1 202 Accepted Location: /package/http/endpoint/requests/TGfviR-lsV0YdRfk2-Z_IH-OBZ3z6U5E_2AWsPBExHujXI-DByCBm3eSDppQXC6D

Step 2: retrieve the result. This is a GET, curl's default, so no -X is needed. Repeat until the status is 200 rather than 202:

curl -i "https://api.automate.sensewp.com/package/http/endpoint/requests/TGfviR-lsV0YdRfk2-Z_IH-OBZ3z6U5E_2AWsPBExHujXI-DByCBm3eSDppQXC6D"

Submitting for specific employees, including leavers:

curl -i -X POST "https://api.automate.sensewp.com/package/http/endpoint/{your-endpoint-id}" \   -H "Authorization: your-api-key-here" \   -H "Content-Type: application/json" \   -d '{         "screenName": "Job details",         "listType": "ACTIVE_AND_LEAVERS",         "senseHrId": [           "111e3eb6-e8c9-47d7-9626-043439d7e293",           "6e6d2b45-5701-47e3-b64d-525b307dd8f1"         ]       }'

Do not add -L: the Location header is not a redirect, and following it with a POST will not return your data.

Submit and poll: shell

BASE="https://api.automate.sensewp.com" KEY="your-api-key-here" ENDPOINT="$BASE/package/http/endpoint/{your-endpoint-id}"  # Step 1: POST to submit, and read the Location header LOCATION=$(curl -sS -X POST -D - -o /dev/null "$ENDPOINT" \   -H "Authorization: $KEY" \   -H "Content-Type: application/json" \   -d '{ "screenName": "Training" }' \   | awk 'BEGIN{IGNORECASE=1} /^location:/ {print $2}' | tr -d '\r')  # Step 2: GET the location until it returns something other than 202 for i in $(seq 1 60); do   sleep 3   CODE=$(curl -sS -o result.json -w '%{http_code}' "$BASE$LOCATION")   [ "$CODE" != "202" ] && echo "Finished with $CODE" && break   echo "Attempt $i: still processing" done

Submit and poll: JavaScript

const BASE = "https://api.automate.sensewp.com"; const KEY = "your-api-key-here"; const ENDPOINT = `${BASE}/package/http/endpoint/{your-endpoint-id}`;  const sleep = (ms) => new Promise((r) => setTimeout(r, ms));  async function getScreenData(body, { timeoutMs = 180000, intervalMs = 3000 } = {}) {   // Step 1: POST to submit, with the parameters as a JSON body   const submitted = await fetch(ENDPOINT, {     method: "POST",     headers: { Authorization: KEY, "Content-Type": "application/json" },     body: JSON.stringify(body),     redirect: "manual",   });   const location = submitted.headers.get("location");   if (!location) throw new Error(`No Location header (status ${submitted.status})`);   const resultUrl = new URL(location, BASE).toString();    // Step 2: GET the location until it stops returning 202   const deadline = Date.now() + timeoutMs;   while (Date.now() < deadline) {     await sleep(intervalMs);     const res = await fetch(resultUrl);     if (res.status === 202) continue;     if (res.status !== 200) throw new Error(`Request failed with status ${res.status}`);     const result = await res.json();     if (result.error) throw new Error(result.error.message);     return result.data;   }   throw new Error("Timed out waiting for the result"); }  const employees = await getScreenData({ screenName: "Training" });

Response

Once ready, the retrieval request returns 200 with Content-Type: application/json. The body names the screen that was read and holds a data array with one entry per employee:

{   "screenName": "Training",   "data": [     { "senseHrId": "…", "name": "…", "records": [ { "recordId": "1", "fields": { "…": "…" } } ] }   ] }

If no employees have data on the screen, data is an empty array.

Employee fields

Field

Type

Description

senseHrId

string

Unique, stable Sense HR identifier for the employee. Matches the senseHrId returned by the Employee Core Data API.

name

string | null

The employee's full name.

records

object[]

The employee's entries on the screen. A form screen has one record; a table screen has one per row.

Record fields

Field

Type

Description

recordId

string

Identifies the record within that employee's entries on the screen, e.g. "1", "2". Records are sorted by it.

eventId

string

Only on screens attached to planner events, such as return-to-work screens. Identifies the event the record belongs to.

fields

object

The screen's fields, keyed by their label exactly as it appears in Sense HR, in the screen's order.

Field values

Because every screen has its own fields, the keys and values inside fields depend on the screen you request and on how it is configured in your account.

  • Values are returned as text, as entered in Sense HR. Numbers and dates are not converted.

  • Dates appear as YYYY-MM-DD, e.g. 2024-04-30.

  • Fields with more than one selected option, such as multi-select dropdowns, return the options as one comma-separated string, e.g. "First aid, Fire marshal".

  • Fields that link to another employee, such as Line manager, return that employee's senseHrId. Several linked employees are returned as one comma-separated string.

  • A field with no value is null. Empty text is returned as null rather than an empty string.

A field label can contain spaces and punctuation, so read values by the exact label, e.g. record.fields["Job title"].

Example response

A request for the Job details screen, a table screen where one employee has two rows:

{   "screenName": "Job details",   "data": [     {       "senseHrId": "01a52697-5564-4b33-9164-01158eac24fe",       "name": "Francisc Abel",       "records": [         {           "recordId": "1",           "fields": {             "Line manager": "ad8ecf24-e326-4fe4-ac8d-7cdbd3006720",             "End date": null,             "Location": "Main office",             "Notes": null,             "Job title": "Cloud Engineer",             "Department": "Dev",             "Start date": "2022-12-01"           }         }       ]     },     {       "senseHrId": "7cb0e774-1ad9-416a-8ed4-4e74578f109f",       "name": "Abidali Sayed",       "records": [         {           "recordId": "1",           "fields": {             "Line manager": "ad8ecf24-e326-4fe4-ac8d-7cdbd3006720",             "End date": "2024-02-29",             "Location": "Manchester",             "Notes": "Row 1",             "Job title": "HR manager",             "Department": "HR",             "Start date": "2023-06-01"           }         },         {           "recordId": "2",           "fields": {             "Line manager": "445f9505-041c-4e8f-83d5-0504caeb6b13",             "End date": "2024-04-30",             "Location": "Higham Ferrers",             "Notes": "Second row",             "Job title": "Cloud Engineer",             "Department": "Administration",             "Start date": "2024-04-01"           }         }       ]     }   ] }

Error responses

A request that cannot be served still finishes with 200 on the retrieval URL, but the body holds an error object in place of data:

{   "screenName": "Trainng",   "error": {     "message": "Screen 'Trainng' was not found. Check the name matches a form or table screen in Sense HR."   } }

Field

Description

screenName

The screen name as received, echoed back for diagnosis. null if none was sent.

error.message

Human-readable explanation, safe to log or show to an operator.

Always check for error before reading data. The messages you may see:

Message

Cause

Fix

screenName is required.

screenName was missing or empty.

Send a screenName.

screenName must be 100 characters or fewer.

The name was too long.

Check the screen name.

The request body is not valid JSON.

The body could not be read.

Send a valid JSON object with Content-Type: application/json.

Screen '…' was not found. …

No form, table or leaver screen has that name.

Check the spelling against the screen name in Sense HR.

Sense HR could not return the screen data. Try again later.

Sense HR did not respond successfully.

Submit the request again later.

Validation happens after submission. The POST returns 202 before the body has been examined, so a rejected request looks like any other: 202, then 200 with an error object.

Notes and guidance

  • Identifying a record. A record is identified by the combination of senseHrId and recordId (plus eventId where present). recordId alone is not unique across employees. If you cache records or perform upserts, key on all of them.

  • Employees with no data. Only employees with at least one entry on the screen are returned. An employee missing from data has nothing recorded on that screen, or is outside your listType or senseHrId filter.

  • Fields can change. Screens are configured in Sense HR, so fields can be added, renamed or removed. Read fields by label and handle a missing label gracefully rather than assuming a fixed set.

  • One screen per request. To read several screens, submit one request per screen and combine the results by senseHrId.

  • Ordering. The order of employees in data is not guaranteed; do not rely on it. Records within an employee are sorted by recordId.

  • Error messages. Treat the list in Error responses as open. Other messages from Sense HR may appear; surface error.message for anything you don't handle.

  • Personal data. Screens can hold sensitive personal data, such as training records, contracts or return-to-work notes. Anyone holding your API key can retrieve them, so limit access to those who need it and make sure you have a lawful basis for the processing.

Troubleshooting

I got a 202 and no data. That is expected on the submission. Read the Location response header and send a GET to that path, prefixed with the API host. See Making a request.

My submission returned no Location header. Check the method. Submitting requires POST; a GET to the endpoint URL returns 405 and submits nothing.

My retrieval returned 404. The submission was rejected. Check the Authorization header holds the key exactly as issued, with no Bearer prefix, and that your IP address is registered if an allow-list is configured. Then submit again.

I keep getting 202 from the retrieval URL. The result is not ready yet. Keep polling every few seconds. If it has not resolved within a few minutes, check you are calling the URL exactly as returned in Location; a truncated or re-encoded token will not resolve.

My retrieval returned 410. The result is no longer available, usually because more than an hour has passed since submission. Submit a new request.

My client followed the Location header automatically and got nothing. 202 is not a redirect, but some clients and gateways treat any Location header as one. Disable redirect following and send the second request yourself.

The response has an error saying the screen was not found. The screenName does not match a form, table or leaver screen. Check the spelling against the screen name in Sense HR.

I asked for one employee but got everyone. The senseHrId value was not a valid ID, so the filter was discarded. Check it against the value returned by the Employee Core Data API.

An employee I expected is missing. They have no entries on that screen, or they are a leaver and listType was ACTIVE (the default). Send "listType": "ACTIVE_AND_LEAVERS" to include leavers.

A field I expected is missing or has a different name. The fields come from the screen's configuration in Sense HR. Check the screen there; field labels are returned exactly as they appear.

For access, API keys, IP registration or any other query, contact your Sense HR representative.

Did this answer your question?