Integrations
FRT Connect API
Connect apps, automations, and AI agents to Flat Rate Tracker.
Connect apps, automations, and AI agents to Flat Rate Tracker.
FRT Connect provides authenticated programmatic access to supported Flat Rate Tracker functionality for the signed-in user’s own account. It is a Pro feature.
Base URL
https://api.flatratetracker.com/connect/v1
All FRT Connect V1 endpoints use this base URL and authenticate with an FRT Connect API key.
Supported in V1
- List and search saved Jobs
- Create Work Orders
- Retrieve Work Orders
V1 does not include Scan RO, billing, Team management, PayTrack, ToolTrack, attachments/photos, webhooks, or a public developer portal.
Getting started
- Sign in to Flat Rate Tracker.
- Open Account → API Access.
- Create an API key (requires Pro).
- Copy the full key when it is shown and store it securely.
-
Send the key as an
Authorization: Bearertoken. - Call endpoints under the Connect V1 base URL above.
The complete key is shown only once at creation. Listing keys later never reveals the secret.
Authentication
Authorization: Bearer frt_live_example.EXAMPLE_SECRET
Use your real key in place of the example. The example credential above is fictional and will not work.
Key format
frt_live_<publicId>.<secret>
Important
- Treat API keys like passwords.
- Store them server-side or in a secrets manager.
- Never commit keys to source control.
- Never embed keys in publicly distributed client-side code.
- The full credential cannot be retrieved again after creation.
- Revoke a compromised key immediately.
- Prefer one key per integration when practical.
Rotation
There is no in-place secret rotation. To rotate:
- Create a new key.
- Update the integration to use the new key.
- Confirm it works.
- Revoke the old key.
Revoked keys stop working immediately and cannot be restored.
API keys authenticate FRT Connect only. They cannot create or manage other API keys, change billing, manage Team membership, or perform account administration. Use the API key Bearer token on every Connect request — browser session cookies are not accepted.
Saved Jobs
GET /jobs
List the authenticated user’s saved Jobs.
Optional query parameters:
| Param | Description |
|---|---|
q |
Name search (case-insensitive). When present, returns matching saved Jobs by name. |
usage |
Default includes usage stats. Pass
usage=false to omit them.
|
sort |
When not searching: name (default),
used, or recent.
|
Example:
GET /connect/v1/jobs?q=brake
Authorization: Bearer frt_live_example.EXAMPLE_SECRET
Example response:
{
"jobs": [
{
"id": "66f0aaaaaaaaaaaaaaaaaaaa",
"name": "Brake pads",
"hours": 1.5,
"pay_type": "customer",
"times_used": 12,
"last_used_date": "20260920"
}
]
}
Use a returned Job id as
saved_job_id when creating a Work Order.
GET /jobs?q=<search>
Same endpoint with q set. Search uses
case-insensitive name matching over the user’s accessible
saved Jobs.
Create a Work Order
POST /work-orders
Create a Work Order for the authenticated account. Connect uses Flat Rate Tracker’s normal Work Order creation behavior (validation, job snapshots, pay calculation, and default flagging).
Headers:
| Header | Required | Description |
|---|---|---|
Authorization |
yes | Bearer API key |
Idempotency-Key |
recommended | Unique string per intended create (max 100 characters). Safe retries return the same Work Order. |
Content-Type |
yes | application/json |
Body fields:
| Field | Type | Notes |
|---|---|---|
ro_number |
string | Repair Order / Work Order number |
date |
string | YYYY-MM-DD |
description |
string | optional short description shown in Flat Rate Tracker |
vehicle |
string | optional |
vin |
string | optional |
odometer |
string | optional |
advisor |
string | optional |
tag |
string | optional RO / vehicle tag identifier (preserve leading zeros; not coerced to a number) |
jobs |
array | Job lines (see below) |
Unknown top-level fields and unknown job properties are
rejected with UNSUPPORTED_FIELD. Do not send
internal Flat Rate Tracker fields.
Ownership is determined by the authenticated API key’s account. Clients cannot assign a Work Order to another Flat Rate Tracker user. API consumers do not send pay snapshots or expected earnings — Flat Rate Tracker calculates pay internally.
Flagging controls are not exposed in Connect V1. Work Orders created through Connect use Flat Rate Tracker’s normal creation default (fully flagged at creation, same as Quick Add).
Job formats
Saved Job reference
{
"saved_job_id": "66f0aaaaaaaaaaaaaaaaaaaa",
"pay_type": "customer"
}
One-time Job
{
"name": "Diagnosis",
"hours": 1.0,
"pay_type": "customer"
}
jobs[].name is the Job description/name (not the
Work Order short description).
Saved Job with name/hours override
{
"saved_job_id": "66f0aaaaaaaaaaaaaaaaaaaa",
"name": "Brake pads",
"hours": 1.6,
"pay_type": "warranty"
}
pay_type values:
customerwarrantyinternal
These map to Flat Rate Tracker’s existing labor types.
Each job line must include either a
saved_job_id or a name and
hours.
Example create request
POST /connect/v1/work-orders
Authorization: Bearer frt_live_example.EXAMPLE_SECRET
Idempotency-Key: agent-run-7f3c-ro-54821
Content-Type: application/json
{
"ro_number": "54821",
"date": "2026-09-29",
"description": "Customer waiting",
"vehicle": "2022 Toyota Camry",
"vin": "1FTFW1E57MFA18462",
"odometer": "64218",
"advisor": "Mike",
"tag": "A17",
"jobs": [
{
"saved_job_id": "66f0aaaaaaaaaaaaaaaaaaaa",
"pay_type": "customer"
},
{
"name": "Diagnosis",
"hours": 0.8,
"pay_type": "internal"
}
]
}
Example 201 response:
{
"work_order": {
"id": "66f0cccccccccccccccccccc",
"ro_number": "54821",
"date": "2026-09-29",
"description": "Customer waiting",
"vehicle": "2022 Toyota Camry",
"vin": "1FTFW1E57MFA18462",
"odometer": "64218",
"advisor": "Mike",
"tag": "A17",
"booked_hours": 2.3,
"flagged_hours": 2.3,
"jobs": [
{
"name": "Brake pads",
"hours": 1.5,
"pay_type": "customer",
"saved_job_id": "66f0aaaaaaaaaaaaaaaaaaaa"
},
{
"name": "Diagnosis",
"hours": 0.8,
"pay_type": "internal",
"saved_job_id": null
}
],
"created_at": "2026-09-29T23:10:00.000Z"
}
}
Retrieve a Work Order
GET /work-orders/:id
Fetch a Work Order owned by the authenticated account. Other
accounts’ Work Order IDs return 404. Manager/Team
peek is not available through Connect.
GET /connect/v1/work-orders/66f0cccccccccccccccccccc
Authorization: Bearer frt_live_example.EXAMPLE_SECRET
The response uses the same work_order object
shape as create.
Idempotency
Send an Idempotency-Key header when creating Work
Orders.
Idempotency-Key: agent-run-7f3c-ro-54821
Generate a unique Idempotency-Key for each intended Work Order creation.
If a request may have succeeded but the client is unsure (timeout, network failure), retry the same Work Order request with the same Idempotency-Key.
Behavior
| Situation | Result |
|---|---|
| Same Idempotency-Key + same/equivalent Work Order request | Returns the originally created Work Order. Does not create a duplicate. |
| Same Idempotency-Key + different Work Order request |
409 Conflict with
IDEMPOTENCY_KEY_REUSE
|
| Concurrent identical requests with the same key | At most one Work Order is created |
Example conflict response:
{
"error": {
"code": "IDEMPOTENCY_KEY_REUSE",
"message": "This Idempotency-Key was already used with a different request."
},
"code": "IDEMPOTENCY_KEY_REUSE",
"message": "This Idempotency-Key was already used with a different request."
}
Do not use the RO number itself as the Idempotency-Key unless you can guarantee the semantics you need. Prefer a generated unique request identifier. RO numbers are not globally unique.
Errors
Connect returns JSON with a stable code nested
under error and mirrored at the top level:
{
"error": {
"code": "INVALID_API_KEY",
"message": "Invalid API key."
},
"code": "INVALID_API_KEY",
"message": "Invalid API key."
}
| Status | Codes |
|---|---|
400 |
MALFORMED_REQUEST,
UNSUPPORTED_FIELD,
INVALID_IDEMPOTENCY_KEY
|
401 |
API_KEY_REQUIRED,
INVALID_API_KEY (includes missing,
malformed, invalid, and revoked keys)
|
402 |
payment_required (inactive
trial/subscription when writing)
|
403 |
capability_required (missing Pro /
Connect entitlement),
not_tracked_technician,
CONNECT_ACCESS_DISABLED
|
404 |
WORK_ORDER_NOT_FOUND,
UNKNOWN_SAVED_JOB
|
409 |
IDEMPOTENCY_KEY_REUSE |
422 |
INVALID_WORK_ORDER,
INVALID_JOB,
INVALID_PAY_TYPE, invalid hours/date
|
429 |
RATE_LIMITED |
CONNECT_ACCESS_DISABLED means Connect access for
the account has been disabled independently of the user’s
normal Flat Rate Tracker login, subscription, and app access.
Existing API keys are not deleted when Connect is disabled.
Rate limits
Applied only to /connect/v1:
- 120 requests per minute per API key
- 180 requests per minute per IP
Exceeding a limit returns 429 with
RATE_LIMITED. Responses include a
Retry-After header (seconds).
Limits protect service reliability. There is no daily quota in V1.
Flat Rate Tracker may rate-limit or disable Connect access
when necessary to protect the service. Disabling Connect
blocks /connect/v1 for that account only and does
not suspend the user’s Flat Rate Tracker
account, subscription, or normal app access.
Pro entitlement
FRT Connect requires Pro-level entitlement for Connect.
- Creating keys in Account → API Access requires Pro.
-
Every
/connect/v1request requires Connect entitlement. - List and revoke remain available after a downgrade so keys can be cleaned up.
- Existing keys are not deleted or revoked when Pro ends; Connect requests stop until eligible entitlement returns.
- Work Order writes also keep Flat Rate Tracker’s normal active-entitlement and tracked-technician rules.
Security and key management
- Use one API key per integration.
- Give keys descriptive names.
- Store secrets server-side.
- Never commit credentials.
- Revoke exposed credentials immediately.
- Replace credentials when rotating or retiring an integration.
- Remove keys for integrations no longer in use.
Revoked credentials cannot be restored. Create a new key and revoke the previous one to rotate.
Machine-readable copy
The same documentation is available as Markdown at:
https://flatratetracker.com/connect.md