API ACCESS · VERSION 1

Assuraz API

Connect Assuraz to the systems you already use: report in Power BI or Excel, keep employees in step with your HR system or Active Directory, and bring in training completed on other platforms.

Getting started

API Access is a paid add-on, available on every plan and priced by the size of your plan. Once it is on your account:

  1. An Admin-level user goes to Settings > API Access and creates a key for each system they want to connect, choosing what it may do.
  2. The key is shown once. Copy it into the other system's secure settings.
  3. Send it with every call. All addresses start https://www.assuraz.co.uk/api/v1, and every call only ever sees your own company's data.

Calls use HTTPS and JSON. Dates are yyyy-mm-dd; times are UTC. GET /api/v1 lists everything the API offers.

Authentication

Send the key in the Authorization header (or an X-API-Key header if your tool can't set Authorization):

Authorization: Bearer azk_XXXXXXXX_your-key

Each key has one or more permissions:

readRead employees, training, incidents, actions, non-conformities, risks, objectives, audits, contractors and suppliers (for Power BI, Excel and other reporting).
employees:writeAdd and update employees and record leavers from your HR system or Active Directory.
training:writeRecord completed training, with its certificate, from another e-learning or training system (e.g. iHASCO).

Keys can be given an expiry date and revoked at any time in Settings > API Access; a revoked key stops working straight away.

Rate limits

Limits are per company (shared by all its keys) and follow the size of your plan:

Plan sizeRequests a minuteRequests a day
Lite (up to 15 employees)605,000
Standard (up to 60 employees)12015,000
Enterprise 1 (up to 150 employees)18030,000
Enterprise 2 (up to 300 employees)24050,000
Enterprise 3 (up to 450 employees)30075,000
Enterprise 4 (up to 600 employees)450100,000
Larger or custom plans600150,000
  • The daily count resets at midnight UTC.
  • A page holds up to 2,000 rows (default 500); a sync call up to 1,000 employees or training records; a request body up to 2 MB.
  • Every response tells you where you are: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset (seconds), X-RateLimit-Daily-Limit and X-RateLimit-Daily-Remaining.
  • Over a limit, the call is refused with 429 and a Retry-After header (seconds). Wait and try again.
  • A nightly refresh of a few registers uses a few dozen requests: the limits are there to keep the service fast for everyone, not to get in the way of normal reporting.

Reading data

GET /api/v1/<register> returns one page of a register. Needs the read permission.

AddressWhat it returnsDate filter
/api/v1/employeesEveryone on the Employee Register, with their department, location and manager. Is_Current is 1 for people employed today.Employment_Start_Date
/api/v1/locationsYour locations (offices, sites) with their address and contact details.-
/api/v1/departmentsYour departments.-
/api/v1/coursesThe Master Course List.-
/api/v1/training-recordsEvery training record, with the employee and course, and whether it is valid, expiring soon (within 60 days) or expired.Date_Completed
/api/v1/incidentsIncidents, accidents and near misses, with category, type and location.Incident_Date
/api/v1/non-conformitiesNon-conformities, complaints and other issues, with status, owner and dates.Date_Raised
/api/v1/actionsCorrective and improvement actions from every module, with who they are assigned to and when they are due.Due_Date
/api/v1/risksThe Risk and Opportunities Register, with initial and residual scores.-
/api/v1/objectivesObjectives and KPIs with their targets.-
/api/v1/objective-resultsThe monthly results for each objective or KPI (one row per KPI per month).MeasurementPeriod
/api/v1/auditsInternal and external audits, with planned and completed dates and status.Planned_Date
/api/v1/contractorsThe Contractor Register (no bank details).-
/api/v1/suppliersThe Supplier Register.-

Options

pagePage number, from 1.
pageSizeRows per page, up to 2,000 (default 500).
updatedSinceOnly rows added or changed since this date, for registers that record it. The reply includes a note if a register doesn't.
from, toOn or after / on or before a date, on the register's main date (shown above).
includeInactivetrue to include deleted (inactive) rows.
formatcsv for a CSV file (opens in Excel) instead of JSON.
curl -H "Authorization: Bearer azk_XXXXXXXX_your-key" \
  "https://www.assuraz.co.uk/api/v1/training-records?pageSize=500&page=1"
{
  "resource": "training-records",
  "page": 1,
  "pageSize": 500,
  "total": 1284,
  "hasMore": true,
  "next": "/api/v1/training-records?pageSize=500&page=2",
  "data": [
    {
      "ID_TrainingRecord": 5521,
      "ID_Employee": 88,
      "ID_Course": 12,
      "Date_Completed": "2026-03-14T00:00:00.000Z",
      "Expiry_Date": "2029-03-14T00:00:00.000Z",
      "Staff_ID": "1042",
      "First_Name": "Sophie",
      "Last_Name": "Brown",
      "Employee_Email": "sophie.brown@example.co.uk",
      "Course_Title": "Emergency First Aid at Work",
      "Training_Status": "Valid"
    }
  ]
}

Rows are ordered by their ID, so paging is stable. Keep requesting next until hasMore is false. Columns are the register's own, plus friendly names from related tables (category, location, person); new columns appear as Assuraz grows, so build reports on the names you use rather than column positions. For privacy the API never returns files, signatures, bank or tax details, or diversity information (gender, ethnicity, disability).

Power BI and Excel

Power BI Desktop

  1. Home > Get data > Blank query, then Advanced editor.
  2. Paste the query below, put in your key and the register you want (incidents, training-records, actions…), and choose Done.
  3. If asked how to connect, choose Anonymous (the key is in the query). Repeat for each register and relate them on their ID columns (e.g. ID_Employee).
  4. Publish to the Power BI service and set a scheduled refresh; the query fetches every page each time.
let
    // Your API key (Settings > API Access in Assuraz) and the register you want
    Key = "azk_XXXXXXXX_your-key",
    Url = "https://www.assuraz.co.uk/api/v1/incidents",
    GetPage = (page as number) =>
        Json.Document(Web.Contents(Url, [
            Query = [page = Text.From(page), pageSize = "2000"],
            Headers = [Authorization = "Bearer " & Key]
        ])),
    Pages = List.Generate(
        () => [n = 1, r = GetPage(1)],
        each [r] <> null,
        each if [r][hasMore] then [n = [n] + 1, r = GetPage([n] + 1)] else [n = [n], r = null],
        each [r][data]
    ),
    Rows = List.Combine(Pages),
    Result = Table.FromRecords(Rows, null, MissingField.UseNull)
in
    Result

Excel

The same query works in Excel: Data > Get Data > From Other Sources > Blank Query > Advanced Editor, paste, Close & Load, then Data > Refresh All whenever you want the latest figures. For a quick one-off, Data > From Web > Advanced, with the address https://www.assuraz.co.uk/api/v1/incidents?format=csv&pageSize=2000 and an HTTP request header Authorization = Bearer your-key.

Keep the key out of shared workbooks: anyone with the file can read the query. For shared reports, use Power BI with the key held by the report owner.

Power Automate

Add Assuraz to Power Automate (and Power Apps) as a custom connector. You then get ready-made actions such as List incidents, List training records, Sync employees and Add training completions, with every field available as dynamic content in your flows. Custom connectors need a Power Automate premium licence.

Set up the connector (once per organisation)

  1. Download the Assuraz connector file.
  2. In Power Automate, go to Data > Custom connectors (under More if you can't see it), then New custom connector > Import an OpenAPI file.
  3. Name it Assuraz, choose the file you downloaded, and select Continue.
  4. On the General tab you can add the Assuraz icon and a background colour. On the Security tab check it says API Key, with the parameter name X-API-Key in the header. Give the label a friendly name such as Assuraz API key.
  5. Select Create connector. You can share the connector with colleagues from its menu.

Use it in a flow

  1. Add an action, choose the Custom tab and pick Assuraz.
  2. The first time, create a connection and paste an API key from Settings > API Access exactly as shown (no “Bearer”). Use a key with only the permissions the flow needs.
  3. For the List actions, open the action's Settings and turn on Pagination (set a threshold such as 5,000) to get every page, or use Changed since to fetch only recent changes.
  4. Loop over the results with Apply to each on the register's list (for example Incidents), and use its fields in later steps.

Ideas

  • Every morning, post incidents reported since yesterday to a Microsoft Teams channel.
  • Every Monday, email each manager the training records in their team that are Expiring soon or Expired.
  • When a row is added to an Excel or SharePoint list of new starters, add them with Sync employees.
  • When your e-learning system (for example iHASCO) emails a completion certificate, record the training and attach the certificate with Add training completions: see Training completions.

Flows that start the moment something happens in Assuraz (for example “when an incident is reported”) are coming later. For now, run flows on a schedule and use Changed since.

Employee sync (HR systems and Active Directory)

POST /api/v1/sync/employees adds and updates employees and records leavers. Needs the employees:write permission. Run it from your HR system's integration tools, Power Automate, or a scheduled script, typically nightly.

  • Each employee is matched on staffId, then email. A match is updated; anyone new is added (within your plan's employee limit) and asked to sign your declarations, as when added on screen.
  • Only the fields you send are changed; send null to clear one. Fields: staffId, email, firstName, lastName, jobTitle, telephone, department, location, managerStaffId or managerEmail, workingPattern (Office Based, Home Based, Field Based, Hybrid Worker), startDate, leavingDate.
  • A department that doesn't exist yet is added (send "createDepartments": false to stop this). Locations must already exist in Assuraz; an unknown one is reported as a warning.
  • Send leavingDate for a leaver. Or, if each call sends your complete list of current staff, add "markMissingAsLeavers": true and everyone not in the list is marked as leaving today (or on leavingDate). As a safeguard, a change that would mark more than a quarter of current employees as leavers is refused unless you also send "confirmLargeLeaverChange": true.
  • The reply lists what happened to every row; a bad row never stops the others.
POST https://www.assuraz.co.uk/api/v1/sync/employees
Authorization: Bearer azk_XXXXXXXX_your-key
Content-Type: application/json

{
  "employees": [
    {
      "staffId": "1042",
      "email": "sophie.brown@example.co.uk",
      "firstName": "Sophie",
      "lastName": "Brown",
      "jobTitle": "IT Manager",
      "department": "IT",
      "location": "Stockport Office",
      "managerEmail": "james.okafor@example.co.uk",
      "workingPattern": "Hybrid Worker",
      "startDate": "2024-02-05"
    },
    { "staffId": "0977", "leavingDate": "2026-10-31" }
  ],
  "markMissingAsLeavers": false
}
{
  "created": 1, "updated": 1, "unchanged": 0, "leavers": 0, "errors": 0,
  "results": [
    { "row": 1, "staffId": "1042", "action": "created", "id": 311 },
    { "row": 2, "staffId": "0977", "action": "updated", "id": 154, "changed": ["Termination_Date"] }
  ]
}

Example: Active Directory, nightly

# Run on a server with the ActiveDirectory PowerShell module, e.g. as a nightly scheduled task.
$Key = 'azk_XXXXXXXX_your-key'   # better: read it from a secure store, not the script
$Uri = 'https://www.assuraz.co.uk/api/v1/sync/employees'

$users = Get-ADUser -Filter 'Enabled -eq $true' -SearchBase 'OU=Staff,DC=example,DC=local' `
  -Properties EmployeeID, Mail, GivenName, Surname, Title, Department, Office, TelephoneNumber, Manager

$rows = foreach ($u in $users) {
  $managerMail = $null
  if ($u.Manager) { $managerMail = (Get-ADUser $u.Manager -Properties Mail).Mail }
  [ordered]@{
    staffId = $u.EmployeeID; email = $u.Mail; firstName = $u.GivenName; lastName = $u.Surname
    jobTitle = $u.Title; department = $u.Department; location = $u.Office
    telephone = $u.TelephoneNumber; managerEmail = $managerMail
  }
}

# Up to 1000 employees per call
for ($i = 0; $i -lt $rows.Count; $i += 1000) {
  $batch = $rows[$i..([Math]::Min($i + 999, $rows.Count - 1))]
  $body = @{ employees = @($batch) } | ConvertTo-Json -Depth 4
  $result = Invoke-RestMethod -Method Post -Uri $Uri -Headers @{ Authorization = "Bearer $Key" } `
    -ContentType 'application/json; charset=utf-8' -Body ([Text.Encoding]::UTF8.GetBytes($body))
  "Created $($result.created), updated $($result.updated), errors $($result.errors)"
}

For Microsoft Entra ID (Azure AD) or an HR system such as BambooHR, Personio, Sage HR or Cezanne, use the same call from Power Automate, Logic Apps or the system's own webhooks or scheduled exports. Ask us if you would like help.

Training completions

POST /api/v1/sync/training-records records training completed on another platform (an e-learning system, a training provider's portal). Needs the training:write permission.

  • Identify the employee by employeeStaffId, employeeEmail or employeeId, and the course by courseId or its exact courseTitle on your Master Course List (add "createCourses": true to add unknown courses).
  • dateCompleted is required; expiryDate is optional.
  • A completion already recorded (same employee, course and date) is skipped, so it is safe to send the same records again.
  • Certificates: add certificateContent (the file, base64-encoded), certificateFileName and, if you know it, certificateContentType. PDF, PNG, JPEG, GIF or WebP, up to 5 MB each and 25 MB per request. The certificate is attached to the training record, so View certificate on the Skills Matrix and Training Records opens it.
  • Sending a certificate for a completion that is already recorded adds it to that record if it has none. Add "replaceCertificate": true to replace one that is already there.
  • If a certificate can't be saved (not a PDF or image, too large, or the company's storage allowance is full), the completion is still recorded and that row's certificate result says why.
POST https://www.assuraz.co.uk/api/v1/sync/training-records
Authorization: Bearer azk_XXXXXXXX_your-key
Content-Type: application/json

{
  "records": [
    { "employeeEmail": "sophie.brown@example.co.uk", "courseTitle": "Fire Safety Awareness", "dateCompleted": "2026-10-20" },
    { "employeeStaffId": "1042", "courseId": 12, "dateCompleted": "2026-10-21", "expiryDate": "2029-10-21" },
    {
      "employeeEmail": "tom.reid@example.co.uk",
      "courseTitle": "Manual Handling",
      "dateCompleted": "2026-10-22",
      "certificateFileName": "Manual-Handling-certificate.pdf",
      "certificateContentType": "application/pdf",
      "certificateContent": "JVBERi0xLjcKJcfsj6IKNSAwIG9iago8PC9MZW5ndGggNiAwIFI..."
    }
  ]
}

Certificates from iHASCO and other online training providers

Using iHASCO? You don't need Power Automate. Paste your iHASCO API key on Settings > API Access > iHASCO training and Assuraz brings in each pass with its certificate every morning. The steps below are for other providers.

Most providers, iHASCO included, issue a certificate as soon as a course is passed and email it to the learner or the training administrator. Power Automate can pass each one straight to Assuraz:

  1. Have the provider send certificate emails to one mailbox (or forward them there with an Outlook rule).
  2. In Power Automate, start a flow with When a new email arrives (V3) on that mailbox, filtered to the provider's sender and Only with attachments.
  3. Work out who and what from the email (the subject or body usually has the learner's name or email and the course title). Or send the learnerGet employees from Assuraz can turn a name into a staff ID.apos;s email as employeeEmail; List employees from Assuraz can turn a name into a staff ID.
  4. Add the Assuraz action Add training completions with the employee, course title, completion date (the email's received date is usually right), and for the certificate the attachment's Name, Content type and Content Bytes.

If your provider offers an API with results (iHASCO's Client API does, with an access token from your iHASCO account), a scheduled flow can also send completions without waiting for the emails. Ask us if you would like help setting up either.

Errors

400Something in the request isn't right; the message says what.
401Missing, unknown, revoked or expired key.
403The add-on isn't active, the key lacks the permission, or the account is read-only (suspended or expired subscriptions can still read but not write).
404Unknown address or register.
409A large leaver change that needs confirming.
413The request is too large; send smaller batches.
429Rate limit reached; wait for Retry-After seconds.
500Something went wrong on our side; try again, and contact support if it continues.

Errors come back as JSON: { "error": "What went wrong" }.

Security and data protection

  • Keys are stored only as a one-way hash; we can't read them back. Every call is over HTTPS and limited to the key's company.
  • Every call is logged (key, address, result, time), and the latest calls and usage are shown in Settings > API Access.
  • You are the controller of the data you take out through the API. Once it is in another system (a Power BI report, a spreadsheet, your HR system), protecting it there is your responsibility, as set out in our terms.
  • Version 1 won't change in ways that break your integrations: new registers and columns may be added, and we will give at least six months' notice before retiring anything.

Questions about the API: contact your Assuraz account manager or use the Contact page.