← Back to home

Docs · REST API · OpenAPI

Machine-readable contract.

OpenAPI 3.1 covering /api/v1/* and the webhook envelope. Use it to generate a typed client, browse in Swagger UI, or import into Postman / Insomnia in one click.

Why OpenAPI

A typed contract beats prose docs for any non-trivial integration. Hand the spec to openapi-generator, openapi-typescript, oapi-codegen (Go), or whatever your language's tooling is, and you get a client that catches breaking changes at compile time. We publish the same spec our internal tooling consumes.

Where it lives

# Always-current production spec
GET https://dirtfleet.app/openapi.yaml

# Or pin a major
# (We don't pin minors. Additive changes — new endpoints, new optional
# fields, new enum members — ship without a major bump. Breaking
# changes go to /api/v2/.)
GET https://dirtfleet.app/openapi.yaml#v1

Quickstart

Generate a typed client

The full per-language guide with copy-paste commands lives at /docs/api/sdk (TS, Go, Python, Ruby + pointers to Rust / C# / Java / Swift / PHP). Quick summary below.

TypeScript / Node

# Generate types only — fast, zero runtime
npx openapi-typescript https://dirtfleet.app/openapi.yaml \
  -o ./src/dirtfleet-types.ts

# Then in your code
import type { paths } from "./dirtfleet-types";
type Flag = paths["/api/v1/flags"]["get"]["responses"]["200"]["content"]["application/json"]["flags"][number];

Go

# Install: go install github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@latest
oapi-codegen -package dirtfleet \
  -generate types,client \
  https://dirtfleet.app/openapi.yaml > dirtfleet/dirtfleet.go

Python

# pip install datamodel-code-generator
datamodel-codegen \
  --url https://dirtfleet.app/openapi.yaml \
  --output dirtfleet_models.py \
  --output-model-type pydantic_v2.BaseModel

Browse

Render in Swagger UI

Open the official Swagger Editor at editor-next.swagger.io (the URL pre-loads our spec). For a self-hosted reader, npx @scalar/cli reference https://dirtfleet.app/openapi.yaml is the smallest setup.

Postman / Insomnia

One-click import

Two options. Easiest: import the hand-curated collection at /postman_collection.json — Postman File → Import → Link or Insomnia Create → File → URL. It pre-builds every endpoint with example bodies and an apiKey collection variable; replace the variable with your key and you're running requests in 30 seconds.

Alternatively, import the OpenAPI spec directly — both tools accept the YAML URL and generate the collection on import. The hand-curated collection wins on day one because the example bodies are real; the spec wins when you want every path including ones we haven't curated yet.

Versioning + deprecation policy

  • v1 is current. Additive changes ship in-place — new endpoints, new optional response fields, new enum members.
  • Breaking changes go to v2. Removing fields, changing types, tightening required-ness, or renaming paths bumps the major and lives at /api/v2/.
  • 6-month deprecation window. When v2 ships, v1 stays available for at least six months with a deprecation header on every response and an email to integrators we can identify.

What's in the spec today

  • GET /api/v1/me — whoami. No scope required.
  • GET /api/v1/changelog — public release notes (no auth).
  • GET / POST /api/v1/assets + POST /api/v1/assets/batch + GET / PATCH /api/v1/assets/{id} — full CRUD-lite plus bulk import (cap 50). Each create triggers a Stripe quantity sync. PATCH covers focused fields (identity, plates, renewals, financial summary, lifecycle). Scopes assets:read + assets:write.
  • GET /api/v1/flags + POST + GET /api/v1/flags/{id} + PATCH /api/v1/flags/{id} — list (with severity/status/asset filters, default OPEN), raise a new flag, detail, or resolve. Scopes flags:read + flags:write.
  • GET /api/v1/hours + POST + GET /api/v1/hours/{id} + POST /api/v1/hours/batch — list (filter by asset / since), detail, single create, or bulk-import up to 100 entries with per-entry partial-success semantics. POST runs anomaly detection + AUTO_PM flagging server-side. Scopes hours:read + hours:write. Header Idempotency-Key on single POST; per-entry clientMutationId on batch.
  • GET /api/v1/work-orders + POST + GET /api/v1/work-orders/{id} + PATCH — full CRUD-lite. Scopes workorders:read + workorders:write.
  • GET /api/v1/tools + POST + GET /api/v1/tools/{id} + PATCH — full CRUD-lite plus POST /api/v1/tools/batch for bulk import (cap 100; each entry returns its scanToken for label printing). Plus three action endpoints — POST /tools/{id}/checkout (idempotent per actor; pass force: true to override an existing checkout), POST /tools/{id}/checkin (records observed condition; BROKEN auto-spawns a WO), and POST /tools/{id}/report (failure or replacement request; spawns the WO + marks the tool BROKEN or MISSING). Scopes tools:read + tools:write.
  • GET /api/v1/projects + POST + GET /api/v1/projects/{id} + PATCH — full CRUD-lite plus POST /api/v1/projects/batch for bulk import (cap 50). Scopes projects:read + projects:write.
  • GET /api/v1/version + GET /api/v1/health — public deploy metadata (commit, uptime) and a stable namespaced health probe (DB ping, returns 503 on degraded).
  • GET /api/v1/repairs + POST + GET /api/v1/repairs/{id} — labor + parts + cost history. Filter list by asset / project / work-order / since; detail includes the meta JSON blob omitted from listings; POST creates a log and marks any linked work order DONE. Reuses workorders:read + workorders:write scopes.
  • PATCH /api/v1/flags/{id} — resolve an open flag. status=RESOLVED only.
  • GET / POST /api/v1/yards + POST /api/v1/yards/batch + GET / PATCH / DELETE /api/v1/yards/{id} — full CRUD plus bulk import (cap 50), with org-unique name handling. Detail includes asset + tool counts. Delete unassigns related assets/tools via SET NULL (no cascade). Scopes yards:read + yards:write.
  • GET / POST / DELETE /api/v1/webhooks + GET / PATCH /api/v1/webhooks/{id} + GET /api/v1/webhooks/{id}/deliveries + POST /api/v1/webhooks/{id}/test — full subscription management, partial update (toggle active / URL / events without losing the secret), recent delivery history with status filter, and synthetic test deliveries. Scopes events:read + events:write.
  • Webhook envelope schema (WebhookEnvelope) with the full event-type enum.
  • Error contract (Error) shared by every endpoint, plus the canonical 401/403/422/429 response shapes (ValidationError for 422).

More endpoints land per integrator demand. If you need POST /api/v1/hours, GET /api/v1/work-orders, or anything else, open a ticket at /support with your integration use case — that's how the priority queue gets ordered.

← Back to the API reference · Copy-paste examples →