List, fetch, and create inspection templates. Use the same API key as for Inspections. All endpoints require the Authorization header (Bearer token or Basic auth) when used from an integration.
Send Authorization: Bearer <token> or Basic auth with the API key from Authentication. Same credentials as for Inspections, Sites, and other APIs. Requests without a valid key return 401.
| Goal | Endpoint |
|---|---|
| Get template IDs for inspection import or dropdowns | GET /api/templates — returns a light list (id, title, type, status, …). |
| Get full template: questions in order + logic rules (for import or cloning) | GET /api/templates/{id} — replace {id} with a template ID from the list. |
| Create a new template (sections, questions, conditional rules) | POST /api/templates — send createdBy, name, type, and optionally sections, questions, logicRules. |
| Method | Path | Description |
|---|---|---|
GET | /api/templates | List templates (light). Query: publishedOnly=false for drafts. |
GET | /api/templates/{id} | Get one template with sections, questions, and logic rules. |
POST | /api/templates | Create a template (body: createdBy, name, type, sections, questions, logicRules). |
Returns templates for your organization. Response is a plain array of template objects (not { templates: [...] }). By default only published templates are returned; use these as templateId in POST /api/inspections. Set publishedOnly=false to include drafts.
GET /api/templates HTTP/1.1
Host: <your-app-host>
Authorization: Bearer <your_api_key>
Accept: application/json
# Optional query: include draft/archived (default is published only)
GET /api/templates?publishedOnly=falseReplace <your-app-host> with your deployment base URL (e.g. https://yourapp.com). Replace <your_api_key> with your Bearer token or use Basic auth.
| Parameter | Description |
|---|---|
publishedOnly | Default true. Set to false to include DRAFT/archived templates. |
HTTP/1.1 200 OK
Content-Type: application/json
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Daily Pump Check",
"initialTitle": null,
"type": "ASSET",
"status": "PUBLISHED",
"version": 2,
"isActive": true,
"assetTypeId": "at_xyz",
"assetType": { "id": "at_xyz", "name": "Pumps" },
"organizationId": "org_1",
"createdAt": "2025-01-15T10:00:00.000Z",
"updatedAt": "2025-02-01T14:30:00.000Z"
}
]| Field | Description |
|---|---|
id | Template ID — use as templateId in POST /api/inspections or in GET /api/templates/{id}. |
title | Template title. |
type | ASSET or AUDIT. AUDIT inspections require siteId. |
status | PUBLISHED or DRAFT. Only published templates can be used for inspection import. |
version, assetTypeId, assetType | Metadata. assetType is { id, name } when set. |
Status codes: 200 — success. 401 — missing or invalid API key. 429 — rate limit exceeded.
Returns a single template with sections, questions in order, and logic rules. Use this to build inspection import payloads (you need question ids for answers[].questionId) or to replicate template structure including conditional “show question when…” rules.
GET /api/templates/550e8400-e29b-41d4-a716-446655440000 HTTP/1.1
Host: <your-app-host>
Authorization: Bearer <your_api_key>
Accept: application/jsonReplace 550e8400-e29b-41d4-a716-446655440000 with a template id from GET /api/templates.
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Daily Pump Check",
"type": "ASSET",
"status": "PUBLISHED",
"sections": [
{
"id": "sec_1",
"title": "Safety",
"position": 0,
"questions": [
{
"id": "q_1",
"text": "Is the area clear?",
"required": true,
"position": 0,
"responseType": { "id": "rt_1", "name": "Yes/No", "inputType": "SELECT", "uiLabel": "Yes/No" },
"options": [{ "id": "opt_1", "label": "Yes", "value": "yes", "position": 0 }, { "id": "opt_2", "label": "No", "value": "no", "position": 1 }],
"logicRules": [
{
"id": "rule_1",
"order": 0,
"condition": { "type": "equals", "value": "yes" },
"actionType": "ask_questions",
"triggeredQuestionId": "q_2",
"triggeredQuestion": { "id": "q_2", "text": "Describe the issue.", "position": 0 }
}
],
"triggerRule": null
},
{
"id": "q_2",
"text": "Describe the issue.",
"required": false,
"position": 1,
"responseType": { "id": "rt_2", "name": "Text", "inputType": "TEXT", "uiLabel": "Text" },
"options": [],
"logicRules": [],
"triggerRule": { "id": "rule_1", "condition": { "type": "equals", "value": "yes" }, "questionId": "q_1", "question": { "id": "q_1", "text": "Is the area clear?", "position": 0 } }
}
]
}
],
"standaloneQuestions": []
}logicRules on a question: rules that this question triggers (when its answer matches condition, triggeredQuestion is shown). triggerRule on a question: the rule that causes this question to be shown; triggerRule.question is the source question and triggerRule.condition is the condition.
| Field | Description |
|---|---|
id | Question ID — use as questionId in POST /api/inspections answers[]. |
text, required, position | Label, required flag, order. |
responseType | { id, name, inputType, uiLabel }. |
options | For choice questions: [{ id, label, value, position }]. Use value or id in rule conditions and in answers. |
logicRules | Rules on this question: condition (e.g. { type, value }), actionType, triggeredQuestionId, triggeredQuestion. |
triggerRule | If conditional: condition, questionId, question (source question). |
Status codes: 200 — success. 401 — unauthorized. 403 — template belongs to another org. 404 — template not found. 429 — rate limited.
Creates a new template in your organization. With API key you must send createdBy (a user ID in your org). Template is created in DRAFT status; publish from the app if you need it for inspection import.
POST /api/templates HTTP/1.1
Host: <your-app-host>
Authorization: Bearer <your_api_key>
Content-Type: application/json
{
"createdBy": "<user_id_from_your_org>",
"name": "Daily Equipment Check",
"type": "ASSET",
"description": "Optional description",
"assetTypeId": null,
"sections": [
{
"title": "Safety",
"questions": [
{ "key": "q1", "text": "Is the area clear?", "required": true, "responseTypeId": "<response_type_id>" },
{ "key": "q2", "text": "Describe the issue.", "required": false, "responseTypeId": "<response_type_id>" }
]
}
],
"questions": [],
"logicRules": [
{ "sourceKey": "q1", "targetKey": "q2", "condition": { "type": "equals", "value": "Yes" }, "actionType": "ask_questions", "order": 0 }
]
}| Field | Required | Description |
|---|---|---|
createdBy | Yes (API key) | User ID in your organization (e.g. from GET /api/users or your user list). |
name | Yes | Template title. |
type | Yes | ASSET or AUDIT. |
description | No | Optional description. |
assetTypeId | No | For ASSET templates, link to an asset type. |
sections | No | Array of { title, description?, questions: [{ key?, text, required?, responseTypeId?, hint? }] }. Use key for questions that participate in logicRules. |
questions | No | Standalone questions (same shape; no section). |
logicRules | No | Array of { sourceKey, targetKey, condition: { type, value }, actionType?, order? }. See Logic rules below. |
Where to get IDs: createdBy — use a user ID from your org (e.g. GET /api/users if available, or from the app). responseTypeId — response types (Yes/No, Text, Number, etc.) are defined in your organization; use the app (e.g. template builder or admin) to see IDs, or omit for optional questions.
HTTP/1.1 200 OK
Content-Type: application/json
{
"success": true,
"message": "Template saved successfully",
"template": {
"id": "550e8400-e29b-41d4-a716-446655440001",
"title": "Daily Equipment Check",
"type": "ASSET",
"status": "DRAFT",
"sections": [...],
"standaloneQuestions": [...]
}
}The template object includes the created template with id, sections, and standaloneQuestions. The app UI uses sections only; standaloneQuestions is deprecated.
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": "Template name and type are required"
}
# Or when using API key without createdBy:
{
"error": "createdBy (user ID) is required when using API key. Use a user in your organization."
}Give questions that participate in rules an optional key (e.g. "q1", "q2"). In logicRules, sourceKey is the question whose answer is evaluated; targetKey is the question to show when the condition is met. For choice questions, condition.value should match the option’s value (or option id) as returned by GET /api/templates/{id}.
| Field | Description |
|---|---|
sourceKey | Key of the trigger question. |
targetKey | Key of the question to show. |
condition.type | equals, is_selected, is_not_selected, is_not_equals, is_empty, is_not_empty, is_one_of, is_not_one_of, greater_than, less_than. |
condition.value | Value to compare (e.g. option value for choice questions). |
actionType | Optional; default ask_questions. |
order | Optional; order when multiple rules apply. |
Rules whose sourceKey or targetKey do not match any question key are skipped.
Same as other APIs (per API key). See Error Handling for details.
| Code | Meaning |
|---|---|
400 | Bad request — missing required fields (e.g. name, type, or createdBy when using API key), or invalid body. |
401 | Unauthorized — missing or invalid API key. |
403 | Forbidden — e.g. template belongs to another organization, or (POST without API key) not an admin. |
404 | Not found — template ID does not exist or not in your org (GET). |
429 | Rate limit exceeded. |
500 | Server error — see response body for details. |