DocsAPI Reference
Auliq Apps

Overview

The Auliq API is a REST API over HTTPS. Requests and responses are JSON, identifiers are prefixed by resource type, and timestamps are ISO 8601 UTC.

Base URL

https://construction.auliq.net/api/v1

Auth scheme

Bearer API key in the Authorization header.

Sandbox

Same base URL with a test key (aul_test_…).

Quickstart

1

Create an API key in Platform → API, then keep it server-side.

2

Authenticate every request with your key in the Authorization header.

bash
curl -G "https://construction.auliq.net/api/v1/projects" \
  -H "Authorization: Bearer aul_test_YOUR_KEY"
3

Create your first resource — an employee record.

bash
curl -X POST "https://construction.auliq.net/api/v1/employees" \
  -H "Authorization: Bearer aul_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "full_name": "Dana Whitfield",
    "email": "dana.whitfield@example.com",
    "role": "foreman",
    "project_id": "prj_01J8XK92M4"
  }'

Authentication

Every request is authenticated with an API key sent as a Bearer token. Keys are scoped and typed: secret keys act on production data, test keys on sandbox data.

http
# undefined header
Authorization: Bearer aul_sk_51HtXq2f...

Secret key

aul_sk_…

Full access to live data. Keep it server-side only, never in browser code.

Test key

aul_test_…

Requests run against sandbox data and never touch production records.

Publishable key

aul_pk_…

Identifies your integration in browser contexts. Grants no write access.

Authorization scopes

Each key carries a set of scopes. A request whose endpoint needs an ungranted scope returns 403 insufficient_scope.

NameTypeDescription
employees:readscopeList and retrieve employee records.
employees:writescopeCreate, update and deactivate employees.
projects:readscopeList and retrieve projects.
projects:writescopeCreate and update projects.
rfis:readscopeList and retrieve RFIs.
rfis:writescopeCreate, answer and close RFIs.
submittals:writescopeCreate submittals and update their review status.
change_orders:readscopeList and retrieve change orders.
tasks:readscopeList and retrieve tasks.
tasks:writescopeCreate, assign and complete tasks.
webhooks:writescopeCreate and delete webhook subscriptions.

Endpoints

Fourteen endpoints across employees, projects, RFIs, submittals, change orders, tasks and webhooks. Select any endpoint to expand its full specification.

Employees

POSThttps://construction.auliq.net/api/v1/employees

Creates a new employee and assigns them to a project. Email addresses must be unique across the workspace; a duplicate returns 409 Conflict.

Requires scope employees:write

Request body schema

NameTypeDescription
full_namerequiredstringFull name of the employee.
emailrequiredstringUnique work email address.
rolerequiredstringSite role of the employee.laboreroperatorforemansupervisorengineerproject_manager
project_idrequiredstringID of the project the employee is assigned to.
tradestringOptional trade or specialty.
hourly_ratenumberBillable hourly rate in USD.
start_datestring (date)First day on site, ISO 8601 date.

Code example

bash
curl -X POST "https://construction.auliq.net/api/v1/employees" \
  -H "Authorization: Bearer aul_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "full_name": "Dana Whitfield",
  "email": "dana.whitfield@example.com",
  "role": "foreman",
  "project_id": "prj_01J8XK92M4",
  "trade": "carpentry",
  "hourly_rate": 48.5,
  "start_date": "2026-10-19"
}'

Responses

NameTypeDescription
201CreatedEmployee created. Returns the employee object.
400invalid_requestMalformed body or unknown project_id.
401unauthorizedMissing or invalid API key.
409conflictAn employee with this email already exists.
422validation_errorOne or more fields failed validation.
json
{
  "id": "emp_01J9F3WD8N",
  "object": "employee",
  "full_name": "Dana Whitfield",
  "email": "dana.whitfield@example.com",
  "role": "foreman",
  "trade": "carpentry",
  "project_id": "prj_01J8XK92M4",
  "hourly_rate": 48.5,
  "start_date": "2026-10-19",
  "status": "active",
  "created_at": "2026-10-10T09:41:07Z"
}

Projects

RFIs

Submittals

Change orders

Tasks

Webhooks

Data schemas

Core objects returned by the API. Every object carries id, object, created_at and updated_at in addition to the fields listed.

Employee

NameTypeDescription
idstringUnique identifier, prefixed emp_.
objectstringAlways "employee".
full_namestringEmployee full name.
emailstringUnique work email address.
rolestringSite role.laboreroperatorforemansupervisorengineerproject_manager
tradestringOptional trade or specialty.
project_idstringAssigned project.
hourly_ratenumberBillable hourly rate in USD.
start_datestringFirst day on site, ISO 8601 date.
statusstringEmployment status.activeinactive
created_atstringCreation timestamp, ISO 8601 UTC.

Project

NameTypeDescription
idstringUnique identifier, prefixed prj_.
objectstringAlways "project".
namestringHuman-readable project name.
codestringUnique short project code.
clientstringClient or owner organization.
statusstringProject status.planningactivecompleted
budget_amountnumberApproved contract budget in USD.
percent_completenumberOverall progress, 0-100.
created_atstringCreation timestamp, ISO 8601 UTC.

