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

# GET /v1/verify/upi — Verify a UPI VPA for Mule Risk

> Check a single UPI Virtual Payment Address against the FraudTrace mule intelligence database and receive a structured risk verdict with evidence.

The Verify UPI endpoint lets you look up any UPI Virtual Payment Address (VPA) against the FraudTrace mule intelligence database in real time. You receive a structured verdict — `FLAGGED` or `CLEARED` — along with a confidence score, a risk category, cluster membership details, and the evidence sources that informed the decision. Use this endpoint for point-of-payment checks, onboarding screening, or manual investigations.

## Endpoint

<ParamField header="Authorization" type="string" required>
  Your API key, passed as a Bearer token: `Authorization: Bearer YOUR_API_KEY`
</ParamField>

**`GET https://api.fraudtraceai.com/v1/verify/upi`**

***

## Query Parameters

<ParamField query="upi" type="string" required>
  The UPI Virtual Payment Address (VPA) to check. Must be a valid VPA in the format `handle@provider` (e.g., `user@ybl`, `merchant@okaxis`).
</ParamField>

***

## Request Examples

<CodeGroup>
  ```bash cURL theme={null}
  curl -G https://api.fraudtraceai.com/v1/verify/upi \
    -H "Authorization: Bearer YOUR_API_KEY" \
    --data-urlencode "upi=xxxxx@ybl"
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://api.fraudtraceai.com/v1/verify/upi",
      headers={"Authorization": "Bearer YOUR_API_KEY"},
      params={"upi": "xxxxx@ybl"},
  )

  data = response.json()
  print(data["status"])       # "FLAGGED" or "CLEARED"
  print(data["confidence"])   # e.g. 0.94
  ```

  ```javascript Node.js theme={null}
  const params = new URLSearchParams({ upi: "xxxxx@ybl" });

  const response = await fetch(
    `https://api.fraudtraceai.com/v1/verify/upi?${params}`,
    {
      headers: {
        Authorization: "Bearer YOUR_API_KEY",
      },
    }
  );

  const data = await response.json();
  console.log(data.status);      // "FLAGGED" or "CLEARED"
  console.log(data.confidence);  // e.g. 0.94
  ```
</CodeGroup>

***

## Response

The response body is a JSON object. When the VPA has been identified as a mule-linked account, `status` is `FLAGGED` and all risk fields are populated. When no intelligence matches the VPA, `status` is `CLEARED` and risk fields return `null` or empty values.

### FLAGGED Response

```json theme={null}
{
  "upi": "xxxxx@ybl",
  "status": "FLAGGED",
  "confidence": 0.94,
  "risk_category": "mule",
  "cluster_id": "MC-2104",
  "cluster_size": 7,
  "first_seen": "2025-11-14T08:22:00Z",
  "last_seen": "2026-04-01T16:45:00Z",
  "sources": [
    {
      "url": "https://bet-quick-in.com",
      "category": "gambling",
      "captured_at": "2025-12-01T10:00:00Z",
      "screenshot_available": true
    },
    {
      "url": "https://spinwin-247.net",
      "category": "gambling",
      "captured_at": "2026-01-15T14:30:00Z",
      "screenshot_available": true
    }
  ],
  "evidence_count": 3
}
```

### CLEARED Response

```json theme={null}
{
  "upi": "clean99@okaxis",
  "status": "CLEARED",
  "confidence": null,
  "risk_category": null,
  "cluster_id": null,
  "cluster_size": 0,
  "first_seen": null,
  "last_seen": null,
  "sources": [],
  "evidence_count": 0
}
```

### Response Fields

<ResponseField name="upi" type="string">
  The UPI VPA that was queried. Echoed back for easy correlation in your application.
</ResponseField>

<ResponseField name="status" type="string">
  The risk verdict for this VPA. One of:

  * `FLAGGED` — the VPA appears in the mule intelligence database
  * `CLEARED` — no intelligence match found
</ResponseField>

<ResponseField name="confidence" type="float | null">
  A score between `0.0` and `1.0` indicating how confidently FraudTrace has identified this VPA as a mule-linked account. Higher values indicate stronger evidence. Returns `null` when `status` is `CLEARED`.
</ResponseField>

<ResponseField name="risk_category" type="string | null">
  The primary risk category associated with the VPA. Returns `null` when `status` is `CLEARED`. Possible values:

  * `mule` — account used to move illicit funds
  * `gambling` — account linked to illegal gambling platforms
  * `phishing` — account used in phishing campaigns
  * `scam` — account associated with known scam operations
  * `nbfc_impersonation` — account impersonating an NBFC or regulated lender
</ResponseField>

<ResponseField name="cluster_id" type="string | null">
  The identifier of the mule cluster this VPA belongs to (e.g., `MC-2104`). Returns `null` when the VPA is `CLEARED` or when it is flagged but not yet assigned to a cluster. Use this ID with the [Cluster Lookup](/api-reference/muletrace/cluster-lookup) endpoint to retrieve all members of the cluster.
</ResponseField>

<ResponseField name="cluster_size" type="integer">
  The number of VPAs in the cluster identified by `cluster_id`. Returns `0` when the VPA is `CLEARED` or not part of a cluster.
</ResponseField>

<ResponseField name="first_seen" type="string | null">
  ISO 8601 timestamp of when this VPA first appeared in FraudTrace intelligence sources. Returns `null` when `status` is `CLEARED`.
</ResponseField>

<ResponseField name="last_seen" type="string | null">
  ISO 8601 timestamp of the most recent intelligence capture involving this VPA. Returns `null` when `status` is `CLEARED`.
</ResponseField>

<ResponseField name="sources" type="array">
  An array of evidence source objects that link this VPA to mule or fraud activity. Returns an empty array when `status` is `CLEARED`.

  <Expandable title="source object fields">
    <ResponseField name="sources[].url" type="string">
      The URL of the web page or online source where this VPA was observed.
    </ResponseField>

    <ResponseField name="sources[].category" type="string">
      The category of the source page. One of: `gambling`, `phishing`, `scam`, `telegram`.
    </ResponseField>

    <ResponseField name="sources[].captured_at" type="string">
      ISO 8601 timestamp of when FraudTrace captured the evidence from this source.
    </ResponseField>

    <ResponseField name="sources[].screenshot_available" type="boolean">
      Whether a screenshot of the source page is archived and available for review. Contact FraudTrace support to request archived screenshots for compliance or legal purposes.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="evidence_count" type="integer">
  The total number of distinct evidence items associated with this VPA across all sources. Returns `0` when `status` is `CLEARED`.
</ResponseField>

***

## Error Codes

| HTTP Status                 | Meaning                                                                               |
| --------------------------- | ------------------------------------------------------------------------------------- |
| `400 Bad Request`           | The `upi` query parameter is missing or not a valid VPA format.                       |
| `401 Unauthorized`          | The `Authorization` header is missing or the API key is invalid.                      |
| `429 Too Many Requests`     | You have exceeded your rate limit. Check the `Retry-After` header for the wait time.  |
| `500 Internal Server Error` | An unexpected error occurred on the FraudTrace side. Retry with exponential back-off. |

<Warning>
  A `CLEARED` response means the VPA was not found in the FraudTrace intelligence database at the time of the query. It does not guarantee the VPA is free of risk — new intelligence is ingested continuously. For high-value transactions, consider combining this check with additional due diligence signals.
</Warning>

<Tip>
  If a VPA returns `cluster_id`, call [GET /v1/verify/upi/cluster/{id}](/api-reference/muletrace/cluster-lookup) to see the full scope of the associated mule network before making a block or allow decision.
</Tip>
