> For the complete documentation index, see [llms.txt](https://docs.stopbot.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.stopbot.net/v2/api-v2-documentation/smarturls.md).

# SmartURLs

SmartURLs combines shortlink configuration with visitor IP, user agent, device, country, hostname, and reputation checks before returning the final redirect decision.

### Endpoint

```
GET https://api.stopbot.net/services/shorterlink
```

### Parameters

| Parameter | Required | Description                              |
| --------- | -------- | ---------------------------------------- |
| `apikey`  | Yes      | Your STOPBOT API key                     |
| `ip`      | Yes      | Visitor IPv4 or IPv6 address             |
| `keyname` | Yes      | SmartURLs keyname from the STOPBOT panel |
| `ua`      | No       | Visitor user agent                       |
| `url`     | No       | Current requested URL or path            |

### Parameter Rules

| Parameter | Rule                                                                |
| --------- | ------------------------------------------------------------------- |
| `ip`      | Must be a valid IPv4 or IPv6 address                                |
| `keyname` | Must be 1-64 characters using `A-Z`, `a-z`, `0-9`, `.`, `_`, or `-` |
| `ua`      | Optional user agent value used for device and bot/crawler detection |
| `url`     | Optional requested URL or path                                      |

If `keyname` is invalid, inactive, removed, or not registered for the API key owner, SmartURLs returns a success response with `detectActivity: BLOCK BY INVALID KEYNAME`.

### Example Request

```bash
curl "https://api.stopbot.net/services/shorterlink?apikey={API_KEY}&ip=1.1.1.1&keyname={KEYNAME}&ua={USER_AGENT}&url=https%3A%2F%2Fexample.com"
```

### Example Response

```json
{
  "ip": "1.1.1.1",
  "hostname": "one.one.one.one",
  "asn": 13335,
  "userType": "hosting",
  "connectionType": "Corporate",
  "company": "Cloudflare, Inc.",
  "isp": "Cloudflare, Inc.",
  "city": "Sydney",
  "district": "",
  "region": "New South Wales",
  "postcode": "1001",
  "country": "Australia",
  "countryCode": "AU",
  "latitude": -33.8688,
  "longitude": 151.209,
  "timezone": "Australia/Sydney",
  "isAnycast": true,
  "device": "Desktop",
  "ua": "{USER_AGENT}",
  "isBot": 1,
  "blockAccess": 0,
  "threatURL": 0,
  "detectActivity": "BLOCK BY HOSTNAME DATABASE.",
  "redirectTo": "https://www.google.com",
  "jsResponse": 1,
  "uniqueCode": "abc123def4567890",
  "status": "success",
  "executionTime": "4.44ms",
  "timeResponse": "2026-07-07 12:00:00"
}
```

### Invalid Input Example

If the `ip` parameter is missing or is not a valid IPv4/IPv6 address, SmartURLs returns `400 Bad Request`.

```bash
curl "https://api.stopbot.net/services/shorterlink?apikey={API_KEY}&ip=not-an-ip&keyname={KEYNAME}"
```

Example response:

```json
{
  "status": "error",
  "errorMessage": "Please enter a valid IP FORMAT.",
  "executionTime": "9.4us",
  "timeResponse": "2026-07-07 12:00:00"
}
```

### Invalid Keyname Example

Invalid, inactive, removed, or unowned keynames do not return a validation error. They return a normal JSON response with a block decision.

```json
{
  "ip": "1.1.1.1",
  "hostname": "one.one.one.one",
  "asn": 13335,
  "userType": "hosting",
  "connectionType": "Corporate",
  "company": "Cloudflare, Inc.",
  "isp": "Cloudflare, Inc.",
  "city": "Sydney",
  "district": "",
  "region": "New South Wales",
  "postcode": "1001",
  "country": "Australia",
  "countryCode": "AU",
  "latitude": -33.8688,
  "longitude": 151.209,
  "timezone": "Australia/Sydney",
  "isAnycast": true,
  "device": "Desktop",
  "ua": "{USER_AGENT}",
  "isBot": 1,
  "blockAccess": 1,
  "threatURL": 0,
  "detectActivity": "BLOCK BY INVALID KEYNAME",
  "status": "success",
  "executionTime": "3.90ms",
  "timeResponse": "2026-07-07 12:00:00"
}
```

### Response Fields

Successful SmartURLs responses may include the following fields:

| Field            | Description                                                                                                                                                        |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `ip`             | Visitor IP address from the `ip` request parameter                                                                                                                 |
| `hostname`       | Hostname or PTR value resolved for the visitor IP. If no hostname is available, the IP itself may be returned                                                      |
| `asn`            | Autonomous System Number from IP geolocation data                                                                                                                  |
| `userType`       | Network user type from IP geolocation data. Current values are `business`, `cellular`, `hosting`, and `residential`. If unavailable, STOPBOT returns `unknown`     |
| `connectionType` | Network connection type from IP geolocation data. Current values are `Cable/DSL`, `Cellular`, `Corporate`, and `Dialup`. If unavailable, STOPBOT returns `unknown` |
| `company`        | Autonomous system organization or company name from IP geolocation data. If unavailable, STOPBOT returns `unknown`                                                 |
| `isp`            | Internet service provider name from IP geolocation data. If unavailable, STOPBOT returns `unknown`                                                                 |
| `city`           | City name from IP geolocation data. If unavailable, STOPBOT may return `unknown`                                                                                   |
| `district`       | District or second subdivision from IP geolocation data when available                                                                                             |
| `region`         | Region or first subdivision from IP geolocation data. If unavailable, STOPBOT may return `unknown`                                                                 |
| `postcode`       | Postal code from IP geolocation data when available                                                                                                                |
| `country`        | Country name from IP geolocation data. If unavailable, STOPBOT returns `unknown`                                                                                   |
| `countryCode`    | Country ISO code from IP geolocation data. If unavailable, STOPBOT returns `NN`                                                                                    |
| `latitude`       | Latitude from IP geolocation data. If unavailable, the value may be `0`                                                                                            |
| `longitude`      | Longitude from IP geolocation data. If unavailable, the value may be `0`                                                                                           |
| `timezone`       | Timezone from IP geolocation data. If unavailable, STOPBOT returns `UTC`                                                                                           |
| `isAnycast`      | `true` when the IP geolocation data marks the IP as anycast; otherwise `false`                                                                                     |
| `device`         | Device classification derived from the `ua` request parameter                                                                                                      |
| `ua`             | User agent value from the request. This field is only included when `ua` is provided                                                                               |
| `isBot`          | Visitor classification signal: `0` visitor/non-bot, `1` detected bot/threat, `2` user list match                                                                   |
| `blockAccess`    | `1` means blocked redirect behavior should be applied; `0` means normal redirect behavior can be used                                                              |
| `threatURL`      | `1` when the request is treated as threat-related; otherwise `0`                                                                                                   |
| `detectActivity` | Detection reason returned by the SmartURLs decision flow                                                                                                           |
| `redirectTo`     | Destination URL returned when the keyname configuration is found                                                                                                   |
| `jsResponse`     | JavaScript verification setting from the SmartURLs configuration. `1` means verification is enabled                                                                |
| `uniqueCode`     | Verification token returned when JavaScript verification is enabled                                                                                                |
| `status`         | API result status                                                                                                                                                  |
| `executionTime`  | Server-side execution time for the request                                                                                                                         |
| `timeResponse`   | Response timestamp in `YYYY-MM-DD HH:mm:ss` format                                                                                                                 |

### Redirect Fields

| Field         | Description                                                                                                     |
| ------------- | --------------------------------------------------------------------------------------------------------------- |
| `redirectTo`  | Destination URL your SmartURLs client should use                                                                |
| `jsResponse`  | JavaScript verification setting from the SmartURLs configuration. `1` means verification is enabled             |
| `uniqueCode`  | Present only when `jsResponse` is `1` and a verification token was generated                                    |
| `blockAccess` | `1` means SmartURLs selected the blocked redirect behavior; `0` means SmartURLs selected the normal destination |

Use `blockAccess` and `redirectTo` for the final action. The `detectActivity` field explains the detection reason and may still contain a block reason when the configuration is set to monitor or allow the visitor.

Do not use `isBot` as the final redirect decision. SmartURLs can block or redirect a human/non-bot visitor based on your keyname configuration. For example, a country restriction can return:

```json
{
  "isBot": 0,
  "blockAccess": 1,
  "detectActivity": "BLOCK BY COUNTRY."
}
```

In this case, the visitor is not classified as a bot, but the SmartURLs client should still use the blocked `redirectTo` value because `blockAccess` is `1`.

### JavaScript Verification Flow

When JavaScript verification is enabled for the keyname, the normal SmartURLs response includes `uniqueCode`.

The browser should complete verification before the final redirect. Your SmartURLs client should call the same endpoint again with:

```
apikey={API_KEY}
ip={VISITOR_IP}
keyname={KEYNAME}
js=1
code={uniqueCode}
```

Example:

```bash
curl "https://api.stopbot.net/services/shorterlink?apikey={API_KEY}&ip=1.1.1.1&keyname={KEYNAME}&js=1&code={UNIQUE_CODE}"
```

Successful verification response:

```json
{
  "AddVisitorStatus": 1,
  "status": "success",
  "executionTime": "3.04ms",
  "timeResponse": "2026-07-07 12:00:00"
}
```

If the verification code does not match a pending SmartURLs visitor record, the response may still return `status: success` without `AddVisitorStatus`.

When JavaScript verification is not enabled, `uniqueCode` is not returned.

### JavaScript Verification Response Fields

| Field              | Description                                                                                   |
| ------------------ | --------------------------------------------------------------------------------------------- |
| `AddVisitorStatus` | `1` means the pending SmartURLs visitor record was successfully marked as JavaScript verified |
| `status`           | Verification request status                                                                   |
| `executionTime`    | Server-side execution time for the request                                                    |
| `timeResponse`     | Response timestamp in `YYYY-MM-DD HH:mm:ss` format                                            |

### Device Values

The `device` field is derived from the `ua` request parameter.

| Value     | Meaning                                                                                                                                                                                                         |
| --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Mobile`  | The user agent contains a known mobile keyword, such as Android, iPhone, iPad, Windows Phone, BlackBerry, Nokia, Kindle, PlayBook, `mobi`, Silk, Opera Mini, Opera Mobile, UCBrowser, Symbian, Blazer, or WebOS |
| `Desktop` | The user agent does not match the mobile keyword list, or no user agent is provided                                                                                                                             |

### User Type

The `userType` field is copied from the IP geolocation data field `traits.user_type`.

The current STOPBOT IP geolocation database contains these `userType` values:

| Value         | Meaning                                |
| ------------- | -------------------------------------- |
| `business`    | Business or organization network       |
| `cellular`    | Mobile carrier network                 |
| `hosting`     | Hosting, cloud, or data center network |
| `residential` | Residential ISP network                |

If the IP geolocation data does not provide a value, STOPBOT returns:

```
unknown
```

### Connection Type

The `connectionType` field is copied from the IP geolocation data field `traits.connection_type`.

The current STOPBOT IP geolocation database contains these `connectionType` values:

| Value       | Meaning                                               |
| ----------- | ----------------------------------------------------- |
| `Cable/DSL` | Fixed broadband connection                            |
| `Cellular`  | Mobile network connection                             |
| `Corporate` | Corporate or organization network connection category |
| `Dialup`    | Dial-up connection                                    |

If the IP geolocation data does not provide a value, STOPBOT returns:

```
unknown
```

### Common Detection Reasons

The `detectActivity` value can include:

| Value                          | Meaning                                                                        |
| ------------------------------ | ------------------------------------------------------------------------------ |
| `Visitor`                      | No block reason detected                                                       |
| `BLOCK BY IP DATABASE.`        | IP matched STOPBOT IP database or IP range checks                              |
| `BLOCK BY MALICIOUS ACTIVITY.` | IP matched malicious activity or DNS blacklist checks                          |
| `BLOCK BY HOSTNAME DATABASE.`  | Hostname matched STOPBOT hostname database                                     |
| `BLOCK BY PROXY/VPN/TOR.`      | Proxy, VPN, Tor, or spam-source detection                                      |
| `BLOCK BY COUNTRY.`            | Country is not allowed by configuration                                        |
| `BLOCK BY IP NON-ISP.`         | Non-ISP network blocked by configuration                                       |
| `BLOCK BY SPIDER CRAWLER`      | User agent matched bot or crawler detection                                    |
| `BLOCK BY THREAT URL`          | Request matched repeated failed traffic logic                                  |
| `BLOCK BY INVALID KEYNAME`     | Keyname is invalid, inactive, removed, or not registered for the API key owner |
| `BLOCK BY DEVICE DESKTOP`      | Blocked by configured desktop device rule                                      |
| `BLOCK BY DEVICE MOBILE`       | Blocked by configured mobile device rule                                       |
| `BLOCK BY BLACKLIST IP (USER)` | IP matched the user's own IP blacklist                                         |
| `ALLOW BY WHITELIST IP (USER)` | IP matched the user's own IP whitelist                                         |
| `BLOCK BY THREAT FEEDS`        | IP matched STOPBOT threat feeds                                                |
| `BLOCK BY HOSTNAME (USER)`     | Hostname matched the user's own hostname blacklist                             |

### Error Response Fields

Failed SmartURLs responses may include:

| Field           | Description                                                                         |
| --------------- | ----------------------------------------------------------------------------------- |
| `errorMessage`  | Human-readable error message                                                        |
| `status`        | Failed validation may return `error` or `failed`, depending on the validation stage |
| `executionTime` | Server-side execution time for the request                                          |
| `timeResponse`  | Response timestamp in `YYYY-MM-DD HH:mm:ss` format                                  |

### V1 Difference

Legacy SmartURLs used keyname-based JavaScript tracking.

Current SmartURLs uses a `uniqueCode` verification token:

```
js=1&keyname={KEYNAME}&code={uniqueCode}
```

Use `code` for the verification token returned by the current SmartURLs response.
