Reference

Generated from openapi.json — the same document the API serves, so this page cannot drift from the routes it describes.

Generated at publish · source: GET /api/v1/openapi.json
Document
OpenAPI 3.1
Bearer-key-authenticated access to a company's FixGrid records, including managing webhook subscriptions. Mint a key on the Integrations page. Keys are company credentials for server-side use only -- never ship one in a browser, a mobile app, or a Claude/MCP connector; user-level OAuth is a later, separate door and is not this key.
Access
No key needed
This document. Returns this OpenAPI document. Public -- no key required.
Operations
26
26 operations across 23 paths: Meta 2 · Tickets 4 · Properties 2 · Units 2 · Occupancy 2 · Assets 2 · Vendors 2 · Inspections 2 · Turns 2 · Meters 3 · Webhooks 3.

meta

GET/api/v1/whoamiany active key
Summary
Identify the presented key. Returns the company and key metadata for the presented bearer key. Accepts any active key regardless of scope.
Responses
200WhoamiThe key and company.
401ErrorMissing or invalid API key.
403ErrorThe key's scope does not allow this, or the company is inactive.
429ErrorRate limit exceeded for this key. Allowance: 120 per minute.
Example
curl
curl "https://app.fixgrid.app/api/v1/whoami" \
  -H "Authorization: Bearer $FIXGRID_KEY"
Fields · Whoami
NameTypeNotes
api_versionstring
companyobject
keyobject
GET/api/v1/openapi.jsonpublic
Summary
This document. Returns this OpenAPI document. Public -- no key required.
Responses
200objectThe OpenAPI document.
Example
curl
curl "https://app.fixgrid.app/api/v1/openapi.json"

tickets

GET/api/v1/ticketsscope: read
Summary
List tickets. A keyset-paginated page of the company's tickets, ordered by id ascending.
Parameters
NameTypeNotes
limitquery · integerMax rows to return (default 50, maximum 200). Default 50. Maximum 200.
cursorquery · stringOpaque pagination cursor from a previous page's next_cursor.
property_idquery · integerOnly rows for this property id.
unit_idquery · integerOnly rows tied to this unit (location) id.
statusquery · stringFilter to rows with this status -- see this parameter's enum for the live vocabulary.
updated_sincequery · string/date-timeOnly rows updated at or after this ISO 8601 UTC timestamp, e.g. 2026-01-01T00:00:00Z.
ticket_numberquery · integerOnly the ticket with this ticket_number (requires property_id).
Responses
200Page of TicketA page of results.
400ErrorBad request -- an invalid limit or cursor was supplied.
401ErrorMissing or invalid API key.
403ErrorThe key's scope does not allow this, or the company is inactive.
429ErrorRate limit exceeded for this key. Allowance: 120 per minute.
422ErrorA filter value is outside its enum.
Example
curl
curl "https://app.fixgrid.app/api/v1/tickets?limit=50" \
  -H "Authorization: Bearer $FIXGRID_KEY"
Fields · Ticket
NameTypeNotes
schema_versionintegerThe DTO shape version. Always 1 today.
entity_typestringAlways 'ticket' for this resource.
entity_idintegerThe FixGrid ticket id.
ticket_numberinteger | nullThe ticket number shown to staff and residents.
titlestringShort summary of the ticket.
descriptionstring | nullThe full reported description.
categorystringThe ticket category.
subcategorystring | nullThe ticket subcategory, if set.
prioritystringOne of 'Low', 'Medium', 'High', 'Emergency'.
statusstringOne of 'Open', 'In Progress', 'On Hold', 'Completed', 'Cancelled'.
propertyobjectThe property this ticket belongs to.
unitobject | nullThe unit this ticket is tied to, or null.
unit_numberstring | nullThe free-text unit number captured on the ticket.
roomstring | nullThe room within the unit, if captured.
room_instancestring | nullDisambiguates multiple rooms of the same type.
permission_to_enterbooleanWhether the resident granted permission to enter unattended.
preferred_access_timestring | nullFree-text preferred access window.
assigneeobject | nullThe staff user assigned, or null if unassigned.
assigned_vendorobject | nullThe assigned vendor relationship, or null.
photo_urlstring | nullURL of the ticket photo, if one was attached.
created_atstring/date-timeISO 8601 UTC creation timestamp.
updated_atstring/date-timeISO 8601 UTC last-updated timestamp.
completed_atstring | null/date-timeISO 8601 UTC completion timestamp, or null.
cancelled_atstring | null/date-timeISO 8601 UTC cancellation timestamp, or null.
cancellation_reason_codestring | nullThe locked cancellation reason code, or null.
external_idstring | nullRule 230 companion: the external system id, if synced.
sourcestringRule 230 companion: how this record was created, e.g. 'resident_portal'.
urlstring/uriAbsolute FixGrid link to this record.
POST/api/v1/ticketsscope: write
Summary
Create a ticket. Creates a ticket on the given unit, with status always 'Open'. Requires the Idempotency-Key header; a write-scoped key is required.
Parameters
NameTypeNotes
Idempotency-Keyheader · string · requiredA client-chosen key, 64 characters or fewer. A retried request with the same key and the same body replays the original response. Up to 64 characters.
Request body
NameTypeNotes
unit_idinteger · requiredThe unit's id, from GET /units.
asset_idintegerOptional. Must belong to the same property as unit_id.
titlestring · required
descriptionstringOptional. Defaults to an empty string.
prioritystring One of: Low · Medium · High · Emergency.
categorystring · required One of: HVAC · Plumbing · Electrical · Mechanical · Life Safety · Elevator · Appliance · Doors/Windows · Flooring · Painting · Roofing · Leak · Pest Control · Structural · Grounds · Parking Garage · Pool · Security · Common Area · General · Other.
Responses
201TicketThe ticket was created, or this response replays an earlier creation for a duplicate Idempotency-Key. Header X-Idempotent-Replay: Present with value '1' when this response is a replay of the original creation for a duplicate Idempotency-Key.
400Error`idempotency_key_required` -- An Idempotency-Key header is required to create a ticket. `invalid_request` -- The Idempotency-Key header must be 64 characters or fewer. `invalid_request` -- The request body is not a valid ticket payload.
404Error`not_found` -- No unit with that id is visible to this key. `not_found` -- No asset with that id is visible to this key. `not_found` -- No asset with that id is visible to this key on that property.
409Error`idempotency_in_progress` -- A request with this Idempotency-Key is already being processed. `idempotency_mismatch` -- This Idempotency-Key was already used with a different ticket payload. Use a new Idempotency-Key for a different request.
422Error`invalid_request` -- This endpoint always creates a ticket with status 'Open'. Remove `status` from the request body. `created_by_missing` -- This key has no minting administrator on file. Mint a new key on the Integrations page to create tickets. `invalid_request` -- Unknown ticket priority -- see this field's enum for the live vocabulary. `invalid_request` -- The `category` field must be one of the values in this field's enum. `invalid_request` -- The `title` field must be 150 characters or fewer.
401ErrorMissing or invalid API key.
403ErrorThe key's scope does not allow this, or the company is inactive.
429ErrorRate limit exceeded for this key. Allowance: 120 per minute.
Example
curl
curl -X POST "https://app.fixgrid.app/api/v1/tickets" \
  -H "Authorization: Bearer $FIXGRID_KEY" \
  -H "Idempotency-Key: $IDEMPOTENCY_KEY" \
  -H "Content-Type: application/json" \
  -d '{"unit_id":0,"asset_id":0,"title":"string","description":"string","priority":"string","category":"string"}'
