ProLine Partner API (1.0)

Download OpenAPI specification:

ProLine support: [email protected]

Read and write a ProLine company's projects, claims, contacts, events, activities and files on behalf of an integration partner.

Overview

The Partner API lets an approved integration partner read and write data in a ProLine company that has shared its company key with the partner. Every request is a POST with a JSON body to a fixed path under https://api.proline.app/v1/, authenticated with two keys (see Authentication). Responses are JSON.

Endpoints are grouped by the record they work on. Record lists are paged; configuration lookups return all available options; finds return a single record (or an empty array when nothing matches); the bulk finds (/v1/find/events, /v1/find/projects, /v1/find/contacts) look up as many as 100 keys in one call; project and contact edits create or update; Edit Activity updates an existing communication activity only. Imports create records in bulk-friendly shapes and are idempotent on an external_id you supply.

Authentication

Two keys travel as request headers on every call:

Header What it identifies Where it comes from
PARTNER_KEY Your integration. One key per partner, used against every company you serve. Issued by ProLine when your application is approved.
COMPANY_KEY The ProLine company the request acts on. The company's admin copies it from Settings → Developer → Company Keys and gives it to you.

A request with a missing or unknown key is refused with 401. Rate limits (below) are per company key, so one slow integration never affects another company's.

Keep both keys server-side. The company key in particular grants access to that company's customer data; treat it like a password.

Rate limits

Limits are enforced per company key and per path, as a fixed interval between calls. A call inside the interval is refused with 429, a body of { "error": "Rate limit exceeded for <path>. Try again in <n> seconds." } and a Retry-After header carrying the same wait in whole seconds. Concurrent calls to one path are not admitted together: one is accepted and the rest are refused, so send calls to a path in sequence and wait out Retry-After before retrying.

