`complete`, `partial`, `empty`: The Three States of Data You're Not Handling
Most APIs return data or an error. The reality is more nuanced: data can be complete, partially available, or entirely absent — and each state deserves a different response.
The most common API contract in SaaS products is binary: return the data if it exists, return an error if it does not. This works for simple read operations but fails comprehensively for any system where data is produced asynchronously over time. An audit that takes three minutes to complete produces data in stages. A score that requires multiple upstream signals may be missing one while the others are complete. A user who has not yet run an analysis has no data at all. These three situations — incomplete process, partial results, absent data — are meaningfully different from each other and should not be conflated into a single "no data" response.
State 1: Complete
The complete state means the process that generates this data has finished and the result is a full, accurate, authoritative representation. In the UI, this state permits the highest level of confidence: render everything, enable all interactions, show all scores. No caveats, no banners, no indicators of incompleteness. The data is done. The user should see it as done.
State 2: Partial
The partial state means either the generating process is still running, or the process completed but a specific sub-component has not yet produced its contribution to this response. In either case, some data is available and valid, and some is not. The UI should show the available data with a clear indication that more is coming. It should never hide the available data (patronising) or pretend the missing data does not exist (dishonest). Partial is the most complex state to render well — it requires distinguishing between what is certain and what is provisional.
State 3: Empty
The empty state means no process has run to generate this data, or the system is not configured to generate it, or the record simply does not exist. This is the state that products most commonly paper over with placeholder content. The correct response is a precise statement of why the data does not exist and what action would cause it to exist. "No audit has been run for this domain. Start an audit to generate intelligence." is an honest empty state. An empty-looking skeleton that implies data is coming is not.
◆Add a state field to every API response that involves asynchronous data production. The three values — complete, partial, empty — encode more useful information than null checks, HTTP status codes, and status strings combined. The frontend can render the correct UI with zero inference from these three values.
Implementing the Pattern
The implementation is straightforward. On the backend, every data-producing route calculates its state before returning: if the job is not configured, return empty; if the job is running or the result is missing, return partial; if the job is complete and the result is present, return complete. Wrap the data and the state in a standard envelope. On the frontend, read the state before deciding how to render. Never render a metric as if it were complete when the state says partial. Never render a graph as if nodes are coming when the state says empty. The state field is the source of truth. Trust it.