Fields · Ticket
NameTypeNotes
schema_versionintegerThe DTO shape version. Always 1 today.
entity_typestringAlways 'ticket' for this resource.
entity_idintegerThe FixGrid ticket id.
ticket_numberinteger | nullThe ticket number shown to staff and residents.
titlestringShort summary of the ticket.
descriptionstring | nullThe full reported description.
categorystringThe ticket category.
subcategorystring | nullThe ticket subcategory, if set.
prioritystringOne of 'Low', 'Medium', 'High', 'Emergency'.
statusstringOne of 'Open', 'In Progress', 'On Hold', 'Completed', 'Cancelled'.
propertyobjectThe property this ticket belongs to.
unitobject | nullThe unit this ticket is tied to, or null.
unit_numberstring | nullThe free-text unit number captured on the ticket.
roomstring | nullThe room within the unit, if captured.
room_instancestring | nullDisambiguates multiple rooms of the same type.
permission_to_enterbooleanWhether the resident granted permission to enter unattended.
preferred_access_timestring | nullFree-text preferred access window.
assigneeobject | nullThe staff user assigned, or null if unassigned.
assigned_vendorobject | nullThe assigned vendor relationship, or null.
photo_urlstring | nullURL of the ticket photo, if one was attached.
created_atstring/date-timeISO 8601 UTC creation timestamp.
updated_atstring/date-timeISO 8601 UTC last-updated timestamp.
completed_atstring | null/date-timeISO 8601 UTC completion timestamp, or null.
cancelled_atstring | null/date-timeISO 8601 UTC cancellation timestamp, or null.
cancellation_reason_codestring | nullThe locked cancellation reason code, or null.
external_idstring | nullRule 230 companion: the external system id, if synced.
sourcestringRule 230 companion: how this record was created, e.g. 'resident_portal'.
urlstring/uriAbsolute FixGrid link to this record.
GET/api/v1/tickets/{ticket_id}scope: read
Summary
Fetch a ticket. A single ticket by id.
Parameters
NameTypeNotes
ticket_idpath · integer · required
Responses
200TicketThe record.
401ErrorMissing or invalid API key.
403ErrorThe key's scope does not allow this, or the company is inactive.
404ErrorNo record with that id is visible to this key.
429ErrorRate limit exceeded for this key. Allowance: 120 per minute.
Example
curl
curl "https://app.fixgrid.app/api/v1/tickets/{ticket_id}" \
  -H "Authorization: Bearer $FIXGRID_KEY"
Fields · Ticket
NameTypeNotes
schema_versionintegerThe DTO shape version. Always 1 today.
entity_typestringAlways 'ticket' for this resource.
entity_idintegerThe FixGrid ticket id.
ticket_numberinteger | nullThe ticket number shown to staff and residents.
titlestringShort summary of the ticket.
descriptionstring | nullThe full reported description.
categorystringThe ticket category.
subcategorystring | nullThe ticket subcategory, if set.
prioritystringOne of 'Low', 'Medium', 'High', 'Emergency'.
statusstringOne of 'Open', 'In Progress', 'On Hold', 'Completed', 'Cancelled'.
propertyobjectThe property this ticket belongs to.
unitobject | nullThe unit this ticket is tied to, or null.
unit_numberstring | nullThe free-text unit number captured on the ticket.
roomstring | nullThe room within the unit, if captured.
room_instancestring | nullDisambiguates multiple rooms of the same type.
permission_to_enterbooleanWhether the resident granted permission to enter unattended.
preferred_access_timestring | nullFree-text preferred access window.
assigneeobject | nullThe staff user assigned, or null if unassigned.
assigned_vendorobject | nullThe assigned vendor relationship, or null.
photo_urlstring | nullURL of the ticket photo, if one was attached.
created_atstring/date-timeISO 8601 UTC creation timestamp.
updated_atstring/date-timeISO 8601 UTC last-updated timestamp.
completed_atstring | null/date-timeISO 8601 UTC completion timestamp, or null.
cancelled_atstring | null/date-timeISO 8601 UTC cancellation timestamp, or null.
cancellation_reason_codestring | nullThe locked cancellation reason code, or null.
external_idstring | nullRule 230 companion: the external system id, if synced.
sourcestringRule 230 companion: how this record was created, e.g. 'resident_portal'.
urlstring/uriAbsolute FixGrid link to this record.
PATCH/api/v1/tickets/{ticket_id}scope: write
Summary
Change a ticket's status. Changes a ticket's status. There is no transition graph -- any status is reachable from any other, including reopening a Completed or Cancelled ticket. `note` is required (5+ words) only when status is 'Completed'; `cancellation_reason_code` is required only when status is 'Cancelled', and `cancellation_notes` is accepted only when `cancellation_reason_code` is 'see_notes'. Requires the Idempotency-Key header; a write-scoped key is required.
Parameters
NameTypeNotes
Idempotency-Keyheader · string · requiredA client-chosen key, 64 characters or fewer. A retried request with the same key and the same body replays the original response. Up to 64 characters.
Request body
NameTypeNotes
statusstring · required One of: Open · In Progress · On Hold · Completed · Cancelled.
notestringRequired, 5+ words, only when status is 'Completed'. Not accepted for any other status.
cancellation_reason_codestringRequired only when status is `Cancelled`. Not accepted for any other status. One of: duplicate_ticket · no_access_repeated · resident_cancelled · resolved_independently · scheduled_for_later · see_notes · wrong_property.
cancellation_notesstringAccepted only when status is `Cancelled` and `cancellation_reason_code` is `see_notes`, 5+ words. Not accepted otherwise.
Responses
200TicketThe ticket status was changed, or this response replays an earlier change for a duplicate Idempotency-Key. Header X-Idempotent-Replay: Present with value '1' when this response is a replay of the original change for a duplicate Idempotency-Key.
400Error`idempotency_key_required` -- An Idempotency-Key header is required to change a ticket's status. `invalid_request` -- The Idempotency-Key header must be 64 characters or fewer. `invalid_request` -- The request body is not a valid ticket status payload. `invalid_request` -- The `cancellation_notes` field is accepted only when `cancellation_reason_code` is `see_notes`.
404Error`not_found` -- No ticket with that id is visible to this key.
409Error`idempotency_in_progress` -- A request with this Idempotency-Key is already being processed. `idempotency_mismatch` -- This Idempotency-Key was already used with a different ticket request. Use a new Idempotency-Key for a different request.
422Error`invalid_request` -- The `status` field must be one of the values in this field's enum. `invalid_request` -- a field in the request body is not accepted for the given `status` -- recognized fields are legal only for the statuses that need them. `created_by_missing` -- This key has no minting administrator on file. Mint a new key on the Integrations page to change a ticket status. `invalid_request` -- this company requires a photo on the ticket before it can be completed, and the ticket has none. `invalid_request` -- the status change was refused by FixGrid's own rules for the target status (a missing or too-short closing note on Completed, a missing cancellation reason on Cancelled, or too-short cancellation notes) -- see `message` for the exact sentence.
401ErrorMissing or invalid API key.
403ErrorThe key's scope does not allow this, or the company is inactive.
429ErrorRate limit exceeded for this key. Allowance: 120 per minute.
Example
curl
curl -X PATCH "https://app.fixgrid.app/api/v1/tickets/{ticket_id}" \
  -H "Authorization: Bearer $FIXGRID_KEY" \
  -H "Idempotency-Key: $IDEMPOTENCY_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status":"string","note":"string","cancellation_reason_code":"string","cancellation_notes":"string"}'
