Overview
Integration model OAuth & rolling tokens Requests Responses Item synchronisation Read-only resources Webhooks VersioningEZICHEQ API
The EZICHEQ API is designed for integrations where another system already owns much of the company, people and asset data, while EZICHEQ remains the system where checks are performed and compliance activity is recorded.
Integration model
The API is deliberately read-heavy. Items are the primary business resource that may be created and updated through the API. Webhook registrations may also be managed because they are integration configuration.
The following business/activity resources are read-only through OAuth API endpoints:
- certified checks and selfchecks;
- checklist definitions;
- users;
- divisions;
- companies/accounts;
- item types;
- certifications and user certification records; and
- item actions.
Checks cannot be created, edited or deleted through this API. A check webhook means EZICHEQ recorded a check internally; it does not imply that checks can be posted through the API.
Item attachments/images, declared addresses and sign-in/out operations use dedicated item lifecycle endpoints. Geographic location observations, item status history, division movement history and parent/child relationships are read-only. Arbitrary external GPS observations are intentionally not accepted because EZICHEQ currently has no provenance field to distinguish them from check/GPS-unit observations.
Programmers should use the OpenAPI 3 contract as the machine-readable source of truth.
OAuth 2 and rolling refresh tokens
EZICHEQ keeps its existing OAuth 2 Authorisation Code + Refresh Token model. Client Credentials is not supported.
- Authorisation endpoint: https://ezicheq.com/api/authorise
- Token endpoint: https://api.ezicheq.com/oauth2/token
- Grant types:
authorization_code,refresh_token
The user chooses/authorises a company during connection. The returned OAuth scope is that company ID. Access tokens are strictly pinned to that company; the API will fail rather than falling back to another company if the user's access later changes.
Initial connection
Redirect the user's browser to the authorisation endpoint with response_type=code, your client_id, a CSRF-resistant state, and your registered redirect_uri. Exchange the returned code at the token endpoint using HTTP Basic authentication with your client ID and secret.
Rolling refresh tokens
Refresh tokens are one-time-use rolling tokens. Every successful refresh consumes the refresh token supplied and returns a replacement refresh token.
Store the replacement refresh token atomically before allowing another refresh attempt. If multiple workers may refresh the same connection, coordinate them with a lock or a single token-refresh service. Two workers must not attempt to consume the same refresh token concurrently.
Call the token endpoint using grant_type=refresh_token and the current refresh_token, again using HTTP Basic authentication for the client.
Endpoint authentication
Send the access token in the HTTP header:
Authorization: Bearer <access_token>
Requests
- GET reads a resource or list.
- POST creates supported resources or performs explicit integration actions.
- PUT updates supported resources. Item external-ID upsert is idempotent.
- DELETE on an item decommissions the item; it does not erase check history.
- JSON request bodies use
Content-Type: application/json. - Item attachment uploads use
multipart/form-datawith anattachmentfile part. - List endpoints use 100 records per page where paging is applicable; pages start at
page=1.
Responses and errors
Successful endpoint responses use a common JSON envelope. The payload field is results (plural):
{
"status_code": 200,
"status": "OK",
"date": "2026-09-03T14:00:00+12:00",
"request_method": "GET",
"request_uri": "/item/v2",
"count": 1,
"results": [],
"error": null
}
Warnings may also be returned. Integrations should use the HTTP status code for control flow and treat response warnings as additional diagnostic information.
Item synchronisation
/item/v2 is the preferred item API for new integrations. It gives customer systems a stable external key and uses integration-oriented field names.
External IDs
external_id maps to EZICHEQ's existing per-company asset cross-reference (xref). It is unique within the company and is the recommended key for integrations.
GET /item/v2/external/{external_id}finds an item by the customer's key.PUT /item/v2/external/{external_id}creates the item when missing or updates it when present.POST /item/v2/bulk-upsertprocesses up to 100 external-ID records and returns a result for each input record. Records are processed independently, so a response can contain both successes and failures.
Delta reads
Use updated_since with page for incremental item synchronisation. Division restrictions are applied to delta reads exactly as they are to normal item reads.
Writable item fields
Creation supports item type, optional EZICHEQ label, external ID, serial number, asset description, division, DOM, categories, custom fields, private fields, checklist assignments/frequency overrides, assignee users and direct-email assignees where the company feature permits them.
Updates support the same synchronisable metadata plus status/decommissioning. Categories, private fields, direct-email assignees and direct checklist assignments are treated as complete direct-assignment sets when supplied. Checklist frequency overrides can be changed in the same item update.
categories is the effective combined category list in item responses. Responses also include direct_categories, item_type_categories and checklist_categories. API category writes replace only direct_categories; inherited item-type/checklist categories are never rewritten.
The generic item create/update body still rejects accepted previous-check fields, accepted previous-action fields, direct attachment ownership, location/geolocation state and parent/child relationship writes. Attachments, declared addresses and sign-in/out are writable only through the dedicated endpoints below, so normal item upserts cannot manufacture lifecycle history.
Private fields
private_fields is returned in the item v2 representation and can be supplied on create/update as an array of {name, value} objects. When supplied during update it replaces the item's complete private-field set. These fields are separate from private file attachments.
Attachments and images
GET /item/v2/{id}/attachmentslists attached images/documents. Private files are included only when the authorising user has the existing private-file right.POST /item/v2/{id}/attachmentsuploads a file usingmultipart/form-data. The file part is namedattachment; optional parts aredescription,captionandprivate. Existing EZICHEQ upload validation and the 32 MB per-file limit apply.DELETE /item/v2/{id}/attachments/{key}permanently deletes an attached file.PUT /item/v2/{id}/primary-image/{key}selects an attached image as primary.DELETE /item/v2/{id}/primary-imageclears the selection without deleting the file.
Uploading a private attachment requires the same private-file permission used by the application. The first uploaded image becomes the primary image automatically when the item does not already have one.
Declared address and geographic history
EZICHEQ distinguishes a declared item address from geographic observations recorded by checks/GPS data.
GET /item/v2/{id}/addressreturns the current declared address.PUT /item/v2/{id}/addressaccepts{"address":"..."}. EZICHEQ geocodes/normalises the address and keeps prior declarations in history.GET /item/v2/{id}/address/historyreturns declared-address history.GET /item/v2/{id}/locationsreturns non-address geographic observations.
The geographic-observation endpoint is read-only. The API does not accept arbitrary latitude/longitude observations yet because externally supplied GPS data needs explicit provenance before it can safely be mixed with EZICHEQ-generated location records.
Sign-in / sign-out
GET /item/v2/{id}/sign-in-outreturns the current in/out state.GET /item/v2/{id}/sign-in-out/historyreturns the complete audit history, including amendments and on-behalf-of information.POST /item/v2/{id}/sign-outsigns an item out with location plus optional job number, expected return and on-behalf-of data.POST /item/v2/{id}/sign-insigns it back in.
These operations call the normal EZICHEQ sign-in/out business logic. Company feature flags, item-type rules, certification requirements, user permissions and API company/division scope are all enforced.
Item audit history
GET /item/v2/{id}/status-history exposes item status history and GET /item/v2/{id}/division-history exposes division movement history. Both are read-only audit resources.
Read-only resources
The v2 checklist response includes the checklist's question/line definition rather than only checklist metadata. User v2 returns users by immutable ID and includes division membership. Divisions, certification definitions, user-certification records and item actions are available as read APIs for integration/reference purposes.
Certified checks and selfchecks have GET routes only. Existing v1/v2 check paths are retained for compatibility, but there is deliberately no POST, PUT, PATCH or DELETE route for either resource.
Webhooks
Webhook registrations are writable integration configuration. Supported event kinds remain item.create, item.update, check.create and selfcheck.create.
check.create and selfcheck.create mean that a check record was created inside EZICHEQ. They are outbound notifications only.
Signing
Each registration has a 64-character hexadecimal signing secret. Delivery requests include:
X-Ezicheq-Event-Id— stable event ID; use this for consumer idempotency.X-Ezicheq-Timestamp— Unix timestamp used in the signature.X-Ezicheq-Signature—sha256=<hex digest>.
Verify the signature by calculating HMAC-SHA256 over the exact bytes:
<X-Ezicheq-Timestamp> + "." + <raw HTTP request body>
using the registration secret, then compare the hexadecimal digest using a constant-time comparison. Reject timestamps outside a reasonable replay window and deduplicate using the event ID.
Retries and delivery history
Non-2xx deliveries are retried with increasing delays. After the maximum attempts the delivery remains recorded as failed instead of being silently deleted. HTTP 410 Gone disables the webhook registration. Delivery history can be read and a retained event can be explicitly replayed. A registration's signing secret can also be rotated.
Versioning and compatibility
Endpoint families are independently versioned. Existing v1 item/label endpoints remain available for compatibility, but new integrations should prefer item v2. Read-only boundaries that protect check history or authorisation are security/data-integrity rules and may also be enforced on legacy endpoints.