Contracting & Hierarchies API Overview

Before a producer can sell a carrier's product, they have to be contracted for it — approved to sell that product, at agreed commission terms, in specific states. Keeping track of who is contracted for what, and at what rate, is the work this API automates.

Those relationships also form a chain. A producer contracts with an agency, the agency sits below an IMO (Independent Marketing Organization), and the IMO connects to the carrier. Every commission payout, every "ready to sell" check, and every compliance review depends on knowing that chain accurately.

What you can get:

  • Producers — the individuals and firms contracted in your organization
  • Contracts and contract assignments — who is contracted to sell which product, and the status of each
  • Assignment changes — a dated record of every amendment, for reconciliation and audit
  • Carriers, products, and commission levels — your contracting catalog and compensation structure
  • Your distribution hierarchy — every position, with its upline, commission level, states, and status — see Hierarchy Nodes
  • The hierarchy as it looked on any past date — for answering "who was this producer's upline when this commission was earned?"

Common Use Cases

Commissions — determine the upline chain at transaction time by querying the hierarchy with as_of set to the transaction date and walking the upline links. Commission level names and values are inlined on each node, so no second call is needed. Detect changes in real time via hierarchy.producer.changed.

Reconciliation and audit — pull the node list as of a reconciliation date and diff against your local records. Compare two as_of snapshots to identify what changed in a window; there is no date-range filter.

Carriers — synchronize your product catalog so assignments always reflect current offerings, and track amendments over time with updated_since on assignment changes.

Agencies and MGAs — read your account configuration (assigned carriers, products, and commission levels) in three calls, then keep downstream systems current with updated_since polling plus webhook events.

Technology partners — integrate contracting data into agency management systems or producer portals, and build automated compliance checkpoints on assignment status.

How It Works

The customer-facing API is versioned under /v2 and is read-only — every endpoint is a GET. Contracting records are created and maintained in the AgentSync application; your integration consumes them.

Hierarchies are not a separate system layered on top. A hierarchy position is a contract assignment, and the tree is formed by the upline links between assignments. That is why the two share one base URL, one set of credentials, one scope model, and one set of response conventions — and why you need carrier, product, and contract assignment data before hierarchy data means anything.

Responses are purpose-built for integrations:

  • Inlined names — reference data appears as an ...Id plus a ...Name companion (assignmentStatusId / assignmentStatusName), so there are no lookup round trips.
  • Incremental syncupdated_since (RFC3339 UTC) returns only records modified at or after that instant. Supported on producers, contracts, contract assignments, assignment changes, assigned carriers, assigned products, and assigned commission levels.
  • Field conventions — JSON fields are lowerCamelCase; query parameters are lower_snake_case. Timestamps end in At (RFC3339 UTC); dates end in On (yyyy-MM-dd).
  • Account scoping — a resource that doesn't exist or belongs to another customer returns 404, never 403.

Reads require a contracting.* scope; see Authentication for the scope-to-endpoint mapping, Base URLs, and Pagination for the token-pagination contract.

Hierarchy Nodes

GET /v2/organizations/{organizationId}/hierarchies returns your distribution hierarchy as a token-paginated flat list of nodes. Each node is one position, keyed by contractAssignmentId — the same key the hierarchy.producer.* webhook events use, so you can update a stored tree directly from an event.

Four fields carry behavior worth knowing before you build against them:

FieldWhy it matters
contractAssignmentIdThe node's key. Stable across amendments.
uplineContractAssignmentIdThe parent's key, or null for root nodes. This is the edge that forms the tree.
type, personId, firmIdtype is AGENT or FIRM and determines which identifier is populated. Both are Identity API identifiers and resolve directly.
activeComputed over the tree — a node is inactive when its own status is inactive or any node above it is.

A producer is a single entity discriminated by type, not two records — an individual is never stored as both a person and a firm. Whichever identifier does not apply is null.

Detecting firms: test firmId for presence, not personId for null. These fields behave differently across surfaces. On this REST resource a FIRM node has personId: null. In the hierarchy.producer.* webhook events, personId is always populated, with firmId alongside it for firms. Logic branching on personId == null works against REST, then silently classifies every firm as an individual when pointed at the event stream. Checking firmId for presence is correct in both.

Reconstructing the tree: identify root nodes (uplineContractAssignmentId == null), group the rest by uplineContractAssignmentId, then attach children to their parent keyed on contractAssignmentId. Fetch every page first — a child can appear on a later page than its parent.

Point-in-time snapshots: pass as_of=yyyy-MM-dd to get the hierarchy as it existed on that date. This is the primary mechanism for commissions reconciliation; omit it for current state, and always supply an explicit as_of when querying for historical purposes.

Not yet available on a node: carrier context, partnership fields, and commission split percentages. If your integration needs these, contact support@agentsync.io so we can factor it into prioritization.

Files and Versioning

Contract packets carry implicit versioning — an initial version and a counter-signed version, surfaced as distinct states.

Files uploaded through the onboarding upload component have no explicit version control. They are versioned at the storage layer, but that history is not exposed: there is no version list and no diff. Webhook events fire when a new file is loaded, so you can detect that a file changed even though you cannot retrieve its history.

Webhook Events

The API publishes events for contract, assignment, assignment-change, packet, producer-status, responsible-party, and hierarchy changes. Hierarchy lifecycle events are pushed alongside the contracting ones:

EventWhen it fires
hierarchy.producer.addedA producer is newly placed under an upline
hierarchy.producer.changedA position changes — upline and/or commission level. Includes a changedFields array.
hierarchy.producer.relationship.terminatedA hierarchy relationship ends — its assignment enters a terminal status

See Contracting API Webhook Events for the full catalog with payload schemas, and the Webhooks Quick Start Guide to register an endpoint.

Getting Started

Start here: the Contracting & Hierarchies API Quick Start Guide walks through authentication, reading your account configuration, producers, assignments and hierarchy, reconstructing the tree, point-in-time snapshots, resolving contact details from Identity, and incremental sync — with curl and Python examples throughout.

For every endpoint, request/response schema, and field constraint, see the interactive API Reference.