Versioning and Diff
How It Works
The Nompd API uses a version-based diff mechanism that allows you to fetch only the data that has changed since your last request. This is useful for keeping a local cache in sync without downloading the full dataset each time.
Version Number
Every response includes a currentVersion number. This is a monotonically increasing integer that increments each time the server syncs with upstream data sources (typically once per day).
Workflow
Client Server
│ │
│ GET /api/v1/treatmentGroup │
│──────────────────────────────────>│
│ │
│ { currentVersion: 5, items: [...all items...] }
│<──────────────────────────────────│
│ │
│ (store version = 5 locally) │
│ │
│ ... time passes, nightly sync happens ...
│ │
│ GET /api/v1/treatmentGroup?sinceVersion=5
│──────────────────────────────────>│
│ │
│ { currentVersion: 6, items: [...only changes...] }
│<──────────────────────────────────│
│ │
│ (update version = 6 locally) │
Step by Step
1. Initial fetch
Fetch all data without sinceVersion:
curl -H "X-API-KEY: key" \
https://api.example.com/api/v1/treatmentGroup
Response:
{
"currentVersion": 5,
"items": [
{ "data": { "id": "aaa", "name": "Group A" }, "isDeleted": false },
{ "data": { "id": "bbb", "name": "Group B" }, "isDeleted": false }
]
}
Store currentVersion: 5 in your system.
2. Subsequent fetches
Pass the stored version as sinceVersion:
curl -H "X-API-KEY: key" \
https://api.example.com/api/v1/treatmentGroup?sinceVersion=5
Response (only changes):
{
"currentVersion": 6,
"items": [
{ "data": { "id": "aaa", "name": "Group A (updated)" }, "isDeleted": false },
{ "data": { "id": "ccc", "name": "Group C" }, "isDeleted": false },
{ "data": { "id": "bbb", "name": "Group B" }, "isDeleted": true }
]
}
Update your stored version to 6.
3. Apply changes locally
For each item in the diff response:
isDeleted: false— Upsert (insert or update) the item in your local store.isDeleted: true— Remove the item from your local store.
4. Handle empty diffs
If nothing changed, the response will have an empty items array:
{
"currentVersion": 6,
"items": []
}
Client Implementation Example
public class NompdClient
{
private long _lastVersion = 0;
private readonly Dictionary<string, TreatmentGroup> _cache = new();
public async Task SyncAsync()
{
var url = _lastVersion == 0
? "/api/v1/treatmentGroup"
: $"/api/v1/treatmentGroup?sinceVersion={_lastVersion}";
var response = await _httpClient.GetFromJsonAsync<VersionedResponse>(url);
foreach (var item in response.Items)
{
if (item.IsDeleted)
_cache.Remove(item.Data.Id);
else
_cache[item.Data.Id] = item.Data;
}
_lastVersion = response.CurrentVersion;
}
}
Edge Cases
| Scenario | Behavior |
|---|---|
sinceVersion=0 |
Returns all items (equivalent to full fetch, but includes deleted items) |
sinceVersion higher than current |
Returns empty items list with current version |
| Multiple syncs between your requests | All accumulated changes are included |
| Client has never fetched before | Omit sinceVersion to get all active items |
Recommendations
- Always store
currentVersionfrom every response, even if the items list is empty. - Use full fetch for initial load (no
sinceVersion). This returns only active items, giving you a clean starting point. - Use
sinceVersionfor subsequent calls. This is more efficient and includes deletion information. - Sync at most once per day. Data updates nightly, so more frequent polling gives no benefit.