Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions postman/collections/Fleetbase API/.resources/definition.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ variables:
driver_password_reset_code: ""
manifest_id: ""
manifest_stop_id: ""
# Forms are published from the console, so List Inspection Forms chains the
# first published one; a contract run has to seed it.
inspection_form_id: ""
inspection_id: ""
# Fleet hierarchy. The parent is the fleet created first; the subfleet is
# created beneath it and deleted before it.
parent_fleet_id: ""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
$kind: collection
description: |-
Inspections are the driver's vehicle inspection reports — a DVIR filed before or after a trip against a form the organisation has published from the console.

These endpoints are for the driver filing the inspection: read the published forms, submit against one, and read back what was filed and what it produced. A failed item can raise an issue and open a work order, depending on how the form is configured; both come back on the submission.

Authoring and publishing forms, and reviewing or resolving submissions, is fleet management and is not part of the consumable API. The requests here need at least one published form in the organisation, which a contract run has to seed.
order: 7750
180 changes: 180 additions & 0 deletions postman/collections/Fleetbase API/Inspections/.resources/object.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
$kind: object
name: Inspection
description: |-
An inspection is one filed report against a published inspection form: the vehicle and driver it was filed for, the driver's answer to every field of the form, the pass/fail results derived from the `pass-fail` answers, the photos and signature filed with it, and the issue or work order the form's settings raised from any failed items.
example: |
{
"id": "inspection_submission_4Mnp8Qx2Vz",
"form": { "id": "inspection_form_9Kd2Lm7Aq1", "name": "Pre-trip DVIR", "type": "dvir" },
"vehicle": { "id": "vehicle_7Hx3Pq9Rt2", "plate_number": "TRK-7" },
"driver": { "id": "driver_2Fb8Nc4Wm6", "name": "Dana Driver" },
"issue": null,
"work_order": null,
"custom_field_values": [
{
"custom_field": "0d2b7f1e-4a3c-4d5e-9f61-2c8b7a6d5e4f",
"name": "brakes",
"label": "Brakes",
"type": "pass-fail",
"value_type": "object",
"value": {
"passed": true,
"not_applicable": false,
"severity": null,
"comments": null,
"photos": [],
"unsafe": false
}
},
{
"custom_field": "7c1a9e42-6b8d-4f30-8a52-1d9f3b6c4e70",
"name": "odometer",
"label": "Odometer",
"type": "number",
"value_type": "number",
"value": 120400
},
{
"custom_field": "b8e5d3c1-2f74-4a96-bc08-5e1a7d2f9c63",
"name": "signature",
"label": "Sign here",
"type": "signature",
"value_type": "file",
"value": {
"id": "file_5Qw8Zt2Nb7",
"url": "https://files.fleetbase.io/inspections/4Mnp8Qx2Vz/lq8w1c0v9xk3.png",
"filename": "lq8w1c0v9xk3.png",
"content_type": "image/png"
}
}
],
"files": [
{
"id": "file_5Qw8Zt2Nb7",
"uuid": "3a6c9e21-7b4d-4f18-9c05-2d8e1f7a6b34",
"url": "https://files.fleetbase.io/inspections/4Mnp8Qx2Vz/lq8w1c0v9xk3.png",
"original_filename": "lq8w1c0v9xk3.png",
"content_type": "image/png",
"type": "inspection_signature",
"caption": null,
"created_at": "2026-09-09T07:30:00.000000Z"
}
],
"item_results": [
{
"id": "b3f0c4a2-1d6e-4c1a-9c2b-8e7f6a5d4c3b",
"item_key": "brakes",
"label": "Brakes",
"category": "Safety",
"status": "passed",
"severity": null,
"passed": true,
"comments": null,
"photos": [],
"meta": {},
"submission_id": "inspection_submission_4Mnp8Qx2Vz",
"updated_at": "2026-09-09T07:30:00.000000Z",
"created_at": "2026-09-09T07:30:00.000000Z"
}
],
"type": "dvir",
"status": "submitted",
"result": "passed",
"source": "navigator",
"odometer": 120400,
"engine_hours": null,
"total_items": 1,
"failed_items": 0,
"location": { "latitude": 1.3521, "longitude": 103.8198 },
"signature": {},
"attachments": [],
"meta": {},
"form_name": "Pre-trip DVIR",
"vehicle_name": "Truck 7",
"driver_name": "Dana Driver",
"has_failures": false,
"started_at": "2026-09-09T07:10:00.000000Z",
"submitted_at": "2026-09-09T07:30:00.000000Z",
"resolved_at": null,
"updated_at": "2026-09-09T07:30:00.000000Z",
"created_at": "2026-09-09T07:30:00.000000Z"
}
fields:
- name: id
type: string
description: Public inspection identifier.
- name: form
type: object
description: The inspection form the report was filed against, when loaded.
- name: vehicle
type: object
description: The vehicle inspected, when loaded.
- name: driver
type: object
description: The driver who filed the inspection, when loaded.
- name: issue
type: object
description: The issue raised from the failed items, when the form asks for one and any item failed.
- name: work_order
type: object
description: The work order opened for the failed items, when the form asks for one and any item failed.
- name: custom_field_values
type: array of objects
description: The driver's answer to each field of the form — the field's `custom_field` id, `name`, `label`, `type` and `value_type` beside the `value`. A `pass-fail` value is an object of `passed`, `not_applicable`, `severity`, `comments`, `photos` and `unsafe`; a photo or signature value is resolved to `{ id, url, filename, content_type }` rather than the base64 that was sent.
- name: files
type: array of objects
description: The photos and signatures filed with the inspection, however they arrived — inside the submit body, or dropped on the console's Photos panel.
- name: item_results
type: array of objects
description: One result per `pass-fail` answer, derived from `custom_field_values` — `item_key`, `label`, `category`, `status` (`passed`, `failed` or `not_applicable`), `severity`, `passed`, `comments` and `photos`. This is what issues, work orders and the vehicle's history are built from.
- name: type
type: string
description: Inspection type, taken from the form — `dvir`, `pre_trip`, `post_trip`, or a custom type.
- name: status
type: string
description: Lifecycle status — `submitted`, `needs_review` or `resolved`.
- name: result
type: string
description: "`passed` when every item passed, otherwise `failed`."
- name: source
type: string
description: How it was filed — `navigator` for the driver app, `public_link` for a tokenised link.
- name: odometer
type: number
description: Odometer reading at the time of the inspection.
- name: engine_hours
type: number
description: Engine hours at the time of the inspection.
- name: total_items
type: integer
description: Number of item results.
- name: failed_items
type: integer
description: Number of item results that did not pass.
- name: location
type: object
description: Where the inspection was filed from.
- name: signature
type: object
description: The driver's signature, as the app captured it.
- name: attachments
type: array
description: Additional files attached to the inspection.
- name: has_failures
type: boolean
description: Whether any item failed.
- name: started_at
type: timestamp
description: When the driver began the inspection.
- name: submitted_at
type: timestamp
description: When the inspection was filed.
- name: resolved_at
type: timestamp
description: When the failed items were resolved from the console, if they have been.
- name: updated_at
type: timestamp
description: Timestamp when the inspection was last updated.
- name: created_at
type: timestamp
description: Timestamp when the inspection was created.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
$kind: queryParams
fields:
- name: vehicle
type: string
required: false
description: Only forms that apply to this vehicle — bound to it, or bound to no vehicle at all.
- name: type
type: string
required: false
description: Only forms of these types, such as `dvir` or `pre_trip,post_trip`.
- name: limit
type: integer
required: false
description: Maximum forms to return. Defaults to 30.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
$kind: http-request
name: "List Inspection Forms"
description: |-
Lists the inspection forms the organisation has published, newest first. Draft and archived forms are never listed: a driver can only file against a published one.