Fields · Ticket
NameTypeNotes
schema_versionintegerThe DTO shape version. Always 1 today.
entity_typestringAlways 'ticket' for this resource.
entity_idintegerThe FixGrid ticket id.
ticket_numberinteger | nullThe ticket number shown to staff and residents.
titlestringShort summary of the ticket.
descriptionstring | nullThe full reported description.
categorystringThe ticket category.
subcategorystring | nullThe ticket subcategory, if set.
prioritystringOne of 'Low', 'Medium', 'High', 'Emergency'.
statusstringOne of 'Open', 'In Progress', 'On Hold', 'Completed', 'Cancelled'.
propertyobjectThe property this ticket belongs to.
unitobject | nullThe unit this ticket is tied to, or null.
unit_numberstring | nullThe free-text unit number captured on the ticket.
roomstring | nullThe room within the unit, if captured.
room_instancestring | nullDisambiguates multiple rooms of the same type.
permission_to_enterbooleanWhether the resident granted permission to enter unattended.
preferred_access_timestring | nullFree-text preferred access window.
assigneeobject | nullThe staff user assigned, or null if unassigned.
assigned_vendorobject | nullThe assigned vendor relationship, or null.
photo_urlstring | nullURL of the ticket photo, if one was attached.
created_atstring/date-timeISO 8601 UTC creation timestamp.
updated_atstring/date-timeISO 8601 UTC last-updated timestamp.
completed_atstring | null/date-timeISO 8601 UTC completion timestamp, or null.
cancelled_atstring | null/date-timeISO 8601 UTC cancellation timestamp, or null.
cancellation_reason_codestring | nullThe locked cancellation reason code, or null.
external_idstring | nullRule 230 companion: the external system id, if synced.
sourcestringRule 230 companion: how this record was created, e.g. 'resident_portal'.
urlstring/uriAbsolute FixGrid link to this record.

properties

GET/api/v1/propertiesscope: read
Summary
List properties. A keyset-paginated page of the company's properties.
Parameters
NameTypeNotes
limitquery · integerMax rows to return (default 50, maximum 200). Default 50. Maximum 200.
cursorquery · stringOpaque pagination cursor from a previous page's next_cursor.
Responses
200Page of PropertyA page of results.
400ErrorBad request -- an invalid limit or cursor was supplied.
401ErrorMissing or invalid API key.
403ErrorThe key's scope does not allow this, or the company is inactive.
429ErrorRate limit exceeded for this key. Allowance: 120 per minute.
422ErrorA filter value is outside its enum.
Example
curl
curl "https://app.fixgrid.app/api/v1/properties?limit=50" \
  -H "Authorization: Bearer $FIXGRID_KEY"
Fields · Property
NameTypeNotes
schema_versionintegerThe DTO shape version. Always 1 today.
entity_typestringAlways 'property' for this resource.
entity_idintegerThe FixGrid property id.
namestringThe property name.
addressstringThe street address.
citystring | null
statestring | null
postal_codestring | nullZIP/postal code (Rule 230 B wire name).
building_typestring | null
construction_typestring | null
unit_countinteger | null
year_builtinteger | null
latitudenumber | null
longitudenumber | null
created_atstring/date-time
external_idstring | nullRule 230 companion: the external system id, if synced.
sourcestringRule 230 companion: how this record was created.
urlstring/uriAbsolute FixGrid link to this record.
GET/api/v1/properties/{property_id}scope: read
Summary
Fetch a property. A single property by id.
Parameters
NameTypeNotes
property_idpath · integer · required
Responses
200PropertyThe record.
401ErrorMissing or invalid API key.
403ErrorThe key's scope does not allow this, or the company is inactive.
404ErrorNo record with that id is visible to this key.
429ErrorRate limit exceeded for this key. Allowance: 120 per minute.
Example
curl
curl "https://app.fixgrid.app/api/v1/properties/{property_id}" \
  -H "Authorization: Bearer $FIXGRID_KEY"
Fields · Property
NameTypeNotes
schema_versionintegerThe DTO shape version. Always 1 today.
entity_typestringAlways 'property' for this resource.
entity_idintegerThe FixGrid property id.
namestringThe property name.
addressstringThe street address.
citystring | null
statestring | null
postal_codestring | nullZIP/postal code (Rule 230 B wire name).
building_typestring | null
construction_typestring | null
unit_countinteger | null
year_builtinteger | null
latitudenumber | null
longitudenumber | null
created_atstring/date-time
external_idstring | nullRule 230 companion: the external system id, if synced.
sourcestringRule 230 companion: how this record was created.
urlstring/uriAbsolute FixGrid link to this record.

units

GET/api/v1/unitsscope: read
Summary
List units. A keyset-paginated page of the company's units (locations with location_type='unit').
Parameters
NameTypeNotes
limitquery · integerMax rows to return (default 50, maximum 200). Default 50. Maximum 200.
cursorquery · stringOpaque pagination cursor from a previous page's next_cursor.
property_idquery · integerOnly rows for this property id.
Responses
200Page of UnitA page of results.
400ErrorBad request -- an invalid limit or cursor was supplied.
401ErrorMissing or invalid API key.
403ErrorThe key's scope does not allow this, or the company is inactive.
429ErrorRate limit exceeded for this key. Allowance: 120 per minute.
422ErrorA filter value is outside its enum.
Example
curl
curl "https://app.fixgrid.app/api/v1/units?limit=50" \
  -H "Authorization: Bearer $FIXGRID_KEY"
Fields · Unit
NameTypeNotes
schema_versionintegerThe DTO shape version. Always 1 today.
entity_typestringAlways 'unit' for this resource.
entity_idintegerThe FixGrid unit (location) id.
namestringe.g. 'Unit 204B'.
unit_numberstring | null
unit_statusstring | null
propertyobjectThe property this unit belongs to.
floorplanobject | nullThe unit's floorplan, or null if unassigned.
buildingobject | nullThe building this unit sits in, or null.
floorobject | nullThe declared floor, or null.
created_atstring/date-time
external_idstring | nullRule 230 companion: the external system id, if synced.
sourcestringRule 230 companion: how this record was created.
projected_ready_onstring | null/dateThe projected date this unit's active turn will be ready, derived from the Turn Board; null when the unit has no active turn. FixGrid-native, not the MITS MadeReadyDate (an actual completed date, a different fact).
urlstring/uriAbsolute FixGrid link to this record.
GET/api/v1/units/{unit_id}scope: read
Summary
Fetch a unit. A single unit by id.
Parameters
NameTypeNotes
unit_idpath · integer · required
Responses
200UnitThe record.
401ErrorMissing or invalid API key.
403ErrorThe key's scope does not allow this, or the company is inactive.
404ErrorNo record with that id is visible to this key.
429ErrorRate limit exceeded for this key. Allowance: 120 per minute.
Example
curl
curl "https://app.fixgrid.app/api/v1/units/{unit_id}" \
  -H "Authorization: Bearer $FIXGRID_KEY"