Rfi

NameTypeDescription
idstringUnique identifier, prefixed rfi_.
referencestringHuman-readable number, e.g. RFI-0142.
project_idstringProject the RFI belongs to.
subjectstringShort summary of the question.
questionstringFull question text.
answerstringAnswer text, set when answered.
disciplinestringDiscipline.architecturalstructuralmechanicalelectricalplumbingcivilgeneral
prioritystringResponse urgency.lowmediumhighurgent
statusstringWorkflow status.draftsubmittedansweredclosed
due_datestringRequested answer date, ISO 8601.
created_atstringCreation timestamp, ISO 8601 UTC.

Submittal

NameTypeDescription
idstringUnique identifier, prefixed sub_.
referencestringHuman-readable number, e.g. SUB-0087.
project_idstringProject the submittal belongs to.
titlestringSubmittal title.
typestringSubmittal type.materialproduct_datashop_drawingmockupsampleother
disciplinestringReview discipline.architecturalstructuralmechanicalelectricalplumbingcivilgeneral
vendorstringVendor or manufacturer.
statusstringReview status.draftsubmittedunder_reviewapprovedrejected
due_datestringReview due date, ISO 8601.
created_atstringCreation timestamp, ISO 8601 UTC.

ChangeOrder

NameTypeDescription
idstringUnique identifier, prefixed co_.
referencestringHuman-readable number, e.g. CO-0031.
project_idstringProject the change order belongs to.
contract_referencestringContract the change modifies.
descriptionstringScope of the change.
amountnumberChange amount in USD.
statusstringApproval status.draftpending_approvalapprovedissued
issued_datestringDate issued, ISO 8601.
created_atstringCreation timestamp, ISO 8601 UTC.

Task

NameTypeDescription
idstringUnique identifier, prefixed tsk_.
titlestringTask description.
project_idstringProject the task belongs to.
assigneestringAssignee email address.
statusstringTask status.todoin_progressreviewdone
prioritystringTask priority.lowmediumhigh
due_datestringDue date, ISO 8601.
created_atstringCreation timestamp, ISO 8601 UTC.

Webhook

NameTypeDescription
idstringUnique identifier, prefixed wh_.
urlstringHTTPS endpoint receiving deliveries.
eventsarraySubscribed event types.
statusstringDelivery state.enableddisabled
secretstringSigning secret, returned once at creation.
created_atstringCreation timestamp, ISO 8601 UTC.

Errors

Auliq uses conventional HTTP status codes. Every error response shares one envelope and carries a request_id you can quote in support requests.

json
{
  "error": {
    "type": "validation_error",
    "code": 422,
    "message": "email is not a valid email address.",
    "param": "email",
    "request_id": "req_01J9M7DQ5B"
  }
}
NameTypeDescription
400invalid_requestThe request is malformed: a bad query parameter, header or body.
401unauthorizedNo API key supplied, or the key is invalid or revoked.
403insufficient_scopeThe key is valid but lacks the scope this endpoint requires.
404not_foundThe requested resource does not exist or was archived.
409conflictThe resource already exists, e.g. a duplicate employee email.
422validation_errorOne or more fields failed validation; error.param names the first offender.
429rate_limitedToo many requests. Honor the Retry-After header.
500internal_errorUnexpected error on our side. Retry with backoff.
503service_unavailableTemporary outage or maintenance window. Retry with backoff.

Pagination, filtering & rate limits

List endpoints use cursor pagination, accept server-side filters and sorting, and are rate limited per API key.

Pagination

List responses return an object: "list" envelope with a meta.next_cursor. Pass that cursor as the cursor query parameter to fetch the next page, and stop when meta.has_more is false. limit defaults to 25 and maxes at 100.

json
{
  "object": "list",
  "data": [ /* up to limit objects */ ],
  "meta": {
    "next_cursor": "cur_01J9KQ",
    "has_more": true
  }
}

Filtering & sorting

Filters are plain query parameters documented on each list endpoint (e.g. status=active, project_id=prj_…). Sorting uses sort with an optional descending prefix, e.g. sort=-created_at. Filtering, counting and sorting run server-side.

Rate limits

120 requests per minute per key, with a short burst of 20 requests per second. Exceeding the limit returns 429 rate_limited; back off per the Retry-After header.

NameTypeDescription
X-RateLimit-LimitheaderRequests allowed in the current window (120).
X-RateLimit-RemainingheaderRequests left in the current window.
X-RateLimit-ResetheaderUnix time when the window resets.
Retry-AfterheaderSeconds to wait before retrying, sent with 429 responses.

Webhooks

Subscribe to events over POST /webhooks and receive signed JSON payloads at your HTTPS endpoint when things happen in Auliq.

Event catalog

NameTypeDescription
employee.createdeventAn employee record was created.
project.createdeventA project was created.
task.assignedeventA task was assigned to a user.
task.completedeventA task was marked done.
rfi.createdeventA new RFI was submitted.
rfi.answeredeventAn RFI received an answer.
rfi.closedeventAn RFI was closed.
submittal.reviewedeventA submittal received a review decision.
change_order.approvedeventA change order was approved.

