# Inspect

> Get customs data for every item in a photo with the border.bot API: name, description, quantity, category, material, 6-digit HS code, country of origin and value, each item with its box in the photo and a confidence on the code, origin and value.

Source: https://border.bot/docs/inspect
Last updated: 2026-10-22

> Documentation index: https://border.bot/llms.txt. Every page is Markdown at its URL + `.md`.


Inspect takes a photo of goods and returns customs data for every item in it: name, description, quantity, category, material, 6-digit HS code, country of origin and value. The HS code, origin and value each come with a confidence, every item has its box in the photo, and items below your review threshold are marked with the reasons. The [Inspect page](https://border.bot/inspect) explains how it works.

## Inspect a photo

```json
POST /v1/inspect
{
  "imageUrl": "https://shop.example/photos/parcel-0142.jpg"
}
```

| Field | |
| --- | --- |
| `imageUrl` | Required. The photo, as an https link or a base64 data URL (JPEG, PNG or WebP, up to 6 MB), the same as Classify's `imageUrl` |
| `language` | The language of each item's `name` and `description` (a BCP 47 tag, default `en`). The `customsDescription` is always English |

Send an `Idempotency-Key` header to make a retry safe, as on every billable request.

## What comes back

```json
{
  "data": {
    "items": [
      {
        "id": "item-1",
        "name": "Crew-neck T-shirt",
        "description": "A folded white crew-neck T-shirt in jersey knit",
        "customsDescription": "cotton knitted t-shirt",
        "quantity": { "value": 1, "unit": "piece" },
        "category": "Apparel",
        "materials": ["cotton"],
        "hsCode": {
          "code": "610910",
          "codeFormatted": "6109.10",
          "description": "Of cotton",
          "level": "subheading",
          "probability": 0.9
        },
        "origin": {
          "country": "VN",
          "probability": 1,
          "basis": "label",
          "evidence": "Made in Vietnam",
          "alternatives": []
        },
        "value": {
          "amount": 24,
          "low": 15,
          "high": 35,
          "currency": "USD",
          "probability": 0.6,
          "basis": "estimate"
        },
        "condition": "new",
        "detectedText": "100% cotton. Made in Vietnam",
        "region": { "x": 0.2, "y": 0.1, "w": 0.5, "h": 0.5 },
        "needsReview": false,
        "reviewReasons": []
      }
    ],
    "unreadable": null,
    "truncated": false,
    "calibrated": false
  },
  "credits": { "charged": 1, "remaining": 96, "usageId": "usg_01m5dc29tdkdmpffnd43jmg1w5" },
  "replayed": false
}
```

Each item:

| Field | |
| --- | --- |
| `name`, `description` | What the item is, in your language |
| `customsDescription` | An English description fit for a declaration |
| `quantity` | `value` and `unit` (`piece`, `pair`, `set` or `pack`) |
| `category` | The kind of product, in plain words |
| `materials` | What it is made of, main material first |
| `hsCode` | The 6-digit HS subheading (`level: "subheading"`), checked against the live tariff, with its official `description` and a `probability`. A subheading the tariff doesn't have is cut back to its heading (`level: "heading"`) and marked for review. Null when no heading matched |
| `origin` | Where it was made: `basis: "label"` when a "Made in" was read (quoted in `evidence`); `basis: "estimate"` when it was estimated where the item was most likely manufactured, from the brand's manufacturing footprint and where that kind of product is made, never from where the brand is based. An estimate is never above 0.6 and lists the other likely countries in `alternatives`. Null when there was nothing to go on |
| `value` | An estimated retail price of one unit (`amount`, `low`, `high`, in `currency` USD) and a `probability` that the price falls in the range. Null when the photo gives no idea |
| `condition` | `new`, `used` or `unknown` |
| `detectedText` | Label, brand and model text read off the item |
| `region` | Where the item is in the photo (`x`, `y`, `w`, `h` as fractions of its width and height), or null |
| `needsReview`, `reviewReasons` | Whether a person should check the item, and why |

Codes stay at six digits: the Harmonized System subheading every country shares. For a destination's full national line, classify the item with [`POST /v1/classify`](https://border.bot/docs/classify).

The value is an estimate, not the customs value: customs value is usually the price actually paid, which a photo can't show. Declare the price the buyer paid.

Beside `items`:

- `unreadable`: present when the photo shows no product, with the reason. The request is refunded.
- `truncated`: true when the photo held more items than were returned.
- `calibrated`: whether the probabilities are calibrated on photos with known answers. Until they are, they are the photo model's own confidence.

## Costs and limits

An inspection costs the Inspect price per photo (`GET /v1/pricing`) and is refunded if it fails or the photo shows no product. Photos follow Classify's limits.

## Also from

- **Free tool:** [HS code from a photo](https://border.bot/tools/hs-code-from-photo), no account needed.
- **MCP:** `inspect_photo` (see [MCP](https://border.bot/docs/mcp)).
- **Classify:** for a destination's full tariff line, one product at a time (see [Classify](https://border.bot/docs/classify)).
