Detecting changes
One endpoint tells you everything of yours that has changed, and what it changed to:
Each record comes back with its credit decision already attached, so detecting a change and reading it is one call rather than three.
The loop
Between polls you keep one thing: the cursor.
First call only, name a starting point
Omit updatedSince entirely to read your whole history from the beginning.
Sending both updatedSince and cursor is a 400. A cursor already carries a position, and
quietly preferring one would let a client with broken cursor handling look like it works while
skipping records on every poll.
What an item contains
application is exactly what GET /institution/applications/{id} returns. outcome is exactly
what GET /institution/applications/{id}/outcome returns — see
Credit outcomes for how to read it.
outcome is null when the application has never been assessed. That is not the same as an
outcome reporting no credit.
Current state, not history
An application that changes five times appears in five polls, each time carrying its latest state. There is no event log and no replay of individual changes, so:
- Deduplicate on
application.idand keep the newest copy. - You get the new state, not a diff. Compare against your own copy if you need to know which field moved.
There is no retention limit. The feed queries live records rather than a log, so any
historical updatedSince works. If you ever lose your own copy, replay everything by passing an
old timestamp.
The feed cannot tell you an application was deleted — a deleted record simply stops appearing. If you need to detect removals, reconcile periodically with a full replay.
Timestamps must carry an offset
updatedSince requires a full ISO-8601 timestamp with an explicit offset. A bare date is
rejected rather than assumed, because the assumption is measurably wrong:
Z is 10am in Sydney, so a caller asking for “the 11th” silently loses a morning and never finds
out. After your first call the cursor handles this for you — which is most of why it is opaque.
Ordering, and the short delay
Records arrive in the order they changed, and the cursor is a position in that order, so paging stays correct even while the feed is being written to.
The feed deliberately stops about 30 seconds short of now. A record’s timestamp is taken when the change is made but only becomes visible when its transaction commits, so a change stamped slightly earlier can become visible slightly later. Reading right up to the present would let such a record slip behind an advancing cursor and be lost permanently — not delayed, lost. The window trades a few seconds of latency for not losing records.
So a change made seconds ago will not be in the page you are reading. It will be in the next one.
A worked poll
Note the cursor is only overwritten when the response carries one — an empty page returns
nextCursor: null, and the position you already hold is still the right one.