Each form carries its structure as `grouped_fields` — the groups of typed fields a driver fills in — so a list is enough to render a form picker without reading each one.

Send `vehicle` to narrow the list to what applies to one vehicle — forms bound to that vehicle, and forms bound to nothing, which are the organisation-wide ones. Send `type` to narrow by form type, as one value or a comma separated list.
url: "{{base_url}}/{{namespace}}/inspection-forms"
method: GET
queryParams:
vehicle: "{{vehicle_id}}"

scripts:
- type: afterResponse
code: |-
// Forms are published from the console, not this API, so the first
// published form is what Retrieve an Inspection Form and Submit an
// Inspection address. A contract run has to seed one.
const forms = pm.response.json();

if (Array.isArray(forms) && forms.length) {
pm.environment.set("inspection_form_id", forms[0].id);
}
language: text/javascript

order: 1000
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
$kind: queryParams
fields:
- name: driver
type: string
required: false
description: Only inspections filed by this driver.
- name: vehicle
type: string
required: false
description: Only inspections of this vehicle.
- name: type
type: string
required: false
description: Only inspections of these types, such as `dvir` or `pre_trip,post_trip`.
- name: result
type: string
required: false
description: "`passed` or `failed`."
- name: status
type: string
required: false
description: "`submitted`, `needs_review` or `resolved`."
- name: limit
type: integer
required: false
description: Maximum inspections to return. Defaults to 30.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
$kind: http-request
name: "List Inspections"
description: |-
Lists filed inspections, newest first.