Fields · Unit
NameTypeNotes
schema_versionintegerThe DTO shape version. Always 1 today.
entity_typestringAlways 'unit' for this resource.
entity_idintegerThe FixGrid unit (location) id.
namestringe.g. 'Unit 204B'.
unit_numberstring | null
unit_statusstring | null
propertyobjectThe property this unit belongs to.
floorplanobject | nullThe unit's floorplan, or null if unassigned.
buildingobject | nullThe building this unit sits in, or null.
floorobject | nullThe declared floor, or null.
created_atstring/date-time
external_idstring | nullRule 230 companion: the external system id, if synced.
sourcestringRule 230 companion: how this record was created.
projected_ready_onstring | null/dateThe projected date this unit's active turn will be ready, derived from the Turn Board; null when the unit has no active turn. FixGrid-native, not the MITS MadeReadyDate (an actual completed date, a different fact).
urlstring/uriAbsolute FixGrid link to this record.

occupancy

POST/api/v1/units/{unit_id}/noticescope: write
Summary
Record a notice to vacate. Records a departure on the unit's current resident. Requires the Idempotency-Key header; a write-scoped key is required.
Parameters
NameTypeNotes
Idempotency-Keyheader · string · requiredA client-chosen key, 64 characters or fewer. A retried request with the same key and the same body replays the original response. Up to 64 characters.
Request body
NameTypeNotes
move_out_datestring/date · required
ntv_reason_codestring
departure_destination_codestring
notesstring
providerstring · requiredRequired. A short slug identifying the feeding system, e.g. rentvine, zapier, api.
external_idstringOptional. Rule 230 companion.
Responses
201OccupancyRecordThe notice was recorded, or this response replays an earlier recording for a duplicate Idempotency-Key. Header X-Idempotent-Replay: Present with value '1' when this response is a replay of the original recording for a duplicate Idempotency-Key.
400Error`idempotency_key_required` -- An Idempotency-Key header is required to record a notice. `invalid_request` -- The Idempotency-Key header must be 64 characters or fewer. `invalid_request` -- The request body is not a valid notice payload. `invalid_request` -- A provider slug is required. `invalid_request` -- The provider slug must be 40 characters or fewer.
404Error`not_found` -- No unit with that id is visible to this key.
409Error`idempotency_in_progress` -- A request with this Idempotency-Key is already being processed. `idempotency_mismatch` -- This Idempotency-Key was already used with a different ticket request. Use a new Idempotency-Key for a different request.
422Error`created_by_missing` -- This key has no minting administrator on record. `invalid_request` -- No active resident found on this unit.
401ErrorMissing or invalid API key.
403ErrorThe key's scope does not allow this, or the company is inactive.
429ErrorRate limit exceeded for this key. Allowance: 120 per minute.
Example
curl
curl -X POST "https://app.fixgrid.app/api/v1/units/{unit_id}/notice" \
  -H "Authorization: Bearer $FIXGRID_KEY" \
  -H "Idempotency-Key: $IDEMPOTENCY_KEY" \
  -H "Content-Type: application/json" \
  -d '{"move_out_date":"string","ntv_reason_code":"string","departure_destination_code":"string","notes":"string","provider":"string","external_id":"string"}'
Fields · OccupancyRecord
NameTypeNotes
schema_versionintegerThe DTO shape version. Always 1 today.
entity_typestringAlways 'occupancy' for this resource.
entity_idintegerThe FixGrid id of the underlying transition record.
unit_idintegerThe unit's id, from GET /units.
statusstringThe transition's own status column, e.g. 'active'.
move_in_datestring | null/dateISO 8601 date, or null.
move_out_datestring | null/dateISO 8601 date, or null on a move-in response.
occupancy_sourcestring | nullThe feed provider slug (lower-cased, stripped), or null.
occupancy_fed_atstring | null/date-timeISO 8601 UTC timestamp of this write, or null.
external_idstring | nullRule 230 companion: the external system id, if supplied.
leaseobject | nullThe lease this move-in created, or null on a notice response.
partiesarray of objectThe leaseholders/guarantors on this lease, or [] on a notice response. Never carries email or phone.
urlstring/uriAbsolute FixGrid link to this unit's transitions.
POST/api/v1/units/{unit_id}/move-inscope: write
Summary
Record a move-in. Creates a new resident tenancy on the unit. Parties are stored with named leaseholders first (a stable reorder); guarantors and any other entries follow in their original relative order. The response echoes the STORED order, which may differ from the request order. Requires the Idempotency-Key header; a write-scoped key is required.
Parameters
NameTypeNotes
Idempotency-Keyheader · string · requiredA client-chosen key, 64 characters or fewer. A retried request with the same key and the same body replays the original response. Up to 64 characters.
Request body
NameTypeNotes
move_in_datestring/date · required
lease_start_datestring/date · required
lease_end_datestring/dateOptional. Present implies a fixed-term lease; absent implies month-to-month.
predecessor_transition_idintegerOptional. Names the outgoing resident this move-in succeeds, when the unit is currently occupied.
providerstring · requiredRequired. A short slug identifying the feeding system, e.g. rentvine, zapier, api.
external_idstringOptional. Rule 230 companion.
partiesarray of object · required
Responses
201OccupancyRecordThe move-in was recorded, or this response replays an earlier recording for a duplicate Idempotency-Key. Header X-Idempotent-Replay: Present with value '1' when this response is a replay of the original recording for a duplicate Idempotency-Key.
400Error`idempotency_key_required` -- An Idempotency-Key header is required to record a move-in. `invalid_request` -- The Idempotency-Key header must be 64 characters or fewer. `invalid_request` -- The request body is not a valid move-in payload. `invalid_request` -- A provider slug is required. `invalid_request` -- The provider slug must be 40 characters or fewer.
404Error`not_found` -- No unit with that id is visible to this key.
409Error`idempotency_in_progress` -- A request with this Idempotency-Key is already being processed. `idempotency_mismatch` -- This Idempotency-Key was already used with a different ticket request. Use a new Idempotency-Key for a different request.
422Error`created_by_missing` -- This key has no minting administrator on record. `invalid_request` -- An active resident already occupies this unit. `invalid_request` -- No outgoing transition with that id is visible on this unit. `invalid_request` -- The `parties` field must be a non-empty list of at most 20 entries, with at least one leaseholder carrying a first and last name. `invalid_request` -- The `lease_end_date` field must be on or after `lease_start_date`.
401ErrorMissing or invalid API key.
403ErrorThe key's scope does not allow this, or the company is inactive.
429ErrorRate limit exceeded for this key. Allowance: 120 per minute.
Example
curl
curl -X POST "https://app.fixgrid.app/api/v1/units/{unit_id}/move-in" \
  -H "Authorization: Bearer $FIXGRID_KEY" \
  -H "Idempotency-Key: $IDEMPOTENCY_KEY" \
  -H "Content-Type: application/json" \
  -d '{"move_in_date":"string","lease_start_date":"string","lease_end_date":"string","predecessor_transition_id":0,"provider":"string","external_id":"string","parties":[]}'
Fields · OccupancyRecord
NameTypeNotes
schema_versionintegerThe DTO shape version. Always 1 today.
entity_typestringAlways 'occupancy' for this resource.
entity_idintegerThe FixGrid id of the underlying transition record.
unit_idintegerThe unit's id, from GET /units.
statusstringThe transition's own status column, e.g. 'active'.
move_in_datestring | null/dateISO 8601 date, or null.
move_out_datestring | null/dateISO 8601 date, or null on a move-in response.
occupancy_sourcestring | nullThe feed provider slug (lower-cased, stripped), or null.
occupancy_fed_atstring | null/date-timeISO 8601 UTC timestamp of this write, or null.
external_idstring | nullRule 230 companion: the external system id, if supplied.
leaseobject | nullThe lease this move-in created, or null on a notice response.
partiesarray of objectThe leaseholders/guarantors on this lease, or [] on a notice response. Never carries email or phone.
urlstring/uriAbsolute FixGrid link to this unit's transitions.

