# Bulk scam lookup API

Bewary's batch API runs up to 1,000 lookups of any type (links, domains, phone numbers, short codes, emails, IP addresses, wallets, IBANs, apps and payment handles) in one request, at 1 credit each. Results come back in your order, and an invalid item gets an error entry and is not charged. It needs an API key. A call costs 1 credit, a free key gets 1,000 credits a month, no card.

Updated 2026-10-30.

## At a glance

- Endpoint: POST https://api.bewary.app/v1/batch
- Price: 1 credit
- Free key: 1,000 credits a month, no card
- Returns: verdict, p_scam, entities with typed facts, reason codes

## Used for

- Back-filling reputation for a list of domains or numbers.
- Nightly re-checks of the links in your database.
- Scoring a CSV of leads.

## Call it

curl:

```bash
curl -X POST "https://api.bewary.app/v1/batch" \
  -H "Authorization: Bearer $BEWARY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"items":[{"type":"domain","value":"paypal-login-secure.top"},{"type":"email","value":"signup@mailinator.com"},{"type":"phone","value":"+18008291040"}]}'
```

Python:

```python
import os
import requests

r = requests.post(
    "https://api.bewary.app/v1/batch",
    json={
        "items": [{"type":"domain","value":"paypal-login-secure.top"},{"type":"email","value":"signup@mailinator.com"},{"type":"phone","value":"+18008291040"}],
    },
    headers={"Authorization": f"Bearer {os.environ['BEWARY_API_KEY']}"},
    timeout=120,
)
result = r.json()
for item in result["results"]:
    print(item.get("verdict") or item["error"]["code"])
```

JavaScript:

```javascript
const res = await fetch("https://api.bewary.app/v1/batch", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.BEWARY_API_KEY}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "items": [
      {
        "type": "domain",
        "value": "paypal-login-secure.top"
      },
      {
        "type": "email",
        "value": "signup@mailinator.com"
      },
      {
        "type": "phone",
        "value": "+18008291040"
      }
    ]
  }),
})
const result = await res.json()
for (const item of result.results) console.log(item.verdict ?? item.error.code)
```

## Act on the result

Python:

```python
import os, requests

items = [{"type": "domain", "value": "paypal-login-secure.top"},
         {"type": "email", "value": "signup@mailinator.com"},
         {"type": "phone", "value": "+18008291040"}]
r = requests.post("https://api.bewary.app/v1/batch", json={"items": items},
                  headers={"Authorization": f"Bearer {os.environ['BEWARY_API_KEY']}"}, timeout=120)
r.raise_for_status()
for item, res in zip(items, r.json()["results"]):
    print(item["value"], res.get("verdict") or res["error"]["code"])
```

TypeScript, with the types from https://bewary.app/types/bewary.d.ts:

```typescript
import type { BatchResponse } from "./bewary"

const items = [
  { type: "domain", value: "paypal-login-secure.top" },
  { type: "email", value: "signup@mailinator.com" },
]
const res = await fetch("https://api.bewary.app/v1/batch", {
  method: "POST",
  headers: { "Content-Type": "application/json", Authorization: `Bearer ${process.env.BEWARY_API_KEY}` },
  body: JSON.stringify({ items }),
  signal: AbortSignal.timeout(120_000),
})
const batch: BatchResponse = await res.json()
batch.results.forEach((r, i) => console.log(items[i].value, "verdict" in r ? r.verdict : r.error.code))
```

## The fields you will use

- `results[]`: One per item, in your order: a lookup answer, or {error: {code}}.
- `credits`: Credits charged: one per valid item.

## Response type

From https://bewary.app/types/bewary.d.ts:

```typescript
export interface BatchResponse {
  schema_version: string
  request_id: string
  checked_at: string
  /** Credits charged: one per valid item. */
  credits: number
  /** In the order of items. */
  results: Array<Envelope | BatchError>
}

export interface BatchError {
  error: ItemError
}
```

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `items` | body | array | yes |  |
| `items[].type` | body | domain \| url \| ip \| phone \| shortcode \| email \| wallet \| iban \| app \| payment_handle | yes | What value is: domain, url, ip, phone, shortcode (US), email, wallet, iban, app (a store link, or apple:<id> / google_play:<package>). |
| `items[].value` | body | string | yes |  |
| `items[].claimed_country` | body | string | no | iban only: the country the payee claims, ISO 3166-1 alpha-2 (IBAN_COUNTRY_MISMATCH). |

## Questions

### How do I check a list of domains or phone numbers at once?

POST up to 1,000 items to /v1/batch, each {type, value}. Types can be mixed in one request.

### Are invalid items charged?

No. They get {error: {code: invalid_input}} in their place and cost nothing.
