> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tumban.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create scan

> Submit a single profile URL for analysis.

Submit a single profile URL for ToS compliance analysis. The request
returns a `scan_id` immediately; processing happens in the background.

The scan mode is selected by the path you call:

| Mode  | Endpoint                  | Behaviour                                                                                                                                                                           |
| ----- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Deep  | `POST /api/v2/scan/deep`  | Full analysis — profile data plus link traversal, social-media scraping, and external context search. Typically completes in under two minutes.                                     |
| Quick | `POST /api/v2/scan/quick` | Cheaper and faster — skips link traversal, social-media scraping, and external context search; runs a fast model on the profile data only. Typically completes in about 30 seconds. |

Both modes accept the same request body and return the same response
shape (the `scan_mode` field echoes which one ran). The resulting
[triage report](/api/scans/get) has the same fields in either mode;
read the [`coverage`](/concepts/coverage) object to see which steps a
quick scan skipped. See [Scan modes](/concepts/scans-and-batches#scan-modes)
for the full comparison.

```http theme={null}
POST /api/v2/scan/deep
POST /api/v2/scan/quick
```

## Request body

<ParamField body="profile_url" type="string" required>
  The creator profile URL to analyze. Must be a valid HTTP or HTTPS URL.
</ParamField>

<ParamField body="callback_url" type="string">
  HTTPS endpoint Tumban will `POST` the result to when the scan
  finishes. Optional: if omitted, Tumban falls back to the
  organization's [`default_callback_url`](/api/org/update-settings). If
  neither is set, the scan still runs and the result is available via
  [`GET /api/v2/scans/{scan_id}`](/api/scans/get) — no webhook is sent.
</ParamField>

<ParamField body="metadata" type="object" default="{}">
  Arbitrary JSON object echoed back in the webhook payload and
  persisted on the scan record. Use it to thread your own correlation
  ids (`reviewer_id`, `case_id`, etc.) through the pipeline.
</ParamField>

## Response

<ResponseField name="scan_id" type="string" required>
  UUID of the scan. Use it to poll
  [`GET /api/v2/scans/{scan_id}`](/api/scans/get).
</ResponseField>

<ResponseField name="status" type="string" required>
  Always `processing` on success. See
  [Status values](/reference/status).
</ResponseField>

<ResponseField name="submitted_at" type="string" required>
  ISO 8601 UTC timestamp of when Tumban accepted the scan.
</ResponseField>

<ResponseField name="estimated_completion" type="string" required>
  ISO 8601 UTC timestamp of the expected completion time. A deep scan
  typically finishes in under two minutes; a quick scan in about 30
  seconds.
</ResponseField>

<ResponseField name="scan_mode" type="string" required>
  Which mode ran: `deep` or `quick`. Echoes the endpoint you called.
</ResponseField>

## Example

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://api-v2.tumban.com/api/v2/scan/deep \
    -H "Authorization: Bearer sk_xxx" \
    -H "Content-Type: application/json" \
    -d '{
      "profile_url": "https://creator.example/username",
      "callback_url": "https://your-app.example/webhooks/tumban",
      "metadata": {"reviewer_id": "rv_42"}
    }'
  ```

  ```python python theme={null}
  import httpx

  response = httpx.post(
      "https://api-v2.tumban.com/api/v2/scan/deep",
      headers={"Authorization": "Bearer sk_xxx"},
      json={
          "profile_url": "https://creator.example/username",
          "callback_url": "https://your-app.example/webhooks/tumban",
          "metadata": {"reviewer_id": "rv_42"},
      },
  )
  ```

  ```js node theme={null}
  const res = await fetch("https://api-v2.tumban.com/api/v2/scan/deep", {
    method: "POST",
    headers: {
      Authorization: "Bearer sk_xxx",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      profile_url: "https://creator.example/username",
      callback_url: "https://your-app.example/webhooks/tumban",
      metadata: { reviewer_id: "rv_42" },
    }),
  });
  ```
</CodeGroup>

```json theme={null}
{
  "scan_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "processing",
  "submitted_at": "2026-04-29T12:00:00.123456+00:00",
  "estimated_completion": "2026-04-29T12:02:00.123456+00:00",
  "scan_mode": "deep"
}
```

To run a quick scan instead, call `/api/v2/scan/quick` with the same
body. The response is identical except `scan_mode` is `"quick"` and
`estimated_completion` is roughly 30 seconds out:

```bash theme={null}
curl -X POST https://api-v2.tumban.com/api/v2/scan/quick \
  -H "Authorization: Bearer sk_xxx" \
  -H "Content-Type: application/json" \
  -d '{"profile_url": "https://creator.example/username"}'
```

## Errors

| Status | Detail                                                                                                                                                                               |
| ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 422    | Body failed schema validation — typically a malformed `profile_url`. See [Errors → validation](/api/errors#error-envelope).                                                          |
| 429    | The org's `daily_scan_limit` has been hit. Body is a structured object: `{"error": "daily_scan_limit_exceeded", "limit": N, "used": N}`. See [Rate limits](/api/errors#rate-limits). |

## Using the dashboard

<Steps>
  <Step title="Open Scan">
    From the sidebar, click **Scan**.
  </Step>

  <Step title="Submit a profile URL">
    In the **Submit Scan** tile, paste the profile URL into the
    **Profile URL** field. By default the result is delivered via
    your organization's [default callback URL](/api/org/update-settings).

    To override per-scan, toggle **Send result to callback URL** on
    and enter a URL in the revealed **Callback URL** field.
  </Step>

  <Step title="Pick a scan mode">
    Under **Scan mode**, choose **Deep scan** (default) or **Quick
    scan**. Deep runs the full pipeline; quick is faster and cheaper
    and skips link traversal, social scraping, and external context
    search.
  </Step>

  <Step title="Submit and watch">
    Click **Submit Scan**. The new row appears at the top of the
    **Scans** table with status **Processing**. The page polls in-flight
    rows every five seconds and updates them in place. Click the row
    once it reaches a terminal status to open
    [Get scan](/api/scans/get) detail.
  </Step>
</Steps>
