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

# Quickstart

> Get a token, submit a document, and poll for the result.

Set these environment variables using the credentials provided by Trelent.
See [Authentication](/document-verification/authentication#get-credentials) for details.

| Variable                | Value                      |
| ----------------------- | -------------------------- |
| `TRELENT_API_URL`       | Your deployment’s base URL |
| `TRELENT_CLIENT_ID`     | Your client ID             |
| `TRELENT_CLIENT_SECRET` | Your client secret         |

Typical turnaround is **60–120 seconds**, with processing time continually
improving.

## Three requests

This cURL outline shows the flow with abbreviated responses. Copy the returned
token into `ACCESS_TOKEN` and the detection ID into `DETECTION_ID` before
sending the next request.

```bash theme={null}
# 1. Get a token.
curl -X POST "$TRELENT_API_URL/token" \
  --data-urlencode "grant_type=client_credentials" \
  --data-urlencode "client_id=$TRELENT_CLIENT_ID" \
  --data-urlencode "client_secret=$TRELENT_CLIENT_SECRET" \
  --data-urlencode "scope=DocumentVerification:*"
# { "access_token": "eyJhbGciOi...", ... }

# 2. Create a detection. Replace the example URL with your document URL.
curl -X POST "$TRELENT_API_URL/v1/detection" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "source_url": "https://files.example.com/id-card.pdf",
    "doc_type": "id_card",
    "region": "BR"
  }'
# { "id": "detection-...", "status": "QUEUED", ... }

# 3. Repeat every 5 seconds until COMPLETED or FAILED.
curl "$TRELENT_API_URL/v1/detection/$DETECTION_ID" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
# { "id": "detection-...", "status": "COMPLETED", "score": 87, ... }
```

## Run the flow

The Python example uses `requests`; the TypeScript example uses Node.js with
built-in `fetch`. Both stop polling on success or failure and allow up to
40 minutes before timing out.

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    import os
    import time
    import requests

    base = os.environ["TRELENT_API_URL"].rstrip("/")

    # 1. Get a token.

    response = requests.post(f"{base}/token", data={
    "grant_type": "client_credentials",
    "client_id": os.environ["TRELENT_CLIENT_ID"],
    "client_secret": os.environ["TRELENT_CLIENT_SECRET"],
    "scope": "DocumentVerification:\*",
    }, timeout=10)
    response.raise_for_status()
    headers = {"Authorization": f"Bearer {response.json()['access_token']}"}

    # 2. Create a detection.

    response = requests.post(f"{base}/v1/detection", headers=headers, json={
    "source_url": "https://files.example.com/id-card.pdf",
    "doc_type": "id_card",
    "region": "BR",
    }, timeout=120)
    response.raise_for_status()
    detection_id = response.json()["id"]

    # 3. Poll for the result.

    deadline = time.monotonic() + 2400
    while time.monotonic() < deadline:
    response = requests.get(
    f"{base}/v1/detection/{detection_id}", headers=headers, timeout=30,
    )
    response.raise_for_status()
    detection = response.json()
    if detection["status"] == "FAILED":
    raise RuntimeError(detection["failure_message"])
    if detection["status"] == "COMPLETED":
    print(detection["score"])
    break
    time.sleep(5)
    else:
    raise TimeoutError(f"Detection {detection_id} is still pending")

    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    const base = process.env.TRELENT_API_URL!.replace(/\/$/, "");
    const readJson = async (response: Response) => {
      if (!response.ok) throw new Error(`HTTP ${response.status}`);
      return response.json();
    };

    // 1. Get a token.
    const { access_token } = await readJson(await fetch(`${base}/token`, {
      method: "POST",
      body: new URLSearchParams({
        grant_type: "client_credentials",
        client_id: process.env.TRELENT_CLIENT_ID!,
        client_secret: process.env.TRELENT_CLIENT_SECRET!,
        scope: "DocumentVerification:*",
      }),
      signal: AbortSignal.timeout(10_000),
    }));
    const headers = { Authorization: `Bearer ${access_token}` };

    // 2. Create a detection.
    const { id } = await readJson(await fetch(`${base}/v1/detection`, {
      method: "POST",
      headers: { ...headers, "Content-Type": "application/json" },
      body: JSON.stringify({
        source_url: "https://files.example.com/id-card.pdf",
        doc_type: "id_card",
        region: "BR",
      }),
      signal: AbortSignal.timeout(120_000),
    }));

    // 3. Poll for the result.
    const deadline = Date.now() + 2_400_000;
    while (true) {
      if (Date.now() >= deadline) throw new Error(`Detection ${id} is still pending`);
      const detection = await readJson(await fetch(`${base}/v1/detection/${id}`, {
        headers,
        signal: AbortSignal.timeout(30_000),
      }));
      if (detection.status === "FAILED") throw new Error(detection.failure_message);
      if (detection.status === "COMPLETED") {
        console.log(detection.score);
        break;
      }
      await new Promise((resolve) => setTimeout(resolve, 5000));
    }
    ```
  </Tab>
</Tabs>

Display the score and detailed reasoning in your platform for human review
of high-risk documents. A higher score means a higher likelihood of fraud, but
does not guarantee fraud. Humans should always review high-risk cases.

Some completed detections have a null
score and an `authoritative` finding instead. See
[Get a detection](/document-verification/api-reference/get-a-detection) for
result fields, and
[Start a detection](/document-verification/api-reference/start-a-detection)
for supported inputs and request errors.

For sample allowances, see [Billing](/document-verification/billing). To try
requests interactively, download an
[API collection](/document-verification/api-collection).
