Hierarchies API: Quick Start Guide
This guide walks through querying AgentSync's distribution hierarchy data — finding the product hierarchies for your organization, reading the hierarchy node list, and using point-in-time snapshots for commissions reconciliation.
Who this is for: Engineers at commissions platforms, carriers, or agencies integrating with AgentSync hierarchy data.
What you'll do: Authenticate, find your organization, list product hierarchies, retrieve hierarchy nodes, reconstruct the tree, and pull historical snapshots.
Before You Start
- Sandbox credentials with the
rino_api_agency_readscope — email support@agentsync.io to request access - Access token — follow the Authentication guide before proceeding
- Your AgentSync organization ID (UUID) — see Step 1 below; you can also obtain this from your AgentSync account team
- Hierarchies API endpoints use the same
/contractingbase URL as the Contracting API — see API Base URLs
Prerequisite data: Hierarchy data is built from contract assignments in the Contracting API. If your account has no carriers, products, or contract assignments yet, see the Contracting API Quick Start Guide first.
Step 1: Get Your Organization ID
The Hierarchies API uses organization IDs to scope queries. Your organization ID is a UUID that identifies your agency or carrier in AgentSync. If you already know it, skip to Step 2.
Fetch it from the Contracting API using your carrier or agency name:
curl -X GET \
"https://api.sandbox.agentsync.io/contracting/v1/customers/carriers" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Example response:
{
"_embedded": {
"carriers": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Acme Insurance Company",
"naic": "12345"
}
]
}
}
The id field in the carrier response is the organization ID you'll use in Hierarchies API calls.
Step 2: List Product Hierarchies for Your Organization
With your organization ID, fetch all product hierarchy records. Each record represents a position in the distribution chain for a specific product. You'll use the id from these records to fetch hierarchy nodes and changelogs.
curl -X GET \
"https://api.sandbox.agentsync.io/contracting/v1/organizations/ORG_ID/productHierarchies" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Replace ORG_ID with your organization UUID from Step 1.
Example response:
{
"_embedded": {
"decoratedProductHierarchyList": [
{
"id": "ph-uuid-1111",
"organizationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"organizationName": "Acme IMO",
"productId": "prod-uuid-2222",
"productName": "Term Life 10-Year",
"lineOfBusinessName": "Life",
"lastEditedBy": "user-uuid-5555",
"lastEditedByName": "Jane Admin",
"lastEditedAt": "2025-03-01T08:00:00",
"_links": {
"self": { "href": "/contracting/v1/productHierarchies/ph-uuid-1111" },
"product": { "href": "/contracting/v1/products/prod-uuid-2222" },
"organization": { "href": "/contracting/v1/organizations/a1b2c3d4-e5f6-7890-abcd-ef1234567890" }
}
},
{
"id": "ph-uuid-2222",
"organizationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"organizationName": "Acme IMO",
"productId": "prod-uuid-3333",
"productName": "Whole Life",
"lineOfBusinessName": "Life",
"lastEditedBy": "user-uuid-5555",
"lastEditedByName": "Jane Admin",
"lastEditedAt": "2025-03-01T08:00:00"
}
]
},
"_links": {
"self": { "href": "/contracting/v1/organizations/a1b2c3d4.../productHierarchies" }
},
"page": {
"size": 250,
"totalElements": 2,
"totalPages": 1,
"number": 0
}
}
Key fields:
id— the product hierarchy record ID, used in all subsequent callsproductName,lineOfBusinessName— identifies which product this position coverslastEditedAt— when this hierarchy record was last modified
Pagination: Default page size is 250. Pass ?size=250&page=0 to control paging.
Searching Product Hierarchies
To filter by product name or line of business, use the /search endpoint:
curl -X GET \
"https://api.sandbox.agentsync.io/contracting/v1/organizations/ORG_ID/productHierarchies/search?productName=Term+Life" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Available search parameters:
| Parameter | Type | Description |
|---|---|---|
productName | string | Partial match on product name |
lineOfBusinessIds | UUID (repeatable) | Filter to specific lines of business |
Step 3: Get the Hierarchy Node List
The hierarchy endpoints return a flat list of HierarchyNode objects. Each node represents a single position in the distribution chain — a producer or organization at a specific commission level. Upline relationships are expressed via uplineContractAssignmentChangeId (the parent node's ID) and the path array (full chain from root to this node).
curl -X GET \
"https://api.sandbox.agentsync.io/contracting/v1/productHierarchies/PH_ID/hierarchies" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Replace PH_ID with a product hierarchy ID from Step 2.
Example response:
[
{
"contractAssignmentId": "ca-uuid-1111",
"contractAssignmentChangeId": "cac-uuid-imo",
"uplineContractAssignmentChangeId": null,
"assignmentStatusId": "status-uuid-active",
"assignmentStatusName": "Active",
"producerName": "Acme IMO",
"productId": "prod-uuid-2222",
"productName": "Term Life 10-Year",
"commissionLevelName": "L1",
"level": 100.00,
"stateAbbreviations": ["CA", "TX", "NY"],
"toOrganizationName": "Acme IMO",
"startDate": "2024-01-15",
"endDate": null,
"active": true,
"writingNumber": null,
"path": ["cac-uuid-imo"],
"uplineName": null,
"uplineAssignmentStatusName": null
},
{
"contractAssignmentId": "ca-uuid-2222",
"contractAssignmentChangeId": "cac-uuid-agency",
"uplineContractAssignmentChangeId": "cac-uuid-imo",
"assignmentStatusId": "status-uuid-active",
"assignmentStatusName": "Active",
"producerName": "Westside Agency",
"productId": "prod-uuid-2222",
"productName": "Term Life 10-Year",
"commissionLevelName": "L2",
"level": 90.00,
"stateAbbreviations": ["CA"],
"toOrganizationName": "Westside Agency",
"startDate": "2024-02-01",
"endDate": null,
"active": true,
"writingNumber": null,
"path": ["cac-uuid-imo", "cac-uuid-agency"],
"uplineName": "Acme IMO",
"uplineAssignmentStatusName": "Active"
},
{
"contractAssignmentId": "ca-uuid-3333",
"contractAssignmentChangeId": "cac-uuid-producer",
"uplineContractAssignmentChangeId": "cac-uuid-agency",
"assignmentStatusId": "status-uuid-active",
"assignmentStatusName": "Active",
"producerName": "Joe Producer",
"productId": "prod-uuid-2222",
"productName": "Term Life 10-Year",
"commissionLevelName": "L3",
"level": 80.00,
"stateAbbreviations": ["CA"],
"toOrganizationName": "Westside Agency",
"startDate": "2024-03-01",
"endDate": null,
"active": true,
"writingNumber": "WN-15645555",
"path": ["cac-uuid-imo", "cac-uuid-agency", "cac-uuid-producer"],
"uplineName": "Westside Agency",
"uplineAssignmentStatusName": "Active"
}
]
Reading the flat list:
- Root nodes:
uplineContractAssignmentChangeId == null - Depth:
path.length— a path of length 1 is a root, length 2 is one level below root - Direct upline:
path[path.length - 2]gives the immediate upline'scontractAssignmentChangeId - Inactive positions:
active: falsemeans this position (and everything below it) is not currently active
To reconstruct a tree client-side, group nodes by uplineContractAssignmentChangeId and attach children to their parent using contractAssignmentChangeId as the key.
Node List by Organization
To get all hierarchy nodes across all products for an entire organization:
curl -X GET \
"https://api.sandbox.agentsync.io/contracting/v1/organizations/ORG_ID/hierarchies" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Node List for a Specific Producer
To get the hierarchy view scoped to a specific producer:
curl -X GET \
"https://api.sandbox.agentsync.io/contracting/v1/organizations/ORG_ID/persons/PERSON_ID/hierarchies" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Replace PERSON_ID with the producer's AgentSync person UUID (from the Producer Profile API or Contracting API contract assignment data).
Step 4: Get a Point-in-Time Snapshot
All hierarchy node endpoints accept an optional ?date parameter (yyyy-MM-dd). When provided, the response reflects the hierarchy as it existed on that date.
curl -X GET \
"https://api.sandbox.agentsync.io/contracting/v1/productHierarchies/PH_ID/hierarchies?date=2025-01-15" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
This is the primary mechanism for commissions reconciliation — query the hierarchy as of the transaction date to confirm who the upline was at that moment.
No date provided → today's hierarchy. Always supply an explicit
?datewhen querying for historical purposes. Omitting it returns the current state, which may have changed since the transaction.
Step 5: Read the Changelog
The changelog records every change made to a product hierarchy position, sorted most-recent-first by default. Each entry is a full snapshot of the position at the time of the change — producer name, upline, commission level, status, and effective dates.
curl -X GET \
"https://api.sandbox.agentsync.io/contracting/v1/productHierarchies/PH_ID/changelog" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Example response:
{
"_embedded": {
"hierarchyChangelogViewList": [
{
"contractAssignmentChangeId": "cac-uuid-1111",
"contractAssignmentId": "ca-uuid-2222",
"contractAssignmentDisplayNumber": "CA-00123",
"producerName": "Joe Producer",
"uplineName": "Westside Agency",
"commissionLevelName": "L3",
"writingNumber": "WN-15645555",
"contractAssignmentChangeAssignmentStatusName": "Active",
"contractAssignmentAssignmentStatusName": "Active",
"effectiveDate": "2024-03-01",
"expirationDate": null,
"startDate": "2024-03-01",
"endDate": null,
"modifiedDate": "2025-03-01T08:00:00Z",
"modifiedByName": "Jane Admin"
}
]
},
"_links": {
"self": { "href": "/contracting/v1/productHierarchies/ph-uuid-1111/changelog" }
},
"page": {
"size": 250,
"totalElements": 1,
"totalPages": 1,
"number": 0
}
}
Use modifiedDate from changelog entries alongside ?date queries on the hierarchy node endpoints to reconstruct exactly what happened and when.
Detecting producer lifecycle events via changelog:
| What changed | What to look for |
|---|---|
| Producer added to hierarchy | New contractAssignmentChangeId appears in the changelog with an earliest startDate |
| Position changed (new upline) | Same producer, uplineName differs between two entries |
| Commission level changed | Same producer, commissionLevelName differs between two entries |
| Relationship terminated | contractAssignmentAssignmentStatusName transitions to a terminal status (e.g., Terminated) or endDate becomes populated |
Recommended Workflows
Commissions: Determine Upline Chain at Transaction Time
1. GET /organizations/{orgId}/productHierarchies/search?productName={productName}
→ Find product hierarchy records for the relevant product
2. GET /productHierarchies/{phId}/hierarchies?date={transactionDate}
→ Get the node list as of the transaction date
3. Find the producer's node by matching producerName or contractAssignmentId
→ uplineName gives the direct upline
→ path[] gives the full chain: path[0] is root, path[path.length-1] is this node
4. Read commissionLevelName and level from the node for this producer's commission tier
Commissions: Detect Upline or Commission Level Changes
1. GET /productHierarchies/{phId}/changelog?sort=modifiedDate,desc
→ Pull entries since your last-synced modifiedDate
2. For each new entry:
- uplineName changed vs. prior entry for same contractAssignmentId → position change
- commissionLevelName changed → commission level change
- contractAssignmentAssignmentStatusName is terminal → relationship terminated
3. When changes are detected, pull updated node list and trigger recalculation
Lifecycle Event Detection (Polling)
There are currently no webhook events for hierarchy changes. Use this polling pattern:
1. Store the latest modifiedDate seen per productHierarchyId
2. GET /productHierarchies/{phId}/changelog?sort=modifiedDate,desc
→ Check most recent modifiedDate against your stored timestamp
3. For entries since last-seen timestamp, check:
- New contractAssignmentId not seen before → producer added
- uplineName differs from prior entry → position change (transfer/restructure)
- commissionLevelName differs → commission level change
- contractAssignmentAssignmentStatusName is terminal or endDate populated → termination
- contractAssignmentChangeAssignmentStatusName is pending → change awaiting approval
- startDate or effectiveDate is newly set → relationship became active
- expirationDate or endDate newly populated → relationship expired or will expire
4. Repeat for each productHierarchyId you monitor
See Webhook Events for the full list of currently available events. Hierarchy lifecycle webhooks are planned for a future release.
Full Hierarchy Reconciliation
1. GET /organizations/{orgId}/hierarchies?date={reconciliationDate}
→ Pull all nodes for the organization as of the reconciliation date
2. Match each node to your local records on contractAssignmentId
3. Nodes in AgentSync but not in your system → new positions to add
Nodes in your system but not in AgentSync → terminated or restructured
Nodes in both → compare uplineName, commissionLevelName, assignmentStatusName
Look Up a Specific Producer's Position
1. GET /organizations/{orgId}/persons/{personId}/hierarchies
→ Returns all nodes for this producer across products
2. Each node shows:
- commissionLevelName, level → their commission tier
- uplineName, uplineAssignmentStatusName → their direct upline
- path[] → full reporting chain from root to this producer
- stateAbbreviations[] → which states this position covers
- assignmentStatusName → current status of this assignment
Annualization
1. GET /productHierarchies/{phId}/hierarchies
→ Read annualizationName and annualizationProportion on the node
2. To detect changes to annualization:
GET /productHierarchies/{phId}/changelog
→ Compare annualizationName across entries for the same contractAssignmentId
Partnerships
1. GET /productHierarchies/{phId}/hierarchies
→ Nodes where partnershipId != null belong to a partnership arrangement
→ partnershipName identifies which partnership
2. To find all nodes under a partnership:
→ Filter the flat list by partnershipId
3. To detect when a partnership assignment is used vs. an individual one:
→ partnershipId == null → individual assignment
→ partnershipId != null → partnership assignment
Note: Commission split percentages across partnership members are not
currently available in this API.
All Changes Under a Single Contract Assignment
1. GET /productHierarchies/{phId}/hierarchies
→ Filter the flat node list by contractAssignmentId
→ Each node with the same contractAssignmentId is a different
point-in-time change (ContractAssignmentChange) on that contract
2. Sort by startDate or effectiveDate to see the history of changes
on that contract assignment
Date-Range: Active Relationships Within a Window
Note: The API only supports point-in-time snapshots via ?date — there is
no native date-range filter. To find relationships active within a window:
1. GET /organizations/{orgId}/hierarchies?date={windowStart}
→ Pull nodes active at the start of the window
2. GET /organizations/{orgId}/hierarchies?date={windowEnd}
→ Pull nodes active at the end of the window
3. Compare the two sets to identify positions that started or ended
within the window
Endpoint Reference Summary
All endpoints use base URL https://api.sandbox.agentsync.io/contracting (sandbox) or https://api.agentsync.io/contracting (production).
| Endpoint | Default Page Size | Sort Default | Key Query Params |
|---|---|---|---|
GET /v1/productHierarchies/{id} | — | — | — |
GET /v1/organizations/{orgId}/productHierarchies | 250 | productName | page, size, sort |
GET /v1/organizations/{orgId}/productHierarchies/search | 250 | productName | productName, lineOfBusinessIds |
GET /v1/productHierarchies/{id}/hierarchies | — | — | date (yyyy-MM-dd) |
GET /v1/organizations/{orgId}/hierarchies | — | — | date (yyyy-MM-dd) |
GET /v1/organizations/{orgId}/persons/{personId}/hierarchies | — | — | date (yyyy-MM-dd) |
GET /v1/productHierarchies/{id}/changelog | 250 | modifiedDate,desc | page, size, sort |
Error Handling
Hierarchies API errors follow the same format as the Contracting API:
{
"status": 404,
"timestamp": 1773867190,
"messages": ["Product hierarchy not found."],
"path": "/contracting/v1/productHierarchies/unknown-id",
"error": "Not Found"
}
See API Status Codes for the full list of expected codes.
Support
Need help? Contact us at support@agentsync.io