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

# Spotter

> Identify the company behind a visitor in real time, directly in your customer's browser.

Spotter lets a page running your Radar script ask which company is visiting, while the visitor is still on the page. Your customers can use it to personalize content or trigger their own workflows, without waiting for a webhook.

> [!WARNING]
>
> Spotter might not be enabled for your account yet. Contact support to enable it.

> [!NOTE]
>
> Each identified visitor IP uses reveal credits on your plan. See [Credits and Usage](#credits-and-usage).

## Enable Spotter

Once Spotter is enabled for your account, it's still off for each tracking script until you turn it on. To do that, set `spotter_enabled` and make sure the script has at least one domain. You can do both when you create a script or on an existing one:

```bash Existing script theme={null}
curl -X PATCH 'https://api.snitcher.com/radar/operator/v1/tracking-scripts/YOUR_TRACKING_SCRIPT_ID' \
     -H 'Authorization: Bearer YOUR_API_KEY' \
     -H 'Content-Type: application/json' \
     -d '{
       "domains": ["example.com"],
       "spotter_enabled": true
     }'
```

```bash New script theme={null}
curl -X POST 'https://api.snitcher.com/radar/operator/v1/tracking-scripts' \
     -H 'Authorization: Bearer YOUR_API_KEY' \
     -H 'Content-Type: application/json' \
     -d '{
       "internal_identifier": "customer-abc-123",
       "domains": ["example.com"],
       "spotter_enabled": true
     }'
```

A change can take up to 10 minutes to apply. Set `spotter_enabled` to `false` to turn Spotter off again. The script keeps its domains.

If Spotter isn't enabled for your account, turning it on returns a `422`. Scripts keep their `spotter_enabled` value if Spotter is later turned off for your account, but browser calls are refused until it's back on.

### Which Domains Can Call Spotter

Spotter uses the same `domains` list as event ingestion:

| Entry | Spotter accepts |
| - | - |
| `example.com` | `example.com` and all of its subdomains |
| `shop.example.com` | `shop.example.com` only |

> [!WARNING]
>
> Spotter needs at least one domain, so that other websites can't spend your credits. The API returns a `422` if you enable Spotter on a script without domains, or remove all domains while Spotter is enabled.

## Get the Identification

Call `getSpotterIdentification()` once the tracker has loaded. It isn't available before then, so call it from an `initialized` listener added right after the loader script:

```javascript theme={null}
YourAppName.on('initialized', async () => {
  const identification = await YourAppName.getSpotterIdentification();

  if (identification?.success) {
    console.log('Company:', identification.data.name);
    console.log('Industry:', identification.data.industry);
  }
});
```

If a visitor has already been identified in this browser session, the tracker returns the stored result without making another request.

### Response

```javascript theme={null}
{
  success: true,
  data: {
    uuid: "abc123",
    name: "Acme Corporation",
    website: "acme.com",
    email: "info@acme.com",
    phone: "+1-555-0100",
    industry: "Software",
    founded: 2010,
    size: "51-200 employees",
    logo: "https://...",
    address: {
      street: "Market Street",
      street_number: "123",
      postal_code: "94102",
      city: "San Francisco",
      state: "California",
      country: "United States",
      full_address: "123 Market Street, San Francisco, CA 94102",
      latitude: 37.7749,
      longitude: -122.4194
    },
    profiles: [
      { name: "linkedin", handle: "acme-corp", url: "https://linkedin.com/company/acme-corp" }
    ],
    tags: [],
    segments: []
  }
}
```

This data reaches the visitor's browser, so anyone on the page can read it.

### When There Is No Result

`getSpotterIdentification()` resolves to `undefined` and logs a warning to the console when:

* The visitor can't be matched to a company
* Spotter is off for this script or for your account
* The page isn't on one of the script's domains
* Your reveal credits have run out

Always check for a result before using it.

## Credits and Usage

Each successful identification is logged as a reveal:

* You pay one credit per visitor IP, per tracking script, per monthly window. Repeat calls for the same IP in that window don't cost more.
* Spotter shares this count with the IP to Company API and with webhook reveals, so an IP revealed through more than one of them still costs one credit.
* Visitors Spotter can't identify don't cost a credit.
* Once your reveal credits run out, Spotter stops returning identifications.

To see your usage, call `GET /radar/operator/v1/company/usage`. `revealUsage` is what you're billed for. `apiUsage` and `spotterUsage` split it by where the reveal came from. An IP revealed through both counts in each, so the two can add up to more than `revealUsage`.

> [!NOTE]
>
> Spotter only runs when a page asks for it: when it calls `getSpotterIdentification()`, or when it has a `window.SpotterSettings.callback` set before the loader script.

## Using Your Own Proxy

Spotter requests go through the API host in your loader script, and rely on two things reaching Radar:

* **The `Origin` header**, to check the domain. Without it, the request is refused.
* **The visitor's IP address**, to identify the company.

The [CloudFront setup](https://docs.snitcher.com/powered-by-snitcher/radar/installation.md) in the installation guide already forwards both. If you use a different proxy, make sure it does too.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.