assets

GET/api/v1/assetsscope: read
Summary
List assets. A keyset-paginated page of the company's assets, including retired ones.
Parameters
NameTypeNotes
limitquery · integerMax rows to return (default 50, maximum 200). Default 50. Maximum 200.
cursorquery · stringOpaque pagination cursor from a previous page's next_cursor.
property_idquery · integerOnly rows for this property id.
unit_idquery · integerOnly rows tied to this unit (location) id.
statusquery · stringFilter to rows with this status -- see this parameter's enum for the live vocabulary.
updated_sincequery · string/date-timeOnly rows updated at or after this ISO 8601 UTC timestamp, e.g. 2026-01-01T00:00:00Z.
Responses
200Page of AssetA page of results.
400ErrorBad request -- an invalid limit or cursor was supplied.
401ErrorMissing or invalid API key.
403ErrorThe key's scope does not allow this, or the company is inactive.
429ErrorRate limit exceeded for this key. Allowance: 120 per minute.
422ErrorA filter value is outside its enum.
Example
curl
curl "https://app.fixgrid.app/api/v1/assets?limit=50" \
  -H "Authorization: Bearer $FIXGRID_KEY"
Fields · Asset
NameTypeNotes
schema_versionintegerThe DTO shape version. Always 1 today.
entity_typestringAlways 'asset' for this resource.
entity_idintegerThe FixGrid asset id.
namestring
categorystring
sub_categorystring | null
asset_tagstring | null
makestring
modelstring
serial_numberstring | null
statusstringOne of 'Active', 'Needs Service', 'Out of Service', 'Retired'. A retired asset still lists and fetches.
propertyobjectThe property this asset belongs to.
locationobject | nullThe location, or null. May be a mechanical room, not just a unit.
yearinteger | null
installed_onstring | null/dateISO 8601 date, no time component.
warranty_expires_onstring | null/dateISO 8601 date, no time component.
expected_life_yearsinteger | null
created_atstring/date-time
updated_atstring/date-time
external_idstring | nullRule 230 companion: the external system id, if synced.
sourcestringRule 230 companion: how this record was created.
urlstring/uriAbsolute FixGrid link to this record.
GET/api/v1/assets/{asset_id}scope: read
Summary
Fetch an asset. A single asset by id, including a retired one.
Parameters
NameTypeNotes
asset_idpath · integer · required
Responses
200AssetThe record.
401ErrorMissing or invalid API key.
403ErrorThe key's scope does not allow this, or the company is inactive.
404ErrorNo record with that id is visible to this key.
429ErrorRate limit exceeded for this key. Allowance: 120 per minute.
Example
curl
curl "https://app.fixgrid.app/api/v1/assets/{asset_id}" \
  -H "Authorization: Bearer $FIXGRID_KEY"
Fields · Asset
NameTypeNotes
schema_versionintegerThe DTO shape version. Always 1 today.
entity_typestringAlways 'asset' for this resource.
entity_idintegerThe FixGrid asset id.
namestring
categorystring
sub_categorystring | null
asset_tagstring | null
makestring
modelstring
serial_numberstring | null
statusstringOne of 'Active', 'Needs Service', 'Out of Service', 'Retired'. A retired asset still lists and fetches.
propertyobjectThe property this asset belongs to.
locationobject | nullThe location, or null. May be a mechanical room, not just a unit.
yearinteger | null
installed_onstring | null/dateISO 8601 date, no time component.
warranty_expires_onstring | null/dateISO 8601 date, no time component.
expected_life_yearsinteger | null
created_atstring/date-time
updated_atstring/date-time
external_idstring | nullRule 230 companion: the external system id, if synced.
sourcestringRule 230 companion: how this record was created.
urlstring/uriAbsolute FixGrid link to this record.

vendors

GET/api/v1/vendorsscope: read
Summary
List vendors. A keyset-paginated page of the company's vendor relationships, including inactive ones.
Parameters
NameTypeNotes
limitquery · integerMax rows to return (default 50, maximum 200). Default 50. Maximum 200.
cursorquery · stringOpaque pagination cursor from a previous page's next_cursor.
Responses
200Page of VendorA page of results.
400ErrorBad request -- an invalid limit or cursor was supplied.
401ErrorMissing or invalid API key.
403ErrorThe key's scope does not allow this, or the company is inactive.
429ErrorRate limit exceeded for this key. Allowance: 120 per minute.
422ErrorA filter value is outside its enum.
Example
curl
curl "https://app.fixgrid.app/api/v1/vendors?limit=50" \
  -H "Authorization: Bearer $FIXGRID_KEY"
Fields · Vendor
NameTypeNotes
schema_versionintegerThe DTO shape version. Always 1 today.
entity_typestringAlways 'vendor' for this resource.
entity_idintegerThe FixGrid vendor relationship id.
namestringThe nickname, else the legal name.
businessobjectThe shared vendor legal entity (hand-picked allowlist -- never the full business record).
avg_ratingnumber | null
rating_countinteger
is_activebooleanAn inactive relationship still lists and fetches.
property_visibilitystring
onboarded_atstring/date-time
retired_atstring | null/date-time
urlstring/uriAbsolute FixGrid link to this record.
last_compliance_statestringOne of 'compliant', 'expiring', 'noncompliant', 'missing', 'unknown'. NULL serialises as 'unknown'.
GET/api/v1/vendors/{vendor_id}scope: read
Summary
Fetch a vendor. A single vendor relationship by id, including an inactive one.
Parameters
NameTypeNotes
vendor_idpath · integer · required
Responses
200VendorThe record.
401ErrorMissing or invalid API key.
403ErrorThe key's scope does not allow this, or the company is inactive.
404ErrorNo record with that id is visible to this key.
429ErrorRate limit exceeded for this key. Allowance: 120 per minute.
Example
curl
curl "https://app.fixgrid.app/api/v1/vendors/{vendor_id}" \
  -H "Authorization: Bearer $FIXGRID_KEY"
Fields · Vendor
NameTypeNotes
schema_versionintegerThe DTO shape version. Always 1 today.
entity_typestringAlways 'vendor' for this resource.
entity_idintegerThe FixGrid vendor relationship id.
namestringThe nickname, else the legal name.
businessobjectThe shared vendor legal entity (hand-picked allowlist -- never the full business record).
avg_ratingnumber | null
rating_countinteger
is_activebooleanAn inactive relationship still lists and fetches.
property_visibilitystring
onboarded_atstring/date-time
retired_atstring | null/date-time
urlstring/uriAbsolute FixGrid link to this record.
last_compliance_statestringOne of 'compliant', 'expiring', 'noncompliant', 'missing', 'unknown'. NULL serialises as 'unknown'.

inspections

