Executive Summary: An incomplete Cobalt Secretary of State response without cachedData does not say the business is unregistered, the lookup failed, or the applicant is risky. It says only that no interim cached match was available for that open live request. The correct integration response is to preserve retryId, keep the request in a live-pending state, and wait for polling or callback completion before drawing any business conclusion.
What Does an Incomplete Response Without cachedData Mean?
Which fact is actually known?
The integration knows that the live search is still processing and that the optional cached branch did not supply a match. Cobalt documents 202 + Incomplete as continued processing, not a failed request.[1] The response's retryId keeps the open operation addressable.
The new feature does not promise a cached record for every request. It adds one when a cached match is available. Absence therefore describes the interim data path, not the state registry's final result.
Which conclusions are not supported?
Do not label the business unregistered, mark verification failed, start adverse handling, or create a fraud signal. Do not tell an underwriter that the state returned no results. The state search has not finished.
Cobalt's cache-miss guidance explicitly says a cached lookup that does not find a record does not prove absence from the state registry.[2] That boundary becomes even more important when cache absence appears inside a still-running live request.
No interim match is a pending-state condition, not a business verdict.
Why Must Cache Absence Stay Separate From Final No-Match?
How do the two states arise?
Cache absence occurs before live completion and refers to an optional stored-data branch. Final no-match occurs only after the live state search reaches a terminal response without a qualifying record. Different sources, timing, and process states produce them.
Cobalt's status guide gives incomplete, cache-related, no-results, and failure responses different meanings.[3] A lender's internal model should preserve those distinctions.
What breaks when they share one code?
A shared not_found code can trigger exception queues, customer notices, repeat requests, or decision rules before the state search completes. When a later live match arrives, the system must reverse an outcome it should never have created. Reporting also becomes unreliable because cache coverage is mixed with final registry outcomes.
Use source-and-phase-aware codes:
• live_pending_no_cache. Open request, no interim observation.
• live_pending_cache_rejected. Observation exists but lender policy withheld use.
• live_complete_no_match. Terminal live search returned no qualifying result.
• terminal_provider_error. Processing ended in a documented error state.
• invalid_correlation. The consumer cannot resolve the request identity.
• live_complete_match. Terminal live result contains a qualifying record.
Names may differ in your system, but the meanings must remain separate.
Document the mapping at every boundary. The API adapter may use provider language, the orchestration service may use lifecycle states, and the underwriting tool may use reviewer-facing labels. A translation table should show that all three refer to the same condition. Without it, one team can correctly store live_pending_no_cache while another displays No result, recreating the error outside the database.
How Should the Request Be Stored and Correlated?
Which fields should remain on the open request?
Persist the lender-owned request key, Cobalt retryId, exact search inputs, state, receipt time, delivery path, current process state, and policy version. Leave the interim observation empty rather than inserting a placeholder business record.
{
"verificationRequestId": "vr_1042",
"providerRetryId": "provider-id-from-response",
"processState": "live_pending_no_cache",
"searchState": "CA",
"interimObservation": null,
"finalObservation": null
}
This is a lender-side storage example, not a Cobalt response schema. Cobalt's public SOS reference documents retryId as the mechanism for later status retrieval.[4]
Why should the integration avoid an empty entity row?
An empty row often looks like a completed no-result to analytics, rules, and user interfaces. It may also be enriched by other services and become difficult to distinguish from a real entity record. Keep process state on the request and create observations only for actual provider payloads.
If a downstream contract requires a response object, include an explicit verificationPhase and dataAvailable field. Never rely on blank business fields to communicate that work is pending.
Protect the request from stale workers. A poll started while the request is pending may return after a callback has already completed it. Before writing, the worker should reload or conditionally update the current version. It may append diagnostics, but it cannot replace the terminal live observation with an earlier incomplete state. An optimistic version number or atomic compare-and-set can enforce that rule.
What Should the Workflow Do While Live Processing Continues?
How should polling behave?
Poll using the documented retryId path and a customer-controlled backoff schedule. Avoid tight loops and do not create a new search after every incomplete response. AWS recommends backoff for retryable distributed operations so repeated requests do not amplify load.[5]
Stop polling when a valid terminal result arrives, when a documented terminal error occurs, or when lender policy moves the request to an authorized exception path. Elapsed time alone should not become final no-match.
How should callbacks behave?
If callbackUrl is used, retain the same internal request and correlation. Cobalt supports callbacks for long-running and batch workflows while polling remains an alternative.[6] Both paths should call one transition function.
Make completion idempotent. A callback and a poll can race, and a delivery can repeat. One terminal-transition key should allow one final business effect while safely recognizing later duplicates.
What Should Operations and Underwriters See?
Which label prevents the main misunderstanding?
Show Live SOS search in progress and, where useful, No interim cached match available. Do not show No match, Not registered, or Verification failed. Include the request start time and the next expected system action rather than a blank result card.
Cobalt publishes state-level response-time guidance because timing varies by jurisdiction.[7] Use that guidance for workflow planning, not as a promise that every request completes within one number.
What manual actions should be controlled?
Prevent users from interpreting the pending card as a terminal result or repeatedly resubmitting the same search. If an authorized manual restart exists, require a reason and a new attempt identity, and link it to the original request.
Give operations a direct path to inspect current state, correlation, last poll or callback event, and any error. A visible pending state is more useful than a generic spinner because it names what the system is waiting for.
Add a separate support view for integration diagnostics rather than exposing raw provider details to every reviewer. Support may need the full retryId, timestamps, and transport history, while an underwriter needs a plain pending label and next action. Role-appropriate views reduce the chance that a process identifier or internal error is mistaken for business evidence.
How Should Timeouts and Errors Differ From Cache Absence?
When does a waiting policy apply?
A lender may define a threshold for alerting on unusually long pending requests. That threshold triggers operational attention, not a conclusion about registration. Record the threshold, time observed, and next action. Continue only through documented provider and customer procedures.
Microsoft's asynchronous request-reply pattern separates acceptance, status monitoring, and eventual result.[8] The status resource can remain pending without implying a negative business outcome.
How should a terminal error be represented?
Use the exact documented status and message, preserve the request history, and route it to the lender's error policy. Do not rewrite a provider error as no-match. Likewise, do not rewrite a cache absence as a provider error.
Cobalt's response-status documentation identifies failure and invalid-retry conditions separately from incomplete processing.[3] Internal exception codes should retain enough detail for support and replay decisions.
Define who may authorize a new attempt after a terminal error and how it relates to the old one. Preserve the first request, create a new attempt identity, and copy only approved search inputs. Never overwrite the failed history with a successful retry. This keeps support analysis possible and prevents two late completions from competing for the same terminal slot.
How Should the Final Live Result Close the Request?
What happens when live returns a match?
Store the raw live observation, receipt time, source, and correlation, then transition the request from live_pending_no_cache to the applicable terminal match state. Apply final verification and lender decision rules only after that transition.
The absence of an interim match should remain in the event history as a process fact. It should not count against the final record or appear as a prior failed verification.
What happens when live returns no match?
Store the terminal result and route it through the lender's documented no-match process. The result now comes from the completed live search, so operations may perform the approved exception steps, verify query inputs, or request additional evidence.
The no-match exception operations guide covers that later phase. This article's rule is narrower: do not enter it merely because interim cache data was absent.
How Should the Branch Be Tested and Measured?
Which test cases prove the distinction?
Test incomplete with no cachedData, incomplete with an empty optional array if allowed by the contract, delayed live match, delayed live no-match, callback completion, polling completion, duplicate completion, terminal error, invalid retryId, and user resubmission. Assert both the visible label and downstream business effects.
Create a negative assertion that live_pending_no_cache can never emit a final no-match event. Also assert that a live match can close the same request without manual repair.
Run the tests against every consumer that reacts to verification state, not only the API adapter. Inspect the underwriter screen, workflow queue, decision service, notification service, and reporting events. A correct core state can still produce harm if one consumer maps a blank interim observation to a terminal negative. The release passes only when every downstream surface preserves the pending meaning. Keep one approved trace as a regression fixture for future releases.
Which metrics are useful without overstating impact?
Measure how often the no-cache branch occurs, how long it remains pending, how it closes, how often users attempt resubmission, and how many illegal transitions are blocked. These are operational observations, not promised savings or approval improvements.
Log request identity, prior and next state, transport, status, reason, and action. OWASP recommends including event status, reason, and resulting action in application logs.[9] Protect sensitive data and follow lender retention policy.
Retain operational records according to the lender's approved schedule and access model. NIST describes log management as a lifecycle that includes generation, transmission, storage, access, and disposal.[10] The presence of one log event does not establish that a legal or examination requirement has been satisfied.
For the broader retry design, read Cobalt's retry and graceful-failure guide. To map the live-pending branch into your system, schedule a demo.












.png)