Conventions

Shared conventions across the ThinkLP APIs — IDs, requests, search, pagination, and dates.

These conventions apply across every ThinkLP API domain.

Requests and responses

  • All request and response bodies are application/json.
  • Send your access token as a bearer token on every request (see
    Authentication).
  • Send every request over HTTPS.

Record identifiers

Records are identified by their Salesforce record ID (15- or 18-character).
Retrieve a single record by passing its id as a query parameter:

GET /theft-cases?id=a0nXXXXXXXXXXXXXXX

Creating and updating

  • CreatePOST the record body to the collection. A successful canonical
    create returns 200 OK with the record envelope (see Response shapes).

    POST /vehicles
  • UpdatePUT the record body, identifying the record with ?id=. If the
    body also contains an id, it must match the query parameter or the request
    is rejected with BAD_REQUEST. A successful update returns 200 OK with the
    record envelope.

    PUT /persons?id=a16XXXXXXXXXXXXXXX

    PUT replaces the whole record: a writable field you omit is cleared.

  • Partial updatePATCH changes only the keys you send.

    PATCH /locations?id=001XXXXXXXXXXXXXXX

Not every domain supports every verb — each domain's reference lists the ones it
accepts. Anything else returns 405 Method Not Allowed.

Response shapes

The shape of a successful response depends on the kind of endpoint:

EndpointResponse shapeStatus
Retrieve, create, update, partial updateEnvelope: { "detail": {…}, "fieldSpecs": […] }200
Lookup by natural key (by-sku, by-plate)A flat record DTO (no envelope)200
SearchA bare JSON array of lightweight preview records200
Attach a related record (sub-resource POST)The flat junction record201
Detach (DELETE)Empty body204
  • detail carries the record itself. fieldSpecs is per-field metadata
    (label, type, required, options, and so on) you can use to render a form. The
    fieldSpecs entries share one shape across every domain.
  • Lookups and search are convenience reads and deliberately skip the envelope.

Insights (case linkage)

The /insights/… endpoints are a distinct surface for creating theft cases from
Frontier point-of-sale transactions. They share the same authentication and the
same { code, message } error envelope. They use purpose-specific request and
response shapes rather than the { detail, fieldSpecs } envelope:

  • POST /insights/cases creates a case from an embedded transaction set. It
    returns 201 with a summary object, not the envelope. The summary carries
    caseId, caseUrl, and counts of the linked transactions, involved persons,
    and case items, plus any skipped employees.
  • GET /insights/cases/{caseId}/transactions returns a bare array of the
    transactions linked to a case.
  • GET /insights/cases/badges?transactionIds=… returns an object keyed by
    transaction id. Each value indicates whether that transaction is already linked
    to a case (null if not).

See Errors for the Insights-specific error codes.

Related records on a case

A theft case links to the vehicles, persons, and items involved in it. Manage
those links with sub-resources:

POST   /theft-cases/{caseId}/involved-vehicles     Attach a vehicle
DELETE /theft-cases/{caseId}/involved-vehicles?ids=a1X...,a1Y...   Detach vehicles

To remove links in bulk, pass a comma-separated list of link IDs in the ids
query parameter. The same pattern applies to involved-persons and
case-items.

You can also manage links inline on the case. A PUT /theft-cases?id= body
may embed involvedVehicles[], involvedPersons[], and caseItems[] arrays.
Those arrays create, update, or replace the links in the same call that updates
the case.

Each array is judged on its own. Omitting one is not the same as sending it
empty:

You sendResult
Absent, or nullThose links are left alone.
An array of entriesBecomes the complete set — omitted ones removed.
[]All of them are removed.

Search and lookup

Domains that support discovery expose two styles of endpoint:

  • Search — filter a collection by one or more criteria. You must supply at
    least one filter. A search with no criteria is rejected with
    UNDER_SPECIFIED_SEARCH. The response is a bare array of lightweight preview
    records (not the envelope).

    GET /persons/search?lastName=Smith&firstName=Jane
    GET /vehicles/search?make=Ford&state=NY
  • Lookup — resolve a single record by a natural key:

    GET /vehicles/by-plate?plateNumber=ABC123&state=NY
    GET /items/by-sku?sku=SKU-00042

Pagination

Where a search endpoint supports paging, it accepts limit and offset:

GET /persons/search?lastName=Smith&limit=25&offset=50
  • limit caps the number of records returned.
  • offset skips the given number of records. To page through results, increase
    offset by limit on each request.

Dates and times

  • Dates use ISO 8601 calendar format: YYYY-MM-DD (for example,
    2026-07-08).
  • Timestamps use ISO 8601 / RFC 3339 date-time format in UTC (for example,
    2026-07-08T14:30:00Z).
  • Times (time-only fields) are returned as HH:MM:SS (for example,
    14:30:00). A value sent without seconds (14:30) is echoed back with them.

Did this page help you?