GET/api/v1/inspectionsscope: read
Summary
List inspections. A keyset-paginated page of the company's ops inspections. Consulting-engagement-tied inspections (DD/PCA/DD Unit Walk projects) are excluded -- they belong to the consulting product, not this resource.
Parameters
NameTypeNotes
limitquery · integerMax rows to return (default 50, maximum 200). Default 50. Maximum 200.
cursorquery · stringOpaque pagination cursor from a previous page's next_cursor.
property_idquery · integerOnly rows for this property id.
unit_idquery · integerOnly rows tied to this unit (location) id.
statusquery · stringFilter to rows with this status -- see this parameter's enum for the live vocabulary.
Responses
200Page of InspectionA page of results.
400ErrorBad request -- an invalid limit or cursor was supplied.
401ErrorMissing or invalid API key.
403ErrorThe key's scope does not allow this, or the company is inactive.
429ErrorRate limit exceeded for this key. Allowance: 120 per minute.
422ErrorA filter value is outside its enum.
Example
curl
curl "https://app.fixgrid.app/api/v1/inspections?limit=50" \
  -H "Authorization: Bearer $FIXGRID_KEY"
Fields · Inspection
NameTypeNotes
schema_versionintegerThe DTO shape version. Always 1 today.
entity_typestringAlways 'inspection' for this resource.
entity_idintegerThe FixGrid inspection id.
inspection_numberinteger | nullDisplay-only per-property sequence number.
titlestring | nullShort title, or null on a legacy row created before the launch seam existed.
inspection_typestring | nullThe template's type, e.g. 'General', 'Fire Alarm'.
statusstringThe inspection's lifecycle status -- see this property's enum for the live vocabulary. A row finalized on the legacy plain-checklist path publishes as 'Completed' here; its pass/fail verdict rides the separate `result` field instead.
resultstring | nullThe inspection's pass/fail verdict, or null when none applies -- one of 'passed', 'failed'.
propertyobjectThe property this inspection belongs to.
unitobject | nullThe unit this inspection is tied to, or null.
scheduled_datestring | null/dateISO 8601 date, no time component.
completed_datestring | null/dateISO 8601 date, no time component.
assigneeobject | nullThe staff user assigned, or null if unassigned.
is_compliance_inspectionbooleanWhether this inspection tracks a compliance obligation.
compliance_typestring | nullThe compliance log type this inspection is tied to, if any.
created_atstring/date-time
external_idstring | nullRule 230 companion: the external system id, if synced.
sourcestringRule 230 companion: how this record was created.
urlstring/uriAbsolute FixGrid link to this record.
GET/api/v1/inspections/{inspection_id}scope: read
Summary
Fetch an inspection. A single ops inspection by id.
Parameters
NameTypeNotes
inspection_idpath · integer · required
Responses
200InspectionThe record.
401ErrorMissing or invalid API key.
403ErrorThe key's scope does not allow this, or the company is inactive.
404ErrorNo record with that id is visible to this key.
429ErrorRate limit exceeded for this key. Allowance: 120 per minute.
Example
curl
curl "https://app.fixgrid.app/api/v1/inspections/{inspection_id}" \
  -H "Authorization: Bearer $FIXGRID_KEY"
Fields · Inspection
NameTypeNotes
schema_versionintegerThe DTO shape version. Always 1 today.
entity_typestringAlways 'inspection' for this resource.
entity_idintegerThe FixGrid inspection id.
inspection_numberinteger | nullDisplay-only per-property sequence number.
titlestring | nullShort title, or null on a legacy row created before the launch seam existed.
inspection_typestring | nullThe template's type, e.g. 'General', 'Fire Alarm'.
statusstringThe inspection's lifecycle status -- see this property's enum for the live vocabulary. A row finalized on the legacy plain-checklist path publishes as 'Completed' here; its pass/fail verdict rides the separate `result` field instead.
resultstring | nullThe inspection's pass/fail verdict, or null when none applies -- one of 'passed', 'failed'.
propertyobjectThe property this inspection belongs to.
unitobject | nullThe unit this inspection is tied to, or null.
scheduled_datestring | null/dateISO 8601 date, no time component.
completed_datestring | null/dateISO 8601 date, no time component.
assigneeobject | nullThe staff user assigned, or null if unassigned.
is_compliance_inspectionbooleanWhether this inspection tracks a compliance obligation.
compliance_typestring | nullThe compliance log type this inspection is tied to, if any.
created_atstring/date-time
external_idstring | nullRule 230 companion: the external system id, if synced.
sourcestringRule 230 companion: how this record was created.
urlstring/uriAbsolute FixGrid link to this record.

turns

GET/api/v1/turnsscope: read
Summary
List turns. A keyset-paginated page of the company's unit transitions -- occupancy and turnover records, ordered by id ascending. A turn IS the transition record (Ruling 1): every UnitTransition row lists, including a plain first-ever move-in with no move_out_date. The same object the turn.status_changed and turn.schedule_changed webhooks' `data` carries.
Parameters
NameTypeNotes
limitquery · integerMax rows to return (default 50, maximum 200). Default 50. Maximum 200.
cursorquery · stringOpaque pagination cursor from a previous page's next_cursor.
property_idquery · integerOnly rows for this property id.
unit_idquery · integerOnly rows tied to this unit (location) id.
statusquery · stringFilter to rows with this status -- see this parameter's enum for the live vocabulary.
updated_sincequery · string/date-timeOnly rows updated at or after this ISO 8601 UTC timestamp, e.g. 2026-01-01T00:00:00Z.
Responses
200Page of TurnA page of results.
400ErrorBad request -- an invalid limit or cursor was supplied.
401ErrorMissing or invalid API key.
403ErrorThe key's scope does not allow this, or the company is inactive.
429ErrorRate limit exceeded for this key. Allowance: 120 per minute.
422ErrorA filter value is outside its enum.
Example
curl
curl "https://app.fixgrid.app/api/v1/turns?limit=50" \
  -H "Authorization: Bearer $FIXGRID_KEY"
Fields · Turn
NameTypeNotes
schema_versionintegerThe DTO shape version. Always 1 today.
entity_typestringAlways 'turn' for this resource.
entity_idintegerThe FixGrid transition id.
statusstringThe turn's lifecycle status -- see this property's enum for the live vocabulary.
propertyobjectThe property this turn belongs to.
unitobjectThe unit this turn is on.
move_out_datestring | null/dateISO 8601 date, no time component. Null on a transition with no departing resident, e.g. a first-ever move-in.
move_in_datestring | null/dateISO 8601 date, no time component.
projected_ready_onstring | null/dateThe projected date this turn will be ready, derived from the Turn Board; null when this turn has no move_out_date (nothing to make ready) or no board yet. FixGrid-native, not the MITS MadeReadyDate (an actual completed date, a different fact).
occupancy_sourcestring | nullThe feed provider slug (lower-cased, stripped), or null when FixGrid staff manage this transition.
occupancy_fed_atstring | null/date-timeISO 8601 UTC timestamp of the last external feed write, or null.
created_atstring/date-time
updated_atstring/date-time
external_idstring | nullRule 230 companion: the external system id, if synced.
sourcestringRule 230 companion: how this record was created.
urlstring/uriAbsolute FixGrid link to this turn's record (the transition detail page).
GET/api/v1/turns/{turn_id}scope: read
Summary
Fetch a turn. A single unit transition by id -- the same object the turn.status_changed and turn.schedule_changed webhooks send.
Parameters
NameTypeNotes
turn_idpath · integer · required
Responses
200TurnThe record.
401ErrorMissing or invalid API key.
403ErrorThe key's scope does not allow this, or the company is inactive.
404ErrorNo record with that id is visible to this key.
429ErrorRate limit exceeded for this key. Allowance: 120 per minute.
Example
curl
curl "https://app.fixgrid.app/api/v1/turns/{turn_id}" \
  -H "Authorization: Bearer $FIXGRID_KEY"
