Sync Domain Chief data with your system
Load the Domain Chief resources your application needs once to build a local snapshot. If that snapshot must stay current, create an event checkpoint before the initial read and use List team events to retrieve only the resources that change afterward.
The event feed covers domains, contacts, DNS records, web redirects, and mail forwards. Use the same collection requests for a one-time inventory, portfolio dashboard, or report. Skip the checkpoint and event loop when you do not need later changes.
Recommended sync flow
- Decide which supported resource types to sync.
- For continuous sync, call List team events without a cursor and store the returned checkpoint.
- Load domains and contacts when the snapshot needs them.
- For each domain, load the selected DNS record, web redirect, and mail forward collections that apply.
- Poll List team events with the saved cursor.
- Route each event by
resource.type. Useresource.parent.idfor a domain-scoped resource. - Apply deletions directly and retrieve current state for created or changed resources.
- Save the returned cursor only after the complete page has been applied.
- Continue immediately while
meta.has_moreistrue. Otherwise, wait before polling again.
Grant the read scope for each resource type the application stores:
domainchief:domains:readfor domains and for finding domains that own nested resourcesdomainchief:contacts:readfor contactsdomainchief:dns:readfor DNS recordsdomainchief:redirects_web:readfor web redirectsdomainchief:redirects_mail:readfor mail forwards
Continuous sync also needs domainchief:events:read. The broader domainchief:read scope works for a read-only integration that stores every supported type. Resource-specific scopes give a dedicated sync process less access.
Pin the team with X-Chief-Team when the token does not already belong to one team. Use the same team for the snapshot, event feed, and every resource request. The API introduction explains team selection.
Build the initial snapshot
Create a checkpoint for continuous sync
Call List team events without cursor before reading the first selected collection:
Code
The response contains no historical events. Its cursor marks the current position in this team's stream:
Code
Store this cursor before starting the snapshot. If a resource changes while the collection pages are loading, its later event remains visible after the checkpoint.
Skip this request for a one-time inventory. It adds no value unless the application will process later events.
Load every domain page
Call List domains with up to 100 domains per page:
Code
Follow links.next until it is null. Keep the same page size, sort, filters, and expansions on every request. Upsert each domain by its stable id and store its canonical domain name.
The default response includes the TLD as a string and contact roles as contact handles. It also contains the domain's status, renewal and expiration dates, DNS settings, nameservers, renewal price, and metadata.
Request expansions only when the snapshot needs the complete related objects:
expand[]=tldreturns the full TLD resource instead of its name.expand[]=contactsreturns full contacts instead of their handles.expand[]=noticesadds current domain notices.
Expanding contacts repeats the same contact when several domains use it. For a large portfolio, keep the handles, deduplicate them, and retrieve the contacts in batches.
Resolve the contacts you need
Collect the handles from each domain's contacts object and split the unique values into groups of at most 100. Call List specific contacts for each group:
Code
Store contacts by handle, then join each domain role to that handle. A contact's parent is also a handle by default. Add "expand": ["parent"] to the batch body only when the snapshot needs the complete parent contact in the same response.
The batch response preserves request order but can omit contacts that no longer exist or do not belong to the selected team. Match contacts by handle, not array position.
Call List contacts and follow its pagination when your application needs every team contact, including contacts that no current domain uses. Do not load the full contact collection merely to display the contacts already referenced by domains.
Load domain-scoped resources
DNS records, web redirects, and mail forwards belong to a domain. Store the domain ID with each nested resource. Events use that ID in resource.parent.id so the application can call the matching domain-scoped endpoint later.
For each domain in the snapshot, load the collections your application stores:
Code
Code
Code
Follow every collection's pagination and store each item by its stable id plus its parent domain ID. Request DNS records and web redirects when is_using_hosted_dns is true. Request mail forwards when mail_forward_status is not disabled.
Skip collections the application does not store. A complete nested-resource snapshot still starts with List domains, because the nested collection endpoints require a domain name or ID.
Use filters for partial views
Collection filters are useful for a one-time report or customer-specific portfolio. Do not use a partial collection as the baseline for a complete local copy.
query searches domain names, status selects one current status, and metadata[key]=value matches metadata exactly. For example:
Code
Status values are extensible. Preserve values your application does not recognize and do not map them to active or deleted. The Domain schema documents the current fields and values.
Apply event pages
Read the next page
Pass the last saved cursor back unchanged. per_page accepts values from 1 through 100 and defaults to 50:
Code
An event identifies the affected resource. Nested resources include their parent domain:
Code
The parent value is null for domains and contacts. For DNS records, web redirects, and mail forwards, it contains the domain needed by the matching endpoint.
Events are notifications, not resource snapshots. Retrieve current state before updating local fields. Changes made by the same integration also appear in the feed, so process them like any other event.
Event types are extensible. Do not reject a page because it contains a type your application does not recognize. The TeamEvent schema documents the current contract.
Route resource changes
Collect unique resource keys across the page. Use resource.type and resource.id for domains and contacts. Include resource.parent.id in the key for nested resources.
Remove local resources immediately for contact.deleted, dns_record.deleted, web_redirect.deleted, and mail_forward.deleted. These events already describe the current absence, so do not request the deleted resource.
Retrieve current state for the other recognized events. If a resource disappears between the event and the request, treat a 404 Not Found or an omitted batch result as current absence and remove the local copy. Several *.changed notifications for the same resource may be combined into one event. Retrieve each unique resource only once per page.
Record unknown event or resource types for monitoring and continue processing the page. Do not guess which endpoint or local table they belong to.
Refresh domains and contacts in batches
Use List specific domains for up to 100 domain names or IDs. Request notices when the application presents domain notices:
Code
Use List specific contacts for up to 100 contact handles:
Code
Both batch endpoints preserve request order but omit resources that no longer exist or no longer belong to the selected team. Match results by identifier, not array position.
Refresh domain-scoped resources
Use resource.parent.id as $DOMAIN_ID and resource.id as the nested resource ID. Call the matching endpoint for each unique created or changed resource:
Code
Code
Code
Upsert a successful response by its resource ID and parent domain ID. Remove the local resource after 404 Not Found.
Include activity when needed
An event's activity field is null when no domain activity relates to it. Otherwise, the default value is the activity ID. Add expand[]=activity when the application needs the full activity in the event response:
Code
Process every activity event your application uses. Domain Chief does not combine these events.
Commit the cursor
Apply a page in this order:
- Deduplicate events by their stable
id. - Process recognized activity events.
- Apply recognized resource deletion events.
- Retrieve current state once for each remaining unique resource.
- Upsert returned resources and remove resources that are now absent.
- Save
meta.cursor.
If meta.has_more is true, request the next page with the newly saved cursor without waiting for the next polling interval.
Expect safe redelivery
A failed worker can request the same cursor again and receive events it already handled. Make event handling idempotent and deduplicate by event ID. This is safer than saving a cursor before downstream writes finish.
Recover synchronization
Resume an interrupted read
Keep the previous cursor when an event request, resource read, or local write fails. Resume from that cursor after the failure clears. Save the new cursor only after the related local writes succeed.
For an interrupted initial snapshot, request the failed collection page again with the same query parameters and upsert resources by identifier. Do not restart from page 1 unless your local import transaction requires it.
When an event response is empty and meta.has_more is false, save the returned cursor and wait before polling again. Avoid an immediate loop of empty requests.
Replace a lost or invalid cursor
Domain Chief returns 422 Unprocessable Content for an invalid cursor. Do not construct or alter cursor values.
If the saved cursor is missing or invalid:
- Request a new checkpoint without a cursor.
- Rebuild the snapshot for every resource type the application stores.
- Resume event polling from the new checkpoint.
The new snapshot is required because a fresh checkpoint does not replay changes that occurred before it.
Keep one cursor per team
Store each cursor with its team. Use that same team for the event request and every related resource request. Never reuse a cursor across teams.
401 Unauthorized requires a valid token. 403 Forbidden requires corrected team access or scopes. 422 Unprocessable Content means a filter, expansion, page size, sort, batch body, or cursor is invalid. Correct the request before sending it again.
API reference
- List domains
- List specific domains
- List contacts
- List specific contacts
- List DNS records
- Show DNS record
- List web redirects
- Show web redirect
- List mail forwards
- Show mail forward
- List team events
DomainschemaContactschemaDNSRecordschemaWebRedirectschemaMailForwardschemaTeamEventschema
For customer-facing conditions attached to a domain, continue with Handle domain notices.