{"openapi":"3.1.0","info":{"title":"Fleet Centr API","version":"0.1.0","description":"REST API for Fleet Centr aviation and vehicle operations data. Use your API key as a Bearer token."},"servers":[{"url":"http://localhost:3001","description":"Local development"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key generated from Fleet Centr Company Settings"}},"schemas":{"TrackingItemMetadata":{"type":"object","properties":{"displayText":{"type":"string","description":"User-friendly display text for the tracking item"},"type":{"type":"string","enum":["number","string"],"description":"Data type of the tracking item"},"precision":{"type":"number","description":"Number of decimal places for the tracking item, if it's a number"}},"required":["displayText","type"]},"Aircraft":{"type":"object","properties":{"uid":{"type":"string","description":"Aircraft document ID"},"registration":{"type":"string","description":"Aircraft registration","example":"VH-ABC"},"type":{"type":"string","description":"Aircraft type","example":"C206"},"category":{"type":"string","description":"Category (fixed-wing, rotary-wing, drone, etc.)"},"manufacturer":{"type":"string"},"model":{"type":"string"},"engineType":{"type":"string"},"engineCount":{"type":"number"},"status":{"type":"string"},"companyId":{"type":"string"},"maintenanceTrackingItems":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/TrackingItemMetadata"},"description":"Maintenance tracking fields for this aircraft. These are the dynamic fields that appear on flight logs and accumulate into running totals.","example":{"airtimeHours":{"displayText":"Airtime Hours","type":"number","precision":1}}},"logTrackingItems":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/TrackingItemMetadata"},"description":"Log tracking fields for this aircraft. These appear on flight logs but do NOT accumulate into totals.","example":{"engineHours":{"displayText":"Engine Hours","type":"number","precision":1}}},"totals":{"type":"object","additionalProperties":{"type":"number"},"description":"Current running totals for each maintenance tracking item"},"initialValues":{"type":"object","additionalProperties":{"type":"number"},"description":"Starting values for each maintenance tracking item"}},"required":["uid","registration","type","category","engineType","engineCount","status","companyId","maintenanceTrackingItems","logTrackingItems"]},"AircraftListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Aircraft"}},"count":{"type":"number"}},"required":["data","count"]},"FlightLog":{"type":"object","properties":{"uid":{"type":"string","description":"Flight log document ID. Auto-generated on creation.","example":"fL9xk2mQ4wR1nP7"},"timeDate":{"type":"string","description":"Flight date/time (ISO 8601 UTC)","example":"2025-06-15T08:30:00.000Z"},"pilot":{"type":"string","description":"Pilot user ID"},"copilot":{"type":"string","description":"Co-pilot user ID"},"copilotType":{"type":"string","enum":["Co-Pilot","ICUS","Dual"],"description":"Co-pilot role type"},"aircraftId":{"type":"string","description":"Aircraft document ID"},"aircraftRegistration":{"type":"string","description":"Aircraft registration (e.g. N12345, or VH-ABC)","example":"N12345"},"flightNumber":{"type":"string","description":"Flight number"},"startLocation":{"type":"string","description":"Departure location","example":"YSSY"},"endLocation":{"type":"string","description":"Arrival location","example":"YMML"},"pax":{"type":"number","nullable":true,"description":"Number of passengers"},"notes":{"type":"string","description":"Flight notes"},"companyId":{"type":"string","description":"Company ID. Auto-set from your API key — do not send in requests."},"createdAt":{"type":"string","description":"Auto-generated. Timestamp when the flight log was created (ISO 8601).","example":"2025-06-15T08:35:00.000Z"},"updatedAt":{"type":"string","description":"Auto-generated. Timestamp of the last update (ISO 8601).","example":"2025-06-15T09:12:00.000Z"}},"required":["uid","timeDate","pilot","aircraftId","aircraftRegistration","startLocation","endLocation","pax","companyId"],"description":"A flight log entry. In addition to the fixed fields listed here, flight logs may contain **dynamic tracking fields** specific to the aircraft. These fields are defined by the aircraft's `maintenanceTrackingItems` and `logTrackingItems`. For example, an aircraft might have `airtimeHours` (number), `engineHours` (number), or `oilUplift` (number). To discover which tracking fields exist for a given aircraft, call `GET /api/v1/aircraft/{id}`. Tracking fields appear as additional key-value pairs in the response."},"FlightLogListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/FlightLog"}},"count":{"type":"number","description":"Number of results returned in this page"},"nextCursor":{"type":"string","nullable":true,"description":"Cursor for the next page. Pass as the `cursor` query parameter. Null when there are no more results."}},"required":["data","count","nextCursor"]},"WriteResult":{"type":"object","properties":{"uid":{"type":"string","description":"Document ID of the affected flight log"},"status":{"type":"string","enum":["created","updated","deleted","no_changes"],"description":"Outcome of the operation"}},"required":["uid","status"]},"CreateFlightLogBody":{"type":"object","properties":{"timeDate":{"type":"string","description":"Flight date/time (ISO 8601 UTC)","example":"2025-06-15T08:30:00.000Z"},"pilot":{"type":"string","description":"Pilot user ID"},"copilot":{"type":"string","description":"Co-pilot user ID"},"copilotType":{"type":"string","enum":["Co-Pilot","ICUS","Dual"],"description":"Co-pilot role type"},"aircraftId":{"type":"string","description":"Aircraft document ID"},"aircraftRegistration":{"type":"string","description":"Aircraft registration (e.g. VH-ABC)","example":"VH-ABC"},"flightNumber":{"type":"string","description":"Flight number"},"startLocation":{"type":"string","description":"Departure location","example":"YSSY"},"endLocation":{"type":"string","description":"Arrival location","example":"YMML"},"pax":{"type":"number","nullable":true,"description":"Number of passengers"},"notes":{"type":"string","description":"Flight notes"},"trackingItems":{"type":"object","additionalProperties":{"anyOf":[{"type":"number"},{"type":"string"},{"nullable":true},{"nullable":true}]},"description":"Dynamic tracking fields for this aircraft. Keys must match the aircraft's `maintenanceTrackingItems` or `logTrackingItems`. Call `GET /api/v1/aircraft/{aircraftId}` to discover available fields.\n\n**Maintenance tracking items** (e.g. `airtimeHours`) accumulate into the aircraft's running totals. **Log tracking items** (e.g. `engineHours`) are recorded but do not affect totals.\n\nExample: `{ \"airtimeHours\": 1.5, \"engineHours\": 1.3 }`","example":{"airtimeHours":1.5,"engineHours":1.3}}},"required":["timeDate","pilot","aircraftId","aircraftRegistration","startLocation","endLocation","pax"],"description":"Request body for creating a flight log. The `uid`, `companyId`, `createdAt`, and `updatedAt` fields are auto-generated — do not include them.\n\n**Important:** Before creating a flight log, call `GET /api/v1/aircraft/{aircraftId}` to discover the dynamic tracking fields for the aircraft. Include their values in the `trackingItems` object. Unknown or incorrectly typed fields will be rejected.\n\nThe actor performing this action is automatically determined from your API key."},"UpdateFlightLogBody":{"type":"object","properties":{"timeDate":{"type":"string","description":"Flight date/time (ISO 8601 UTC)"},"pilot":{"type":"string","description":"Pilot user ID"},"copilot":{"type":"string","description":"Co-pilot user ID"},"copilotType":{"type":"string","enum":["Co-Pilot","ICUS","Dual"],"description":"Co-pilot role type"},"aircraftId":{"type":"string","description":"Aircraft document ID"},"aircraftRegistration":{"type":"string","description":"Aircraft registration"},"flightNumber":{"type":"string","description":"Flight number"},"startLocation":{"type":"string","description":"Departure location"},"endLocation":{"type":"string","description":"Arrival location"},"pax":{"type":"number","nullable":true,"description":"Number of passengers"},"notes":{"type":"string","description":"Flight notes"},"trackingItems":{"type":"object","additionalProperties":{"anyOf":[{"type":"number"},{"type":"string"},{"nullable":true},{"nullable":true}]},"description":"Dynamic tracking fields for this aircraft. Keys must match the aircraft's `maintenanceTrackingItems` or `logTrackingItems`. Call `GET /api/v1/aircraft/{aircraftId}` to discover available fields.\n\n**Maintenance tracking items** (e.g. `airtimeHours`) accumulate into the aircraft's running totals. **Log tracking items** (e.g. `engineHours`) are recorded but do not affect totals.\n\nExample: `{ \"airtimeHours\": 1.5, \"engineHours\": 1.3 }`","example":{"airtimeHours":1.5,"engineHours":1.3}}},"description":"Request body for updating a flight log. Only include fields you want to change. The `uid`, `companyId`, `createdAt`, and `updatedAt` fields cannot be changed.\n\nIf updating tracking fields, include them in the `trackingItems` object. Changes to maintenance tracking items will automatically update the aircraft's running totals."},"BatchResult":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/WriteResult"},"description":"Successfully processed items"},"errors":{"type":"array","items":{"type":"object","properties":{"index":{"type":"number","description":"Index of the failed item in the input array"},"error":{"type":"string","description":"Error message"}},"required":["index","error"]},"description":"Failed items with error details"}},"required":["results","errors"]},"BatchCreateFlightLogsBody":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/CreateFlightLogBody"},"minItems":1,"maxItems":50,"description":"Flight logs to create (max 50 per batch)"}},"required":["items"],"description":"Batch create multiple flight logs. Each item is validated independently — partial success is possible."},"BatchDeleteFlightLogsBody":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":50,"description":"Flight log document IDs to delete (max 50 per batch)"}},"required":["ids"],"description":"Batch delete multiple flight logs. Each is processed independently — partial success is possible."},"Form":{"type":"object","properties":{"uid":{"type":"string","description":"Form template document ID"},"name":{"type":"string","description":"Form display name"},"code":{"type":"string","description":"Unique code for this form within the company"},"department":{"type":"string","description":"Department or category"},"companyId":{"type":"string","description":"Company ID (set by API)"},"sections":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"fields":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}}}},"required":["name","fields"]},"description":"Form sections and fields"},"status":{"type":"string","enum":["active","inactive"],"description":"active (default) or inactive"},"revision":{"type":"number"},"revisionDate":{"type":"string","description":"Revision date (e.g. ISO or MMM YYYY)"},"signatories":{"type":"array","items":{"type":"string"},"description":"Names of signatories"},"dynamicFields":{"type":"array","items":{"type":"string"}},"toolset":{"type":"string","description":"Category/toolset (e.g. aviation, vehicles)"},"notification":{"type":"boolean"},"notificationRecipients":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}}},"publiclyAvailable":{"type":"boolean"},"publicId":{"type":"string","description":"Short ID for public form URL"},"webhooks":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}}},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["uid","name","code","department","companyId","sections"],"description":"Form template. May contain additional fields (e.g. UI-specific section/field config)."},"FormListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Form"}},"count":{"type":"number","description":"Number of results"}},"required":["data","count"]},"FormWriteResult":{"type":"object","properties":{"uid":{"type":"string","description":"Document ID of the form"},"status":{"type":"string","enum":["created","updated","deleted","no_changes"],"description":"Outcome"}},"required":["uid","status"]},"CreateFormBody":{"type":"object","properties":{"name":{"type":"string","description":"Form display name"},"code":{"type":"string","pattern":"^[a-zA-Z0-9-]+$","description":"Unique stable code within the company. Pattern /^[a-zA-Z0-9-]+$/ (examples: AMO-1, MAINT-DAILY)."},"department":{"type":"string","description":"Department or category"},"sections":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}},"description":"Form sections (each with name, fields, etc.)"},"status":{"type":"string","enum":["active","inactive"],"default":"active"},"revision":{"type":"number"},"revisionDate":{"type":"string"},"signatories":{"type":"array","items":{"type":"string"}},"dynamicFields":{"type":"array","items":{"type":"string"}},"toolset":{"type":"string"},"notification":{"type":"boolean"},"notificationRecipients":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}}},"publiclyAvailable":{"type":"boolean"},"publicId":{"type":"string"},"webhooks":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}}}},"required":["name","code","department","sections"],"description":"Request body for creating a form template. companyId is set by the API."},"UpdateFormBody":{"type":"object","properties":{"name":{"type":"string"},"code":{"type":"string","pattern":"^[a-zA-Z0-9-]+$","description":"Unique stable code within the company. Pattern /^[a-zA-Z0-9-]+$/ (examples: AMO-1, MAINT-DAILY)."},"department":{"type":"string"},"sections":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}}},"status":{"type":"string","enum":["active","inactive"]},"revision":{"type":"number"},"revisionDate":{"type":"string"},"signatories":{"type":"array","items":{"type":"string"}},"dynamicFields":{"type":"array","items":{"type":"string"}},"toolset":{"type":"string"},"notification":{"type":"boolean"},"notificationRecipients":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}}},"publiclyAvailable":{"type":"boolean"},"publicId":{"type":"string"},"webhooks":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}}}},"description":"Request body for updating a form template. Only include fields to change."},"CompletedForm":{"type":"object","properties":{"uid":{"type":"string","description":"Completion document ID"},"code":{"type":"string","description":"Form template code"},"name":{"type":"string","description":"Form name at time of completion"},"userId":{"type":"string","description":"User who completed the form"},"companyId":{"type":"string","description":"Company ID"},"data":{"type":"object","additionalProperties":{"nullable":true},"description":"Submitted field values"},"revision":{"type":"number"},"revisionDate":{"type":"string"},"signatories":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["uid","code","name","userId","companyId","data"],"description":"A completed form submission."},"FormCompletionListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CompletedForm"}},"count":{"type":"number","description":"Number of results in this page"},"nextCursor":{"type":"string","nullable":true,"description":"Cursor for the next page. Null when there are no more results."}},"required":["data","count","nextCursor"]},"FormCompletionSchemaResponse":{"type":"object","additionalProperties":{"nullable":true},"description":"Per-form answer contract. `fields[]` lists every answerable field with the storage `key` and value format (string/number/boolean/array/object/file) plus enum/min/max. Use it to build the `answers` payload for POST /form-completions."},"FormCompletionWriteResult":{"type":"object","properties":{"uid":{"type":"string","description":"Completion document ID"},"status":{"type":"string","enum":["created"]},"sideEffects":{"type":"object","properties":{"scheduleItemsCreated":{"type":"number"},"vehiclesUpdated":{"type":"number"},"warnings":{"type":"array","items":{"type":"string"}}},"required":["scheduleItemsCreated","vehiclesUpdated","warnings"],"description":"Asset side effects applied (defect schedule items, odometer updates)."}},"required":["uid","status"]},"CreateFormCompletionBody":{"type":"object","properties":{"formId":{"type":"string","description":"Form template document ID being completed"},"answers":{"type":"object","additionalProperties":{"nullable":true},"description":"Field answers keyed by field name (preferred) or storage key (`__s{si}_f{fi}` / companion keys). Call GET /forms/{id}/completion-schema first to learn each field's key and value format."},"userId":{"type":"string","description":"User attributed with the completion. Defaults to the API actor."},"signatories":{"type":"array","items":{"type":"string"},"description":"Signatory names recorded on the completion."},"submitterName":{"type":"string","description":"Display name used in history/notifications."},"appBaseUrl":{"type":"string","description":"Base URL used to build view-submission links in notifications and defect documentation."}},"required":["formId","answers"],"description":"Request body for creating a form completion. companyId is set by the API."},"AggregateResponse":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"group":{"type":"string","description":"Group value (or 'all' if no groupBy)"},"period":{"type":"string","nullable":true,"description":"Date period (e.g. '2026-01') or null if no dateGroup"},"value":{"type":"number","description":"Aggregated value for this group+period"},"count":{"type":"number","description":"Number of records in this group+period"}},"required":["group","period","value","count"]},"description":"Aggregated results, one row per group+period combination"},"totals":{"type":"object","additionalProperties":{"type":"number"},"description":"Total aggregated value per group (across all periods)"},"totalCount":{"type":"number","description":"Total number of records that matched the query"},"params":{"type":"object","properties":{"collection":{"type":"string"},"metric":{"type":"string"},"operation":{"type":"string"},"groupBy":{"type":"string","nullable":true},"dateGroup":{"type":"string"},"dateRange":{"type":"object","properties":{"start":{"type":"string","nullable":true},"end":{"type":"string","nullable":true}},"required":["start","end"]},"timezone":{"type":"string"}},"required":["collection","metric","operation","groupBy","dateGroup","dateRange","timezone"],"description":"Echo of the query parameters used"}},"required":["results","totals","totalCount","params"]},"AggregateBody":{"type":"object","properties":{"collection":{"type":"string","enum":["flightLogs","completedForms","aircraft","schedule","vehicles"],"description":"The data collection to aggregate","example":"flightLogs"},"metric":{"type":"string","description":"The field to aggregate. Use any numeric field from the collection — including dynamic tracking fields (e.g. airtimeHours, engineHours, landings for flight logs). Use '__count__' to count records regardless of field values.","example":"airtimeHours"},"operation":{"type":"string","enum":["sum","count","avg","min","max"],"default":"sum","description":"Aggregation operation to perform","example":"sum"},"groupBy":{"type":"string","description":"Field to group results by. Examples: 'aircraftRegistration' for flight logs, 'code' for form completions, 'pilot' for per-pilot summaries. If omitted, all records are aggregated into a single group.","example":"aircraftRegistration"},"dateField":{"type":"string","description":"The date field to use for date range filtering and date-based grouping. Typically 'timeDate' for flight logs, 'createdAt' for forms/completions.","example":"timeDate"},"startDate":{"type":"string","description":"Start of date range (ISO 8601 UTC)","example":"2026-01-01T00:00:00.000Z"},"endDate":{"type":"string","description":"End of date range (ISO 8601 UTC)","example":"2026-03-31T23:59:59.999Z"},"timezone":{"type":"string","default":"UTC","description":"Timezone for date grouping. Supports IANA names (e.g. 'Australia/Brisbane'), abbreviations ('AEST', 'AEDT'), or UTC offset format ('UTC+10'). Dates are converted to this timezone before grouping by day/month/etc.","example":"Australia/Brisbane"},"dateGroup":{"type":"string","enum":["none","day","week","month","quarter","year"],"default":"none","description":"How to group results by date. 'month' groups by YYYY-MM, 'quarter' by YYYY-Q1, etc. 'none' means no date grouping — all records in the range are aggregated together. Requires dateField to be set.","example":"month"},"filters":{"type":"object","additionalProperties":{"type":"string"},"description":"Optional equality filters to narrow the query. Keys are field names, values are the required values. Example: { \"aircraftId\": \"abc123\" } or { \"pilot\": \"user-uid\" }","example":{"aircraftId":"abc123"}}},"required":["collection","metric"],"description":"A flexible server-side aggregation query. Works across all data collections (flight logs, form completions, aircraft, schedule, vehicles). Performs sum/count/avg/min/max on any numeric field, with optional grouping by any field and/or by time period. All queries are automatically scoped to the authenticated company."},"User":{"type":"object","properties":{"uid":{"type":"string","description":"User document ID (Firebase Auth UID)"},"email":{"type":"string","description":"User email address"},"displayName":{"type":"string","description":"Display name"},"firstName":{"type":"string","description":"First name"},"lastName":{"type":"string","description":"Last name"},"status":{"type":"string","description":"User status: Active, Pending, or Inactive"},"roles":{"type":"array","items":{"type":"string"},"description":"Roles within the company (e.g. owner, admin, pilot, driver)"},"phone":{"type":"string","description":"Phone number (E.164 format)"},"timezone":{"type":"string","description":"User timezone preference"}},"required":["uid","email","displayName","status","roles"]},"UserListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/User"}},"count":{"type":"number","description":"Number of users"}},"required":["data","count"]},"ScheduleItem":{"type":"object","properties":{"uid":{"type":"string","description":"Schedule item document ID"},"companyId":{"type":"string","description":"Company ID"},"name":{"type":"string","description":"Name of the schedule item","example":"100 Hour Inspection"},"type":{"type":"string","description":"Schedule type (e.g. Inspection, Service, Overhaul, Warranty Expiry, Life Limit, Renewal, Defect, Calibration, Qualification, Certification, Document)","example":"Inspection"},"documentation":{"type":"array","items":{"type":"string"},"description":"Storage URLs for documentation"},"archivedDocumentation":{"type":"array","items":{"type":"string"},"description":"Archived document URLs"},"relatedTo":{"type":"string","description":"Asset UID (aircraft, vehicle, company, user) or name (equipment) this schedule item is for"},"relatedToType":{"type":"string","enum":["aircraft","vehicle","component","company","user","equipment"],"description":"Type of asset this schedule item relates to"},"recurring":{"type":"boolean","description":"Whether this item recurs after completion"},"recurringInterval":{"type":"number","description":"Interval in tracking units (hours/kms/cycles) between recurrences","example":100},"trackingItem":{"type":"string","description":"Key of the dynamic tracking item to use (e.g. 'airtimeHours', 'kilometers'). Must match a key from the asset's maintenanceTrackingItems."},"dueAtInterval":{"type":"number","description":"The tracking item value at which this item is next due","example":1500},"calendarDateDue":{"type":"string","description":"Calendar date when this item is due (ISO 8601)","example":"2025-12-01T00:00:00.000Z"},"calendarRecurring":{"type":"number","description":"Number of days between calendar recurrences","example":365},"lastCarriedOutDate":{"type":"string","description":"Date when maintenance was last performed (ISO 8601)"},"lastCarriedOutValue":{"anyOf":[{"type":"number"},{"type":"string"}],"description":"Tracking item value when maintenance was last performed"},"status":{"type":"string","enum":["active","inactive"],"description":"Status of the schedule item. 'inactive' means soft-deleted.","example":"active"},"notes":{"type":"string","description":"Notes about this schedule item"},"createdAt":{"type":"string","description":"Auto-generated creation timestamp (ISO 8601)"},"updatedAt":{"type":"string","description":"Auto-generated last update timestamp (ISO 8601)"}},"required":["uid","companyId","name","type","relatedTo","relatedToType","recurring"]},"ScheduleItemListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ScheduleItem"}},"count":{"type":"number","description":"Number of results in this page"},"nextCursor":{"type":"string","nullable":true,"description":"Cursor for the next page. Null when there are no more results."}},"required":["data","count","nextCursor"]},"ScheduleWriteResult":{"type":"object","properties":{"uid":{"type":"string","description":"Document ID of the affected record"},"status":{"type":"string","enum":["created","updated","deleted","restored","no_changes"],"description":"Outcome of the operation"}},"required":["uid","status"]},"CreateScheduleItemBody":{"type":"object","properties":{"name":{"type":"string","description":"Name of the schedule item","example":"100 Hour Inspection"},"type":{"type":"string","description":"Schedule type","example":"Inspection"},"relatedTo":{"type":"string","description":"Asset UID or name this schedule item is for"},"relatedToType":{"type":"string","enum":["aircraft","vehicle","component","company","user","equipment"],"description":"Type of asset"},"recurring":{"type":"boolean","description":"Whether this item recurs after completion"},"recurringInterval":{"type":"number","description":"Interval in tracking units between recurrences"},"trackingItem":{"type":"string","description":"Key of the tracking item (e.g. 'airtimeHours', 'kilometers')"},"dueAtInterval":{"type":"number","description":"Tracking item value at which this item is next due"},"calendarDateDue":{"type":"string","description":"Calendar date when due (ISO 8601)"},"calendarRecurring":{"type":"number","description":"Days between calendar recurrences"},"lastCarriedOutDate":{"type":"string","description":"Date when last performed (ISO 8601)"},"lastCarriedOutValue":{"anyOf":[{"type":"number"},{"type":"string"}],"description":"Tracking item value when last performed"},"status":{"type":"string","enum":["active","inactive"],"default":"active","description":"Initial status"},"notes":{"type":"string"}},"required":["name","type","relatedTo","relatedToType","recurring"],"description":"Request body for creating a schedule item. The `uid`, `companyId`, `createdAt`, and `updatedAt` fields are auto-generated. A schedule item must have at least one threshold: a usage-based threshold (trackingItem + dueAtInterval) or a calendar-based threshold (calendarDateDue)."},"UpdateScheduleItemBody":{"type":"object","properties":{"name":{"type":"string"},"type":{"type":"string"},"relatedTo":{"type":"string"},"relatedToType":{"type":"string","enum":["aircraft","vehicle","component","company","user","equipment"]},"recurring":{"type":"boolean"},"recurringInterval":{"type":"number"},"trackingItem":{"type":"string"},"dueAtInterval":{"type":"number"},"calendarDateDue":{"type":"string"},"calendarRecurring":{"type":"number"},"lastCarriedOutDate":{"type":"string"},"lastCarriedOutValue":{"anyOf":[{"type":"number"},{"type":"string"}]},"notes":{"type":"string"}},"description":"Request body for updating a schedule item. Only include fields you want to change."},"CompletedScheduleItem":{"type":"object","properties":{"uid":{"type":"string","description":"Completed schedule item document ID"},"scheduleItemId":{"type":"string","description":"Reference to the parent schedule item"},"companyId":{"type":"string","description":"Company ID"},"userId":{"type":"string","description":"User who completed the item"},"userDisplayName":{"type":"string","description":"Display name of the user at completion time"},"completedAt":{"type":"string","description":"Completion timestamp (ISO 8601)"},"documents":{"type":"array","items":{"nullable":true},"description":"Uploaded documents associated with this completion"},"notes":{"type":"string","description":"Completion notes"},"trackingValue":{"type":"number","description":"Tracking item value at the time of completion"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["uid","scheduleItemId","companyId","userId","userDisplayName","completedAt","documents"]},"CompletedScheduleItemListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CompletedScheduleItem"}},"count":{"type":"number","description":"Number of results in this page"},"nextCursor":{"type":"string","nullable":true,"description":"Cursor for the next page. Null when there are no more results."}},"required":["data","count","nextCursor"]},"MaintenanceStatusItem":{"type":"object","properties":{"scheduleItemUid":{"type":"string","description":"Schedule item document ID"},"name":{"type":"string","description":"Schedule item name"},"type":{"type":"string","description":"Schedule type"},"relatedTo":{"type":"string","description":"Asset UID"},"relatedToType":{"type":"string","description":"Asset type"},"trackingItem":{"type":"string","description":"Tracking item key (e.g. 'airtimeHours', 'kilometers')"},"trackingItemDisplayText":{"type":"string","description":"Human-readable name for the tracking item (e.g. 'Airtime Hours')"},"dueAtInterval":{"type":"number","description":"Tracking value at which this item is next due"},"currentTotal":{"type":"number","description":"Current running total for the tracking item on the asset"},"remaining":{"type":"number","description":"Remaining tracking units until due (dueAtInterval - currentTotal). Negative means overdue."},"calendarDateDue":{"type":"string","description":"Calendar due date (ISO 8601)"},"calendarDaysRemaining":{"type":"number","description":"Days remaining until calendar due date. Negative means overdue."},"lastCarriedOutDate":{"type":"string"},"lastCarriedOutValue":{"anyOf":[{"type":"number"},{"type":"string"}]},"recurring":{"type":"boolean"},"status":{"type":"string"}},"required":["scheduleItemUid","name","type","relatedTo","relatedToType","recurring"]},"MaintenanceStatusResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/MaintenanceStatusItem"}},"count":{"type":"number"}},"required":["data","count"]},"VehicleTracking":{"type":"object","properties":{"kilometers":{"type":"boolean"},"miles":{"type":"boolean"},"hours":{"type":"boolean"}},"description":"Enabled primary tracking units for this vehicle"},"VehicleTrackingDevice":{"type":"object","properties":{"provider":{"type":"string","enum":["tracksolid"],"description":"Tracking provider"},"imei":{"type":"string","description":"Tracking device IMEI","example":"868120145233604"},"mapIcon":{"type":"string","enum":["car","truck","bus"],"description":"Map marker icon"},"linkedAt":{"type":"string","description":"ISO timestamp when the tracker was linked"},"linkedBy":{"type":"string","description":"User ID that linked the tracker"}},"required":["provider","imei"],"description":"Linked vehicle tracking device."},"VehicleTrackingItemMetadata":{"type":"object","properties":{"displayText":{"type":"string","description":"User-friendly display text for the tracking item"},"type":{"type":"string","enum":["number","string"],"description":"Data type of the tracking item"},"precision":{"type":"number","description":"Number of decimal places for the tracking item, if it's a number"}},"required":["displayText","type"]},"Vehicle":{"type":"object","properties":{"uid":{"type":"string","description":"Vehicle document ID"},"make":{"type":"string","description":"Vehicle make","example":"Toyota"},"model":{"type":"string","description":"Vehicle model","example":"Hiace"},"registration":{"type":"string","description":"Vehicle registration","example":"783EP9"},"status":{"type":"string"},"companyId":{"type":"string"},"vin":{"type":"string","description":"Vehicle identification number"},"serialNumber":{"type":"string"},"year":{"type":"number"},"color":{"type":"string"},"description":{"type":"string"},"registrationState":{"type":"string","description":"Registration state or territory"},"fuelType":{"type":"string","enum":["petrol","diesel","petrolHybrid","dieselHybrid","electric"],"description":"Fuel type","example":"diesel"},"transmissionType":{"type":"string","enum":["manual","automatic"],"description":"Transmission type","example":"automatic"},"engineNumber":{"type":"string","description":"Engine number"},"previousRegistration":{"type":"string","description":"Previous registration"},"totalSeats":{"type":"integer","minimum":0,"description":"Total number of seats"},"passengerCapacity":{"type":"integer","minimum":0,"description":"Passenger capacity"},"tracking":{"$ref":"#/components/schemas/VehicleTracking"},"trackingDevice":{"$ref":"#/components/schemas/VehicleTrackingDevice"},"maintenanceTrackingItems":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/VehicleTrackingItemMetadata"},"description":"Maintenance tracking fields for this vehicle. These are dynamic fields that can accumulate into running totals.","example":{"kilometers":{"displayText":"Kilometers","type":"number","precision":0}}},"logTrackingItems":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/VehicleTrackingItemMetadata"},"description":"Log tracking fields for this vehicle. These appear on logs but do not necessarily accumulate into totals."},"totals":{"type":"object","additionalProperties":{"type":"number"},"description":"Current running totals for each maintenance tracking item"},"initialValues":{"type":"object","additionalProperties":{"type":"number"},"description":"Starting values for each maintenance tracking item"}},"required":["uid","make","model","registration","status","companyId","maintenanceTrackingItems","logTrackingItems"]},"VehicleListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Vehicle"}},"count":{"type":"number"}},"required":["data","count"]},"VehicleWriteResult":{"type":"object","properties":{"uid":{"type":"string","description":"Document ID of the affected vehicle"},"status":{"type":"string","enum":["created","updated","deleted","restored","no_changes"],"description":"Outcome of the operation"}},"required":["uid","status"]},"CreateVehicleBody":{"type":"object","properties":{"make":{"type":"string","description":"Vehicle make","example":"Toyota"},"model":{"type":"string","description":"Vehicle model","example":"Hiace"},"registration":{"type":"string","description":"Vehicle registration","example":"783EP9"},"vin":{"type":"string","description":"Vehicle identification number"},"serialNumber":{"type":"string"},"year":{"type":"number"},"color":{"type":"string"},"description":{"type":"string"},"registrationState":{"type":"string","description":"Registration state or territory"},"fuelType":{"type":"string","enum":["petrol","diesel","petrolHybrid","dieselHybrid","electric"],"description":"Fuel type","example":"diesel"},"transmissionType":{"type":"string","enum":["manual","automatic"],"description":"Transmission type","example":"automatic"},"engineNumber":{"type":"string","description":"Engine number"},"previousRegistration":{"type":"string","description":"Previous registration"},"totalSeats":{"type":"integer","minimum":0,"description":"Total number of seats"},"passengerCapacity":{"type":"integer","minimum":0,"description":"Passenger capacity"},"location":{"type":"string"},"thirdPartyUser":{"type":"object","additionalProperties":{"nullable":true},"description":"Third-party user/contact details for the vehicle."},"photos":{"type":"array","items":{"nullable":true},"description":"Stored photo metadata for the vehicle."},"tracking":{"allOf":[{"$ref":"#/components/schemas/VehicleTracking"},{"description":"Exactly one primary tracking unit should be true. Defaults to miles when omitted.","example":{"miles":true}}]},"trackingDevice":{"allOf":[{"$ref":"#/components/schemas/VehicleTrackingDevice"},{"description":"Linked tracking device."}]},"maintenanceTrackingItems":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/VehicleTrackingItemMetadata"},"description":"Maintenance tracking fields for this vehicle. When omitted, the server creates one default field from tracking."},"logTrackingItems":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/VehicleTrackingItemMetadata"},"description":"Log-only tracking fields for this vehicle."},"totals":{"type":"object","additionalProperties":{"type":"number"},"description":"Current running totals for each maintenance tracking item."},"initialValues":{"type":"object","additionalProperties":{"type":"number"},"description":"Starting values for each maintenance tracking item."}},"required":["make","model","registration"],"description":"Request body for creating a vehicle. The `uid`, `companyId`, `status`, `createdAt`, and `updatedAt` fields are controlled by the server."},"BatchCreateVehiclesResult":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/VehicleWriteResult"},"description":"Successfully created vehicles"},"errors":{"type":"array","items":{"type":"object","properties":{"index":{"type":"number","description":"Index of the failed item in the input array"},"error":{"type":"string","description":"Error message"}},"required":["index","error"]},"description":"Failed items with error details"}},"required":["results","errors"]},"BatchCreateVehiclesBody":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/CreateVehicleBody"},"minItems":1,"maxItems":50,"description":"Vehicles to create (max 50 per batch)"}},"required":["items"],"description":"Batch create multiple vehicles. Each item is validated independently, so partial success is possible."},"UpdateVehicleBody":{"type":"object","properties":{"make":{"type":"string","description":"Vehicle make","example":"Toyota"},"model":{"type":"string","description":"Vehicle model","example":"Hiace"},"registration":{"type":"string","description":"Vehicle registration","example":"783EP9"},"vin":{"type":"string","description":"Vehicle identification number"},"serialNumber":{"type":"string"},"year":{"type":"number"},"color":{"type":"string"},"description":{"type":"string"},"registrationState":{"type":"string","description":"Registration state or territory"},"fuelType":{"type":"string","enum":["petrol","diesel","petrolHybrid","dieselHybrid","electric"],"description":"Fuel type","example":"diesel"},"transmissionType":{"type":"string","enum":["manual","automatic"],"description":"Transmission type","example":"automatic"},"engineNumber":{"type":"string","description":"Engine number"},"previousRegistration":{"type":"string","description":"Previous registration"},"totalSeats":{"type":"integer","minimum":0,"description":"Total number of seats"},"passengerCapacity":{"type":"integer","minimum":0,"description":"Passenger capacity"},"location":{"type":"string"},"thirdPartyUser":{"type":"object","additionalProperties":{"nullable":true},"description":"Third-party user/contact details for the vehicle."},"photos":{"type":"array","items":{"nullable":true},"description":"Stored photo metadata for the vehicle."},"tracking":{"allOf":[{"$ref":"#/components/schemas/VehicleTracking"},{"description":"Exactly one primary tracking unit should be true. Defaults to miles when omitted.","example":{"miles":true}}]},"trackingDevice":{"allOf":[{"$ref":"#/components/schemas/VehicleTrackingDevice"},{"description":"Linked tracking device."}]},"maintenanceTrackingItems":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/VehicleTrackingItemMetadata"},"description":"Maintenance tracking fields for this vehicle. When omitted, the server creates one default field from tracking."},"logTrackingItems":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/VehicleTrackingItemMetadata"},"description":"Log-only tracking fields for this vehicle."},"totals":{"type":"object","additionalProperties":{"type":"number"},"description":"Current running totals for each maintenance tracking item."},"initialValues":{"type":"object","additionalProperties":{"type":"number"},"description":"Starting values for each maintenance tracking item."}},"description":"Request body for updating a vehicle. Only include fields you want to change. The `uid`, `companyId`, `status`, `createdAt`, and `updatedAt` fields cannot be changed."},"CounterBinding":{"type":"object","nullable":true,"properties":{"parentUid":{"type":"string"},"parentType":{"type":"string","enum":["aircraft","vehicle","component"]},"sourceKey":{"type":"string","description":"The tracking key on this specific parent that the counter draws from."},"sourceDisplayText":{"type":"string"},"sourcePrecision":{"type":"number","description":"Parent field precision at bind time. While fitted, display and rounding use this rather than the counter's unit precision."},"parentValue":{"type":"number","description":"The parent's total for sourceKey at the moment of binding."},"selfValue":{"type":"number","description":"This counter's own value at the moment of binding."},"boundAt":{"type":"string"}},"required":["parentUid","parentType","sourceKey","parentValue","selfValue","boundAt"],"description":"Where a counter draws usage from, captured at installation. The current value is always recomputed as selfValue + (parent's current total - parentValue), never accumulated, which makes it idempotent. Rebuilt from scratch on every install."},"ComponentCounter":{"type":"object","properties":{"key":{"type":"string","description":"camelCase key, unique within the component"},"displayText":{"type":"string","example":"Time Since Overhaul"},"unit":{"type":"string","enum":["hours","cycles","landings","distance"],"description":"What the value measures. Used for display precision; does not restrict which parent fields a counter may map to at install time."},"precision":{"type":"number","description":"Decimal places from the unit. Used when unbound; while fitted, binding.sourcePrecision wins."},"basis":{"type":"string","enum":["sinceNew","sinceEvent"],"description":"sinceNew counters never reset, so children can safely bind to them. sinceEvent counters are reset by the user, e.g. after an overhaul."},"binding":{"$ref":"#/components/schemas/CounterBinding"},"sourceDecreased":{"type":"boolean","description":"The value this counter inherits from went backwards, usually a manual reset upstream. The counter is clamped and flagged rather than corrected automatically."}},"required":["key","displayText","unit","precision","basis","binding"]},"Component":{"type":"object","properties":{"uid":{"type":"string"},"companyId":{"type":"string"},"name":{"type":"string","example":"Left Engine"},"type":{"type":"string","example":"Engine"},"partNumber":{"type":"string"},"serialNumber":{"type":"string"},"status":{"type":"string"},"state":{"type":"string","enum":["installed","inStores","inRepair","onLoan","inQuarantine","scrapped","sold"],"description":"Where the component is. State and location are independent: the state decides what the location field means (shelf code when inStores, vendor when inRepair, and so on)."},"manufacturer":{"type":"string"},"description":{"type":"string"},"alternatePartNumbers":{"type":"array","items":{"type":"string"}},"location":{"type":"string","description":"Meaning depends on state. Absent while installed, where it comes from the parent."},"parent":{"type":"object","properties":{"type":{"type":"string","enum":["aircraft","vehicle","component"]},"uid":{"type":"string"},"name":{"type":"string"}},"required":["type","uid","name"]},"installedAt":{"type":"string"},"rootAsset":{"type":"object","properties":{"type":{"type":"string","enum":["aircraft","vehicle"]},"uid":{"type":"string"},"name":{"type":"string"}},"required":["type","uid","name"],"description":"The aircraft or vehicle at the top of the tree."},"ancestorUids":{"type":"array","items":{"type":"string"},"description":"Every ancestor uid, so a whole subtree is one query."},"childCount":{"type":"number"},"canHaveChildren":{"type":"boolean","description":"When false, other components cannot be fitted under this one. Defaults to true."},"parentType":{"type":"string","description":"What this component is intended to fit to: \"aircraft\", \"vehicle\", or a Component.type used in the company (e.g. \"Engine\").","example":"aircraft"},"counters":{"type":"array","items":{"$ref":"#/components/schemas/ComponentCounter"}},"totals":{"type":"object","additionalProperties":{"type":"number"},"description":"Current value per counter key. Derived from the counter anchors."},"condition":{"type":"string"},"grn":{"type":"string"},"notes":{"type":"string"}},"required":["uid","companyId","name","type","partNumber","serialNumber","status","state","ancestorUids","childCount","counters","totals"]},"ComponentListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Component"}},"count":{"type":"number"}},"required":["data","count"]},"InheritableSource":{"type":"object","properties":{"key":{"type":"string"},"displayText":{"type":"string"},"unit":{"type":"string","enum":["hours","cycles","landings","distance"],"description":"What the value measures. Used for display precision; does not restrict which parent fields a counter may map to at install time."},"precision":{"type":"number","description":"Decimal places for this source; copied onto the binding at install."},"basis":{"type":"string","enum":["sinceNew","sinceEvent"]},"currentValue":{"type":"number"}},"required":["key","displayText","unit","precision","basis","currentValue"]},"InheritableSourcesResponse":{"type":"object","properties":{"parentName":{"type":"string"},"sources":{"type":"array","items":{"$ref":"#/components/schemas/InheritableSource"}}},"required":["parentName","sources"]},"ComponentWriteResult":{"type":"object","properties":{"uid":{"type":"string"},"status":{"type":"string","enum":["created","updated","deleted","restored","no_changes","installed","removed"]}},"required":["uid","status"]},"ComponentCounterInput":{"type":"object","properties":{"key":{"type":"string","description":"Omit on create; derived from displayText."},"displayText":{"type":"string","example":"Time Since New"},"unit":{"type":"string","enum":["hours","cycles","landings","distance"],"description":"What the value measures. Used for display precision; does not restrict which parent fields a counter may map to at install time."},"basis":{"type":"string","enum":["sinceNew","sinceEvent"],"description":"Defaults to sinceNew."},"initialValue":{"type":"number","description":"Value already on the clock when the component is added. Defaults to 0."}},"required":["displayText","unit"]},"CreateComponentBody":{"type":"object","properties":{"name":{"type":"string","example":"Left Engine"},"type":{"type":"string","description":"Free text, e.g. Engine, Avionics","example":"Engine"},"partNumber":{"type":"string"},"serialNumber":{"type":"string","description":"Required. A part without a serial number is held as a stock item, not a component."},"manufacturer":{"type":"string"},"description":{"type":"string"},"alternatePartNumbers":{"type":"array","items":{"type":"string"}},"state":{"type":"string","enum":["installed","inStores","inRepair","onLoan","inQuarantine","scrapped","sold"],"description":"Defaults to inStores. Use the install endpoint to fit it to a parent."},"location":{"type":"string"},"condition":{"type":"string"},"grn":{"type":"string"},"notes":{"type":"string"},"canHaveChildren":{"type":"boolean","description":"When false, this component will not accept sub-components. Defaults to true."},"parentType":{"type":"string","description":"What this component is intended to fit to: \"aircraft\", \"vehicle\", or a Component.type used in the company (e.g. \"Engine\").","example":"Engine"},"counters":{"type":"array","items":{"$ref":"#/components/schemas/ComponentCounterInput"},"description":"Usage counters to track. Where each draws from is chosen at installation, not here, because that depends on what the parent tracks."}},"required":["name","type","partNumber","serialNumber"],"description":"Request body for creating a component. The uid, companyId, status, parent, ancestorUids, childCount, createdAt and updatedAt fields are controlled by the server."},"UpdateComponentBody":{"type":"object","properties":{"name":{"type":"string","example":"Left Engine"},"type":{"type":"string","description":"Free text, e.g. Engine, Avionics","example":"Engine"},"partNumber":{"type":"string"},"serialNumber":{"type":"string","description":"Required. A part without a serial number is held as a stock item, not a component."},"manufacturer":{"type":"string"},"description":{"type":"string"},"alternatePartNumbers":{"type":"array","items":{"type":"string"}},"state":{"type":"string","enum":["installed","inStores","inRepair","onLoan","inQuarantine","scrapped","sold"],"description":"Defaults to inStores. Use the install endpoint to fit it to a parent."},"location":{"type":"string"},"condition":{"type":"string"},"grn":{"type":"string"},"notes":{"type":"string"},"canHaveChildren":{"type":"boolean","description":"When false, this component will not accept sub-components. Defaults to true."},"parentType":{"type":"string","description":"What this component is intended to fit to: \"aircraft\", \"vehicle\", or a Component.type used in the company (e.g. \"Engine\").","example":"Engine"},"counters":{"type":"array","items":{"$ref":"#/components/schemas/ComponentCounterInput"},"description":"Usage counters to track. Where each draws from is chosen at installation, not here, because that depends on what the parent tracks."}},"description":"Only include fields you want to change. Use the install and remove endpoints to change the parent, so usage mappings are rebuilt correctly."},"InstallComponentBody":{"type":"object","properties":{"parentType":{"type":"string","enum":["aircraft","vehicle","component"]},"parentUid":{"type":"string"},"mappings":{"type":"array","items":{"type":"object","properties":{"counterKey":{"type":"string"},"sourceKey":{"type":"string","nullable":true,"description":"Omit or set null to leave the counter frozen while fitted."}},"required":["counterKey"]},"description":"One entry per counter. Call the sources endpoint first to see what this parent publishes. Counters with no entry are left unbound."}},"required":["parentType","parentUid"]},"RemoveComponentBody":{"type":"object","properties":{"state":{"type":"string","enum":["inStores","inRepair","onLoan","inQuarantine","scrapped","sold"],"description":"Where it is going. Defaults to inStores."},"location":{"type":"string","description":"Meaning follows the state: shelf code, vendor name, borrower, and so on."},"condition":{"type":"string"}}},"ResetCounterBody":{"type":"object","properties":{"counterKey":{"type":"string"},"newValue":{"type":"number","description":"Usually 0, e.g. zeroing time since overhaul after an overhaul."}},"required":["counterKey","newValue"]}},"parameters":{}},"paths":{"/api/v1/aircraft":{"get":{"tags":["Aircraft"],"summary":"List aircraft","description":"Returns all aircraft for the company, including their tracking item schemas. Use the maintenanceTrackingItems and logTrackingItems fields to understand which dynamic fields are available on flight logs for each aircraft.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Aircraft list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AircraftListResponse"}}}}}}},"/api/v1/aircraft/{id}":{"get":{"tags":["Aircraft"],"summary":"Get aircraft by ID","description":"Returns a single aircraft including its tracking item schemas. Query this before creating flight logs to discover required dynamic fields.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Aircraft details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Aircraft"}}}},"404":{"description":"Aircraft not found"}}}},"/api/v1/flight-logs":{"get":{"tags":["Flight Logs"],"summary":"List flight logs","description":"Returns flight logs for the authenticated company. Supports filtering by aircraft, pilot, and date range. Results are paginated: use the `cursor` query parameter with the `nextCursor` value from a previous response to retrieve the next page. When `nextCursor` is null, there are no more results. Use the `fields` parameter to request only specific fields (e.g. `fields=aircraftRegistration,timeDate,airtimeHours`) — this significantly reduces response size for reporting and analytics queries.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Filter by aircraft document ID","example":"abc123"},"required":false,"name":"aircraftId","in":"query"},{"schema":{"type":"string","description":"Filter by aircraft registration (e.g. N12345, or VH-ABC)","example":"N12345"},"required":false,"name":"aircraftRegistration","in":"query"},{"schema":{"type":"string","description":"Filter by pilot user ID"},"required":false,"name":"pilotId","in":"query"},{"schema":{"type":"string","description":"Start of date range (ISO 8601)","example":"2025-01-01T00:00:00.000Z"},"required":false,"name":"startDate","in":"query"},{"schema":{"type":"string","description":"End of date range (ISO 8601)","example":"2025-12-31T23:59:59.999Z"},"required":false,"name":"endDate","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":500,"default":100,"description":"Maximum number of results (1-500)","example":100},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","description":"Pagination cursor — pass the `nextCursor` value from a previous response to fetch the next page. Results are ordered by date descending."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"string","description":"Comma-separated list of fields to include in each record. When specified, only these fields (plus `uid`) are returned — significantly reducing response size for analytics or reporting queries. Core fields: timeDate, pilot, copilot, copilotType, aircraftId, aircraftRegistration, flightNumber, startLocation, endLocation, pax, notes, companyId, createdAt, updatedAt. Flight logs also contain dynamic tracking fields that vary per aircraft (configured via maintenanceTrackingItems and logTrackingItems on the aircraft). Call `GET /api/v1/aircraft` to discover available tracking fields.","example":"aircraftRegistration,timeDate,airtimeHours"},"required":false,"name":"fields","in":"query"}],"responses":{"200":{"description":"Flight logs list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlightLogListResponse"}}}}}},"post":{"tags":["Flight Logs"],"summary":"Create a flight log","description":"Create a new flight log. Include dynamic tracking fields as additional properties in the body. Query GET /api/v1/aircraft/{id} first to discover valid tracking fields for the aircraft.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFlightLogBody"}}}},"responses":{"201":{"description":"Flight log created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WriteResult"}}}},"400":{"description":"Validation error"}}}},"/api/v1/flight-logs/{id}":{"patch":{"tags":["Flight Logs"],"summary":"Update a flight log","description":"Update an existing flight log. Only include fields you want to change.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFlightLogBody"}}}},"responses":{"200":{"description":"Flight log updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WriteResult"}}}},"400":{"description":"Validation error"},"404":{"description":"Flight log not found"}}},"delete":{"tags":["Flight Logs"],"summary":"Delete a flight log","description":"Delete a flight log. Aircraft maintenance totals will be updated accordingly.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Flight log deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WriteResult"}}}},"404":{"description":"Flight log not found"}}}},"/api/v1/flight-logs/batch":{"post":{"tags":["Flight Logs"],"summary":"Batch create flight logs","description":"Create multiple flight logs (max 50). Partial success is possible - check the errors array.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchCreateFlightLogsBody"}}}},"responses":{"200":{"description":"Batch result with successes and errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchResult"}}}}}}},"/api/v1/flight-logs/batch-delete":{"post":{"tags":["Flight Logs"],"summary":"Batch delete flight logs","description":"Delete multiple flight logs (max 50). Partial success is possible.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchDeleteFlightLogsBody"}}}},"responses":{"200":{"description":"Batch result with successes and errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchResult"}}}}}}},"/api/v1/forms/field-schema":{"get":{"tags":["Forms"],"summary":"Get form field schema","description":"Returns the schema for form template sections and fields: allowed field types, their properties, and accepted values (enums). Call this before creating or updating forms so you know which field types exist and what properties each type accepts. Matches the application types (types/forms.ts).","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Form field schema (baseFieldProperties, sectionShape, fieldTypes)","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"nullable":true}}}}}}}},"/api/v1/forms":{"get":{"tags":["Forms"],"summary":"List forms","description":"Returns form templates for the authenticated company. By default only active forms are returned.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"boolean","nullable":true,"description":"If true, include inactive forms. Default: only active."},"required":false,"name":"includeInactive","in":"query"}],"responses":{"200":{"description":"Form templates list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormListResponse"}}}}}},"post":{"tags":["Forms"],"summary":"Create a form","description":"Create a new form template. companyId is set from your API key. Before calling this endpoint, call GET /forms/field-schema to get allowed field types, their properties, and accepted values.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFormBody"}}}},"responses":{"201":{"description":"Form created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormWriteResult"}}}},"400":{"description":"Validation error"}}}},"/api/v1/forms/{id}":{"get":{"tags":["Forms"],"summary":"Get form by ID","description":"Returns a single form template by its document ID.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Form template","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Form"}}}},"404":{"description":"Form not found"}}},"patch":{"tags":["Forms"],"summary":"Update a form","description":"Update an existing form template. Only include fields you want to change. Before calling this endpoint, call GET /forms/field-schema to get allowed field types, their properties, and accepted values.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFormBody"}}}},"responses":{"200":{"description":"Form updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormWriteResult"}}}},"400":{"description":"Validation error"},"404":{"description":"Form not found"}}}},"/api/v1/form-completions":{"get":{"tags":["Form Completions"],"summary":"List form completions","description":"Returns completed form submissions for the company. Optionally filter by form template code. Results are paginated: use the `cursor` query parameter with the `nextCursor` value from a previous response to retrieve the next page. When `nextCursor` is null, there are no more results. Use the `fields` parameter to request only specific fields (e.g. `fields=code,name,userId,createdAt`) — this significantly reduces response size for reporting and analytics queries.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Filter by form template code (e.g. only completions of form with this code)"},"required":false,"name":"code","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":500,"default":100,"description":"Maximum number of results per page (1-500)","example":100},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","description":"Pagination cursor — pass the `nextCursor` value from a previous response to fetch the next page."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"string","description":"Comma-separated list of fields to include in each record. When specified, only these fields (plus `uid`) are returned. Example: `fields=code,name,userId,createdAt`","example":"code,name,userId,createdAt"},"required":false,"name":"fields","in":"query"}],"responses":{"200":{"description":"Form completions list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormCompletionListResponse"}}}}}},"post":{"tags":["Form Completions"],"summary":"Create a form completion","description":"Submit a completed form. Provide `formId` and `answers` (keyed by field name or storage key — see GET /forms/{id}/completion-schema). companyId is set from your API key. Triggers the same side effects as a normal submission (defect schedule items, odometer updates, notifications, webhooks). File/document-upload fields cannot be set from text — pass pre-uploaded file objects or leave empty.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFormCompletionBody"}}}},"responses":{"201":{"description":"Form completion created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormCompletionWriteResult"}}}},"400":{"description":"Validation error"},"404":{"description":"Form not found"}}}},"/api/v1/form-completions/{id}":{"get":{"tags":["Form Completions"],"summary":"Get form completion by ID","description":"Returns a single form completion by its document ID.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Form completion","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompletedForm"}}}},"404":{"description":"Form completion not found"}}}},"/api/v1/forms/{id}/completion-schema":{"get":{"tags":["Form Completions"],"summary":"Get form completion (answer) schema","description":"Returns the answer contract for a specific form: for every answerable field, the storage `key` and the value format it expects (string/number/boolean/array/object/file), plus enum options and min/max. Call this before POST /form-completions to build a valid `answers` payload.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Form completion answer schema","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormCompletionSchemaResponse"}}}},"404":{"description":"Form not found"}}}},"/api/v1/aggregate":{"post":{"tags":["Aggregate"],"summary":"Aggregate data across collections","description":"Performs server-side aggregation (sum, count, avg, min, max) on any numeric field across flight logs, form completions, aircraft, schedule items, or vehicles. Supports grouping by any field and by time period (day, week, month, quarter, year). Dynamic tracking fields (e.g. airtimeHours, engineHours) are fully supported. Use this instead of fetching raw records for reporting and analytics — it returns compact aggregated results in a single call, regardless of how many records match.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AggregateBody"}}}},"responses":{"200":{"description":"Aggregated results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AggregateResponse"}}}},"400":{"description":"Invalid parameters"}}}},"/api/v1/users":{"get":{"tags":["Users"],"summary":"List company users","description":"Returns all users belonging to the authenticated company, including their roles, status, and contact info. Use this to resolve user names to UIDs for filtering in other endpoints (e.g. flight logs by pilot, form completions by userId).","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Users list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserListResponse"}}}}}}},"/api/v1/users/{uid}":{"get":{"tags":["Users"],"summary":"Get user by UID","description":"Returns a single user by their UID, if they belong to the authenticated company.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"uid","in":"path"}],"responses":{"200":{"description":"User details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}}},"404":{"description":"User not found or not in this company"}}}},"/api/v1/schedule-items":{"get":{"tags":["Schedule Items"],"summary":"List schedule items","description":"Returns schedule items (maintenance, inspections, servicing, etc.) for the company. Filter by asset, type, or status. Results are paginated.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Filter by asset UID (the ID of the aircraft, vehicle, user, etc.)"},"required":false,"name":"relatedTo","in":"query"},{"schema":{"type":"string","enum":["aircraft","vehicle","component","company","user","equipment"],"description":"Filter by asset type"},"required":false,"name":"relatedToType","in":"query"},{"schema":{"type":"string","description":"Filter by schedule type (e.g. 'Inspection', 'Service')"},"required":false,"name":"type","in":"query"},{"schema":{"type":"string","enum":["active","inactive"],"description":"Filter by status. Omit to return all. Use 'active' to exclude soft-deleted items."},"required":false,"name":"status","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":500,"default":100,"description":"Maximum number of results (1-500)","example":100},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","description":"Pagination cursor from a previous response's nextCursor"},"required":false,"name":"cursor","in":"query"}],"responses":{"200":{"description":"Schedule items list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleItemListResponse"}}}}}},"post":{"tags":["Schedule Items"],"summary":"Create a schedule item","description":"Create a new schedule item. A schedule item must have at least one threshold: usage-based (trackingItem + dueAtInterval) or calendar-based (calendarDateDue).","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateScheduleItemBody"}}}},"responses":{"201":{"description":"Schedule item created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleWriteResult"}}}},"400":{"description":"Validation error"}}}},"/api/v1/schedule-items/{id}":{"get":{"tags":["Schedule Items"],"summary":"Get schedule item by ID","description":"Returns a single schedule item with all its configuration details.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Schedule item details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleItem"}}}},"404":{"description":"Schedule item not found"}}},"patch":{"tags":["Schedule Items"],"summary":"Update a schedule item","description":"Update an existing schedule item. Only include fields you want to change.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateScheduleItemBody"}}}},"responses":{"200":{"description":"Schedule item updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleWriteResult"}}}},"400":{"description":"Validation error"},"404":{"description":"Schedule item not found"}}},"delete":{"tags":["Schedule Items"],"summary":"Delete a schedule item (soft delete)","description":"Soft-deletes a schedule item by setting its status to 'inactive'. The item can be restored later using the restore endpoint.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Schedule item soft-deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleWriteResult"}}}},"404":{"description":"Schedule item not found"}}}},"/api/v1/schedule-items/{id}/restore":{"post":{"tags":["Schedule Items"],"summary":"Restore a soft-deleted schedule item","description":"Restores a previously soft-deleted schedule item by setting its status back to 'active'.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Schedule item restored","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleWriteResult"}}}},"404":{"description":"Schedule item not found"}}}},"/api/v1/completed-schedule-items":{"get":{"tags":["Completed Schedule Items"],"summary":"List completed schedule items","description":"Returns completed schedule item records (maintenance history). Filter by parent schedule item ID to see the completion history for a specific item.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Filter by parent schedule item ID. Required if you want completions for a specific schedule item."},"required":false,"name":"scheduleItemId","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":500,"default":100,"description":"Maximum number of results (1-500)"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","description":"Pagination cursor from a previous response's nextCursor"},"required":false,"name":"cursor","in":"query"}],"responses":{"200":{"description":"Completed schedule items list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompletedScheduleItemListResponse"}}}}}}},"/api/v1/completed-schedule-items/{id}":{"get":{"tags":["Completed Schedule Items"],"summary":"Get completed schedule item by ID","description":"Returns a single completion record with its details and documents.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Completed schedule item details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompletedScheduleItem"}}}},"404":{"description":"Completed schedule item not found"}}},"delete":{"tags":["Completed Schedule Items"],"summary":"Delete a completed schedule item","description":"Permanently deletes a completion record.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Completed schedule item deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleWriteResult"}}}},"404":{"description":"Completed schedule item not found"}}}},"/api/v1/maintenance-status":{"get":{"tags":["Schedule Items"],"summary":"Get maintenance status with remaining intervals","description":"Calculates remaining maintenance intervals for active schedule items. For usage-based items (e.g. airtimeHours, kilometers), this fetches the asset's current running totals and computes how many units remain until the item is due. For calendar-based items, it computes days remaining. Negative values indicate the item is overdue.\n\nFilter by asset to get status for a specific aircraft, vehicle, etc.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Filter by asset UID"},"required":false,"name":"relatedTo","in":"query"},{"schema":{"type":"string","enum":["aircraft","vehicle","component","company","user","equipment"],"description":"Filter by asset type (aircraft, vehicle, etc.)"},"required":false,"name":"relatedToType","in":"query"}],"responses":{"200":{"description":"Maintenance status with remaining intervals","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MaintenanceStatusResponse"}}}}}}},"/api/v1/vehicles":{"get":{"tags":["Vehicles"],"summary":"List vehicles","description":"Returns all vehicles for the company, including their tracking item schemas and other vehicle data. Optionally filter by exact registration or VIN, or use search for a partial registration/VIN match.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Exact vehicle registration to match, case-insensitive","example":"783EP9"},"required":false,"name":"registration","in":"query"},{"schema":{"type":"string","description":"Exact VIN to match, case-insensitive"},"required":false,"name":"vin","in":"query"},{"schema":{"type":"string","description":"Case-insensitive partial search across vehicle registration and VIN","example":"783"},"required":false,"name":"search","in":"query"}],"responses":{"200":{"description":"Vehicle list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VehicleListResponse"}}}}}},"post":{"tags":["Vehicles"],"summary":"Create a vehicle","description":"Create a vehicle for the authenticated company. The server controls uid, companyId, status, and timestamps. If tracking metadata is omitted, the vehicle defaults to miles tracking.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVehicleBody"}}}},"responses":{"201":{"description":"Vehicle created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VehicleWriteResult"}}}},"400":{"description":"Validation error"}}}},"/api/v1/vehicles/{id}":{"get":{"tags":["Vehicles"],"summary":"Get vehicle by ID","description":"Returns a single vehicle by document ID, including its tracking item schemas and other vehicle data.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Vehicle details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Vehicle"}}}},"404":{"description":"Vehicle not found"}}},"patch":{"tags":["Vehicles"],"summary":"Update a vehicle","description":"Update an existing vehicle. Only include fields you want to change.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateVehicleBody"}}}},"responses":{"200":{"description":"Vehicle updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VehicleWriteResult"}}}},"400":{"description":"Validation error"},"404":{"description":"Vehicle not found"}}},"delete":{"tags":["Vehicles"],"summary":"Delete a vehicle (soft delete)","description":"Soft-deletes a vehicle by setting its status to 'inactive' and removing it from the company vehicles list. Active schedule items for the vehicle are also soft-deleted.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Vehicle soft-deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VehicleWriteResult"}}}},"404":{"description":"Vehicle not found"}}}},"/api/v1/vehicles/batch":{"post":{"tags":["Vehicles"],"summary":"Batch create vehicles","description":"Create multiple vehicles in one request (max 50). Each vehicle is validated independently; partial success is possible. Check the errors array for failed rows.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchCreateVehiclesBody"}}}},"responses":{"200":{"description":"Batch result with successes and errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchCreateVehiclesResult"}}}}}}},"/api/v1/vehicles/{id}/restore":{"post":{"tags":["Vehicles"],"summary":"Restore a soft-deleted vehicle","description":"Restores a previously soft-deleted vehicle by setting its status back to 'active'.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Vehicle restored","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VehicleWriteResult"}}}},"400":{"description":"Validation error"},"404":{"description":"Vehicle not found"}}}},"/api/v1/components":{"get":{"tags":["Components"],"summary":"List components","description":"Returns all components for the company: their usage counters, current totals, where each is fitted, and its state. Filter by part or serial number, state, direct parent, or by rootAssetUid to get an entire subtree at any depth.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Exact part number, case-insensitive"},"required":false,"name":"partNumber","in":"query"},{"schema":{"type":"string","description":"Exact serial number, case-insensitive"},"required":false,"name":"serialNumber","in":"query"},{"schema":{"type":"string","enum":["installed","inStores","inRepair","onLoan","inQuarantine","scrapped","sold"],"description":"Where the component is. State and location are independent: the state decides what the location field means (shelf code when inStores, vendor when inRepair, and so on)."},"required":false,"name":"state","in":"query"},{"schema":{"type":"string","description":"Direct children of this aircraft, vehicle or component only."},"required":false,"name":"parentUid","in":"query"},{"schema":{"type":"string","description":"Everything fitted anywhere below this asset or component, at any depth."},"required":false,"name":"rootAssetUid","in":"query"},{"schema":{"type":"string","description":"Partial match across name, part number, serial number and type"},"required":false,"name":"search","in":"query"}],"responses":{"200":{"description":"Component list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComponentListResponse"}}}}}},"post":{"tags":["Components"],"summary":"Create a component","description":"Create a component for the authenticated company. The server controls uid, companyId, status, parentage and timestamps. Components start unfitted; use the install endpoint to fit one.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateComponentBody"}}}},"responses":{"201":{"description":"Component created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComponentWriteResult"}}}},"400":{"description":"Validation error"}}}},"/api/v1/components/sources/{parentType}/{parentUid}":{"get":{"tags":["Components"],"summary":"List usage values a parent publishes","description":"Returns the tracking values an aircraft, vehicle or component exposes for inheritance, with the unit and current figure for each. Call this before installing a component so counters can be mapped to the parent fields the operator chooses.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["aircraft","vehicle","component"]},"required":true,"name":"parentType","in":"path"},{"schema":{"type":"string"},"required":true,"name":"parentUid","in":"path"}],"responses":{"200":{"description":"Available inheritance sources","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InheritableSourcesResponse"}}}},"404":{"description":"Parent not found"}}}},"/api/v1/components/{id}":{"get":{"tags":["Components"],"summary":"Get component by ID","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Component details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Component"}}}},"404":{"description":"Component not found"}}},"patch":{"tags":["Components"],"summary":"Update a component","description":"Update an existing component. Only include fields you want to change. The parent cannot be changed here; use install or remove so usage mappings are rebuilt.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateComponentBody"}}}},"responses":{"200":{"description":"Component updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComponentWriteResult"}}}},"400":{"description":"Validation error"},"404":{"description":"Component not found"}}},"delete":{"tags":["Components"],"summary":"Delete a component (soft delete)","description":"Soft-deletes a component by setting its status to 'inactive'. Active schedule items for the component are also soft-deleted. Rejected while other components are fitted to it.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Component soft-deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComponentWriteResult"}}}},"400":{"description":"Validation error"},"404":{"description":"Component not found"}}}},"/api/v1/components/{id}/install":{"post":{"tags":["Components"],"summary":"Fit a component to a parent","description":"Fit a component to an aircraft, vehicle or another component, mapping each counter to a value the parent publishes. Every binding is rebuilt from scratch, so this also handles moving a component between parents. Rejected if it would create a loop or exceed the depth limit.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstallComponentBody"}}}},"responses":{"200":{"description":"Component fitted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComponentWriteResult"}}}},"400":{"description":"Validation error"},"404":{"description":"Component or parent not found"}}}},"/api/v1/components/{id}/remove":{"post":{"tags":["Components"],"summary":"Remove a component from its parent","description":"Detach a component. Its counters stop accruing and freeze at their current values, so fitting it elsewhere later resumes from where it stopped.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemoveComponentBody"}}}},"responses":{"200":{"description":"Component removed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComponentWriteResult"}}}},"404":{"description":"Component not found"}}}},"/api/v1/components/{id}/reset-counter":{"post":{"tags":["Components"],"summary":"Reset a usage counter","description":"Set a counter to a new value, typically zeroing time since overhaul. The counter re-anchors against the parent's current figure, so accrual resumes from the new baseline.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetCounterBody"}}}},"responses":{"200":{"description":"Counter reset","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComponentWriteResult"}}}},"404":{"description":"Component or counter not found"}}}},"/api/v1/components/{id}/restore":{"post":{"tags":["Components"],"summary":"Restore a soft-deleted component","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Component restored","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComponentWriteResult"}}}},"400":{"description":"Validation error"},"404":{"description":"Component not found"}}}}}}