Fields · Turn
NameTypeNotes
schema_versionintegerThe DTO shape version. Always 1 today.
entity_typestringAlways 'turn' for this resource.
entity_idintegerThe FixGrid transition id.
statusstringThe turn's lifecycle status -- see this property's enum for the live vocabulary.
propertyobjectThe property this turn belongs to.
unitobjectThe unit this turn is on.
move_out_datestring | null/dateISO 8601 date, no time component. Null on a transition with no departing resident, e.g. a first-ever move-in.
move_in_datestring | null/dateISO 8601 date, no time component.
projected_ready_onstring | null/dateThe projected date this turn will be ready, derived from the Turn Board; null when this turn has no move_out_date (nothing to make ready) or no board yet. FixGrid-native, not the MITS MadeReadyDate (an actual completed date, a different fact).
occupancy_sourcestring | nullThe feed provider slug (lower-cased, stripped), or null when FixGrid staff manage this transition.
occupancy_fed_atstring | null/date-timeISO 8601 UTC timestamp of the last external feed write, or null.
created_atstring/date-time
updated_atstring/date-time
external_idstring | nullRule 230 companion: the external system id, if synced.
sourcestringRule 230 companion: how this record was created.
urlstring/uriAbsolute FixGrid link to this turn's record (the transition detail page).

meters

GET/api/v1/metersscope: read
Summary
List utility meters. A keyset-paginated page of the company's utility meters (electric, gas, water, sewer, and trash), across all scopes (master, common area, and unit sub-meter).
Parameters
NameTypeNotes
limitquery · integerMax rows to return (default 50, maximum 200). Default 50. Maximum 200.
cursorquery · stringOpaque pagination cursor from a previous page's next_cursor.
property_idquery · integerOnly rows for this property id.
unit_idquery · integerOnly rows tied to this unit (location) id.
updated_sincequery · string/date-timeOnly rows updated at or after this ISO 8601 UTC timestamp, e.g. 2026-01-01T00:00:00Z.
Responses
200Page of UtilityMeterA page of results.
400ErrorBad request -- an invalid limit or cursor was supplied.
401ErrorMissing or invalid API key.
403ErrorThe key's scope does not allow this, or the company is inactive.
429ErrorRate limit exceeded for this key. Allowance: 120 per minute.
Example
curl
curl "https://app.fixgrid.app/api/v1/meters?limit=50" \
  -H "Authorization: Bearer $FIXGRID_KEY"
Fields · UtilityMeter
NameTypeNotes
schema_versionintegerThe DTO shape version. Always 1 today.
entity_typestringAlways 'utility_meter' for this resource.
entity_idintegerThe FixGrid utility meter id.
utility_typestringThe utility this meter tracks -- see this field's enum for the live vocabulary.
meter_scopestringOne of 'master' (property-wide), 'common_area', or 'unit_submeter' (true per-unit consumption). No published enum this slice.
unit_of_measurestring | nullThe consumption unit, e.g. kWh. Null for a flat-fee meter with no consumption unit (e.g. trash).
serial_numberstring | null
providerstring | nullThe utility company, if on file.
account_numberstring | nullThe provider's account number, if on file.
propertyobjectThe property this meter belongs to.
unitobject | nullThe unit/area this meter measures, or null for a master (whole-property) meter.
assetobject | nullThe physical asset this meter is optionally linked to, or null.
data_sourcestringHow this meter's readings arrive -- manual, file_import, api, or iot. No published enum this slice.
is_activebooleanWhether this meter is active. An inactive (soft-retired) meter still lists and fetches -- its history is never hidden.
created_atstring/date-time
updated_atstring/date-time
external_idstring | nullRule 230 companion: the external system id, if synced.
sourcestringRule 230 companion: how this record was created.
urlstring/uriAbsolute FixGrid link to this meter's readings page.
GET/api/v1/meters/{meter_id}scope: read
Summary
Fetch a utility meter. A single utility meter by id.
Parameters
NameTypeNotes
meter_idpath · integer · required
Responses
200UtilityMeterThe record.
401ErrorMissing or invalid API key.
403ErrorThe key's scope does not allow this, or the company is inactive.
404ErrorNo record with that id is visible to this key.
429ErrorRate limit exceeded for this key. Allowance: 120 per minute.
Example
curl
curl "https://app.fixgrid.app/api/v1/meters/{meter_id}" \
  -H "Authorization: Bearer $FIXGRID_KEY"
Fields · UtilityMeter
NameTypeNotes
schema_versionintegerThe DTO shape version. Always 1 today.
entity_typestringAlways 'utility_meter' for this resource.
entity_idintegerThe FixGrid utility meter id.
utility_typestringThe utility this meter tracks -- see this field's enum for the live vocabulary.
meter_scopestringOne of 'master' (property-wide), 'common_area', or 'unit_submeter' (true per-unit consumption). No published enum this slice.
unit_of_measurestring | nullThe consumption unit, e.g. kWh. Null for a flat-fee meter with no consumption unit (e.g. trash).
serial_numberstring | null
providerstring | nullThe utility company, if on file.
account_numberstring | nullThe provider's account number, if on file.
propertyobjectThe property this meter belongs to.
unitobject | nullThe unit/area this meter measures, or null for a master (whole-property) meter.
assetobject | nullThe physical asset this meter is optionally linked to, or null.
data_sourcestringHow this meter's readings arrive -- manual, file_import, api, or iot. No published enum this slice.
is_activebooleanWhether this meter is active. An inactive (soft-retired) meter still lists and fetches -- its history is never hidden.
created_atstring/date-time
updated_atstring/date-time
external_idstring | nullRule 230 companion: the external system id, if synced.
sourcestringRule 230 companion: how this record was created.
urlstring/uriAbsolute FixGrid link to this meter's readings page.
GET/api/v1/meters/{meter_id}/readingsscope: read
Summary
List a meter's readings. A keyset-paginated page of one meter's consumption readings, ordered by id ascending -- chronological, oldest first; the last page carries the latest periods.
Parameters
NameTypeNotes
limitquery · integerMax rows to return (default 50, maximum 200). Default 50. Maximum 200.
cursorquery · stringOpaque pagination cursor from a previous page's next_cursor.
meter_idpath · integer · required
Responses
200Page of UtilityReadingA page of results.
400ErrorBad request -- an invalid limit or cursor was supplied.
401ErrorMissing or invalid API key.
403ErrorThe key's scope does not allow this, or the company is inactive.
429ErrorRate limit exceeded for this key. Allowance: 120 per minute.
404ErrorNo record with that id is visible to this key.
Example
curl
curl "https://app.fixgrid.app/api/v1/meters/{meter_id}/readings?limit=50" \
  -H "Authorization: Bearer $FIXGRID_KEY"
Fields · UtilityReading
NameTypeNotes
schema_versionintegerThe DTO shape version. Always 1 today.
entity_typestringAlways 'utility_reading' for this resource.
entity_idintegerThe FixGrid utility reading id.
period_startstring/dateISO 8601 date, no time component.
period_endstring/dateISO 8601 date, no time component.
utility_typestringCopied down from the parent meter -- a reading has no utility_type column of its own.
unit_of_measurestring | nullCopied down from the parent meter.
consumptionnumberThe metered consumption for this period, in the parent meter's unit_of_measure.
costnumber | nullOptional -- captured for usage visibility even though billing is paused.
entered_byobject | nullThe staff user who entered this reading, or null.
external_idstring | nullRule 230 companion: the external system id, if synced.
sourcestringRule 230 companion: how this record was created.
created_atstring/date-time