Payload structure

Deliveries are POSTs with a JSON body. Treat the payload id as unique; the same event is never delivered twice with the same id.

json
{
  "id": "evt_01J9M9TN2C",
  "event": "rfi.answered",
  "api_version": "2026-09-01",
  "created_at": "2026-10-11T09:30:00Z",
  "data": {
    "object": {
      "id": "rfi_01J9G5TQ2P",
      "object": "rfi",
      "reference": "RFI-0142",
      "project_id": "prj_01J8XK92M4",
      "status": "answered",
      "answer": "Penetration to be cored at 350mm; revised detail S-204-R2 issued."
    }
  }
}

Verifying signatures

Every delivery includes an X-Auliq-Signature header of the form t=<timestamp>,v1=<signature>. The signature is an HMAC-SHA256 of {timestamp}.{rawBody} using your subscription's signing secret. Reject deliveries older than five minutes.

javascript
import crypto from "crypto";

// Raw request body as a string, and the X-Auliq-Signature header
const header = req.headers["x-auliq-signature"]; // e.g. "t=1760167800,v1=5f2a..."
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
const expected = crypto
  .createHmac("sha256", process.env.AULIQ_WEBHOOK_SECRET)
  .update(`${parts.t}.${rawBody}`)
  .digest("hex");

const valid = crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected));
if (!valid) return res.status(400).end(); // reject forged deliveries

Retries

  • Failed deliveries are retried up to 5 times with exponential backoff, starting at 10 seconds, over 24 hours.
  • Subscriptions that fail every attempt for 3 consecutive days are disabled automatically.
  • Respond with any 2xx status within 10 seconds to acknowledge a delivery.

SDKs & code examples

Official SDKs wrap authentication, retries and pagination so you work with plain objects instead of raw HTTP.

JavaScript / TypeScript

javascript
npm install @auliq/api

import { Auliq } from "@auliq/api";

const auliq = new Auliq(process.env.AULIQ_API_KEY);

const rfi = await auliq.rfis.create({
  project_id: "prj_01J8XK92M4",
  subject: "Slab penetration vs. duct routing",
  question: "Detail S-204 shows a 300mm slab penetration where the duct is routed.",
  priority: "high",
});

for await (const employee of auliq.employees.list({ project_id: "prj_01J8XK92M4" })) {
  console.log(employee.full_name);
}

Python

python
pip install auliq

from auliq import Auliq

client = Auliq(api_key=os.environ["AULIQ_API_KEY"])

employees = client.employees.list(project_id="prj_01J8XK92M4", limit=25)
for employee in employees.data:
    print(employee["full_name"])

Prefer plain HTTP? Every endpoint ships a copy-ready cURL example in the Endpoints section above, and the interactive sandbox generates snippets for you.

Interactive sandbox

Pick an endpoint, fill in parameters, and preview the exact request in cURL, JavaScript or Python. Sending runs a sandbox simulation that returns representative sample responses, including validation errors for missing required fields.

Create an employee record

Request preview
bash
curl -X POST "https://construction.auliq.net/api/v1/employees" \
  -H "Authorization: Bearer aul_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "full_name": "Dana Whitfield",
  "email": "dana.whitfield@example.com",
  "role": "foreman",
  "project_id": "prj_01J8XK92M4",
  "trade": "carpentry",
  "hourly_rate": 48.5,
  "start_date": "2026-10-19"
}'
Simulated sandbox: returns sample data, never touches production records.

Versioning & deprecation

The API is versioned twice: a URL version for breaking changes and a date-based specification version for behavior changes within a release.

  • URL versioning. Breaking changes ship under a new path (/v2); /v1 keeps working unchanged.
  • Spec version. Pin a date-based behavior set with the API-Version header (current: 2026-09-01). Omitting it uses the latest stable version.
  • Deprecation. Endpoints are announced 12 months before removal via the changelog and email, and responses carry Deprecation and Sunset headers with the removal date.
  • After the Sunset date a deprecated endpoint returns 410 Gone with a pointer to its replacement.
http
HTTP/1.1 200 OK
Deprecation: version=v1; date="Wed, 01 Jun 2027 00:00:00 GMT"
Sunset: Wed, 01 Jun 2027 00:00:00 GMT

Changelog

All notable changes to the API. Additive changes ship at any time; breaking changes only with a new URL version.

v1.42026-09-01
  • Added webhook subscriptions for change orders (change_order.approved).
  • Added submittal.reviewed event.
  • Pagination cursors are now stable across concurrent writes.
v1.32026-05-20
  • Added PATCH /rfis/{rfi_id} for answering and closing RFIs.
  • Added the sort query parameter to all list endpoints.
  • Error envelope now includes request_id on every response.
v1.22026-02-10
  • Introduced test-mode keys (aul_test_) for sandbox requests.
  • Rate limit headers standardized across all endpoints.
  • DELETE /employees/{id} now archives instead of hard-deleting.
v1.02025-11-01
  • Initial public release of the Auliq API.