Skip to main content
Fetch the full record for a scan, including the triage report once the scan has completed.
GET /api/v2/scans/{scan_id}

Path parameters

scan_id
string
required
The scan_id returned by POST /api/v2/scan/deep (or /scan/quick) or one of the per-profile ids from a batch.

Response

The response is the scan record. Fields you should rely on:
profile_id
string
required
Same value as scan_id. Tumban tracks scans and profile records under the same identifier.
batch_id
string
required
The batch id. Single scans (submitted via POST /api/v2/scan/deep or /scan/quick) get a synthetic single_<scan_id> batch id for internal bookkeeping; match on the single_ prefix to distinguish single-scan submissions from batched ones.
url
string
required
The submitted profile URL.
status
string
required
scan_mode
string
Which mode the scan ran in: deep or quick. A quick scan skips link traversal, social-media scraping, and external context search; the coverage object on the triage report reflects the skipped steps. May be absent on legacy scans submitted before scan modes existed (treat absent as deep).
created_at
string
required
ISO 8601 UTC timestamp of when the scan was submitted.
processing_started_at
string
When pipeline processing actually began. null while waiting for a concurrency slot.
processing_completed_at
string
When pipeline processing finished. null while still processing.
is_banned
boolean
Optional. Absent until the ban-checker has evaluated this profile — the key is omitted (not null) on fresh scans — then true if the creator has been banned by the upstream platform (e.g. 404 / 410 / redirect on the profile URL) or false if the profile is still live. Test for it with "is_banned" in response, not response["is_banned"] is None. Useful for skipping enforcement on already-banned creators.
callback_url
string
The callback URL the scan was submitted with (or the org default if not provided), as a string. Empty when no callback was configured.
metadata
object
The metadata you submitted with the scan, echoed back unchanged.
error
string
Present when status is failed. Brief description of what went wrong.
webhook_delivered_at
string
ISO 8601 UTC timestamp of successful webhook delivery. Absent when no callback was configured or delivery has not (yet) succeeded.
triage_report
object
Present once status reaches a terminal value with a usable result (completed). Shape below.

triage_report

recommendation
string
required
One of no_flags, review_low, review_medium, review_high. See Recommendation values.
risk_score
integer
required
0–100. See Recommendations.
confidence
string
required
low, medium, or high. See Confidence.
reason_codes
string[]
required
Machine-readable codes explaining the decision. See Reason codes.
reason_summary
string
required
Human-readable summary of what was found.
review_targets
string[]
required
URLs your reviewers should look at first.
Short label describing the path Tumban followed (e.g. Profile -> External site).
evidence_index
object[]
Per-URL evidence Tumban cited in support of the decision. See Evidence index.

Coverage

Poll responses include the coverage object too — it lives at triage_report.coverage on GET /api/v2/scans/{scan_id}. On the webhook payload the same object is delivered as a top-level coverage key. Same fields either way; only the placement differs. The scan’s status is completed even when individual steps were skipped — read coverage to see what ran.

Example

curl https://api-v2.tumban.com/api/v2/scans/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer sk_xxx"
{
  "profile_id": "550e8400-e29b-41d4-a716-446655440000",
  "batch_id": "single_550e8400-e29b-41d4-a716-446655440000",
  "url": "https://creator.example/username",
  "status": "completed",
  "scan_mode": "deep",
  "created_at": "2026-04-29T12:00:00.123456+00:00",
  "processing_started_at": "2026-04-29T12:00:01.234567+00:00",
  "processing_completed_at": "2026-04-29T12:01:38.987654+00:00",
  "is_banned": false,
  "callback_url": "https://your-app.example/webhooks/tumban",
  "metadata": {"reviewer_id": "rv_42"},
  "webhook_delivered_at": "2026-04-29T12:01:39.345678+00:00",
  "triage_report": {
    "recommendation": "review_high",
    "risk_score": 85,
    "confidence": "high",
    "reason_codes": ["PROHIBITED_DOMAIN", "ADULT_KEYWORDS"],
    "reason_summary": "Direct link to a prohibited platform combined with adult keywords in bio.",
    "review_targets": ["https://prohibited-platform.example/username"],
    "link_chain": "Profile -> External site",
    "evidence_index": [
      {
        "ref": "link_1",
        "url": "https://prohibited-platform.example/username",
        "type": "traversed_link",
        "domain": "prohibited-platform.example"
      }
    ]
  }
}
The response also includes internal fields not listed above. These reflect the underlying scan record and are subject to change. Do not rely on their names, types, or presence; treat them as opaque.

Errors

StatusDetail
404Scan not found — the scan id does not exist within your organization.

Using the dashboard

Click any non-processing scan row from the Home page or the Scan page to open the scan detail. The page renders these read-only sections:
  • Summary — profile URL, scan id, status, submitted/completed timestamps, webhook delivery timestamp, error.
  • Triage — recommendation badge, risk score, confidence, reason codes, reason summary.
  • Coverage — which analysis steps ran, login-blocked URLs, referrer match counts.
  • Raw JSON — collapsible “Show full document” panel that exposes the entire scan record.