webhooks

GET/api/v1/webhooksany active key
Summary
List webhook subscriptions. A keyset-paginated page of the company's webhook subscriptions. Accepts any active key regardless of scope.
Parameters
NameTypeNotes
limitquery · integerMax rows to return (default 50, maximum 200). Default 50. Maximum 200.
cursorquery · stringOpaque pagination cursor from a previous page's next_cursor.
Responses
200Page of WebhookSubscriptionA page of results.
400ErrorBad request -- an invalid limit or cursor was supplied.
401ErrorMissing or invalid API key.
403ErrorThe key's scope does not allow this, or the company is inactive.
429ErrorRate limit exceeded for this key. Allowance: 120 per minute.
Example
curl
curl "https://app.fixgrid.app/api/v1/webhooks?limit=50" \
  -H "Authorization: Bearer $FIXGRID_KEY"
Fields · WebhookSubscription
NameTypeNotes
schema_versionintegerThe DTO shape version. Always 1 today.
entity_typestringAlways 'webhook_subscription' for this resource.
entity_idintegerThe FixGrid webhook subscription id.
destination_urlstring/urihttps on port 443 to a publicly resolvable host.
eventsarray of stringThe event keys this subscription is registered for.
healthstringDerived delivery health for this subscription: one of 'healthy', 'retrying', 'dead_lettered', or 'paused'.
secret_prefixstringThe first 12 characters of the signing secret, for display only -- never the full secret.
created_atstring/date-time
sourcestringRule 230 companion: how this record was created.
POST/api/v1/webhooksscope: webhook_only
Summary
Create a webhook subscription. Registers a destination URL to receive signed FixGrid-Signature POSTs for the given events. Requires the Idempotency-Key header; a webhook_only-scoped key is required (a write-scoped key also satisfies this).
Parameters
NameTypeNotes
Idempotency-Keyheader · string · requiredA client-chosen key, 64 characters or fewer. A retried request with the same key and the same body replays the original response. Up to 64 characters.
Request body
NameTypeNotes
destination_urlstring/uri · requiredhttps on port 443 to a publicly resolvable host.
eventsarray of stringOne or more event keys. One of: inspection.stale · pm.stale · property.notice.published · ticket.created · ticket.stale · ticket.status_changed · turn.schedule_changed · turn.status_changed · turn.task.stale · vendor.hold.
Responses
201WebhookSubscriptionCreatedThe webhook subscription was created, or this response replays an earlier creation for a duplicate Idempotency-Key. Header X-Idempotent-Replay: Present with value '1' when this response is a replay of the original creation for a duplicate Idempotency-Key; the replayed body omits secret.
400Error`idempotency_key_required` -- An Idempotency-Key header is required to create a webhook subscription. `invalid_request` -- The Idempotency-Key header must be 64 characters or fewer. `invalid_request` -- The request body is not a valid webhook subscription payload.
409Error`idempotency_in_progress` -- A request with this Idempotency-Key is already being processed. `idempotency_mismatch` -- This Idempotency-Key was already used with a different destination_url or events. Use a new Idempotency-Key for a different request.
422Error`invalid_destination_url` -- That destination URL is not allowed. `events_empty` -- Choose at least one event to subscribe to. `events_unknown_key` -- One or more selected events are not on the allow-list.
503Error`vault_unavailable` -- FixGrid will not store a signing secret it cannot encrypt.
401ErrorMissing or invalid API key.
403ErrorThe key's scope does not allow this, or the company is inactive.
429ErrorRate limit exceeded for this key. Allowance: 120 per minute.
Example
curl
curl -X POST "https://app.fixgrid.app/api/v1/webhooks" \
  -H "Authorization: Bearer $FIXGRID_KEY" \
  -H "Idempotency-Key: $IDEMPOTENCY_KEY" \
  -H "Content-Type: application/json" \
  -d '{"destination_url":"https://example.com/hooks","events":["inspection.stale"]}'
Fields · WebhookSubscriptionCreated
NameTypeNotes
schema_versionintegerThe DTO shape version. Always 1 today.
entity_typestringAlways 'webhook_subscription' for this resource.
entity_idintegerThe FixGrid webhook subscription id.
destination_urlstring/urihttps on port 443 to a publicly resolvable host.
eventsarray of stringThe event keys this subscription is registered for.
healthstringDerived delivery health for this subscription: one of 'healthy', 'retrying', 'dead_lettered', or 'paused'.
secret_prefixstringThe first 12 characters of the signing secret, for display only -- never the full secret.
created_atstring/date-time
sourcestringRule 230 companion: how this record was created.
secretstringThe raw signing secret, 'whsec_' + 43 URL-safe characters. Returned ONCE, on the original 201 only; an idempotent replay of the same Idempotency-Key omits this property.
DELETE/api/v1/webhooks/{sub_id}scope: webhook_only
Summary
Delete a webhook subscription. Hard-deletes the subscription and its delivery history. A webhook_only-scoped key is required (a write-scoped key also satisfies this).
Parameters
NameTypeNotes
sub_idpath · integer · required
Responses
204The webhook subscription was deleted.
404Error`not_found` -- No webhook subscription with that id is visible to this key.
401ErrorMissing or invalid API key.
403ErrorThe key's scope does not allow this, or the company is inactive.
429ErrorRate limit exceeded for this key. Allowance: 120 per minute.
Example
curl
curl -X DELETE "https://app.fixgrid.app/api/v1/webhooks/{sub_id}" \
  -H "Authorization: Bearer $FIXGRID_KEY"

llms.txt

A plain-text map of this host for language models and the tools built on them: every page, what it covers, and the URL of the OpenAPI document. It is the same convention the marketing site already publishes at its own root.

text · developers.fixgrid.app/llms.txt

# FixGrid API — developer documentation

> A public API over the maintenance record of one FixGrid customer:
> list and fetch, ticket and occupancy writes, and signed webhooks.
> Keys are minted by the customer's administrator.

## Guides
- [Start here](https://developers.fixgrid.app/): what the key is, included on every plan, how a Company Admin mints it, the first request
- [Authentication](https://developers.fixgrid.app/authentication.html): bearer keys, three scopes, 401 and 403
- [Objects](https://developers.fixgrid.app/objects.html): eight listable resources, occupancy ingest, the list envelope, keyset cursors, per-resource filters, the url deep link and the published enums
- [Errors](https://developers.fixgrid.app/errors.html): the shared shape and all nineteen codes
- [Webhooks](https://developers.fixgrid.app/webhooks.html): ten events, the turn events carry the Turn object, three card-only keys carry an inline dict, hourly first attempt, the signature, the retry ladder, subscriptions over the API
- [Rate limits and versioning](https://developers.fixgrid.app/limits.html)
- [Changelog](https://developers.fixgrid.app/changelog.html): dated changes, 90-day deprecation

## Reference
- [OpenAPI 3.1 document](https://developers.fixgrid.app/openapi.json): the machine-readable contract, no key required
- [Reference](https://developers.fixgrid.app/reference.html): every operation, parameter, response and field, generated from the document
Two files, one publish
openapi.json and llms.txt are files, not pages. Both are copied to this host by the publish step, and the copy of the OpenAPI document must be taken from the running API — never hand-edited here, or the drift check stops meaning anything.