Data Synchronization
Recommended pattern for synchronizing records between an external system and Nomad Media.
Data Synchronization
This guide covers the recommended pattern for building a data synchronization routine that keeps records in Nomad Media in sync with an external system (e.g., a legislative database, a production scheduling system, or any other source of record).
The Recommended Sync Pattern
A single sync pass typically follows four steps:
1. Query the Source System
Retrieve the list of records (and their current state) from your external system. For incremental syncs, filter to records that have changed since the last sync run using a lastModifiedDate or equivalent field.
2. Search Nomad Media by External ID
Rather than fetching records one-by-one, run a single search query against the Nomad Media search index using your external ID field as a filter. This retrieves all matching records in one request, minimizing API round trips.
POST /admin/search
Authorization: Bearer <token>
Content-Type: application/json
{
"filters": [
{ "fieldName": "contentDefinitionId", "value": "<your-content-def-id>" }
],
"pageSize": 500,
"pageOffset": 0
}
For large datasets, page through results using pageOffset. Build a lookup map of externalId → nomadRecordId from the results for the diff step.
3. Diff the Two Sets
Compare the source system records against the Nomad Media results:
| Condition | Action |
|---|---|
| Record exists in source but not in Nomad | Create a new record in Nomad |
| Record exists in both — values differ | Update the Nomad record |
| Record exists in both — values match | Skip (no action needed) |
| Record exists in Nomad but not in source | Delete or archive the Nomad record, per your requirements |
4. Execute Creates, Updates, and Deletes
Use the appropriate API endpoints:
POST /admin/content/{contentDefinitionId}— createPUT /admin/content/{contentDefinitionId}/{recordId}— updateDELETE /admin/content/{contentDefinitionId}/{recordId}— delete
For bulk operations, execute calls sequentially or in small batches. See Bulk Operations for guidance on large-scale data loads.
External ID Strategy
When integrating with an external system, do not attempt to use the external system's identifier as Nomad Media's primary key. Instead:
- Let Nomad Media assign its own UUID to each record
- Add an External ID field to the content definition (a Short Text field)
- Populate this field with the external system's identifier when creating records in Nomad
- Use this field as the lookup key during sync (as shown in Step 2 above)
Why this matters: External systems sometimes change their ID formats, migrate databases, or restructure identifiers. Keeping Nomad Media's UUID decoupled from the external ID protects your integration from upstream changes.
UUID Stability
Every Nomad Media record and asset has a UUID that never changes — regardless of:
- Renaming the record
- Moving an asset to a different folder or storage bucket
- Migrating from AWS S3 to Azure Blob Storage
- Renaming a content definition
This means relationship fields (links between records) remain valid after any of these operations. Your integration can safely store and reference Nomad UUIDs as stable, long-lived identifiers.
Handling Relationships During Sync
When creating or updating records that have relationship fields (e.g., a Meeting that references a Committee), you must have the Nomad UUID of the related record available at write time.
Recommended approach:
- Sync parent records (e.g., Chambers, Committees) before child records (e.g., Meetings)
- Build a lookup map of
externalId → nomadUUIDfor each content definition - Use this map to resolve relationship field values when writing child records
This ensures that relationship fields are populated with valid UUIDs on the first sync pass.
Incremental vs. Full Sync
| Strategy | When to Use |
|---|---|
| Full sync | Initial data load; periodic reconciliation to catch missed changes |
| Incremental sync | Ongoing operation; filter source records by lastModifiedDate to reduce API volume |
For most integrations, run an incremental sync on a scheduled interval (e.g., every 15 minutes) and a full reconciliation sync weekly or on-demand to catch any records that fell through the cracks.
