Skip to main content

Integration patterns

Build each integration around stable resource IDs, explicit scopes, opaque cursors, and request-level observability.

Read and reconcile

For a recurring synchronization:
  1. Read the relevant list with the largest useful page size.
  2. Keep filters and direction stable until the traversal completes.
  3. Upsert downstream records by Canary resource ID.
  4. Record X-Request-ID with each processed page.
  5. Reconcile removed or archived records according to that resource’s lifecycle.
Native ID cursors give stable forward traversal. Work-request and portal compatibility cursors encode offsets, so deduplication by ID protects against concurrent collection changes.

Create a request and approve it

Create a work request with POST /workrequests, then review its compatibility status. When it is ready for work, create a native work order with workRequestId:
This operation approves the request and creates its linked work order atomically. Replaying approval for the same request returns the existing linked work order. Rejected requests return 409 invalid_work_request_state.

Write retries and idempotency

Public v1 has no general Idempotency-Key contract. A connection loss after a successful create can leave the client without the new ID. Use these rules:
  • Retry reads, validation-safe updates, and deletes after inspecting their documented lifecycle.
  • Treat ordinary create requests as potentially duplicating records.
  • Store the returned Canary ID immediately after every successful create.
  • Reconcile uncertain creates with a read and a stable business identifier where the resource exposes one.
  • Use workRequestId approval for its documented replay-safe behavior.
  • Bound retries and log the request ID, HTTP status, and error code.

Custom fields

Definitions are addressed by entity family and integer definition ID. Entity values are written in extraFields using the visible label as the key. Fetch active definitions before validating integration-owned values. Definition labels must be unique within a resource family; collisions return 409 custom_field_label_conflict. Asset, part, and native work-order lists omit extraFields; fetch individual details for those values. Location lists accept expand=extra_fields.

Work-request files

Attachment and thumbnail routes accept raw request bodies up to 1 MiB. Put the original filename in the URL path and set the media type in Content-Type. The returned publicUrl is a signed private URL that expires after 60 minutes. Store fileKey and filename as durable metadata and request a fresh signed URL through a later work-request read. Attachments and thumbnails can be changed only while a request is editable and pending. Lifecycle conflicts return 409 invalid_work_request_state; oversized content returns 413; unsupported picture data returns 415.

Archive and dependency behavior

Deletion semantics are resource-specific:
  • Deleting a meter archives it and preserves its readings. Automation dependencies produce 409 resource_in_use.
  • Deleting a native work order can be blocked when historical records depend on it.
  • Deleting a custom-field definition archives the definition.
  • Retiring an identifier removes its active scan mappings.
Read current state before destructive operations and handle 409 as a reconciliation event.

Operational checklist

  • One API key per workload and deployment environment
  • Minimum read/write scopes
  • Dedicated organization or labeled fixtures for development calls
  • Cursor traversal with stable filters
  • Bounded concurrency within the API-key rate limit
  • Retry-After handling for 429
  • Exponential backoff with jitter for transient 5xx
  • X-Request-ID in logs and support reports
  • Resource-specific duplicate and archive handling