Narrow by `driver` or `vehicle`, and by `type`, `result` and `status`, each as one value or a comma separated list. Defaults to a recent window rather than the organisation's whole history; use `limit` to widen it.

Each row carries the same shape Retrieve an Inspection answers with: the answers as `custom_field_values`, the `item_results` derived from them, and the `files` filed with the inspection.
url: "{{base_url}}/{{namespace}}/inspections"
method: GET
queryParams:
driver: "{{driver_id}}"

order: 4000
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
$kind: queryParams
fields:
- name: type
type: string
required: false
description: Only inspections of these types, such as `dvir` or `pre_trip,post_trip`.
- name: result
type: string
required: false
description: "`passed` or `failed`."
- name: status
type: string
required: false
description: "`submitted`, `needs_review` or `resolved`."
- name: limit
type: integer
required: false
description: Maximum inspections to return. Defaults to 30.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
$kind: http-request
name: "List Vehicle Inspections"
description: |-
Lists a vehicle's inspection history, newest first — the same inspections List Inspections answers with `vehicle`, addressed the way the driver app holds them, from the vehicle's screen.

Narrow by `type`, `result` and `status`, each as one value or a comma separated list.

Each row carries the answers as `custom_field_values`, the `item_results` derived from them, and the `files` filed with the inspection.
url: "{{base_url}}/{{namespace}}/vehicles/:id/inspections"
method: GET
pathVariables:
- key: id
value: "{{vehicle_id}}"
description: (Required) The vehicle whose inspections to list.


order: 6000
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
$kind: http-request
name: "Retrieve an Inspection Form"
description: |-
Retrieves one published inspection form with its structure and `settings`.

A form is groups of typed fields. `grouped_fields` is what a driver renders: one entry per group, in the order the builder laid them out, each with a `name`, a `meta.grid_size` and its `fields`. A field carries an `id`, a `name`, a `label`, a `type` — `pass-fail`, `input`, `textarea`, `number`, `select`, `radio-button`, `boolean`, `date-picker`, `date-time-input`, `file-upload` or `signature` — plus `required`, `options` and `meta`.

A `pass-fail` field's `meta` says what happens when it fails: the default `severity`, whether a photo or a comment is required, whether the defect takes the vehicle out of service (`unsafe_on_fail`), and any `instructions`. A `number` field's `meta` may name its `unit` and the `role` it plays, such as `odometer`.

The first cut's flat `items` checklist is still answered, read-only, for forms that have not been rebuilt; a form built from fields answers both, and `grouped_fields` is the one to render.

A form that is not published — a draft, or one that has been archived — answers 404, the same as one that does not exist: to a driver, a form that cannot be filled in is not there.
url: "{{base_url}}/{{namespace}}/inspection-forms/:id"
method: GET
pathVariables:
- key: id
value: "{{inspection_form_id}}"
description: (Required) The inspection form to retrieve.

scripts:
- type: afterResponse
code: |-
// Submit an Inspection answers this form, so the fields it will answer
// are chained from here by type. A form that has not been rebuilt from
// the first cut carries no fields; the ids are cleared rather than left
// pointing at a previous run's form, and the submit falls back to the
// flat `item_results` body on its own.
pm.test("Retrieve an Inspection Form answers a published form", function () {
pm.expect(pm.response.code, "expected a 2xx").to.be.oneOf([200, 201]);
});

const form = pm.response.json();
const groups = (form && Array.isArray(form.grouped_fields)) ? form.grouped_fields : [];
const fields = groups.reduce((all, group) => all.concat(Array.isArray(group.fields) ? group.fields : []), []);

const firstOfType = (type) => {
const field = fields.find((candidate) => candidate && candidate.type === type);
return field && field.id ? field.id : null;
};

const chain = {
inspection_pass_fail_field_id: firstOfType("pass-fail"),
inspection_number_field_id: firstOfType("number"),
inspection_signature_field_id: firstOfType("signature"),
};

Object.keys(chain).forEach((key) => {
if (chain[key]) {
pm.environment.set(key, chain[key]);
} else {
pm.environment.unset(key);
}
});

pm.test("A form built from fields answers grouped_fields", function () {
if (!groups.length) {
pm.expect(form, "a first-cut form still answers its checklist").to.have.property("items");
return;
}

pm.expect(fields.length, "a group with no fields in it").to.be.above(0);
fields.forEach((field) => {
pm.expect(field.id, "a field with no id cannot be answered").to.be.a("string").and.not.empty;
pm.expect(field.type, "a field with no type cannot be rendered").to.be.a("string").and.not.empty;
});
});
language: text/javascript

order: 2000
Loading
Loading