Identity API Overview
Every producer you work with has details that have to stay accurate — where to mail their paperwork, where to send their commission payments, and whether their errors and omissions (E&O) coverage is still in force. The Identity API is where AgentSync keeps that information, and how your systems read and update it.
What you can get:
- Who the producer is — name, National Producer Number (NPN), date of birth, SSN (masked), and whether they're an individual or a firm
- How to reach them — addresses, phone numbers, email addresses
- How to pay them — bank account details used for commission disbursement
- Whether they're covered — E&O policy records, including expiry dates
Identity vs. ProducerSync: Identity holds what your organization knows about a producer — contact info, bank accounts, E&O coverage — entered by you or the producer. The ProducerSync API surfaces what the state knows, sourced from NIPR: licenses, appointments, and regulatory actions.
Common Use Cases
Commission disbursement — retrieve bank accounts for payment routing, verify E&O coverage is current before releasing payment, and catch account changes for fraud and routing-error checks via the id.producer.bank_account.updated webhook.
Producer onboarding and roster sync — create producers programmatically, trigger invitations in the same call, then keep your roster current with incremental sync or webhook events.
Compliance and audit — monitor E&O expirations via the id.producer.errors_and_omissions.updated webhook, and cross-reference identity data against NIPR records from ProducerSync using the shared NPN.
How It Works
Producer identity is shared across AgentSync products: maintained once, then referenced by ProducerSync for compliance tracking and by Contracting for assignments. Changes — address updates, E&O renewals, bank account changes — are surfaced as webhook events regardless of which part of the platform triggered them.
The customer-facing surface is versioned under /v2, returns plain JSON, and uses token pagination and a consistent error shape with a machine-readable code. Calls require the identity.profiles.read or identity.profiles.write scope. Every result is scoped to your account — requesting another customer's resource returns 404, never 403, so existence is never leaked across account boundaries.
See Base URLs, Authentication, and Pagination for the shared conventions.
Incremental Sync
GET /v2/persons returns every person visible to your account, ordered by modification time. Filter with updated_since (RFC3339 UTC) using your last sync time as a high-water mark, or firm_id to restrict to one firm's people.
GET /v2/bank-accounts works the same way across your whole account, returning every person- or firm-owned account with owner context on each row — use it to reconcile bank accounts without iterating producer IDs.
Bank accounts cannot be bulk uploaded. Create them one at a time against a person or firm. To reconcile an existing population, read account-wide with
GET /v2/bank-accountsrather than iterating producers.
Joining with the Contracting API
Contracting and Identity share producer identifiers — no mapping table, and no lookup by NPN or email.
A Contracting producer or hierarchy node carries type (AGENT or FIRM) plus personId and firmId. Whichever identifier matches the type is an Identity identifier and resolves directly against /v2/persons/{personId} or /v2/firms/{firmId} — and against their /addresses, /phones, /bank-accounts, and /insurance-policies sub-resources.
So building a full producer record is two calls, not a search:
# 1. Read producers from Contracting
curl -H "Authorization: Bearer $ACCESS_TOKEN" \
"https://api.sandbox.agentsync.io/contracting/v2/producers"
# -> { "items": [ { "type": "AGENT", "personId": "a1b2...", "firmId": null, ... } ] }
# 2. Resolve contact details from Identity using that same id
curl -H "Authorization: Bearer $ACCESS_TOKEN" \
"https://api.sandbox.agentsync.io/identity/v2/persons/a1b2.../addresses"
Two practical notes:
- Separate scopes. Contracting reads need
contracting.*; Identity reads needidentity.profiles.read. A Contracting-only credential returns403on every Identity call, so request both up front. - You may not need step 2 at all. The
id.producer.addresses.updatedandid.producer.phone_numbers.updatedwebhooks carry the producer's full current set, so you can maintain contact state from events instead of polling.
Email Fields
Email is a first-class field, but its name varies by resource — map it once at your integration boundary:
| Field | Resource | Notes |
|---|---|---|
primaryEmail | Person | The person's primary address, and the same value Contracting exposes as email on a producer |
secondaryEmail | Person | Optional second address, no special meaning |
email | Firm | The firm's primary contact address |
primaryEmailis contact data, not a sign-in credential. Authentication is anchored on a separate login identity, so changing it does not change how the producer signs in.
There is no field for purpose-specific addresses such as billing, notices, or statements. If you need addresses routed by purpose, raise it with your AgentSync account team rather than overloading secondaryEmail.
Sensitive Data Handling
Sensitive fields are masked by default and retrievable in full only through dedicated, audited endpoints:
| Field | Default | Full value |
|---|---|---|
| Person SSN | ssnLast4 only | GET /v2/persons/{personId}/ssn |
| Firm FEIN | ****{last4} | GET /v2/firms/{firmId}/fein |
| Bank account number | ****{last4} | Single-resource GET — use only when you need the complete value for payment processing |
Every access to a full SSN or FEIN is recorded in a durable audit log.
Webhook Events
Identity publishes events for identity, contact, bank account, E&O, pay distribution, and firm-association changes. See Identity API Webhook Events for the full catalog with payload schemas.
Getting Started
Start here: the Identity API Quick Start Guide walks through authentication, reading and updating a producer, and subscribing to change events.
For every endpoint, request/response schema, and field constraint, see the interactive API Reference.