Paths Interval
Finds of a single record (/v1/find/contact, /v1/find/project, /v1/find/event, /v1/find/team_member, /v1/find/activity), the configuration lookups (/v1/list/event_types, /v1/list/project_stages, /v1/list/project_categories, /v1/list/project_types, /v1/list/project_services, /v1/list/project_tags, /v1/list/project_areas, /v1/list/contact_types, /v1/list/contact_tags, /v1/list/lead_sources, /v1/list/org_stages, /v1/list/org_types, /v1/list/locations, /v1/list/users, /v1/list/custom_field_definitions), /v1/events/availability and the imports (/v1/import/contact, /v1/import/project, /v1/import/file, /v1/import/activity, /v1/import/tags) 1 call per second
Paged record lists (/v1/list/projects, /v1/list/quotes, /v1/list/jobs, /v1/list/orders, /v1/list/invoices, /v1/list/payments, /v1/list/project_files, /v1/list/project_folders), /v1/list/activities, /v1/list/events, the bulk finds (/v1/find/events, /v1/find/projects, /v1/find/contacts) and every claims endpoint 1 call per 5 seconds
Every other write (/v1/edit/*, /v1/events/edit, /v1/events/cancel, /v1/activity/*, /v1/files/create_project_file) 1 call per 5 seconds

Paged record lists return up to 100 records per page; a larger limit is clamped to 100, except List Events, which rejects it. List Events uses cursor pagination and limits source events checked before filtering. Configuration lookups do not accept pagination.

Date filters

The existing record and configuration lists (excluding the claims API lists and /v1/list/events) accept optional created_after, created_before, and updated_after timestamps. Supply a valid full ISO datetime with a timezone; missing or null means no bound. Boundaries are inclusive and combined with AND. An update bound may be later than a creation upper bound. Filters apply before pagination and counts.

Record lists use newest-update-first order with updated_after; otherwise they retain creation-time order. Lookups retain display order and folders retain tree order. Activities missing an update timestamp do not match. These existing timestamps are not a complete related-record or deletion feed. Keep a small overlap between polls and deduplicate returned IDs; page/limit pagination is not a snapshot during concurrent changes.

/v1/list/events instead accepts inclusive start_after and start_before bounds on the event's scheduled start time. It includes historical events and orders them oldest first. Follow next_cursor while has_more is true, even when a filtered page has no results.

Response shapes

Two conventions exist, for historical reasons, and each endpoint says which it follows:

Direct. The newer endpoints (every /v1/list/* path, /v1/find/activity, /v1/find/events, /v1/find/projects, /v1/find/contacts, /v1/edit/activity) answer with the record data as the whole body and a meaningful HTTP status: 200 on success, 400 for an invalid request, 401/403 for a key problem, 429 when rate limited. Edit Activity also returns 404 for a missing activity and 409 for an association conflict or paused automations.

Wrapped. The original endpoints answer 200 whatever happened and wrap the result in a fixed envelope:

{
  "isBase64Encoded": false,
  "statusCode": 200,
  "statusDescription": "200 OK",
  "headers": { "Content-Type": "application/json" },
  "body": { ... }
}

The result, including any error the backend reported, is in body, and the HTTP status says nothing about whether the call worked. Where the failure is reported depends on the endpoint. The finds answer with an empty array when nothing matches. The activity creates and the event endpoints put it at body.error. The project/contact edits and imports (/v1/edit/project, /v1/edit/contact, /v1/import/*, /v1/files/create_project_file) answer body.status: "success" whatever happened and put the outcome in body.response: body.response.error is true on a rejection and body.response.status says why. Each endpoint's 200 response lists the exact keys and gives a rejected example; check those before treating the call as successful. Only errors raised before the request reaches the backend (an unknown key, a rate limit, an invalid JSON body, an unknown body key) carry a real HTTP status and a flat { "error": "..." } body.

Errors

Status Meaning Body
400 Invalid JSON, a body key the endpoint does not accept (Invalid key found: "<key>"), or a missing required key. { "error": "..." }
401 Unknown or inactive partner key, or unknown company key. { "error": "..." }
403 The partner key is not permitted to call this endpoint. { "error": "Permission Denied" }
404 Unknown path, or Edit Activity cannot find the activity in the company. Flat router error, or structured backend error.
405 The endpoint does not support the request method. { "error": "..." }
409 Edit Activity has an association conflict or paused automations, or custom-field definitions conflict. Structured backend error.
429 Rate limited (see Rate limits); Retry-After says how long to wait. { "error": "..." }

Backend errors on the direct endpoints use { "success": false, "error": { "code": "BAD_REQUEST", "message": "..." } }, with a code appropriate to the failure. Each endpoint documents its statuses.

Identifiers

Ids in responses are ProLine ids (opaque strings). Where a company was migrated from the original ProLine platform, requests may also use that platform's legacy ids for the same records, and activity records of migrated data still report their legacy ids. Treat every id as an opaque string.

Custom fields

Projects have field numbers 1 to 7 and contacts 1 to 3, as in the original ProLine platform. Find and import endpoints name them custom_field_1 to custom_field_7 for a project and custom_field_1 to custom_field_3 for a contact; Edit Project names them project_custom_field_1 to project_custom_field_7 and Edit Contact custom_field_1 to custom_field_3. Each number addresses a text custom field. A company gives a text custom field a number in ProLine under Settings, on the custom field itself (its Zapier field number). Companies migrated from the original platform have numbers set for the fields they had there. Fields created in ProLine have no number until the company sets one, and this API cannot read or write them until then.

Find responses return the value of the field that holds each number, or "". List Projects does not include these values. Edit requests write to the field that holds the number and create a text field named "Custom Field N" when no field holds it, so a write never loses a value; a value sent for a number whose field the company deleted is skipped. Import requests write only to live fields that already hold the number; unassigned and deleted slots are skipped.

/v1/list/custom_field_definitions reports every numbered slot for the requested entity_type (project or contact), its label, and whether it is live, deleted, or unassigned. It does not create fields.

Configuration lookups

The project category/type/service/tag/area, contact type/tag, lead source, organization stage/type, location, and user lookups return direct arrays. Send optional date filters, an empty body or {}. Pagination is not accepted. Custom-field definitions require entity_type and return an { entity_type, results } object containing all seven project slots or all three contact slots. With date filters, a matching definition returns the complete slot snapshot; no matches returns results: []. Definitions that were deleted or lost their slot assignment participate in detection.

Lookup IDs are native ProLine IDs. Optional strings are null when unset, and unset flags are false. Archived options are excluded. User lookup includes invited members and regular or limited seats, while excluding staff, disabled users, removed members, and pending or failed removals. A user's role is their permission profile's exact name, or null. Organization types identify organization pipelines.

These lookups always require a known active partner key and company API access. Paused automations do not block them. Ordinary lookup sources above 1,000 records return HTTP 400 with backend error code LOOKUP_TOO_LARGE instead of a partial list. Custom definitions apply that source cap only with effective date filters. Conflicting custom-field definitions return HTTP 409 with code LOOKUP_CONFLICT when building a snapshot.

Insurance claims

Claims have separate create and edit operations; none of these endpoints upserts. Native ProLine IDs identify records. A claim's external_id belongs to the authenticated company and integration and can be used by find/claim instead of claim_id.

Every write requires an Idempotency-Key header containing 8–200 printable non-space ASCII characters, except edit/claim_items with dry_run: true. Retry a lost response within 24 hours with the identical body and the same key. Receipts expire after 24 hours; later retries can execute again. Reusing an unexpired key with a changed body returns a conflict. Edits and deletions require the current resource version as expected_version; bulk item edits and deletions carry one token per entry. A stale version returns HTTP 409. Item batches contain 1–100 entries and succeed or fail atomically.

Claims lists use cursor and limit (maximum 100), not page numbers or the common record date filters above. Always follow next_cursor while has_more is true, including empty result pages, and keep filters and credentials unchanged. Lists are not snapshots or changefeeds. List Claims returns compact headers and phases; Find Claim adds groups and financial totals; List Claim Items returns paginated line items and mappings.

Phase progress is controlled by stage_id. Use initial to identify a virtual legacy Initial phase and native IDs for persisted phases. The phase's stage category is draft, awaiting_carrier, action_required or closed.

PDF extraction and export return HTTP 202 document receipts. Poll List Claim Documents for queued, processing, completed or failed status and the output URL or error; ordinary attachments are ready. Extraction requires AI estimate access and an existing project PDF of at most 50 MB, an empty phase in the Draft stage, additional_only: true, and the claim's current version. Acceptance is not completion. JSON requests are limited to 1 MiB. Existing company API access checks and the five-second company/path rate limit apply to every claims route.

Webhooks

ProLine can call your endpoint when records change. Outbound webhooks are configured by the company in ProLine, not through this API; see ProLine Webhooks.

Claims support claim_created, claim_updated, claim_status_change, claim_assignee_change and claim_deleted. Phase, item, group and attachment changes use claim_updated; there are no separate submission or PDF-completion event types. Use List Claim Documents to poll PDF jobs.

Claim payloads carry schema_version: 1, event_id, event_type, occurred_at (UTC ISO timestamp), company_id, source and data. The source identifies an application or partner action; data contains claim and project IDs plus the claim status, assignee and event-specific changes. Delivery uses the saved event snapshot. Deduplicate event_id and tolerate repeated or out-of-order deliveries. Fetch current state when needed instead of treating delivery order as record order.

Claim webhook requests include X-ProLine-Event-Id and X-ProLine-Signature: t=<unix-seconds>,v1=<hex-signature>. Verify HMAC-SHA256 using the webhook signing secret and the exact UTF-8 bytes of <timestamp>.<event-id>.<raw-request-body>. Compare signatures in constant time and reject stale timestamps according to your receiver's replay window. Do not parse and reserialize the body before verification.

A 2xx response acknowledges delivery. Network failures, 408, 429 and 5xx responses are retried with backoff, for at most seven attempts within 24 hours; other HTTP failures stop delivery. Redirects are not followed.

Measurements

List measurement reports for a project

Complete nested document operation. Omitted children remain unchanged. Nested writes are atomic; explicit remove_ids removes children. No summary/view, page selection, or expected-version parameters. Existing company and partner credentials apply.

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
required
project_id
required
string [ 1 .. 200 ] characters
limit
integer [ 1 .. 100 ]
string or null

Responses

Request samples

Content type
application/json
{
  • "project_id": "string",
  • "limit": 1,
  • "cursor": "string"
}

Response samples

Content type
application/json
{
  • "results": [
    ],
  • "has_more": true,
  • "next_cursor": "string"
}

Get a complete measurement report with structures and values

Complete nested document operation. Omitted children remain unchanged. Nested writes are atomic; explicit remove_ids removes children. No summary/view, page selection, or expected-version parameters. Existing company and partner credentials apply.

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
required
report_id
required
string [ 1 .. 200 ] characters

Responses

Request samples

Content type
application/json
{
  • "report_id": "string"
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "project_id": "string",
  • "name": "string",
  • "notes": "string",
  • "status": "string",
  • "provider": "string",
  • "provider_status": "string",
  • "document": {
    },
  • "created_at": 0,
  • "updated_at": 0,
  • "structures": [
    ],
  • "created_ids": {
    }
}

Create a report with nested structures and measurements

Complete nested document operation. Omitted children remain unchanged. Nested writes are atomic; explicit remove_ids removes children. No summary/view, page selection, or expected-version parameters. Existing company and partner credentials apply.

Authorizations:
(PartnerKeyCompanyKey)
header Parameters
Idempotency-Key
required
string [ 8 .. 200 ] characters ^[!-~]+$

Stable key for one logical write; identical retries reuse the result for 24 hours.

Request Body schema: application/json
required
project_id
required
string [ 1 .. 200 ] characters
name
required
string [ 1 .. 300 ] characters
string or null
status
string
Enum: "draft" "complete"
Array of objects <= 100 items

Responses

Request samples

Content type
application/json
{
  • "project_id": "string",
  • "name": "string",
  • "notes": "string",
  • "status": "draft",
  • "structures": [
    ]
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "project_id": "string",
  • "name": "string",
  • "notes": "string",
  • "status": "string",
  • "provider": "string",
  • "provider_status": "string",
  • "document": {
    },
  • "created_at": 0,
  • "updated_at": 0,
  • "structures": [
    ],
  • "created_ids": {
    }
}

Update a report and nested measurements

Complete nested document operation. Omitted children remain unchanged. Nested writes are atomic; explicit remove_ids removes children. No summary/view, page selection, or expected-version parameters. Existing company and partner credentials apply.

Authorizations:
(PartnerKeyCompanyKey)
header Parameters
Idempotency-Key
required
string [ 8 .. 200 ] characters ^[!-~]+$

Stable key for one logical write; identical retries reuse the result for 24 hours.

Request Body schema: application/json
required
report_id
required
string [ 1 .. 200 ] characters
required
object

Responses

Request samples

Content type
application/json
{
  • "report_id": "string",
  • "patch": {
    }
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "project_id": "string",
  • "name": "string",
  • "notes": "string",
  • "status": "string",
  • "provider": "string",
  • "provider_status": "string",
  • "document": {
    },
  • "created_at": 0,
  • "updated_at": 0,
  • "structures": [
    ],
  • "created_ids": {
    }
}

Get measurement fields, calculations and rounding

Complete nested document operation. Omitted children remain unchanged. Nested writes are atomic; explicit remove_ids removes children. No summary/view, page selection, or expected-version parameters. Existing company and partner credentials apply.

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
required
object (find_measurement_settings)

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
{
  • "fields": [
    ],
  • "calculations": [
    ],
  • "rounding": "string",
  • "created_ids": {
    }
}

Update measurement fields, calculations and rounding

Complete nested document operation. Omitted children remain unchanged. Nested writes are atomic; explicit remove_ids removes children. No summary/view, page selection, or expected-version parameters. Existing company and partner credentials apply.

Authorizations:
(PartnerKeyCompanyKey)
header Parameters
Idempotency-Key
required
string [ 8 .. 200 ] characters ^[!-~]+$

Stable key for one logical write; identical retries reuse the result for 24 hours.

Request Body schema: application/json
required
object
object
rounding
string
Enum: "whole" "hundredth"

Responses

Request samples

Content type
application/json
{
  • "fields": {
    },
  • "calculations": {
    },
  • "rounding": "whole"
}

Response samples

Content type
application/json
{
  • "fields": [
    ],
  • "calculations": [
    ],
  • "rounding": "string",
  • "created_ids": {
    }
}

Claims

List claims

List compact claim headers and phase summaries. Use find/claim for groups and financial totals, and list/claim_items for line items. Filters match within the source page. The default limit is 20.

Both credentials are required. IDs are native ProLine IDs except documented external IDs and the initial phase alias. Unknown fields are refused; the JSON body is limited to 1 MiB. Requests use the existing five-second company/path rate limit.

Cursor pagination may return an empty results array while has_more is true. Always follow next_cursor with the same filters, company and integration. The default limit is 50 unless stated otherwise; the maximum is 100. Pagination is not a snapshot.

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
string or null
limit
integer [ 1 .. 100 ]
project_id
string [ 1 .. 256 ] characters
claim_id
string [ 1 .. 256 ] characters
name_contains
string [ 1 .. 100 ] characters
status
string
Enum: "draft" "negotiation" "approved"
string or null
stage_id
string [ 1 .. 256 ] characters
stage_status
string
Enum: "draft" "awaiting_carrier" "action_required" "closed"

Responses

Request samples

Content type
application/json
{
  • "cursor": "string",
  • "limit": 1,
  • "project_id": "string",
  • "claim_id": "string",
  • "name_contains": "string",
  • "status": "draft",
  • "assignee_id": "string",
  • "stage_id": "string",
  • "stage_status": "draft"
}

Response samples

Content type
application/json
{
  • "results": [
    ],
  • "next_cursor": "string",
  • "has_more": true,
  • "limit": 1
}

Find a claim

Find by exactly one of claim_id or this integration's external_id. Returns header, phases, groups and calculated financial summary. Large aggregates are refused instead of truncated. Planned cost and profit are null when mapping or tax references are unavailable.

Both credentials are required. IDs are native ProLine IDs except documented external IDs and the initial phase alias. Unknown fields are refused; the JSON body is limited to 1 MiB. Requests use the existing five-second company/path rate limit.

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
claim_id
string [ 1 .. 256 ] characters
external_id
string [ 1 .. 256 ] characters

Responses

Request samples

Content type
application/json
{
  • "claim_id": "string",
  • "external_id": "string"
}

Response samples

Content type
application/json
{
  • "claim_id": "string",
  • "project_id": "string",
  • "name": "string",
  • "status": "draft",
  • "claim_type": "string",
  • "assignee_id": "string",
  • "source_file_id": "string",
  • "rendered_pdf_url": "string",
  • "deductible": 0,
  • "policy_includes_depreciation": true,
  • "depreciate_tax": true,
  • "vendor_tax_id": "string",
  • "phases": [
    ],
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z",
  • "version": "string",
  • "groups": [
    ],
  • "summary": {
    }
}

Create a claim

Create a claim on an existing project. An optional source_claim_id copies an existing claim from the same project and always creates a fresh Draft claim. An external_id belongs to the company and this integration; reuse cannot overwrite an existing claim. This operation never upserts.

Both credentials are required. IDs are native ProLine IDs except documented external IDs and the initial phase alias. Unknown fields are refused; the JSON body is limited to 1 MiB. Requests use the existing five-second company/path rate limit.

Supply Idempotency-Key for a write. Retry the same operation with the same key and body within 24 hours to recover the original result; reusing an unexpired key with different content is refused. Receipts expire after 24 hours and later retries can execute again. Creates and edits are separate operations. A stale expected_version returns 409; read the resource again before making a revised request.

Authorizations:
(PartnerKeyCompanyKey)
header Parameters
Idempotency-Key
required
string [ 8 .. 200 ] characters ^[!-~]+$

Unique key for this operation and payload. Optional only when edit_claim_items has dry_run=true.

Request Body schema: application/json
required
project_id
required
string [ 1 .. 256 ] characters
source_claim_id
string [ 1 .. 256 ] characters
external_id
string [ 1 .. 256 ] characters
name
string [ 1 .. 100 ] characters
status
string
Enum: "draft" "negotiation" "approved"
string or null
deductible
number >= 0
policy_includes_depreciation
boolean
depreciate_tax
boolean
string or null

Responses

Request samples

Content type
application/json
{
  • "project_id": "string",
  • "source_claim_id": "string",
  • "external_id": "string",
  • "name": "string",
  • "status": "draft",
  • "assignee_id": "string",
  • "deductible": 0,
  • "policy_includes_depreciation": true,
  • "depreciate_tax": true,
  • "vendor_tax_id": "string"
}

Response samples

Content type
application/json
{
  • "claim_id": "string",
  • "project_id": "string",
  • "name": "string",
  • "status": "draft",
  • "claim_type": "string",
  • "assignee_id": "string",
  • "source_file_id": "string",
  • "rendered_pdf_url": "string",
  • "deductible": 0,
  • "policy_includes_depreciation": true,
  • "depreciate_tax": true,
  • "vendor_tax_id": "string",
  • "phases": [
    ],
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z",
  • "version": "string"
}

Edit a claim

Edit the existing claim header using its current version. Set assignee_id or vendor_tax_id to null to clear it. This operation never creates a missing claim.

Both credentials are required. IDs are native ProLine IDs except documented external IDs and the initial phase alias. Unknown fields are refused; the JSON body is limited to 1 MiB. Requests use the existing five-second company/path rate limit.

Supply Idempotency-Key for a write. Retry the same operation with the same key and body within 24 hours to recover the original result; reusing an unexpired key with different content is refused. Receipts expire after 24 hours and later retries can execute again. Creates and edits are separate operations. A stale expected_version returns 409; read the resource again before making a revised request.

Authorizations:
(PartnerKeyCompanyKey)
header Parameters
Idempotency-Key
required
string [ 8 .. 200 ] characters ^[!-~]+$

Unique key for this operation and payload. Optional only when edit_claim_items has dry_run=true.

Request Body schema: application/json
required
claim_id
required
string [ 1 .. 256 ] characters
expected_version
required
string [ 1 .. 256 ] characters
name
string [ 1 .. 100 ] characters
status
string
Enum: "draft" "negotiation" "approved"
string or null
deductible
number >= 0
policy_includes_depreciation
boolean
depreciate_tax
boolean
string or null

Responses

Request samples

Content type
application/json
{
  • "claim_id": "string",
  • "expected_version": "string",
  • "name": "string",
  • "status": "draft",
  • "assignee_id": "string",
  • "deductible": 0,
  • "policy_includes_depreciation": true,
  • "depreciate_tax": true,
  • "vendor_tax_id": "string"
}

Response samples

Content type
application/json
{
  • "claim_id": "string",
  • "project_id": "string",
  • "name": "string",
  • "status": "draft",
  • "claim_type": "string",
  • "assignee_id": "string",
  • "source_file_id": "string",
  • "rendered_pdf_url": "string",
  • "deductible": 0,
  • "policy_includes_depreciation": true,
  • "depreciate_tax": true,
  • "vendor_tax_id": "string",
  • "phases": [
    ],
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z",
  • "version": "string"
}

Create a claim phase

Create a new supplement phase on the existing claim. Phase progress is controlled by stage_id.

Both credentials are required. IDs are native ProLine IDs except documented external IDs and the initial phase alias. Unknown fields are refused; the JSON body is limited to 1 MiB. Requests use the existing five-second company/path rate limit.

Supply Idempotency-Key for a write. Retry the same operation with the same key and body within 24 hours to recover the original result; reusing an unexpired key with different content is refused. Receipts expire after 24 hours and later retries can execute again. Creates and edits are separate operations. A stale expected_version returns 409; read the resource again before making a revised request.

Authorizations:
(PartnerKeyCompanyKey)
header Parameters
Idempotency-Key
required
string [ 8 .. 200 ] characters ^[!-~]+$

Unique key for this operation and payload. Optional only when edit_claim_items has dry_run=true.

Request Body schema: application/json
required
claim_id
required
string [ 1 .. 256 ] characters
title
string [ 1 .. 100 ] characters
stage_id
string [ 1 .. 256 ] characters

Responses

Request samples

Content type
application/json
{
  • "claim_id": "string",
  • "title": "string",
  • "stage_id": "string"
}

Response samples

Content type
application/json
{
  • "phase_id": "string",
  • "claim_id": "string",
  • "sequence": 0,
  • "title": "string",
  • "stage_id": "string",
  • "stage_name": "string",
  • "stage_status": "string",
  • "stage_changed_at": "2019-08-24T14:15:22Z",
  • "source_file_id": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z",
  • "version": "string"
}

Edit a claim phase

Edit phase title or stage_id using its version. When phase_id is initial, also provide claim_id. Progress changes only through a stage; there is no independent phase status field.

Both credentials are required. IDs are native ProLine IDs except documented external IDs and the initial phase alias. Unknown fields are refused; the JSON body is limited to 1 MiB. Requests use the existing five-second company/path rate limit.

Supply Idempotency-Key for a write. Retry the same operation with the same key and body within 24 hours to recover the original result; reusing an unexpired key with different content is refused. Receipts expire after 24 hours and later retries can execute again. Creates and edits are separate operations. A stale expected_version returns 409; read the resource again before making a revised request.

Authorizations:
(PartnerKeyCompanyKey)
header Parameters
Idempotency-Key
required
string [ 8 .. 200 ] characters ^[!-~]+$

Unique key for this operation and payload. Optional only when edit_claim_items has dry_run=true.

Request Body schema: application/json
required
phase_id
required
string [ 1 .. 256 ] characters
claim_id
string [ 1 .. 256 ] characters
expected_version
required
string [ 1 .. 256 ] characters
title
string [ 1 .. 100 ] characters
stage_id
string [ 1 .. 256 ] characters

Responses

Request samples

Content type
application/json
{
  • "phase_id": "string",
  • "claim_id": "string",
  • "expected_version": "string",
  • "title": "string",
  • "stage_id": "string"
}

Response samples

Content type
application/json
{
  • "phase_id": "string",
  • "claim_id": "string",
  • "sequence": 0,
  • "title": "string",
  • "stage_id": "string",
  • "stage_name": "string",
  • "stage_status": "string",
  • "stage_changed_at": "2019-08-24T14:15:22Z",
  • "source_file_id": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z",
  • "version": "string"
}

List claim items

List line items and their mapping rows for one claim. This endpoint does not include every item in a claim in one response.

Both credentials are required. IDs are native ProLine IDs except documented external IDs and the initial phase alias. Unknown fields are refused; the JSON body is limited to 1 MiB. Requests use the existing five-second company/path rate limit.

Cursor pagination may return an empty results array while has_more is true. Always follow next_cursor with the same filters, company and integration. The default limit is 50 unless stated otherwise; the maximum is 100. Pagination is not a snapshot.

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
required
claim_id
required
string [ 1 .. 256 ] characters
item_id
string [ 1 .. 256 ] characters
external_id
string [ 1 .. 256 ] characters
phase_id
string [ 1 .. 256 ] characters
string or null
approval_status
string
Enum: "pending" "needs_documentation" "approved" "denied"
included
boolean
name_contains
string [ 1 .. 1000 ] characters
string or null
limit
integer [ 1 .. 100 ]
Default: 50

Responses

Request samples

Content type
application/json
{
  • "claim_id": "string",
  • "item_id": "string",
  • "external_id": "string",
  • "phase_id": "string",
  • "group_id": "string",
  • "approval_status": "pending",
  • "included": true,
  • "name_contains": "string",
  • "cursor": "string",
  • "limit": 50
}

Response samples

Content type
application/json
{
  • "results": [
    ],
  • "next_cursor": "string",
  • "has_more": true,
  • "limit": 1
}

Create claim items

Create 1–100 items atomically. A rejected item prevents the whole batch from being written. This operation never updates an existing item. Each item requires name and may carry an integration-owned external_id. Supply rcv or quantity/unit_price/tax_total, never both; supply depreciation_percent or depreciation_amount, never both. mapping accepts explicit rows or template_id, never both. Explicit mappings permit at most 100 rows per item and 1000 rows per batch; an empty rows array clears mappings.

Both credentials are required. IDs are native ProLine IDs except documented external IDs and the initial phase alias. Unknown fields are refused; the JSON body is limited to 1 MiB. Requests use the existing five-second company/path rate limit.

Supply Idempotency-Key for a write. Retry the same operation with the same key and body within 24 hours to recover the original result; reusing an unexpired key with different content is refused. Receipts expire after 24 hours and later retries can execute again. Creates and edits are separate operations. A stale expected_version returns 409; read the resource again before making a revised request.

Authorizations:
(PartnerKeyCompanyKey)
header Parameters
Idempotency-Key
required
string [ 8 .. 200 ] characters ^[!-~]+$

Unique key for this operation and payload. Optional only when edit_claim_items has dry_run=true.

Request Body schema: application/json
required
claim_id
required
string [ 1 .. 256 ] characters
required
Array of objects [ 1 .. 100 ] items

Responses

Request samples

Content type
application/json
{
  • "claim_id": "string",
  • "items": [
    ]
}

Response samples

Content type
application/json
{
  • "results": [
    ]
}

Edit claim items

Edit 1–100 items atomically, each with item_id and expected_version. The version covers the item and its mappings. Supply rcv or quantity/unit_price/tax_total, and only one depreciation field. mapping takes explicit rows or template_id. dry_run validates and returns proposed totals, mapping rows and preview_token without changing data; only this dry run may omit Idempotency-Key. To commit that preview, send the same items, dry_run=false and preview_token with a new idempotency key. A changed resource, price or input invalidates the preview. Mappings are limited to 100 rows per item and 1000 per batch.

Both credentials are required. IDs are native ProLine IDs except documented external IDs and the initial phase alias. Unknown fields are refused; the JSON body is limited to 1 MiB. Requests use the existing five-second company/path rate limit.

Supply Idempotency-Key for a write. Retry the same operation with the same key and body within 24 hours to recover the original result; reusing an unexpired key with different content is refused. Receipts expire after 24 hours and later retries can execute again. Creates and edits are separate operations. A stale expected_version returns 409; read the resource again before making a revised request.

Authorizations:
(PartnerKeyCompanyKey)
header Parameters
Idempotency-Key
string [ 8 .. 200 ] characters ^[!-~]+$

Unique key for this operation and payload. Optional only when edit_claim_items has dry_run=true.

Request Body schema: application/json
required
claim_id
required
string [ 1 .. 256 ] characters
required
Array of objects [ 1 .. 100 ] items
dry_run
boolean
preview_token
string [ 1 .. 256 ] characters

Responses

Request samples

Content type
application/json
{
  • "claim_id": "string",
  • "items": [
    ],
  • "dry_run": true,
  • "preview_token": "string"
}

Response samples

Content type
application/json
{
  • "dry_run": true,
  • "preview_token": "string",
  • "results": [
    ]
}

Delete claim items

Delete 1–100 specified items atomically, each with item_id and expected_version. A stale version prevents every deletion in the batch.

Both credentials are required. IDs are native ProLine IDs except documented external IDs and the initial phase alias. Unknown fields are refused; the JSON body is limited to 1 MiB. Requests use the existing five-second company/path rate limit.

Supply Idempotency-Key for a write. Retry the same operation with the same key and body within 24 hours to recover the original result; reusing an unexpired key with different content is refused. Receipts expire after 24 hours and later retries can execute again. Creates and edits are separate operations. A stale expected_version returns 409; read the resource again before making a revised request.

Authorizations:
(PartnerKeyCompanyKey)
header Parameters
Idempotency-Key
required
string [ 8 .. 200 ] characters ^[!-~]+$

Unique key for this operation and payload. Optional only when edit_claim_items has dry_run=true.

Request Body schema: application/json
required
claim_id
required
string [ 1 .. 256 ] characters
required
Array of objects [ 1 .. 100 ] items

Responses

Request samples

Content type
application/json
{
  • "claim_id": "string",
  • "items": [
    ]
}

Response samples

Content type
application/json
{
  • "results": [
    ]
}

Create a claim group

Create an item group on an existing claim.

Both credentials are required. IDs are native ProLine IDs except documented external IDs and the initial phase alias. Unknown fields are refused; the JSON body is limited to 1 MiB. Requests use the existing five-second company/path rate limit.

Supply Idempotency-Key for a write. Retry the same operation with the same key and body within 24 hours to recover the original result; reusing an unexpired key with different content is refused. Receipts expire after 24 hours and later retries can execute again. Creates and edits are separate operations. A stale expected_version returns 409; read the resource again before making a revised request.

Authorizations:
(PartnerKeyCompanyKey)
header Parameters
Idempotency-Key
required
string [ 8 .. 200 ] characters ^[!-~]+$

Unique key for this operation and payload. Optional only when edit_claim_items has dry_run=true.

Request Body schema: application/json
required
claim_id
required
string [ 1 .. 256 ] characters
name
required
string [ 1 .. 100 ] characters
position
integer [ 0 .. 9007199254740991 ]

Responses

Request samples

Content type
application/json
{
  • "claim_id": "string",
  • "name": "string",
  • "position": 9007199254740991
}

Response samples

Content type
application/json
{
  • "group_id": "string",
  • "claim_id": "string",
  • "name": "string",
  • "position": 0,
  • "version": "string"
}

Edit a claim group

Edit an existing group's name or position using its current version.

Both credentials are required. IDs are native ProLine IDs except documented external IDs and the initial phase alias. Unknown fields are refused; the JSON body is limited to 1 MiB. Requests use the existing five-second company/path rate limit.

Supply Idempotency-Key for a write. Retry the same operation with the same key and body within 24 hours to recover the original result; reusing an unexpired key with different content is refused. Receipts expire after 24 hours and later retries can execute again. Creates and edits are separate operations. A stale expected_version returns 409; read the resource again before making a revised request.

Authorizations:
(PartnerKeyCompanyKey)
header Parameters
Idempotency-Key
required
string [ 8 .. 200 ] characters ^[!-~]+$

Unique key for this operation and payload. Optional only when edit_claim_items has dry_run=true.

Request Body schema: application/json
required
group_id
required
string [ 1 .. 256 ] characters
expected_version
required
string [ 1 .. 256 ] characters
name
string [ 1 .. 100 ] characters
position
integer [ 0 .. 9007199254740991 ]

Responses

Request samples

Content type
application/json
{
  • "group_id": "string",
  • "expected_version": "string",
  • "name": "string",
  • "position": 9007199254740991
}

Response samples

Content type
application/json
{
  • "group_id": "string",
  • "claim_id": "string",
  • "name": "string",
  • "position": 0,
  • "version": "string"
}

Delete a claim group

Delete an existing group using its current version.

Both credentials are required. IDs are native ProLine IDs except documented external IDs and the initial phase alias. Unknown fields are refused; the JSON body is limited to 1 MiB. Requests use the existing five-second company/path rate limit.

Supply Idempotency-Key for a write. Retry the same operation with the same key and body within 24 hours to recover the original result; reusing an unexpired key with different content is refused. Receipts expire after 24 hours and later retries can execute again. Creates and edits are separate operations. A stale expected_version returns 409; read the resource again before making a revised request.

Authorizations:
(PartnerKeyCompanyKey)
header Parameters
Idempotency-Key
required
string [ 8 .. 200 ] characters ^[!-~]+$

Unique key for this operation and payload. Optional only when edit_claim_items has dry_run=true.

Request Body schema: application/json
required
group_id
required
string [ 1 .. 256 ] characters
expected_version
required
string [ 1 .. 256 ] characters

Responses

Request samples

Content type
application/json
{
  • "group_id": "string",
  • "expected_version": "string"
}

Response samples

Content type
application/json
{
  • "group_id": "string",
  • "deleted": true
}

List claim stages

List configured claim stages. The four stage categories are draft, awaiting_carrier, action_required and closed. Results are sorted by position within each source page.

Both credentials are required. IDs are native ProLine IDs except documented external IDs and the initial phase alias. Unknown fields are refused; the JSON body is limited to 1 MiB. Requests use the existing five-second company/path rate limit.

Cursor pagination may return an empty results array while has_more is true. Always follow next_cursor with the same filters, company and integration. The default limit is 50 unless stated otherwise; the maximum is 100. Pagination is not a snapshot.

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
string or null
limit
integer [ 1 .. 100 ]
stage_id
string [ 1 .. 256 ] characters
status
string
Enum: "draft" "awaiting_carrier" "action_required" "closed"

Responses

Request samples

Content type
application/json
{
  • "cursor": "string",
  • "limit": 1,
  • "stage_id": "string",
  • "status": "draft"
}

Response samples

Content type
application/json
{
  • "results": [
    ],
  • "next_cursor": "string",
  • "has_more": true,
  • "limit": 1
}

Create a claim stage

Create a company claim stage with a name, stage category and hexadecimal color.

Both credentials are required. IDs are native ProLine IDs except documented external IDs and the initial phase alias. Unknown fields are refused; the JSON body is limited to 1 MiB. Requests use the existing five-second company/path rate limit.

Supply Idempotency-Key for a write. Retry the same operation with the same key and body within 24 hours to recover the original result; reusing an unexpired key with different content is refused. Receipts expire after 24 hours and later retries can execute again. Creates and edits are separate operations. A stale expected_version returns 409; read the resource again before making a revised request.

Authorizations:
(PartnerKeyCompanyKey)
header Parameters
Idempotency-Key
required
string [ 8 .. 200 ] characters ^[!-~]+$

Unique key for this operation and payload. Optional only when edit_claim_items has dry_run=true.

Request Body schema: application/json
required
name
required
string [ 1 .. 60 ] characters
status
required
string
Enum: "draft" "awaiting_carrier" "action_required" "closed"
color
required
string^#[0-9a-f]{6}$
position
integer [ 0 .. 9007199254740991 ]

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "status": "draft",
  • "color": "string",
  • "position": 9007199254740991
}

Response samples

Content type
application/json
{
  • "stage_id": "string",
  • "name": "string",
  • "status": "string",
  • "color": "string",
  • "position": 0,
  • "version": "string"
}

Edit a claim stage

Edit an existing company claim stage using its current version.

Both credentials are required. IDs are native ProLine IDs except documented external IDs and the initial phase alias. Unknown fields are refused; the JSON body is limited to 1 MiB. Requests use the existing five-second company/path rate limit.

Supply Idempotency-Key for a write. Retry the same operation with the same key and body within 24 hours to recover the original result; reusing an unexpired key with different content is refused. Receipts expire after 24 hours and later retries can execute again. Creates and edits are separate operations. A stale expected_version returns 409; read the resource again before making a revised request.

Authorizations:
(PartnerKeyCompanyKey)
header Parameters
Idempotency-Key
required
string [ 8 .. 200 ] characters ^[!-~]+$

Unique key for this operation and payload. Optional only when edit_claim_items has dry_run=true.

Request Body schema: application/json
required
stage_id
required
string [ 1 .. 256 ] characters
expected_version
required
string [ 1 .. 256 ] characters
name
string [ 1 .. 60 ] characters
status
string
Enum: "draft" "awaiting_carrier" "action_required" "closed"
color
string^#[0-9a-f]{6}$
position
integer [ 0 .. 9007199254740991 ]

Responses

Request samples

Content type
application/json
{
  • "stage_id": "string",
  • "expected_version": "string",
  • "name": "string",
  • "status": "draft",
  • "color": "string",
  • "position": 9007199254740991
}

Response samples

Content type
application/json
{
  • "stage_id": "string",
  • "name": "string",
  • "status": "string",
  • "color": "string",
  • "position": 0,
  • "version": "string"
}

List claim documents

List documents attached to a claim and PDF processing results. Follow continuation cursors to retrieve all matching documents.

Both credentials are required. IDs are native ProLine IDs except documented external IDs and the initial phase alias. Unknown fields are refused; the JSON body is limited to 1 MiB. Requests use the existing five-second company/path rate limit.

Cursor pagination may return an empty results array while has_more is true. Always follow next_cursor with the same filters, company and integration. The default limit is 50 unless stated otherwise; the maximum is 100. Pagination is not a snapshot.

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
required
claim_id
required
string [ 1 .. 200 ] characters
string or null
limit
integer [ 1 .. 100 ]
Default: 50

Responses

Request samples

Content type
application/json
{
  • "claim_id": "string",
  • "cursor": "string",
  • "limit": 50
}

Response samples

Content type
application/json
{
  • "results": [
    ],
  • "next_cursor": "string",
  • "has_more": true,
  • "limit": 1
}

Create a claim document

Attach an existing company project file to a claim. The file must belong to the claim's project.

Both credentials are required. IDs are native ProLine IDs except documented external IDs and the initial phase alias. Unknown fields are refused; the JSON body is limited to 1 MiB. Requests use the existing five-second company/path rate limit.

Supply Idempotency-Key for a write. Retry the same operation with the same key and body within 24 hours to recover the original result; reusing an unexpired key with different content is refused. Receipts expire after 24 hours and later retries can execute again. Creates and edits are separate operations. A stale expected_version returns 409; read the resource again before making a revised request.

Authorizations:
(PartnerKeyCompanyKey)
header Parameters
Idempotency-Key
required
string [ 8 .. 200 ] characters ^[!-~]+$

Unique key for this operation and payload. Optional only when edit_claim_items has dry_run=true.

Request Body schema: application/json
required
claim_id
required
string [ 1 .. 200 ] characters
file_id
required
string [ 1 .. 200 ] characters
"initial" (string) or string
item_id
string [ 1 .. 200 ] characters

Responses

Request samples

Content type
application/json
{
  • "claim_id": "string",
  • "file_id": "string",
  • "phase_id": "initial",
  • "item_id": "string"
}

Response samples

Content type
application/json
{
  • "document_id": "string",
  • "claim_id": "string",
  • "phase_id": "string",
  • "item_id": "string",
  • "file_id": "string",
  • "kind": "attachment",
  • "status": "queued",
  • "filename": "string",
  • "url": "string",
  • "line_count": 0,
  • "error": {
    },
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Extract claim PDF

Queue extraction from an existing project PDF of at most 50 MB into an empty phase in the Draft stage. Requires the claim's current expected_version and additional_only=true. Existing phase items are preserved by refusing extraction into a populated phase. AI estimate access is required. Processing continues asynchronously: HTTP 202 accepts work, and list/claim_documents reports queued, processing, completed or failed status.

Both credentials are required. IDs are native ProLine IDs except documented external IDs and the initial phase alias. Unknown fields are refused; the JSON body is limited to 1 MiB. Requests use the existing five-second company/path rate limit.

Supply Idempotency-Key for a write. Retry the same operation with the same key and body within 24 hours to recover the original result; reusing an unexpired key with different content is refused. Receipts expire after 24 hours and later retries can execute again. Creates and edits are separate operations. A stale expected_version returns 409; read the resource again before making a revised request.

Authorizations:
(PartnerKeyCompanyKey)
header Parameters
Idempotency-Key
required
string [ 8 .. 200 ] characters ^[!-~]+$

Unique key for this operation and payload. Optional only when edit_claim_items has dry_run=true.

Request Body schema: application/json
required
claim_id
required
string [ 1 .. 200 ] characters
file_id
required
string [ 1 .. 200 ] characters
required
"initial" (string) or string
expected_version
required
string = 64 characters
additional_only
required
boolean
Value: true

Responses

Request samples

Content type
application/json
{
  • "claim_id": "string",
  • "file_id": "string",
  • "phase_id": "initial",
  • "expected_version": "stringstringstringstringstringstringstringstringstringstringstri",
  • "additional_only": true
}

Response samples

Content type
application/json
{
  • "document_id": "string",
  • "claim_id": "string",
  • "phase_id": "string",
  • "item_id": "string",
  • "file_id": "string",
  • "kind": "attachment",
  • "status": "queued",
  • "filename": "string",
  • "url": "string",
  • "line_count": 0,
  • "error": {
    },
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Export claim PDF

Queue a claim PDF export using the claim's current expected_version and optional phase_id. Processing continues asynchronously: HTTP 202 accepts work, and list/claim_documents reports status and the resulting URL when ready.

Both credentials are required. IDs are native ProLine IDs except documented external IDs and the initial phase alias. Unknown fields are refused; the JSON body is limited to 1 MiB. Requests use the existing five-second company/path rate limit.

Supply Idempotency-Key for a write. Retry the same operation with the same key and body within 24 hours to recover the original result; reusing an unexpired key with different content is refused. Receipts expire after 24 hours and later retries can execute again. Creates and edits are separate operations. A stale expected_version returns 409; read the resource again before making a revised request.

Authorizations:
(PartnerKeyCompanyKey)
header Parameters
Idempotency-Key
required
string [ 8 .. 200 ] characters ^[!-~]+$

Unique key for this operation and payload. Optional only when edit_claim_items has dry_run=true.

Request Body schema: application/json
required
claim_id
required
string [ 1 .. 200 ] characters
"initial" (string) or string
expected_version
required
string = 64 characters

Responses

Request samples

Content type
application/json
{
  • "claim_id": "string",
  • "phase_id": "initial",
  • "expected_version": "stringstringstringstringstringstringstringstringstringstringstri"
}

Response samples

Content type
application/json
{
  • "document_id": "string",
  • "claim_id": "string",
  • "phase_id": "string",
  • "item_id": "string",
  • "file_id": "string",
  • "kind": "attachment",
  • "status": "queued",
  • "filename": "string",
  • "url": "string",
  • "line_count": 0,
  • "error": {
    },
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

List claim mapping templates

List company claim mapping templates. Rows reference price list items and have absolute or percentage quantities.

Both credentials are required. IDs are native ProLine IDs except documented external IDs and the initial phase alias. Unknown fields are refused; the JSON body is limited to 1 MiB. Requests use the existing five-second company/path rate limit.

Cursor pagination may return an empty results array while has_more is true. Always follow next_cursor with the same filters, company and integration. The default limit is 50 unless stated otherwise; the maximum is 100. Pagination is not a snapshot.

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
string or null
limit
integer [ 1 .. 100 ]
template_id
string [ 1 .. 256 ] characters
name_contains
string [ 1 .. 100 ] characters

Responses

Request samples

Content type
application/json
{
  • "cursor": "string",
  • "limit": 1,
  • "template_id": "string",
  • "name_contains": "string"
}

Response samples

Content type
application/json
{
  • "results": [
    ],
  • "next_cursor": "string",
  • "has_more": true,
  • "limit": 1
}

Create a claim mapping template

Create a company mapping template. This operation never upserts.

Both credentials are required. IDs are native ProLine IDs except documented external IDs and the initial phase alias. Unknown fields are refused; the JSON body is limited to 1 MiB. Requests use the existing five-second company/path rate limit.

Supply Idempotency-Key for a write. Retry the same operation with the same key and body within 24 hours to recover the original result; reusing an unexpired key with different content is refused. Receipts expire after 24 hours and later retries can execute again. Creates and edits are separate operations. A stale expected_version returns 409; read the resource again before making a revised request.

Authorizations:
(PartnerKeyCompanyKey)
header Parameters
Idempotency-Key
required
string [ 8 .. 200 ] characters ^[!-~]+$

Unique key for this operation and payload. Optional only when edit_claim_items has dry_run=true.

Request Body schema: application/json
required
name
required
string [ 1 .. 100 ] characters
quantity_mode
required
string
Enum: "absolute" "percentage"
required
Array of objects [ 1 .. 100 ] items

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "quantity_mode": "absolute",
  • "rows": [
    ]
}

Response samples

Content type
application/json
{
  • "template_id": "string",
  • "name": "string",
  • "quantity_mode": "absolute",
  • "rows": [
    ],
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z",
  • "version": "string"
}

Edit a claim mapping template

Edit an existing mapping template using its current version.

Both credentials are required. IDs are native ProLine IDs except documented external IDs and the initial phase alias. Unknown fields are refused; the JSON body is limited to 1 MiB. Requests use the existing five-second company/path rate limit.

Supply Idempotency-Key for a write. Retry the same operation with the same key and body within 24 hours to recover the original result; reusing an unexpired key with different content is refused. Receipts expire after 24 hours and later retries can execute again. Creates and edits are separate operations. A stale expected_version returns 409; read the resource again before making a revised request.

Authorizations:
(PartnerKeyCompanyKey)
header Parameters
Idempotency-Key
required
string [ 8 .. 200 ] characters ^[!-~]+$

Unique key for this operation and payload. Optional only when edit_claim_items has dry_run=true.

Request Body schema: application/json
required
template_id
required
string [ 1 .. 256 ] characters
expected_version
required
string [ 1 .. 256 ] characters
name
string [ 1 .. 100 ] characters
quantity_mode
string
Enum: "absolute" "percentage"
Array of objects [ 1 .. 100 ] items

Responses

Request samples

Content type
application/json
{
  • "template_id": "string",
  • "expected_version": "string",
  • "name": "string",
  • "quantity_mode": "absolute",
  • "rows": [
    ]
}

Response samples

Content type
application/json
{
  • "template_id": "string",
  • "name": "string",
  • "quantity_mode": "absolute",
  • "rows": [
    ],
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z",
  • "version": "string"
}

Delete a claim mapping template

Delete an existing mapping template using its current version.

Both credentials are required. IDs are native ProLine IDs except documented external IDs and the initial phase alias. Unknown fields are refused; the JSON body is limited to 1 MiB. Requests use the existing five-second company/path rate limit.

Supply Idempotency-Key for a write. Retry the same operation with the same key and body within 24 hours to recover the original result; reusing an unexpired key with different content is refused. Receipts expire after 24 hours and later retries can execute again. Creates and edits are separate operations. A stale expected_version returns 409; read the resource again before making a revised request.

Authorizations:
(PartnerKeyCompanyKey)
header Parameters
Idempotency-Key
required
string [ 8 .. 200 ] characters ^[!-~]+$

Unique key for this operation and payload. Optional only when edit_claim_items has dry_run=true.

Request Body schema: application/json
required
template_id
required
string [ 1 .. 256 ] characters
expected_version
required
string [ 1 .. 256 ] characters

Responses

Request samples

Content type
application/json
{
  • "template_id": "string",
  • "expected_version": "string"
}

Response samples

Content type
application/json
{
  • "template_id": "string",
  • "deleted": true
}

Add claim items to a quote

Add the claim or selected phase to an existing quote using its claim version. The claim and quote must belong to the same project. service_id selects the quote service; rcv_basis chooses requested (default) or approved RCV. Returns the quote page ID.

Both credentials are required. IDs are native ProLine IDs except documented external IDs and the initial phase alias. Unknown fields are refused; the JSON body is limited to 1 MiB. Requests use the existing five-second company/path rate limit.

Supply Idempotency-Key for a write. Retry the same operation with the same key and body within 24 hours to recover the original result; reusing an unexpired key with different content is refused. Receipts expire after 24 hours and later retries can execute again. Creates and edits are separate operations. A stale expected_version returns 409; read the resource again before making a revised request.

Authorizations:
(PartnerKeyCompanyKey)
header Parameters
Idempotency-Key
required
string [ 8 .. 200 ] characters ^[!-~]+$

Unique key for this operation and payload. Optional only when edit_claim_items has dry_run=true.

Request Body schema: application/json
required
claim_id
required
string [ 1 .. 200 ] characters
"initial" (string) or string
quote_id
required
string [ 1 .. 200 ] characters
service_id
required
string [ 1 .. 200 ] characters
option_page_name
string [ 1 .. 200 ] characters
rcv_basis
string
Default: "requested"
Enum: "requested" "approved"
expected_version
required
string = 64 characters

Responses

Request samples

Content type
application/json
{
  • "claim_id": "string",
  • "phase_id": "initial",
  • "quote_id": "string",
  • "service_id": "string",
  • "option_page_name": "string",
  • "rcv_basis": "requested",
  • "expected_version": "stringstringstringstringstringstringstringstringstringstringstri"
}

Response samples

Content type
application/json
{
  • "claim_id": "string",
  • "quote_id": "string",
  • "quote_page_id": "string"
}

List price list items

List company price list items and enterprise items available to this company. Inactive items are excluded unless include_inactive is true; deleted items are always excluded.

Both credentials are required. IDs are native ProLine IDs except documented external IDs and the initial phase alias. Unknown fields are refused; the JSON body is limited to 1 MiB. Requests use the existing five-second company/path rate limit.

Cursor pagination may return an empty results array while has_more is true. Always follow next_cursor with the same filters, company and integration. The default limit is 50 unless stated otherwise; the maximum is 100. Pagination is not a snapshot.

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
string or null
limit
integer [ 1 .. 100 ]
price_list_item_id
string [ 1 .. 256 ] characters
name_contains
string [ 1 .. 100 ] characters
include_inactive
boolean

Responses

Request samples

Content type
application/json
{
  • "cursor": "string",
  • "limit": 1,
  • "price_list_item_id": "string",
  • "name_contains": "string",
  • "include_inactive": true
}

Response samples

Content type
application/json
{
  • "results": [
    ],
  • "next_cursor": "string",
  • "has_more": true,
  • "limit": 1
}

List vendor taxes

List active vendor taxes available to this company.

Both credentials are required. IDs are native ProLine IDs except documented external IDs and the initial phase alias. Unknown fields are refused; the JSON body is limited to 1 MiB. Requests use the existing five-second company/path rate limit.

Cursor pagination may return an empty results array while has_more is true. Always follow next_cursor with the same filters, company and integration. The default limit is 50 unless stated otherwise; the maximum is 100. Pagination is not a snapshot.

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
string or null
limit
integer [ 1 .. 100 ]
vendor_tax_id
string [ 1 .. 256 ] characters

Responses

Request samples

Content type
application/json
{
  • "cursor": "string",
  • "limit": 1,
  • "vendor_tax_id": "string"
}

Response samples

Content type
application/json
{
  • "results": [
    ],
  • "next_cursor": "string",
  • "has_more": true,
  • "limit": 1
}

Projects

List projects

Pages through every project in the company, newest first, with its stage, contacts, budget figures and status dates. Filter by creation date with created_after / created_before (both inclusive). Pages are limited to 100 rows and to an offset of 10,000 rows; beyond that, or when a page would read more than the per-call budget, the call answers 400 with a { "status": "error", "message": "..." } body and you should narrow the date window. total is exact up to 4,000 matching rows and a lower bound past that; has_more is authoritative. project_notes is returned as plain text, or null when absent or empty after formatting is stripped.

Optional created_after, created_before and updated_after filters are inclusive and combined with AND. Missing or null filters impose no bound. The update filter uses existing record timestamps; deletions and changes to related records are not a complete change feed. With updated_after, results are ordered by update time, newest first. Without it, existing creation-time ordering is unchanged.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
page
integer >= 1
Default: 1

1-based page number.

limit
integer [ 1 .. 100 ]
Default: 100

Rows per page. A value above 100 is clamped to 100.

created_after
string or null <date-time>

Only projects created at or after this instant. A full ISO 8601 datetime with timezone (for example 2026-09-01T00:00:00Z); a date alone is refused with 400. null means no bound.

created_before
string or null <date-time>

Only projects created at or before this instant. Same format as created_after; must not be earlier than it.

updated_after
string or null <date-time>

Updated at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone, for example 2026-10-01T00:00:00Z. Null means no bound. Combined with created_after and created_before using AND; it may be later than created_before.

Responses

Request samples

Content type
application/json
{
  • "page": 1,
  • "limit": 50,
  • "created_after": "2026-09-01T00:00:00Z",
  • "updated_after": "2026-10-01T00:00:00Z"
}

Response samples

Content type
application/json
{
  • "page": 1,
  • "limit": 50,
  • "total": 812,
  • "has_more": true,
  • "results": [
    ]
}

List project categories

Returns the company's project categories. Each id identifies a project category.

Returns a direct array, without pagination or an envelope. All IDs are native ProLine IDs. Optional strings are null when unset.

Requires both keys and company API access. An active partner key is always required; paused automations do not block this read. Rate limit: one call per second per company and path. This endpoint does not change data.

Optional created_after, created_before and updated_after filters are inclusive and combined with AND. Missing or null filters impose no bound. The update filter uses existing record timestamps; deletions and changes to related records are not a complete change feed.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
created_after
string or null <date-time>

Created at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Combined with the other date filters using AND.

created_before
string or null <date-time>

Created at or before this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Must be at or after created_after.

updated_after
string or null <date-time>

Updated at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone, for example 2026-10-01T00:00:00Z. Null means no bound. Combined with created_after and created_before using AND; it may be later than created_before.

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
[
  • {
    }
]

List project types

Returns the company's project types. Each id identifies a project type.

Returns a direct array, without pagination or an envelope. All IDs are native ProLine IDs. Optional strings are null when unset.

Requires both keys and company API access. An active partner key is always required; paused automations do not block this read. Rate limit: one call per second per company and path. This endpoint does not change data.

Optional created_after, created_before and updated_after filters are inclusive and combined with AND. Missing or null filters impose no bound. The update filter uses existing record timestamps; deletions and changes to related records are not a complete change feed.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
created_after
string or null <date-time>

Created at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Combined with the other date filters using AND.

created_before
string or null <date-time>

Created at or before this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Must be at or after created_after.

updated_after
string or null <date-time>

Updated at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone, for example 2026-10-01T00:00:00Z. Null means no bound. Combined with created_after and created_before using AND; it may be later than created_before.

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
[
  • {
    }
]

List project services

Returns the company's project services with their display order and color.

Returns a direct array, without pagination or an envelope. All IDs are native ProLine IDs. Optional strings are null when unset.

Requires both keys and company API access. An active partner key is always required; paused automations do not block this read. Rate limit: one call per second per company and path. This endpoint does not change data.

Optional created_after, created_before and updated_after filters are inclusive and combined with AND. Missing or null filters impose no bound. The update filter uses existing record timestamps; deletions and changes to related records are not a complete change feed.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
created_after
string or null <date-time>

Created at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Combined with the other date filters using AND.

created_before
string or null <date-time>

Created at or before this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Must be at or after created_after.

updated_after
string or null <date-time>

Updated at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone, for example 2026-10-01T00:00:00Z. Null means no bound. Combined with created_after and created_before using AND; it may be later than created_before.

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
[
  • {
    }
]

List project tags

Returns the company's project tags. Each id identifies a project tag.

Returns a direct array, without pagination or an envelope. All IDs are native ProLine IDs. Optional strings are null when unset.

Requires both keys and company API access. An active partner key is always required; paused automations do not block this read. Rate limit: one call per second per company and path. This endpoint does not change data.

Optional created_after, created_before and updated_after filters are inclusive and combined with AND. Missing or null filters impose no bound. The update filter uses existing record timestamps; deletions and changes to related records are not a complete change feed.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
created_after
string or null <date-time>

Created at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Combined with the other date filters using AND.

created_before
string or null <date-time>

Created at or before this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Must be at or after created_after.

updated_after
string or null <date-time>

Updated at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone, for example 2026-10-01T00:00:00Z. Null means no bound. Combined with created_after and created_before using AND; it may be later than created_before.

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
[
  • {
    }
]

List project areas

Returns the company's project areas. Each id identifies a project area and can be used as project_area on Edit Project or area on Import Project.

Returns a direct array, without pagination or an envelope. All IDs are native ProLine IDs. Optional strings are null when unset.

Requires both keys and company API access. An active partner key is always required; paused automations do not block this read. Rate limit: one call per second per company and path. This endpoint does not change data.

Optional created_after, created_before and updated_after filters are inclusive and combined with AND. Missing or null filters impose no bound. The update filter uses existing record timestamps; deletions and changes to related records are not a complete change feed.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
created_after
string or null <date-time>

Created at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Combined with the other date filters using AND.

created_before
string or null <date-time>

Created at or before this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Must be at or after created_after.

updated_after
string or null <date-time>

Updated at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone, for example 2026-10-01T00:00:00Z. Null means no bound. Combined with created_after and created_before using AND; it may be later than created_before.

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
[
  • {
    }
]

Find a project

Looks up one project and returns the first match. The keys are tried in this order: project_id, then project_external_id, then contact_id (the first project whose main contact is that contact), then the address fields together. project_stage and project_status do not find a project on their own; they filter the one that was found, so a project in another stage or status answers [].

body is an array with one project, or an empty array when nothing matched (there is no not-found error). An id that does not resolve, in the lookup or in a filter, also answers [].

Response shape: wrapped (see Overview → Response shapes).

To look up many projects in one call, see /v1/find/projects.

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
project_id
string (ProLineId)

A ProLine record id. Opaque; in requests, a legacy id for the same record is also accepted.

project_external_id
string

The project's external_id (the newest project with that value); a legacy project id is also accepted here.

contact_id
string

Main contact id; a legacy id is also accepted.

project_address1
string

Street line, used with project_city, project_state and project_zip only when no id matched.

project_address2
string

Accepted and ignored.

project_city
string
project_state
string
project_zip
string
project_stage
string

Stage id (see /v1/list/project_stages). Filter: the found project must be in this stage.

project_status
string
Enum: "lead" "inspection" "open" "disqualified" "lost" "won" "unfunded" "funded" "complete" "closed"

Filter: the found project's stage must have this status. The underlying value, not the label the response returns in status.

Responses

Request samples

Content type
application/json
{
  • "project_external_id": "CRM-10042"
}

Response samples

Content type
application/json
Example
{
  • "isBase64Encoded": false,
  • "statusCode": 200,
  • "statusDescription": "200 OK",
  • "headers": {
    },
  • "body": [
    ]
}

Find projects in bulk

Looks up as many as 100 projects in one call. Send exactly one of project_ids, external_ids or contact_ids, a list of 1 to 100 keys.

results holds one entry per key, in the order sent; a key sent twice is answered twice. Each entry's project is the object /v1/find/project returns in body[0] when sent that key alone (as project_id, project_external_id or contact_id), or null where that endpoint would answer [].

The 5-second rate limit per company key applies to the call, not to each key in it.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
required
One of
project_ids
required
Array of strings [ 1 .. 100 ] items [ items [ 1 .. 256 ] characters ]

Project ids, each looked up as project_id on /v1/find/project.

external_ids
Array of strings [ 1 .. 100 ] items [ items [ 1 .. 256 ] characters ]

Project external_id values, each looked up as project_external_id on /v1/find/project.

contact_ids
Array of strings [ 1 .. 100 ] items [ items [ 1 .. 256 ] characters ]

Main contact ids, each looked up as contact_id on /v1/find/project.

Responses

Request samples

Content type
application/json
{
  • "external_ids": [
    ]
}

Response samples

Content type
application/json
{
  • "results": [
    ]
}

Create or update a project

Updates an existing project and its main contact, or creates both, in one call, and optionally schedules an event on the project.

Create or update is decided in this order: project_id; otherwise the one project whose external_id matches (two or more matches are rejected, send project_id); otherwise, when edit_contact_latest is true, the contact's newest open project; otherwise a new project is created. external_id_new renames the external id and is refused when another project holds it.

The contact is resolved by contact_id, then contact_phone, then contact_email, then the existing project's main contact, then an unsaved draft with that phone; otherwise a contact is created, which requires contact_fname or contact_name.

Omitted or blank fields are left unchanged on both the project and the contact, so a value cannot be cleared through this endpoint. The one exception is project_tags: when present it replaces the whole tag list, and "" or [] clears it. A new project with no project_stage goes into the first stage of the first project pipeline. Ids that do not resolve (project_assign, project_category, project_location, ...) are dropped and the call still succeeds.

Side effects: a contact may be created, default folders are created on a new project, field changes are logged as activities and project webhooks fire. An event scheduling failure never fails the call; event_scheduled is then "null". An event_external_id held by an event on another project is skipped.

Rejections arrive inside body.response with error: true (the outer status is still "success"). When the company's automations are paused, body is { "ok": true } and nothing is written.

Response shape: wrapped (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
project_id
string (ProLineId)

A ProLine record id. Opaque; in requests, a legacy id for the same record is also accepted.

external_id
string

Your own id for the project; lookup key when project_id is absent.

external_id_new
string

New external_id for the project.

edit_contact_latest
string

true, 1, yes or on: when no project matched by id, edit the contact's newest open project instead of creating one.

project_name
string
project_address1
string
project_address2
string
project_city
string
project_state
string

A full US state name (Louisiana) is stored as its two-letter abbreviation (LA), and a two-letter value is upper-cased. Anything else is stored as sent.

project_zip
string
project_notes
string
project_location
string

Location id. When it is omitted or does not resolve and the project has no location, the company location nearest the project's zip or state is used, otherwise the company's default location.

project_assign
string

Team member id for the sales assignment.

project_inside_sales
string

Team member id.

project_production
string

Team member id.

project_accounting
string

Team member id.

project_category
string

Project category id.

project_type
string

Project type id.

project_stage
string

Stage id (see /v1/list/project_stages). On create, defaults to the first stage of the first project pipeline; a company with no stage at all rejects the call.

project_tags
Array of strings or string

Tag ids, as an array or a comma-separated string. Replaces the whole tag list; "" or [] clears it.

project_custom_field_1
string

Written to the text custom field that holds project field number 1 (see "Custom fields" in the overview). When no field holds the number, a text field named "Custom Field 1" is created and the value is written to it. When the field that held the number was deleted, the value is skipped. Omitted or blank values leave the field unchanged.

project_custom_field_2
string
project_custom_field_3
string
project_custom_field_4
string
project_custom_field_5
string
project_custom_field_6
string
project_custom_field_7
string
project_services
Array of strings or string

Service ids, as an array or a comma-separated string. Replaces the project's service list; an empty value keeps the existing list.

project_area
string

Project area id.

contact_campaign
string

Campaign id for attribution.

contact_id
string

Main contact id; a legacy id is also accepted.

contact_fname
string

First name. One of this or contact_name is required when creating the contact.

contact_name
string

Full name, used when creating the contact without contact_fname.

contact_phone
string

Any format; also a contact lookup key.

contact_email
string

Also a contact lookup key.

contact_type
string

Contact type id for a contact this call creates. Without it, or when it does not resolve, the new contact gets the company's default contact type. An existing contact's type is not changed.

contact_lead_source
string

Lead source id.

contact_tags
Array of strings or string

Contact tag ids, as an array or a comma-separated string. They are added to the contact, new or existing, and the tags it already has are kept.

event_external_id
string

Your id for the event to schedule or reschedule after the edit.

event_external_id_new
string

New external id for that event.

event_start_date
string

Event start. A string with a UTC offset is an absolute instant; one without is wall-clock time in event_time_zone, or UTC when none is given.

event_type
string

Event type id (see /v1/list/event_types).

event_time_zone
string

ProLine time zone value, legacy option key or IANA name for a naive event_start_date.

event_skip_external_create
string

true, 1, yes or on: exclude the event from external calendar sync. The event is still created.

Responses

Request samples

Content type
application/json
{
  • "external_id": "CRM-10042",
  • "contact_fname": "Dana",
  • "contact_phone": "+15125550142",
  • "project_name": "Ortiz re-roof",
  • "project_address1": "12 Elm St",
  • "project_city": "Austin",
  • "project_state": "TX",
  • "project_zip": "78701",
  • "project_stage": "k97f2x1n0cq8vb3d5t6hm4ws2e7a9zq1",
  • "project_tags": [
    ],
  • "event_start_date": "2026-10-15T14:00:00",
  • "event_time_zone": "central",
  • "event_type": "et4c8h2k6sq9nb3v1d7xm5wr0te4a8yc"
}

Response samples

Content type
application/json
Example
{
  • "isBase64Encoded": false,
  • "statusCode": 200,
  • "statusDescription": "200 OK",
  • "headers": {
    },
  • "body": {
    }
}

List project stages

Returns the stages of the company's project pipelines, grouped by pipeline in pipeline order. The id is what /v1/find/project returns as stage_id, and what project_stage takes on /v1/edit/project (/v1/list/projects returns the stage name only). Archived stages are not listed.

Optional created_after, created_before and updated_after filters are inclusive and combined with AND. Missing or null filters impose no bound. The update filter uses existing record timestamps; deletions and changes to related records are not a complete change feed. The update filter also considers the stage's company pipeline timestamp for changes to the returned pipeline name.

Supports at most 1,000 source rows per collection; larger sources return HTTP 400 with LOOKUP_TOO_LARGE, even when date filters would match fewer rows. No results are silently truncated.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
created_after
string or null <date-time>

Created at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Combined with the other date filters using AND.

created_before
string or null <date-time>

Created at or before this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Must be at or after created_after.

updated_after
string or null <date-time>

Updated at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone, for example 2026-10-01T00:00:00Z. Null means no bound. Combined with created_after and created_before using AND; it may be later than created_before.

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
[
  • {
    },
  • {
    }
]

Jobs

List jobs

Pages through every job in the company, newest first, with its project, service and stage. Filter by creation date with created_after / created_before (both inclusive). Pages are limited to 100 rows and to an offset of 10,000 rows; beyond that, or when a page would read more than the per-call budget, the call answers 400 with a { "status": "error", "message": "..." } body and you should narrow the date window. total is exact up to 4,000 matching rows and a lower bound past that; has_more is authoritative. job_description is returned as plain text, or null when absent or empty after formatting is stripped.

Optional created_after, created_before and updated_after filters are inclusive and combined with AND. Missing or null filters impose no bound. The update filter uses existing record timestamps; deletions and changes to related records are not a complete change feed. With updated_after, results are ordered by update time, newest first. Without it, existing creation-time ordering is unchanged.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
page
integer >= 1
Default: 1

1-based page number.

limit
integer [ 1 .. 100 ]
Default: 100

Rows per page. A value above 100 is clamped to 100.

created_after
string or null <date-time>

Only jobs created at or after this instant. A full ISO 8601 datetime with timezone (for example 2026-09-01T00:00:00Z); a date alone is refused with 400. null means no bound.

created_before
string or null <date-time>

Only jobs created at or before this instant. Same format as created_after; must not be earlier than it.

updated_after
string or null <date-time>

Updated at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone, for example 2026-10-01T00:00:00Z. Null means no bound. Combined with created_after and created_before using AND; it may be later than created_before.

Responses

Request samples

Content type
application/json
{
  • "limit": 100
}

Response samples

Content type
application/json
{
  • "page": 1,
  • "limit": 100,
  • "total": 3,
  • "has_more": false,
  • "results": [
    ]
}

Contacts

Find a contact

Looks up one contact by id, phone, email or address and returns the first match. The keys are tried in that order: contact_id, then contact_phone, then contact_email, then the address fields together; the first key that matches wins and the rest are not consulted. Archived contacts and contacts of other companies are not matched.

body is an array with one contact, or an empty array when nothing matched (there is no not-found error). An empty request body returns the empty array.

Response shape: wrapped (see Overview → Response shapes).

To look up many contacts in one call, see /v1/find/contacts.

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
contact_id
string (ProLineId)

A ProLine record id. Opaque; in requests, a legacy id for the same record is also accepted.

contact_phone
string

Any format; the number is normalized before matching. A saved contact is preferred over an unsaved draft with the same number.

contact_email
string

Matched exactly.

contact_address1
string

Street line, used with contact_city, contact_state and contact_zip only when no id, phone or email matched.

contact_address2
string

Accepted and ignored.

contact_city
string
contact_state
string
contact_zip
string

Responses

Request samples

Content type
application/json
{
  • "contact_phone": "+15125550142"
}

Response samples

Content type
application/json
Example
{
  • "isBase64Encoded": false,
  • "statusCode": 200,
  • "statusDescription": "200 OK",
  • "headers": {
    },
  • "body": [
    ]
}

Find contacts in bulk

Looks up as many as 100 contacts in one call. Send exactly one of contact_ids, phones or emails, a list of 1 to 100 keys.

results holds one entry per key, in the order sent; a key sent twice is answered twice. Each entry's contact is the object /v1/find/contact returns in body[0] when sent that key alone (as contact_id, contact_phone or contact_email), or null where that endpoint would answer [].

The 5-second rate limit per company key applies to the call, not to each key in it.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
required
One of
contact_ids
required
Array of strings [ 1 .. 100 ] items [ items [ 1 .. 256 ] characters ]

Contact ids, each looked up as contact_id on /v1/find/contact.

phones
Array of strings [ 1 .. 100 ] items [ items [ 1 .. 256 ] characters ]

Phone numbers in any format, each looked up as contact_phone on /v1/find/contact.

emails
Array of strings [ 1 .. 100 ] items [ items [ 1 .. 256 ] characters ]

Email addresses, each looked up as contact_email on /v1/find/contact.

Responses

Request samples

Content type
application/json
{
  • "phones": [
    ]
}

Response samples

Content type
application/json
{
  • "results": [
    ]
}

Create or update a contact

Updates an existing contact, or creates one when no match is found. The contact is matched by contact_id first; otherwise by contact_phone, against the newest saved contact with the same number, then against an unsaved draft with that number (the draft becomes the contact); otherwise a new contact is created, which requires contact_fname.

Omitted or blank fields are left unchanged, so a value cannot be cleared through this endpoint. external_id is stored on create only and ignored on update.

Side effects: field changes are logged as activities, the company's contact webhooks fire, lead-source attribution on the contact's projects is synced, and a new contact is given the next contact number.

Rejections arrive inside body.response with error: true (the outer status is still "success"): a missing first name on create, a phone number already held by another contact (that contact's id is returned), and others. When the company's automations are paused, body is { "ok": true } and nothing is written.

Response shape: wrapped (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
contact_id
string (ProLineId)

A ProLine record id. Opaque; in requests, a legacy id for the same record is also accepted.

contact_fname
string

First name. Required when creating.

contact_lname
string
contact_organization
string

Organization id.

contact_phone
string

Any format; normalized to E.164. Also the lookup key when contact_id is absent. Refused when another contact already has the number.

contact_email
string
contact_address1
string
contact_address2
string
contact_city
string
contact_state
string
contact_zip
string
contact_notes
string
contact_type
string

Contact type id. Validated together with lead_source.

lead_source
string

Lead source id. Validated together with contact_type.

time_zone
string

ProLine time zone value (central, mountain, pacific, eastern, hawaii, arizona, atlantic, ...), a legacy option key such as central_standard_time, or an IANA name.

external_id
string

Stored as the contact's legacy id on create only; ignored on update.

custom_field_1
string

Written to the text custom field that holds contact field number 1 (see "Custom fields" in the overview). When no field holds the number, a text field named "Custom Field 1" is created and the value is written to it. When the field that held the number was deleted, the value is skipped. Omitted or blank values leave the field unchanged.

custom_field_2
string
custom_field_3
string
contact_tags
string

Accepted and ignored.

contact_campaign_id
string

Accepted and ignored.

custom_date_1
string

Accepted and ignored.

custom_date_2
string

Accepted and ignored.

custom_date_3
string

Accepted and ignored.

Responses

Request samples

Content type
application/json
{
  • "contact_fname": "Dana",
  • "contact_lname": "Ortiz",
  • "contact_phone": "512-555-0142",
  • "contact_email": "[email protected]",
  • "contact_state": "TX",
  • "custom_field_1": "Referral: HOA"
}

Response samples

Content type
application/json
Example
{
  • "isBase64Encoded": false,
  • "statusCode": 200,
  • "statusDescription": "200 OK",
  • "headers": {
    },
  • "body": {
    }
}

List contact types

Returns the company's active contact types. Archived types are excluded.

Returns a direct array, without pagination or an envelope. All IDs are native ProLine IDs. Optional strings are null when unset.

Requires both keys and company API access. An active partner key is always required; paused automations do not block this read. Rate limit: one call per second per company and path. This endpoint does not change data.

Optional created_after, created_before and updated_after filters are inclusive and combined with AND. Missing or null filters impose no bound. The update filter uses existing record timestamps; deletions and changes to related records are not a complete change feed.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
created_after
string or null <date-time>

Created at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Combined with the other date filters using AND.

created_before
string or null <date-time>

Created at or before this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Must be at or after created_after.

updated_after
string or null <date-time>

Updated at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone, for example 2026-10-01T00:00:00Z. Null means no bound. Combined with created_after and created_before using AND; it may be later than created_before.

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
[
  • {
    }
]

List contact tags

Returns the company's active contact tags. Archived tags are excluded.

Returns a direct array, without pagination or an envelope. All IDs are native ProLine IDs. Optional strings are null when unset.

Requires both keys and company API access. An active partner key is always required; paused automations do not block this read. Rate limit: one call per second per company and path. This endpoint does not change data.

Optional created_after, created_before and updated_after filters are inclusive and combined with AND. Missing or null filters impose no bound. The update filter uses existing record timestamps; deletions and changes to related records are not a complete change feed.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
created_after
string or null <date-time>

Created at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Combined with the other date filters using AND.

created_before
string or null <date-time>

Created at or before this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Must be at or after created_after.

updated_after
string or null <date-time>

Updated at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone, for example 2026-10-01T00:00:00Z. Null means no bound. Combined with created_after and created_before using AND; it may be later than created_before.

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
[
  • {
    }
]

List lead sources

Returns the company's active lead sources. Archived sources are excluded.

Returns a direct array, without pagination or an envelope. All IDs are native ProLine IDs. Optional strings are null when unset.

Requires both keys and company API access. An active partner key is always required; paused automations do not block this read. Rate limit: one call per second per company and path. This endpoint does not change data.

Optional created_after, created_before and updated_after filters are inclusive and combined with AND. Missing or null filters impose no bound. The update filter uses existing record timestamps; deletions and changes to related records are not a complete change feed.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
created_after
string or null <date-time>

Created at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Combined with the other date filters using AND.

created_before
string or null <date-time>

Created at or before this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Must be at or after created_after.

updated_after
string or null <date-time>

Updated at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone, for example 2026-10-01T00:00:00Z. Null means no bound. Combined with created_after and created_before using AND; it may be later than created_before.

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
[
  • {
    }
]

Quotes

List quote templates with populated pages and defaults

Complete nested document operation. Omitted children remain unchanged. Nested writes are atomic; explicit remove_ids removes children. No summary/view, page selection, or expected-version parameters. Existing company and partner credentials apply.

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
required
project_id
string [ 1 .. 200 ] characters
limit
integer [ 1 .. 100 ]
string or null

Responses

Request samples

Content type
application/json
{
  • "project_id": "string",
  • "limit": 1,
  • "cursor": "string"
}

Response samples

Content type
application/json
{
  • "results": [
    ],
  • "has_more": true,
  • "next_cursor": "string"
}

Get a complete quote including pages, designs and pricing

Complete nested document operation. Omitted children remain unchanged. Nested writes are atomic; explicit remove_ids removes children. No summary/view, page selection, or expected-version parameters. Existing company and partner credentials apply.

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
required
quote_id
required
string [ 1 .. 200 ] characters

Responses

Request samples

Content type
application/json
{
  • "quote_id": "string"
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "project_id": "string",
  • "name": "string",
  • "number": "string",
  • "type": "string",
  • "status": "string",
  • "archived": true,
  • "expires_at": 0,
  • "created_at": 0,
  • "updated_at": 0,
  • "settings": {
    },
  • "template": {
    },
  • "pricing": {
    },
  • "selection": {
    },
  • "discounts": [
    ],
  • "signers": [
    ],
  • "measurement_reports": [
    ],
  • "references": {
    },
  • "validation": {
    },
  • "pages": [
    ],
  • "pdf": {
    },
  • "created_ids": {
    }
}

Get a complete quote page including content and design

Complete nested document operation. Omitted children remain unchanged. Nested writes are atomic; explicit remove_ids removes children. No summary/view, page selection, or expected-version parameters. Existing company and partner credentials apply.

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
required
page_id
required
string [ 1 .. 200 ] characters

Responses

Request samples

Content type
application/json
{
  • "page_id": "string"
}

Response samples

Content type
application/json
{
  • "id": "string",
  • "quote_id": "string",
  • "template_id": "string",
  • "source_page_id": "string",
  • "parent_page_id": "string",
  • "type": "string",
  • "name": "string",
  • "order": 0,
  • "enabled": true,
  • "hidden": true,
  • "measurement_structure_id": "string",
  • "banner_image_url": "string",
  • "cover_image_url": "string",
  • "config": {
    },
  • "content": {
    },
  • "subscription": {
    },
  • "file_import": {
    },
  • "pricing": {
    },
  • "children": [
    ],
  • "quote": {
    },
  • "created_ids": {
    }
}

List quotes

Pages through the company's quotes, newest first, with the project and contact each belongs to, its sent and signed timestamps, totals and deposit terms. Archived quotes are left out and are not counted in total. Filter by creation date with created_after / created_before (both inclusive). Pages are limited to 100 rows and to an offset of 10,000 rows; beyond that, or when a page would read more than the per-call budget, the call answers 400 with a { "status": "error", "message": "..." } body and you should narrow the date window. total is exact up to 4,000 matching rows and a lower bound past that; has_more is authoritative.

Optional created_after, created_before and updated_after filters are inclusive and combined with AND. Missing or null filters impose no bound. The update filter uses existing record timestamps; deletions and changes to related records are not a complete change feed. With updated_after, results are ordered by update time, newest first. Without it, existing creation-time ordering is unchanged.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
project_id
string

Optional project ID. Returns only that project's quotes; an unavailable project returns an empty page.

page
integer >= 1
Default: 1

1-based page number.

limit
integer [ 1 .. 100 ]
Default: 100

Rows per page. A value above 100 is clamped to 100.

created_after
string or null <date-time>

Only quotes created at or after this instant. A full ISO 8601 datetime with timezone (for example 2026-09-01T00:00:00Z); a date alone is refused with 400. null means no bound.

created_before
string or null <date-time>

Only quotes created at or before this instant. Same format as created_after; must not be earlier than it.

updated_after
string or null <date-time>

Updated at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone, for example 2026-10-01T00:00:00Z. Null means no bound. Combined with created_after and created_before using AND; it may be later than created_before.

Responses

Request samples

Content type
application/json
{
  • "page": 2,
  • "limit": 25,
  • "created_before": "2026-10-01T00:00:00-07:00"
}

Response samples

Content type
application/json
{
  • "page": 2,
  • "limit": 25,
  • "total": 61,
  • "has_more": true,
  • "results": [
    ]
}

Orders

List orders

Pages through the company's orders (purchase and work orders), newest first, with the project, quote, job and vendor each belongs to and its signing status and dates. Filter by creation date with created_after / created_before (both inclusive). Pages are limited to 100 rows and to an offset of 10,000 rows; beyond that, or when a page would read more than the per-call budget, the call answers 400 with a { "status": "error", "message": "..." } body and you should narrow the date window. total is exact up to 4,000 matching rows and a lower bound past that; has_more is authoritative. order_notes is returned as plain text, or null when absent or empty after formatting is stripped.

Optional created_after, created_before and updated_after filters are inclusive and combined with AND. Missing or null filters impose no bound. The update filter uses existing record timestamps; deletions and changes to related records are not a complete change feed. With updated_after, results are ordered by update time, newest first. Without it, existing creation-time ordering is unchanged.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
page
integer >= 1
Default: 1

1-based page number.

limit
integer [ 1 .. 100 ]
Default: 100

Rows per page. A value above 100 is clamped to 100.

created_after
string or null <date-time>

Only orders created at or after this instant. A full ISO 8601 datetime with timezone (for example 2026-09-01T00:00:00Z); a date alone is refused with 400. null means no bound.

created_before
string or null <date-time>

Only orders created at or before this instant. Same format as created_after; must not be earlier than it.

updated_after
string or null <date-time>

Updated at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone, for example 2026-10-01T00:00:00Z. Null means no bound. Combined with created_after and created_before using AND; it may be later than created_before.

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
{
  • "page": 1,
  • "limit": 100,
  • "total": 1,
  • "has_more": false,
  • "results": [
    ]
}

Invoices

List invoices

Pages through the company's invoices, newest first, with totals, balance, status dates and the billing, project and rep details captured on each. Filter by creation date with created_after / created_before (both inclusive). Pages are limited to 100 rows and to an offset of 10,000 rows; beyond that, or when a page would read more than the per-call budget, the call answers 400 with a { "status": "error", "message": "..." } body and you should narrow the date window. total is exact up to 4,000 matching rows and a lower bound past that; has_more is authoritative.

Optional created_after, created_before and updated_after filters are inclusive and combined with AND. Missing or null filters impose no bound. The update filter uses existing record timestamps; deletions and changes to related records are not a complete change feed. With updated_after, results are ordered by update time, newest first. Without it, existing creation-time ordering is unchanged.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
page
integer >= 1
Default: 1

1-based page number.

limit
integer [ 1 .. 100 ]
Default: 100

Rows per page. A value above 100 is clamped to 100.

created_after
string or null <date-time>

Only invoices created at or after this instant. A full ISO 8601 datetime with timezone (for example 2026-09-01T00:00:00Z); a date alone is refused with 400. null means no bound.

created_before
string or null <date-time>

Only invoices created at or before this instant. Same format as created_after; must not be earlier than it.

updated_after
string or null <date-time>

Updated at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone, for example 2026-10-01T00:00:00Z. Null means no bound. Combined with created_after and created_before using AND; it may be later than created_before.

Responses

Request samples

Content type
application/json
{
  • "created_after": "2026-09-01T00:00:00Z",
  • "created_before": "2026-09-30T23:59:59Z"
}

Response samples

Content type
application/json
{
  • "page": 1,
  • "limit": 100,
  • "total": 2,
  • "has_more": false,
  • "results": [
    ]
}

Payments

List payments

Pages through the company's payments, newest first, with the project and invoice each applies to, its status, method and amounts. Filter by creation date with created_after / created_before (both inclusive). Pages are limited to 100 rows and to an offset of 10,000 rows; beyond that, or when a page would read more than the per-call budget, the call answers 400 with a { "status": "error", "message": "..." } body and you should narrow the date window. total is exact up to 4,000 matching rows and a lower bound past that; has_more is authoritative.

Optional created_after, created_before and updated_after filters are inclusive and combined with AND. Missing or null filters impose no bound. The update filter uses existing record timestamps; deletions and changes to related records are not a complete change feed. With updated_after, results are ordered by update time, newest first. Without it, existing creation-time ordering is unchanged.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
page
integer >= 1
Default: 1

1-based page number.

limit
integer [ 1 .. 100 ]
Default: 100

Rows per page. A value above 100 is clamped to 100.

created_after
string or null <date-time>

Only payments created at or after this instant. A full ISO 8601 datetime with timezone (for example 2026-09-01T00:00:00Z); a date alone is refused with 400. null means no bound.

created_before
string or null <date-time>

Only payments created at or before this instant. Same format as created_after; must not be earlier than it.

updated_after
string or null <date-time>

Updated at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone, for example 2026-10-01T00:00:00Z. Null means no bound. Combined with created_after and created_before using AND; it may be later than created_before.

Responses

Request samples

Content type
application/json
{
  • "limit": 10
}

Response samples

Content type
application/json
{
  • "page": 1,
  • "limit": 10,
  • "total": 1,
  • "has_more": false,
  • "results": [
    ]
}

Events

Check team member availability

Returns the open appointment start times for one or more team members between start_date and end_date, one row per team member. Start times come back as a single comma-separated string in the time zone of the company's default location, with no UTC offset. The window may span at most 30 days.

The dates are read as UTC when they carry no offset. When user_id, start_date or end_date is missing, body is [{ "start_times": "" }] rather than an error. A window over 30 days, or a calendar that could not be read, answers a { "status": "...", "error": true } object in body; an unknown team member, event type or date format answers the backend validation error in body. When the company's automations are paused, body is { "ok": true }.

If the upstream response is not valid JSON, the router returns { "error": "Upstream service unavailable" } instead of the wrapped result. It preserves an upstream 4xx or 5xx status; an empty or malformed successful response returns 502.

Response shape: wrapped (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
user_id
required
Array of strings or string

One team member id, or an array of them. Each is echoed back as sent. An unknown id answers the validation error.

start_date
required
string

Start of the window; ISO 8601, UTC when no offset is given.

end_date
required
string

End of the window; at most 30 days after start_date.

event_type
string

Event type id (see /v1/list/event_types); its duration and scheduling rules shape the slots. Optional.

Responses

Request samples

Content type
application/json
{
  • "user_id": "j97b4d2f8kq1nc5v7h3xm6tw9se0a2rz",
  • "start_date": "2026-10-15T00:00:00Z",
  • "end_date": "2026-10-17T00:00:00Z",
  • "event_type": "et4c8h2k6sq9nb3v1d7xm5wr0te4a8yc"
}

Response samples

Content type
application/json
Example
{
  • "isBase64Encoded": false,
  • "statusCode": 200,
  • "statusDescription": "200 OK",
  • "headers": {
    },
  • "body": [
    ]
}

Create or update an event

Reschedules an existing event, or creates one on a project. When event_id names a live event it is updated; otherwise a new event is created, which requires project_id.

start_date is required on every call. The end time is derived from the event type's default duration. The event type is event_type, else the existing event's type, else the company's first event type; the calendar is the existing event's, else the type's default, else the company's first calendar. The event title is always set to the event type name.

Omitted or blank fields are left unchanged, so a value cannot be cleared through this endpoint. An assignee that does not resolve is dropped and the existing assignee kept.

Side effects: a new event gets the project's main-contact email as a participant; event webhooks fire. A missing or unparseable start_date, or a company with no event types, answers the backend validation error in body. Creating without project_id, or with no calendar available, answers a { "status": "...", "error": true } object in body. When the company's automations are paused, body is { "ok": true } and nothing is written.

Response shape: wrapped (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
start_date
required
string

New start. A string with a UTC offset is an absolute instant; one without is wall-clock time in time_zone, or UTC when none is given.

time_zone
string

ProLine time zone value (central, mountain, pacific, eastern, hawaii, arizona, atlantic, ...), a legacy option key such as central_standard_time, or an IANA name, for a start_date without offset.

event_id
string

Event to update; a legacy id is also accepted. Cancelled events do not match.

project_id
string

Project for a new event; a legacy id is also accepted. Required when creating.

event_type
string

Event type id (see /v1/list/event_types); sets the duration.

assignee
string

Team member id.

external_id
string

Your own id for the event, stored on it.

external_reschedule_link
string

A URL stored on the event for rescheduling it in your system.

skip_external_create
string

true, 1, yes or on: exclude the event from external calendar sync. The event is still created.

Responses

Request samples

Content type
application/json
{
  • "project_id": "p12d8f6h4tq0nb2v5k9xm3wr7se1c4ya",
  • "start_date": "2026-10-15T14:00:00",
  • "time_zone": "central",
  • "event_type": "et4c8h2k6sq9nb3v1d7xm5wr0te4a8yc",
  • "assignee": "j97b4d2f8kq1nc5v7h3xm6tw9se0a2rz",
  • "external_id": "cal-88213"
}

Response samples

Content type
application/json
Example
{
  • "isBase64Encoded": false,
  • "statusCode": 200,
  • "statusDescription": "200 OK",
  • "headers": {
    },
  • "body": {
    }
}

Cancel an event

Cancels the event named by event_id. The event is marked cancelled, not deleted; /v1/find/event still returns it by event_id or external_id, with cancelled: true. Cancelling an already cancelled event runs the cancellation again and answers success. An event that came from an external calendar cannot be cancelled here; the call fails inside body.

A missing or unknown event_id answers { "status": "No existing event found.", "error": true } in body. When the company's automations are paused, body is { "ok": true } and nothing is written.

Response shape: wrapped (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
event_id
required
string (ProLineId)

A ProLine record id. Opaque; in requests, a legacy id for the same record is also accepted.

Responses

Request samples

Content type
application/json
{
  • "event_id": "ev9f1j5m8xq3nb6v2d0km4wr7te1c9zd"
}

Response samples

Content type
application/json
Example
{
  • "isBase64Encoded": false,
  • "statusCode": 200,
  • "statusDescription": "200 OK",
  • "headers": {
    },
  • "body": {
    }
}

Find an event

Looks up one event and returns the first match. The keys are tried in this order:

  1. event_id: exact lookup; a cancelled event is returned, with cancelled: true.
  2. external_id: exact lookup; a cancelled event is returned.
  3. project_id: the live event on that project that starts latest within the window: the day of start_date when given, otherwise any time up to 365 days from now, past events included. event_type and assignee narrow the search.
  4. start_date alone: the live event on that day that starts latest, with the same filters, and only for days from today on.

Exact lookups ignore the filters. Date searches skip cancelled events. start_date on the two date searches is read as a plain date; the day window is taken in the server's clock, so an event near midnight may fall on the neighbouring day.

body is an array with one event, or an empty array when nothing matched (there is no not-found error). A project_id, event_type or assignee that does not resolve answers [].

Response shape: wrapped (see Overview → Response shapes).

To look up many events in one call, see /v1/find/events.

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
event_id
string (ProLineId)

A ProLine record id. Opaque; in requests, a legacy id for the same record is also accepted.

external_id
string

The external_id stored on the event.

project_id
string

Project id; a legacy id is also accepted.

start_date
string

A date (YYYY-MM-DD, or a full date-time) selecting the day to search.

event_type
string

Event type id. Filter for the date searches.

assignee
string

Team member id. Filter for the date searches.

Responses

Request samples

Content type
application/json
{
  • "project_id": "p12d8f6h4tq0nb2v5k9xm3wr7se1c4ya",
  • "start_date": "2026-10-15"
}

Response samples

Content type
application/json
Example
{
  • "isBase64Encoded": false,
  • "statusCode": 200,
  • "statusDescription": "200 OK",
  • "headers": {
    },
  • "body": [
    ]
}

Find events in bulk

Looks up as many as 100 events in one call. Send exactly one of project_ids, event_ids or external_ids, a list of 1 to 100 keys.

results holds one entry per key, in the order sent; a key sent twice is answered twice. Each entry's event is the object /v1/find/event returns in body[0] for that key sent alone (with the same filters), or null where that endpoint would answer [].

  • event_ids and external_ids are exact lookups. A cancelled event is returned, with cancelled: true.
  • project_ids returns, for each project, the live event on it that starts latest within the window: the 24 hours from start_date when it is sent (a YYYY-MM-DD date is read as midnight UTC, so that is the UTC day), otherwise any time up to 365 days from now, past events included. Cancelled events are skipped.

start_date, event_type, assignee and calendar narrow the project_ids search only; the exact lookups ignore them. An event_type, assignee or calendar that does not match a record in the company answers null for every project. start_date must parse as a date (YYYY-MM-DD or an ISO 8601 date-time) whichever list you send, or the call is refused with 400.

The 5-second rate limit per company key applies to the call, not to each key in it.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
required
One of
project_ids
required
Array of strings [ 1 .. 100 ] items [ items [ 1 .. 256 ] characters ]

Project ids (a legacy id is also accepted), each searched as project_id on /v1/find/event.

event_ids
Array of strings [ 1 .. 100 ] items [ items [ 1 .. 256 ] characters ]

Event ids, each looked up as event_id on /v1/find/event.

external_ids
Array of strings [ 1 .. 100 ] items [ items [ 1 .. 256 ] characters ]

The external_id values stored on the events, each looked up as external_id on /v1/find/event.

start_date
string [ 1 .. 256 ] characters

A date (YYYY-MM-DD) or ISO 8601 date-time. Narrows the project_ids search to the 24 hours from this time.

event_type
string [ 1 .. 256 ] characters

Event type id. Filter for the project_ids search.

assignee
string [ 1 .. 256 ] characters

Team member id. Filter for the project_ids search.

calendar
string [ 1 .. 256 ] characters

Calendar id. Filter for the project_ids search; /v1/find/event has no such filter.

Responses

Request samples

Content type
application/json
{
  • "project_ids": [
    ],
  • "start_date": "2026-10-15"
}

Response samples

Content type
application/json
{
  • "results": [
    ]
}

List calendar events

Finds company events without requiring a project ID, including historical events. Results are ordered by event start time, oldest first. All filters combine with AND. Start bounds filter the event's scheduled start time, not when the record was created, and include equality. Deleted events are always excluded; cancelled events are excluded unless requested.

This endpoint uses cursor pagination. limit bounds the number of source events checked in each call, before optional filters. A response can have fewer matching results, including an empty results array, while has_more is true. Always continue with next_cursor until has_more is false. Keep all filters unchanged between pages. No total count is returned, and concurrent edits are not a snapshot.

Related IDs are native ProLine IDs. An unset link is null; a stored ID can remain after its record is deleted, with its name null. Existing project, calendar and event-type records belonging to another company are suppressed. The stored assignee ID remains even if the user was deleted or moved companies; name and email are returned only when safely attributable to this company. The assignee is not necessarily the booker or actual call host. Guest emails are the stored event participants and may include both internal staff and external guests.

An empty body or {} lists events without filters. Null is accepted only for cursor; unknown keys, wrong types and blank text filters are refused. This endpoint uses start_after/start_before, not the creation/update date filters on the other list endpoints. An unknown or unavailable related-record ID returns no matches, except a native assignee ID can still match the company's historical events after that user leaves or is deleted.

Both PARTNER_KEY and COMPANY_KEY are required. An active partner key is always required and the company's API access gate applies. Paused automations do not block this read. Rate limit: one request per five seconds per company and path.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
start_after
string <date-time>

Event starts at or after this instant, inclusive. Full ISO datetime with seconds and timezone; date-only values are refused.

start_before
string <date-time>

Event starts at or before this instant, inclusive. Same format as start_after; must not precede it.

title_contains
string [ 1 .. 500 ] characters

Case-insensitive literal substring of the title. Surrounding whitespace is trimmed. Blank strings are refused; no regex or fuzzy matching.

assignee
string [ 1 .. 256 ] characters

Native ProLine or legacy user ID. A native ID matches stored historical assignments even after the user moves companies or is deleted; a legacy ID must still resolve safely within this company. Surrounding whitespace is trimmed.

project_id
string [ 1 .. 256 ] characters

Optional native ProLine or legacy project ID. Omit to include events with or without projects. Surrounding whitespace is trimmed.

event_type
string [ 1 .. 256 ] characters

Native ProLine or legacy event type ID. Surrounding whitespace is trimmed.

calendar
string [ 1 .. 256 ] characters

Native ProLine or legacy calendar ID. Surrounding whitespace is trimmed.

guest_email
string <email> [ 1 .. 320 ] characters

Trimmed and lowercased exact match against stored event participant emails. Can match internal staff as well as customers.

include_cancelled
boolean
Default: false
cursor
string or null [ 1 .. 16384 ] characters

Opaque next_cursor returned by the previous call. Omit or use null for the first page. Keep filters unchanged.

limit
integer [ 1 .. 100 ]
Default: 50

Maximum source events checked per call before optional filters, so results may be smaller or empty. Values outside 1–100 are refused.

Responses

Request samples

Content type
application/json
{
  • "start_after": "2026-10-28T14:30:00Z",
  • "start_before": "2026-10-28T15:30:00Z",
  • "title_contains": "ProLine Demo",
  • "limit": 50
}

Response samples

Content type
application/json
{
  • "results": [ ],
  • "next_cursor": "opaque-continuation-token",
  • "has_more": true,
  • "limit": 50
}

List event types

Returns every event type in the company, the default type first and the rest by name A to Z. There is no paging and no envelope. name and label carry the same value. The id is what event endpoints take as the event type.

Optional created_after, created_before and updated_after filters are inclusive and combined with AND. Missing or null filters impose no bound. The update filter uses existing record timestamps; deletions and changes to related records are not a complete change feed.

Supports at most 1,000 source rows per collection; larger sources return HTTP 400 with LOOKUP_TOO_LARGE, even when date filters would match fewer rows. No results are silently truncated.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
created_after
string or null <date-time>

Created at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Combined with the other date filters using AND.

created_before
string or null <date-time>

Created at or before this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Must be at or after created_after.

updated_after
string or null <date-time>

Updated at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone, for example 2026-10-01T00:00:00Z. Null means no bound. Combined with created_after and created_before using AND; it may be later than created_before.

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
[
  • {
    },
  • {
    }
]

Activities

List activities

Pages through the activity feed of one project, contact or organization, newest first, optionally restricted to a set of activity types. Exactly one of project_id, contact_id or org_id is required. A parent that does not exist in the company gives an empty page with total: 0, not an error. Filter by creation date with created_after / created_before (both inclusive).

Each call has a database-query budget and may read at most about 12,000 records or 10 MB. Whichever limit is reached first applies. When a page cannot be served within these limits, or the offset is past 10,000 rows, the call answers 400 with a { "status": "error", "message": "..." } body. Project and organization feeds read only the selected parent's links. Without updated_after, a creation window reads only that window's links, however long the history. total is exact up to 4,000 matching rows (1,000 for a project or organization feed without updated_after) and a lower bound past that; has_more is authoritative.

Call rows omit the transcript segments; /v1/find/activity returns them. Ids on activities of migrated companies may be legacy ids (see Overview → Identifiers).

Optional created_after, created_before and updated_after filters are inclusive and combined with AND. Missing or null filters impose no bound. The update filter uses existing record timestamps; deletions and changes to related records are not a complete change feed. With updated_after, results are ordered by update time, newest first. Without it, existing creation-time ordering is unchanged. Activities without an update timestamp do not match updated_after. Existing historical imports may have backdated timestamps; future imports record the actual write time separately from the historical activity date.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
required
project_id
string (ProLineId)

A ProLine record id. Opaque; in requests, a legacy id for the same record is also accepted.

contact_id
string (ProLineId)

A ProLine record id. Opaque; in requests, a legacy id for the same record is also accepted.

org_id
string (ProLineId)

A ProLine record id. Opaque; in requests, a legacy id for the same record is also accepted.

type
Array of strings

Activity type names to include, for example call_created, note_created, email_sent, message_received, stage_change, quote_signed. Omitted or empty means every type. A name that is not an activity type is refused with 400 (Invalid activity type).

page
integer >= 1
Default: 1

1-based page number.

limit
integer [ 1 .. 100 ]
Default: 100

Rows per page. A value above 100 is clamped to 100.

created_after
string or null <date-time>

Only activities created at or after this instant. A full ISO 8601 datetime with timezone (for example 2026-09-01T00:00:00Z); a date alone is refused with 400. null means no bound.

created_before
string or null <date-time>

Only activities created at or before this instant. Same format as created_after; must not be earlier than it.

updated_after
string or null <date-time>

Updated at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone, for example 2026-10-01T00:00:00Z. Null means no bound. Combined with created_after and created_before using AND; it may be later than created_before.

Responses

Request samples

Content type
application/json
{
  • "project_id": "k57abc1n0cq8vb3d5t6hm4ws2e7a9zq1",
  • "type": [
    ],
  • "limit": 20
}

Response samples

Content type
application/json
{
  • "page": 1,
  • "limit": 20,
  • "total": 7,
  • "has_more": false,
  • "results": [
    ]
}

Find an activity

Returns one activity by id, in the same shape as a /v1/list/activities row. For a call activity the transcript segments are included under call.transcript. The id may be a ProLine id or a legacy id.

When no activity with that id is visible to the company the call still answers 200, with an empty array [] as the body, not 404. An activity whose detail is larger than the response limit answers 400.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
required
activity_id
required
string non-empty

The activity's id (ProLine or legacy). Surrounding whitespace is trimmed.

Responses

Request samples

Content type
application/json
{
  • "activity_id": "1718301234567x123456789012345678"
}

Response samples

Content type
application/json
Example
{
  • "activity_id": "1718301234567x123456789012345678",
  • "type": "call_created",
  • "created_at": "2026-09-11T14:02:00.000Z",
  • "title": "Outbound call",
  • "description": null,
  • "notes": null,
  • "project_id": "1718300000000x111111111111111111",
  • "project_ids": [
    ],
  • "org_ids": [ ],
  • "contact_id": "1718300000000x222222222222222222",
  • "created_by": {
    },
  • "call": {
    }
}

Correct an existing communication activity

Corrects the date, notes, project or contact association of an existing activity in the authenticated company. It does not create an activity. Activities may have been created by a partner, a person, or another integration; eligibility depends on the stored activity type.

Allowed types: call, call_created, message, message_sent, message_received, email, email_sent, email_received, note, and note_created. All other types are refused, including signed quotes, stage changes, payments, alerts, and email_opened. The type cannot change.

Supply activity_id and at least one editable field. Omitted fields stay unchanged. Unknown keys, null, invalid types, blank IDs and invalid dates are refused. All supplied IDs must resolve within the authenticated company. An invalid field or association rejects the whole update.

For a note, notes replaces the main timeline text, which Find Activity returns in title; the separate description and returned notes stay unchanged. For a call it updates the call notes and activity description. For a message or email it updates a separate annotation returned in notes. The original description and sent or received content stay unchanged, including imported bodies stored only in the description.

Date corrections change the activity's timeline date, ordering and date filtering, while preserving original provider timestamps and the creator. Association corrections affect this activity's CRM links; they do not change communication participants or email-thread ownership.

Both PARTNER_KEY and COMPANY_KEY are required. An active partner key is always required for this endpoint, and the company's API access gate applies. Paused automations return 409 without an update. Rate limit: one request per five seconds per company and path.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
required
>= 2 properties
activity_id
required
string [ 1 .. 256 ] characters

Existing activity ID, native ProLine or legacy. Surrounding whitespace is trimmed; blank IDs are refused.

notes
string <= 100000 characters

Main timeline text for a note; call notes for a call; an activity annotation for a message or email. An empty string clears call notes or annotations. For note and note_created, empty or whitespace-only text is refused.

activity_date
string <date-time>

Valid full ISO timestamp with seconds and a timezone (Z or an explicit offset). A date-only value is refused.

project_id
string [ 1 .. 256 ] characters

Native ProLine or legacy project ID in this company. Adds the association when none exists or replaces the sole current project. When several projects are linked, a target already among them leaves those links unchanged; any other target returns 409. A conflict with an existing claim's project also returns 409. Cannot clear the association.

contact_id
string [ 1 .. 256 ] characters

Native ProLine or legacy contact ID in this company. Replaces the selected activity's contact association. Cannot clear the association.

Responses

Request samples

Content type
application/json
{
  • "activity_id": "1758012345678x111222333444555666",
  • "notes": "Corrected: this was actually a callback, not the initial call.",
  • "activity_date": "2026-08-13T15:30:00.000Z",
  • "project_id": "1750887134929x854390172933511600",
  • "contact_id": "1750800842162x68417017012148480"
}

Response samples

Content type
application/json
{
  • "status": "Activity updated.",
  • "activity_id": "1758012345678x111222333444555666",
  • "error": false
}

Create an alert activity

Creates an "alert" activity, titled alert_text, on a contact and/or a project. At least one of contact_id or project_id is required. One activity is created per project involved: the project you name plus the project linked to the contact, so a contact with a linked project yields two. A contact with no project gets a single contact-only activity. Nothing is deduplicated.

The answer's activity_created is the number of activities created, as a string; it is not an id (the call and message endpoints return an id under the same key).

Response shape: wrapped (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
alert_text
required
string

Activity title. Required by the backend.

alert_extended
string

Activity description.

contact_id
string

Contact to alert on, by ProLine or legacy id. One of contact_id or project_id is required.

project_id
string

Project to alert on, by ProLine or legacy id. One of contact_id or project_id is required.

Responses

Request samples

Content type
application/json
{
  • "contact_id": "j97f2x1n0cq8vb3d5t6hm4ws2e7a9zq1",
  • "alert_text": "Insurance adjuster scheduled",
  • "alert_extended": "Adjuster visit Tuesday 10am"
}

Response samples

Content type
application/json
Example
{
  • "isBase64Encoded": false,
  • "statusCode": 200,
  • "statusDescription": "200 OK",
  • "headers": {
    },
  • "body": {
    }
}

Create a call activity

Logs a phone call with a contact: a call record is stored and a call activity is created from it. contact and type are required by the backend. The call is outbound when type is "outgoing" and inbound for any other value; a voicemail URL marks it as a voicemail.

Dedupe is by external_id: when a call with that external id already exists, nothing is created and body is { "error": "A call already exists with that external ID." }. An unknown contact answers the same way with "No contact could be found for that ID." Without external_id, repeated sends log the call again.

Response shape: wrapped (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
contact
required
string

The contact, by ProLine or legacy id. Required by the backend.

type
required
string

"outgoing" for an outbound call; any other value is logged as inbound. Required by the backend.

user
string

The team member on the call, by ProLine or legacy id. An unknown user is ignored.

duration
string

Call length in seconds, as a numeric string.

recording
string <uri>

URL of the call recording.

voicemail
string <uri>

URL of the voicemail. When present the call is logged as a voicemail.

external_id
string

Your id for the call. Dedupe key; a repeat is refused.

call_note
string

Note on the call.

Responses

Request samples

Content type
application/json
{
  • "contact": "j97f2x1n0cq8vb3d5t6hm4ws2e7a9zq1",
  • "type": "incoming",
  • "duration": "312",
  • "external_id": "ringcentral-88211",
  • "call_note": "Asked for a Saturday inspection"
}

Response samples

Content type
application/json
Example
{
  • "isBase64Encoded": false,
  • "statusCode": 200,
  • "statusDescription": "200 OK",
  • "headers": {
    },
  • "body": {
    }
}

Create a message activity

Logs a text message exchanged with a contact: a message record is stored, attached to the contact's latest project, and a message-sent or message-received activity is created from it. contact, type and message_body are required by the backend. The message is outbound when type is "outgoing" and inbound for any other value.

Dedupe is by external_id: when a message with that external id already exists, nothing is created and body is { "error": "A message already exists with that external ID." }. An unknown contact answers the same way with "No contact could be found for that ID." Without external_id, repeated sends log the message again.

Response shape: wrapped (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
contact
required
string

The contact, by ProLine or legacy id. Required by the backend.

type
required
string

"outgoing" for a message the company sent; any other value is logged as received. Required by the backend.

message_body
required
string

The message text. Required by the backend.

message_note
string

Note on the message.

user
string

The team member who sent or received it, by ProLine or legacy id.

external_id
string

Your id for the message. Dedupe key; a repeat is refused.

Responses

Request samples

Content type
application/json
{
  • "contact": "j97f2x1n0cq8vb3d5t6hm4ws2e7a9zq1",
  • "type": "outgoing",
  • "message_body": "Your crew arrives Thursday at 8am.",
  • "external_id": "twilio-SM9f3a1c"
}

Response samples

Content type
application/json
Example
{
  • "isBase64Encoded": false,
  • "statusCode": 200,
  • "statusDescription": "200 OK",
  • "headers": {
    },
  • "body": {
    }
}

Files

List project files

Pages through the files of one project, newest first, with each file's download URL, folder and photo details. project_id is required. Restrict the listing to one folder with folder_id (null for the files in no folder), to a media type with mime_type_prefix (for example image/), and to a creation window with created_after / created_before (both inclusive). Archived folders and the files in them are left out. A project or folder that does not exist in the company gives an empty page, not an error.

A project with more than 2,000 folders cannot be listed whole: the call answers 400 and you pass folder_id to list one folder at a time. Pages are limited to 100 rows and to an offset of 10,000 rows; beyond that, or when a page would read more than the per-call budget, the call answers 400 with a { "status": "error", "message": "..." } body. total is exact up to 4,000 matching rows and a lower bound past that; has_more is authoritative.

Optional created_after, created_before and updated_after filters are inclusive and combined with AND. Missing or null filters impose no bound. The update filter uses existing record timestamps; deletions and changes to related records are not a complete change feed. With updated_after, results are ordered by update time, newest first. Without it, existing creation-time ordering is unchanged.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
required
project_id
required
string (ProLineId)

A ProLine record id. Opaque; in requests, a legacy id for the same record is also accepted.

folder_id
string or null non-empty

Only files directly in this folder. null means files in no folder. Omitted means every folder.

mime_type_prefix
string or null non-empty

Only files whose media type starts with this prefix, for example image/ or application/pdf. null is the same as omitting it. A blank string is refused with 400.

page
integer >= 1
Default: 1

1-based page number.

limit
integer [ 1 .. 100 ]
Default: 100

Rows per page. A value above 100 is clamped to 100.

created_after
string or null <date-time>

Only files created at or after this instant. A full ISO 8601 datetime with timezone (for example 2026-09-01T00:00:00Z); a date alone is refused with 400. null means no bound.

created_before
string or null <date-time>

Only files created at or before this instant. Same format as created_after; must not be earlier than it.

updated_after
string or null <date-time>

Updated at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone, for example 2026-10-01T00:00:00Z. Null means no bound. Combined with created_after and created_before using AND; it may be later than created_before.

Responses

Request samples

Content type
application/json
{
  • "project_id": "k57abc1n0cq8vb3d5t6hm4ws2e7a9zq1",
  • "folder_id": null,
  • "mime_type_prefix": "image/",
  • "limit": 50
}

Response samples

Content type
application/json
{}

List project folders

Pages through the folders of one project. project_id is required. With parent_folder_id the direct children of that folder are returned (null for the top level); without it every live folder is returned in tree order, each folder followed by its descendants. Rows are in tree order, not newest first. Archived folders are left out. A project or folder that does not exist in the company gives an empty page, not an error.

Date filters apply after resolving the live hierarchy, so an unchanged parent does not hide a changed child. A project with more than 2,000 folders cannot be listed whole: the call answers 400 and you pass parent_folder_id to list one level at a time. Pages are limited to 100 rows and to an offset of 10,000 rows. total is exact up to 4,000 matching rows and a lower bound past that; has_more is authoritative.

Optional created_after, created_before and updated_after filters are inclusive and combined with AND. Missing or null filters impose no bound. The update filter uses existing record timestamps; deletions and changes to related records are not a complete change feed.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
required
project_id
required
string (ProLineId)

A ProLine record id. Opaque; in requests, a legacy id for the same record is also accepted.

parent_folder_id
string or null non-empty

Only the direct children of this folder. null means the top-level folders. Omitted means every folder, in tree order. A blank string is refused with 400.

page
integer >= 1
Default: 1

1-based page number.

limit
integer [ 1 .. 100 ]
Default: 100

Rows per page. A value above 100 is clamped to 100.

created_after
string or null <date-time>

Created at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Combined with the other date filters using AND.

created_before
string or null <date-time>

Created at or before this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Must be at or after created_after.

updated_after
string or null <date-time>

Updated at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone, for example 2026-10-01T00:00:00Z. Null means no bound. Combined with created_after and created_before using AND; it may be later than created_before.

Responses

Request samples

Content type
application/json
{
  • "project_id": "k57abc1n0cq8vb3d5t6hm4ws2e7a9zq1",
  • "parent_folder_id": null
}

Response samples

Content type
application/json
{
  • "page": 1,
  • "limit": 100,
  • "total": 3,
  • "has_more": false,
  • "results": [
    ]
}

Attach a file to a project

Downloads the file at file_url and attaches it to the project named by project_id. It is the same storage path as /v1/import/file, but the project is given by id only; use the import endpoint to target a project by external id or through a contact. Nothing is deduplicated: sending the same URL twice stores two files.

project_id and file_url are required by the backend. The URL is probed before download; the file may be at most 50,000,000 bytes (50 MB). When the probe fails or reports a larger size, body is an error object with statusCode: 400 and a message beginning "Temporary error connecting to CloudFlare Functions - Get File Size", rather than the usual outcome shape. The URL must be publicly reachable.

This endpoint needs the import permission on your partner key, as the /v1/import/* paths do, not a general one.

Values are sent as strings; arrays are flattened to comma-separated text.

Response shape: wrapped (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
project_id
required
string

Target project, by ProLine or legacy id. Required by the backend.

file_url
required
string <uri>

Public URL to download. Required by the backend.

file_name
string

Name to store the file under, truncated to 100 characters. Defaults to the file name in the URL.

Responses

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
Example
{
  • "isBase64Encoded": false,
  • "statusCode": 200,
  • "statusDescription": "200 OK",
  • "headers": {
    },
  • "body": {
    }
}

Import

Import a project

Creates one project from an external system, and its main contact when no existing contact matches. The call is idempotent on project_external_id: when a project with that external id (or the project named by proline_id) already exists, nothing is created and the answer carries duplicate: true with the existing ids. The duplicate message always names the external id, even when proline_id matched.

The contact is found by contact_id, then contact_external_id, then contact_email, then contact_phone. When none matches, a contact is created from the contact_* fields; at least one of first name, last name, email or phone must be supplied, or the import fails. Lookup values such as stage, lead_source and assignee take a ProLine id, a legacy id or the record's name; an unresolved value is skipped, except stage, which falls back to the first stage of the company's project pipeline.

Side effects: a created contact gets its default folders, field-change activities and the contact-created webhook; the project is queued for accounting sync, address geocoding and stage workflows.

Response shape: wrapped (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
project_external_id
string

Your id for the project. Idempotency key; a repeat is skipped with duplicate: true.

proline_id
string

An existing project's ProLine or legacy id. When found, the call is skipped as a duplicate.

contact_id
string

Existing contact to attach, by ProLine or legacy id.

contact_external_id
string

Existing contact to attach, by the external id given at contact import.

contact_email
string

Finds an existing contact by email; otherwise the email of the created contact.

contact_phone
string

Finds an existing contact by phone; otherwise the phone of the created contact.

contact_first_name
string

First name of the contact to create.

contact_last_name
string

Last name of the contact to create.

contact_type
string

Contact type, by ProLine id, legacy id or name. Unresolved values are skipped.

lead_source
string

Lead source, by ProLine id, legacy id or name. Unresolved values are skipped.

string or Array of strings

Tags for the contact, as an array or a comma-separated string; trimmed and deduplicated. Unknown tags are skipped, not created.

project_name
string

Project name. Defaults to a name built from the contact.

project_number
string

Project number. When given it is used as-is and the company's counter moves past it; otherwise the next number is allocated.

stage
string

Project stage, by ProLine id, legacy id or name. Unresolved values fall back to the company's first project stage; a company with no project stage fails the import.

location
string

Location, by ProLine id, legacy id or name. Unresolved values are skipped.

area
string

Area, by ProLine id, legacy id or name. Unresolved values are skipped.

assignee
string

Assigned team member, by ProLine id, legacy id or name. Unresolved values are skipped.

category
string

Project category, by ProLine id, legacy id or name. Unresolved values are skipped.

type
string

Project type, by ProLine id, legacy id or name. Unresolved values are skipped.

string or Array of strings

Services, as an array or a comma-separated string of ids, legacy ids or names.

string or Array of strings

Project tags, as an array or a comma-separated string. Unknown tags are skipped, not created.

address1
string
address2
string
city
string
state
string
zip
string
notes
string

Project notes. When cost is sent, "Imported cost: …" is appended.

custom_field_1
string

Written to the text custom field that holds project field number 1 (see "Custom fields" in the overview). Skipped when no live field holds the number, including when its definition was deleted.

custom_field_2
string

As custom_field_1, field number 2.

custom_field_3
string

As custom_field_1, field number 3.

custom_field_4
string

As custom_field_1, field number 4.

custom_field_5
string

As custom_field_1, field number 5.

custom_field_6
string

As custom_field_1, field number 6.

custom_field_7
string

As custom_field_1, field number 7.

revenue
string

Expected revenue as a numeric string. Non-numeric values are skipped.

cost
string

Not stored as a budget; appended to notes as "Imported cost: …".

lead_date
string

Date the project became a lead. ISO 8601 or MM/DD/YYYY; a value without an offset is read in the company's time zone. Unparseable values are skipped.

inspection_date
string

As lead_date.

open_date
string

As lead_date.

won_date
string

As lead_date.

completed_date
string

As lead_date.

closed_date
string

As lead_date.

disqualified_date
string

As lead_date.

lost_date
string

As lead_date.

Responses

Request samples

Content type
application/json
{
  • "project_external_id": "crm-7781",
  • "contact_first_name": "Dana",
  • "contact_last_name": "Whitfield",
  • "contact_email": "[email protected]",
  • "contact_phone": "(555) 010-2244",
  • "project_name": "Whitfield re-roof",
  • "stage": "New Lead",
  • "lead_source": "Angi",
  • "address1": "14 Juniper Ct",
  • "city": "Boise",
  • "state": "ID",
  • "zip": "83702",
  • "services": [
    ],
  • "revenue": "18500",
  • "lead_date": "2026-09-30"
}

Response samples

Content type
application/json
Example
{
  • "isBase64Encoded": false,
  • "statusCode": 200,
  • "statusDescription": "200 OK",
  • "headers": {
    },
  • "body": {
    }
}

Import a contact

Creates one contact from an external system. The call is idempotent on external_id only: when a contact with that external id already exists, nothing is created and the answer carries duplicate: true with the existing ids. There is no matching by email or phone, so repeated sends without external_id create duplicate contacts.

At least one of first_name, last_name, email or phone is required, or the import fails. The phone is normalised to E.164 (digits only as a fallback) and dropped when too short. Lookup values (assigned, contact_type, lead_source, organization, contact_tags) take a ProLine id, a legacy id or the record's name; an unresolved value is skipped, never created.

Side effects: the contact gets its default folders, field-change activities and the contact-created webhook.

Response shape: wrapped (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
external_id
string

Your id for the contact. Idempotency key; a repeat is skipped with duplicate: true.

first_name
string
last_name
string
email
string
phone
string

Normalised to E.164; dropped when too short to be a phone number.

organization
string

Organization, by ProLine id, legacy id or name. Unresolved values are skipped.

address1
string
address2
string
city
string
state
string
zip
string
assigned
string

Assigned team member, by ProLine id, legacy id or name. Unresolved values are skipped.

contact_type
string

Contact type, by ProLine id, legacy id or name. Unresolved values are skipped.

lead_source
string

Lead source, by ProLine id, legacy id or name. Unresolved values are skipped.

string or Array of strings

Tags, as an array or a comma-separated string; trimmed and deduplicated. Unknown tags are skipped, not created.

notes
string
custom_field_1
string

Written to the text custom field that holds contact field number 1 (see "Custom fields" in the overview). Skipped when no live field holds the number, including when its definition was deleted.

custom_field_2
string

As custom_field_1, field number 2.

custom_field_3
string

As custom_field_1, field number 3.

Responses

Request samples

Content type
application/json
{
  • "external_id": "hs-20931",
  • "first_name": "Marcus",
  • "last_name": "Oyelaran",
  • "email": "[email protected]",
  • "phone": "5550198877",
  • "contact_type": "Homeowner",
  • "lead_source": "Website",
  • "contact_tags": "referral,spring-promo",
  • "city": "Tulsa",
  • "state": "OK"
}

Response samples

Content type
application/json
Example
{
  • "isBase64Encoded": false,
  • "statusCode": 200,
  • "statusDescription": "200 OK",
  • "headers": {
    },
  • "body": {
    }
}

Import an activity

Logs a historical activity (a call, message, note or email) against a contact and/or a project. One activity record is created; no call or message record is, unlike /v1/activity/create_call and /v1/activity/create_message. Nothing is deduplicated: sending the same activity twice logs it twice.

activity_type and date must be present or the request is refused with 400 before it reaches the backend. At least one of contact_id, contact_external_id, project_id or project_external_id must resolve, or the import fails. The activity's title is subject, else note, else "Imported "; its description is body, else note when a subject was given.

Values are sent as strings; arrays are flattened to comma-separated text.

Response shape: wrapped (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
required
activity_type
required
string

Case-insensitive. call, message, text or sms (both logged as a message), note or email. Any other value is logged as a note; the value you sent is kept on the activity.

date
required
string

When the activity happened. ISO 8601 or MM/DD/YYYY; a value without an offset is read in the company's time zone. An unparseable value falls back to now.

subject
string

Activity title.

body
string

Activity description.

note
string

Fallback for the title when subject is absent, or for the description when subject is present and body is absent.

user
string

The team member who performed the activity, by ProLine id, legacy id or name.

voicemail
string

Voicemail URL. Stored on the activity only; no call record is created.

recording
string

Recording URL. Stored on the activity only.

duration
string

Duration in seconds, as a string. Stored on the activity only.

contact_id
string

Contact to log against, by ProLine or legacy id.

contact_external_id
string

Contact to log against, by the external id given at contact import.

project_id
string

Project to log against, by ProLine or legacy id.

project_external_id
string

Project to log against, by the external id given at project import.

Responses

Request samples

Content type
application/json
{
  • "activity_type": "call",
  • "date": "2026-09-28T15:30:00-06:00",
  • "contact_external_id": "hs-20931",
  • "subject": "Follow-up call",
  • "body": "Discussed shingle colors",
  • "duration": "420",
}

Response samples

Content type
application/json
Example
{
  • "isBase64Encoded": false,
  • "statusCode": 200,
  • "statusDescription": "200 OK",
  • "headers": {
    },
  • "body": {
    }
}

Import a project file

Downloads the file at file_url and attaches it to a project. The project is found by project_id or project_external_id; failing those, by contact_id or contact_external_id, in which case the contact's newest project is used. A contact with no project fails the import.

file_name and file_url must be present, along with at least one of the four reference keys, or the request is refused with 400 before it reaches the backend. The URL must be publicly reachable. The file may be at most 50,000,000 bytes (50 MB); larger files fail the import. Nothing is deduplicated: sending the same URL twice stores two files.

Values are sent as strings; arrays are flattened to comma-separated text.

Response shape: wrapped (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
required
file_name
required
string

Name to store the file under, truncated to 100 characters. The key must be present; a blank value falls back to the file name in the URL.

file_url
required
string <uri>

Public URL to download. A blank value fails the import.

project_id
string

Target project, by ProLine or legacy id.

project_external_id
string

Target project, by the external id given at project import.

contact_id
string

Contact whose newest project is the target, by ProLine or legacy id. Used only when no project key is given.

contact_external_id
string

Contact whose newest project is the target, by the external id given at contact import. Used only when no project key is given.

Responses

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
Example
{
  • "isBase64Encoded": false,
  • "statusCode": 200,
  • "statusDescription": "200 OK",
  • "headers": {
    },
  • "body": {
    }
}

Import taxonomy values

Creates taxonomy values (contact types, tags, lead sources, project types, categories, services and areas) by name, so that later imports can refer to them by name. Each key takes an array or a comma-separated string of names. A name that already exists in the company (or matches a legacy id) is left alone and listed under ignored; the others are created and listed under created. {} is accepted and answers with empty created and ignored objects.

Response shape: wrapped (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
string or Array of strings (NameList)
string or Array of strings (NameList)
string or Array of strings (NameList)
string or Array of strings (NameList)
string or Array of strings (NameList)
string or Array of strings (NameList)
string or Array of strings (NameList)
string or Array of strings (NameList)

Responses

Request samples

Content type
application/json
{
  • "lead_sources": [
    ],
  • "project_services": "Roof Replacement, Gutters"
}

Response samples

Content type
application/json
{
  • "isBase64Encoded": false,
  • "statusCode": 200,
  • "statusDescription": "200 OK",
  • "headers": {
    },
  • "body": {
    }
}

General

List organization stages

Returns active stages in the company's organization pipelines. Archived stages are excluded. Each id identifies a stage; pipeline_id identifies its organization pipeline.

Returns a direct array, without pagination or an envelope. All IDs are native ProLine IDs. Optional strings are null when unset.

Requires both keys and company API access. An active partner key is always required; paused automations do not block this read. Rate limit: one call per second per company and path. This endpoint does not change data.

Optional created_after, created_before and updated_after filters are inclusive and combined with AND. Missing or null filters impose no bound. The update filter uses existing record timestamps; deletions and changes to related records are not a complete change feed. The update filter also considers the stage's company pipeline timestamp for changes to the returned pipeline name.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
created_after
string or null <date-time>

Created at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Combined with the other date filters using AND.

created_before
string or null <date-time>

Created at or before this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Must be at or after created_after.

updated_after
string or null <date-time>

Updated at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone, for example 2026-10-01T00:00:00Z. Null means no bound. Combined with created_after and created_before using AND; it may be later than created_before.

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
[
  • {
    }
]

List organization types

Returns the company's organization pipelines. An organization type in this API is an Org pipeline; each id identifies that pipeline.

Returns a direct array, without pagination or an envelope. All IDs are native ProLine IDs. Optional strings are null when unset.

Requires both keys and company API access. An active partner key is always required; paused automations do not block this read. Rate limit: one call per second per company and path. This endpoint does not change data.

Optional created_after, created_before and updated_after filters are inclusive and combined with AND. Missing or null filters impose no bound. The update filter uses existing record timestamps; deletions and changes to related records are not a complete change feed.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
created_after
string or null <date-time>

Created at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Combined with the other date filters using AND.

created_before
string or null <date-time>

Created at or before this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Must be at or after created_after.

updated_after
string or null <date-time>

Updated at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone, for example 2026-10-01T00:00:00Z. Null means no bound. Combined with created_after and created_before using AND; it may be later than created_before.

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
[
  • {
    }
]

List company locations

Returns the company's locations. Time zones use IANA names, such as America/Chicago. Optional address and time-zone values are null when unset.

Returns a direct array, without pagination or an envelope. All IDs are native ProLine IDs. Optional strings are null when unset.

Requires both keys and company API access. An active partner key is always required; paused automations do not block this read. Rate limit: one call per second per company and path. This endpoint does not change data.

Optional created_after, created_before and updated_after filters are inclusive and combined with AND. Missing or null filters impose no bound. The update filter uses existing record timestamps; deletions and changes to related records are not a complete change feed.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
created_after
string or null <date-time>

Created at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Combined with the other date filters using AND.

created_before
string or null <date-time>

Created at or before this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Must be at or after created_after.

updated_after
string or null <date-time>

Updated at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone, for example 2026-10-01T00:00:00Z. Null means no bound. Combined with created_after and created_before using AND; it may be later than created_before.

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
[
  • {
    }
]

List company users

Returns active company members, including invited members and regular or limited seats. Staff, disabled users, removed members, and members with pending or failed removals are excluded. role is the assigned permission profile's exact name, or null when no valid company profile is available; it is not a numeric access level.

Returns a direct array, without pagination or an envelope. All IDs are native ProLine IDs. Optional strings are null when unset.

Requires both keys and company API access. An active partner key is always required; paused automations do not block this read. Rate limit: one call per second per company and path. This endpoint does not change data.

Optional created_after, created_before and updated_after filters are inclusive and combined with AND. Missing or null filters impose no bound. The update filter uses existing record timestamps; deletions and changes to related records are not a complete change feed. Updates to the user's company permission profile also match the update filter, so changes to the returned role can be discovered.

Response shape: direct (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
created_after
string or null <date-time>

Created at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Combined with the other date filters using AND.

created_before
string or null <date-time>

Created at or before this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Must be at or after created_after.

updated_after
string or null <date-time>

Updated at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone, for example 2026-10-01T00:00:00Z. Null means no bound. Combined with created_after and created_before using AND; it may be later than created_before.

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
[
  • {
    }
]

List numbered custom-field definitions

Describes the company's numbered custom-text-field slots. Supply entity_type as project for slots 1–7, or contact for slots 1–3. Other entity types, including organizations, are unsupported.

Without date filters, returns every slot in numeric order. A live slot has a current field definition and its configured label. A deleted slot retains the label of its deleted definition. An unassigned slot has no definition and a null label. This read never creates fields or assigns slots.

These are the field numbers used by Find, Edit and Import Project/Contact. Find returns the current value as custom_field_N, or an empty string. Edit Project writes project_custom_field_N; Edit Contact and both imports use custom_field_N. Editing an unassigned slot creates a text field named "Custom Field N"; imports skip unassigned slots. Both skip deleted slots. Omitted or blank write values leave existing values unchanged.

Clearing or moving a field's number leaves its previous slot unassigned; a later edit can create a new field for that slot. Deleting a definition that retains its number leaves the slot deleted until that definition is restored or the number is assigned to another field.

Requires both keys and company API access. An active partner key is always required; paused automations do not block this read. Rate limit: one call per second per company and path. When returning a snapshot, conflicting slot configuration returns 409 instead of choosing a definition arbitrarily.

Date filters are inclusive and combined with AND against each company/entity definition, including deleted definitions and definitions no longer assigned to a slot. If any definition matches, results contains the complete seven-project-slot or three-contact-slot snapshot. Otherwise results is empty. With no effective date filters, all slots are always returned. This allows clearing or moving a slot to be detected without returning partial slot mappings. A change to an unnumbered field can also return the snapshot. Hard deletions without a retained definition are not a change feed.

Response shape: direct (see Overview → Response shapes). This endpoint returns an entity_type/results object, without pagination.

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
required
entity_type
required
string
Enum: "project" "contact"

Exact lowercase entity type. Null, other values and omitted values are refused with 400.

created_after
string or null <date-time>

Created at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Combined with the other date filters using AND.

created_before
string or null <date-time>

Created at or before this instant (inclusive). A valid full ISO 8601 datetime with timezone; null means no bound. Must be at or after created_after.

updated_after
string or null <date-time>

Updated at or after this instant (inclusive). A valid full ISO 8601 datetime with timezone, for example 2026-10-01T00:00:00Z. Null means no bound. Combined with created_after and created_before using AND; it may be later than created_before.

Responses

Request samples

Content type
application/json
{
  • "entity_type": "contact"
}

Response samples

Content type
application/json
{
  • "entity_type": "contact",
  • "results": [
    ]
}

Find a team member

Looks up one team member of the company by ProLine phone number, email or display name. The strategies are tried in that order and the first match wins: proline_number is normalised to E.164 and matched against the company's ProLine phone lines; user_email is an exact, case-sensitive match; display_name is matched on the text before its first comma, trimmed and ignoring case.

Administrators of the ProLine platform and limited-access users are never returned. The answer is an array with at most one element; no match, or an empty body, gives [].

Values are sent as strings; arrays are flattened to comma-separated text.

Response shape: wrapped (see Overview → Response shapes).

Authorizations:
(PartnerKeyCompanyKey)
Request Body schema: application/json
optional
proline_number
string

A ProLine phone line assigned to the member, in any common format.

user_email
string

The member's login email, matched exactly (case-sensitive).

display_name
string

The member's display name. Only the text before the first comma is compared, ignoring case and surrounding spaces.

Responses

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
Example
{
  • "isBase64Encoded": false,
  • "statusCode": 200,
  • "statusDescription": "200 OK",
  • "headers": {
    },
  • "body": [
    ]
}