Installer.com Docs

Integration API (V1)

REST API for third-party systems to create, read, update and dispatch orders

Overview

The Integration API (V1) lets third-party systems (ERP, CRM, etc.) create orders, read and update them, find them by your own reference, manage tags, and dispatch orders to installers. These endpoints use API key authentication and are designed for server-to-server integrations.

See the API Reference for every endpoint's request and response schema.

Authentication

All Integration API endpoints require a Bearer token. See Authentication for how to create API keys.

Endpoints

Orders

EndpointDescription
Create OrderCreate a new order from your external system
List OrdersList orders, or find one by job id, external id, idempotency key or email
Get OrderGet one order by its id
Patch OrderUpdate order details and custom fields
Add NoteAdd a note to an order
Dispatch OrderDispatch an order to a contractor
Cancel OrderCancel an existing order

Files

EndpointDescription
Upload FileUpload a file to attach to an order

Order Tags

EndpointDescription
List Order TagsRetrieve all order tags
Create Order TagsCreate new order tags
Assign Tag to OrderAssign a tag to an order
Remove Tag from OrderRemove a tag from an order

Installers

EndpointDescription
List InstallersList available installer partners

Finding an order by your own reference

An order has several identifiers. Use whichever one your system stores:

IdentifierWhat it is
idOur order id (UUID). Create Order returns it as value.
displayIdThe job id shown in the app, for example P1-123.
idempotencyKeyThe key you sent when you created the order. Filter only; not returned.
externalIdYour own reference, set on Create Order or Patch Order. Not unique.
customFieldsValues keyed by each field's customId. Returned on every order, not filterable yet.

Pass one of them as a filter to List Orders, for example GET /v1/order?displayId=P1-123. The response is always a list, because externalId is not unique. Unknown or empty filters are rejected with 422.

To look orders up by your CRM or ERP id, send it as externalId when you create the order, or set it later with Patch Order.

Get Order, List Orders and Patch Order all return the same order object, except that only Get Order includes workflow. Text fields with no value are empty strings; description, externalId and state can also be null. status and source may gain new values; treat unknown values as opaque.

What you can rely on

  • Order fields (ids, name, description, contact, address, status, timestamps) are stable. New fields may be added; existing ones keep their name and type.
  • status and source keep their meaning, but new values may be added. Treat unknown values as opaque.
  • customFields are configured by the operator. A field can be renamed, removed or change type, so map on stable customIds that you agree on with the operator.
  • tags: match on id. Names and colors can be edited.
  • workflow is read-only progress. Its steps and actors come from the operator's workflow template, so map on templateCustomId, templateStepId and actor slug, not on titles or names. Bookings, offers and step answers are not part of the order object.

Workflow progress

Get Order returns workflow; List Orders and Patch Order leave it out. Orders created before workflows existed have none, and the field is left out.

FieldWhat it is
idThe order's workflow
templateId, templateCustomIdThe template, same across versions. Send either back on create: templateId as workflowId, templateCustomId as workflowCustomId.
templateName, templateVersionThe template's name and the published version the order runs on
actors[]Roles on the order: slug, name, and the organization that accepted it (null until then). organization.externalId is your own id for it: the sub-organization's external id, or your partnership external id.
steps[]In template order: id, templateStepId, title, type, status, completedAt, actorSlug. title can be null; use type to label the step.
steps[].statusSee workflow states. A step that has not started is todo.
steps[].assigneeThe person who answers for the step in your organization, or in the sub-organization that performs it. null otherwise. People at other organizations are never shown.

When an installer forwards a job to another organization, the role's slug moves to the organization that now holds it. The installer that forwarded it stays in actors under a generated slug that contains __fwd__, and the steps it already handled move to that slug. Key on the role slugs from your workflow template; other slugs, such as __fwd__ ones, are generated and can change.

Paging and syncing

List Orders returns up to limit orders (default 25, max 100), newest first, and a nextCursor. Pass it as cursor with the same filters to get the next page. nextCursor is null on the last page. Orders created while you page do not shift pages.

To keep your system in sync, pass updatedAfter to fetch only what changed since your last poll. Set it to the time your previous poll started, not the latest updatedAt you received, and remove duplicates by id.

  • updatedAt changes when the order's own fields change. Workflow progress does not change it yet, and List Orders does not return workflow. To follow progress, fetch each open order with Get Order.
  • Deleted orders are left out. Get Order returns 404 for them.
  • Test orders are left out of List Orders.
  • status is the order's lifecycle: PENDING (open), CANCELLED or DONE.

Typical Integration Flow

A common ERP integration follows this pattern:

1. ERP creates order     → Create Order
2. ERP assigns tag       → Assign Tag to Order
3. ERP dispatches        → Dispatch Order
4. Webhook notifies      → step state change
5. ERP fetches result    → Get Order

Use webhooks to receive real-time notifications when order status changes, rather than polling.

Error Handling

StatusDescriptionAction
200SuccessProcess the response
400Bad request, such as an unknown custom field or an invalid cursorCheck request payload
401UnauthorizedVerify API key
404Not found, or not owned by your organizationCheck resource IDs
409An order with this idempotency key already existsUse the returned orderId
422Validation error in the body or queryCheck fields and query parameters
429Rate limit reachedWait for Retry-After seconds, then retry

Reading orders (List Orders and Get Order) is limited to 600 requests per minute per organization, shared by all its API keys. Retry 429 responses after the Retry-After header, with exponential backoff.

On this page