Status polling pattern
The typical polling flow looks like this:1
Create submission
POST to create a submission and read the
submissionId.2
Poll status
GET the submission at regular intervals.
3
Check completion
When the submission is
complete, partial, or failed, stop polling. queued and processing are both non-terminal — keep polling through them.4
Retrieve results
Fetch each asset’s result and its issues or clustered topics.
Getting submission status
UseGET /api/submissions/{submission_id} — there is no /status suffix.
errorMessage, errorType, isRetryable, retryCount — not a nested error object. The terminal submission statuses are complete, partial, and failed. A queued status means every asset is accepted and waiting for a free review slot — it is non-terminal, so keep polling.
Assets are admitted to review a few at a time, so don’t infer progress from the submission status alone: it reads processing as soon as the first asset starts and stays there until the last one settles. Read assets[].processingStatus to see which assets are still queued versus already compliant / in_review / failed.
startedAt and completedAt report when work actually happened, so completedAt - startedAt is the real processing time. Both are per attempt: they sit at null while an asset waits in the queue, and a retry re-stamps startedAt and clears completedAt. completedAt is set for any terminal outcome, so on a failed asset it is the failure time rather than a success time. At the submission level, startedAt is the earliest asset start.
Polling strategy
Basic polling loop
Exponential backoff
For long-running submissions, start with short intervals and back off over time:Retrieving results
Once an asset is done, fetch its result withGET /api/submissions/{submission_id}/assets/{asset_id}. The result includes the asset’s status, issueCount, and an issues array. For the flat enriched issue list call .../assets/{asset_id}/issues; for AI-clustered topics call .../assets/{asset_id}/topics.
severity is one of CRITICAL | MAJOR | MINOR | INFO, and issue status is one of OPEN | ACKNOWLEDGED | AWAITING_HUMAN_INPUT | RESOLVED | DISMISSED.
The clustered topics endpoint returns { "assetId", "topics", "orphanIssues", "metadata" }. Topics group two or more related issues; orphanIssues are unclustered singletons and are normal. The issues and topics endpoints return 404 if the asset has not finished processing yet.
Complete polling example
A full end-to-end example:Polling recommendations
Polling vs webhooks
For production systems with high volume, webhooks are recommended. See Webhook subscriptions.
Handling timeouts
If a submission does not finish within your timeout:- Re-fetch the submission later — it may simply still be processing.
- Check the per-asset
errorMessage,errorType, andisRetryablefields. - Retry a failed, retryable asset with
POST .../assets/{asset_id}/retry. - Switch to webhooks for more reliable completion detection.