> For the complete documentation index see https://domscan.net/llms.txt. Markdown versions of every docs page are available by appending .md to the page URL.

Source: https://domscan.net/docs/products/website-categorization

# Website Categorization API

Categorize a website by industry, content type, and topics. Use this reference to choose an operation and integrate its documented response contract.

[View product page](https://domscan.net/website-categorization-api)

## Operations

GET `/v1/categorize` [View API reference](https://domscan.net/docs/products/website-categorization#categorizeWebsite)

GET `/v1/categorize/taxonomy` [View API reference](https://domscan.net/docs/products/website-categorization#getCategorizationTaxonomy)

POST `/v1/categorize/bulk` [View API reference](https://domscan.net/docs/products/website-categorization#categorizeWebsiteBulk)

## GET `/v1/categorize`

Operation: `categorizeWebsite`
Credits and authentication: 3
Authentication required

GET /v1/categorize Credits: 3

#### Query parameters

| Parameter | Type | required |
| --- | --- | --- |
| url | string | optional |
| domain | string | optional |
| skip_cache | string Allowed values `0`, `1` | optional |
| min_confidence | integer Default `0` | optional |

#### Response fields

| Field | Type |
| --- | --- |
| `cache_age_s` | integer |
| `url` | string |
| `primary_category` | string \| null |
| `primary_category_id` | string \| null |
| `categories[]` | object[] |
| `categories[]` | object |
| `categories[].category_id` | string |
| `categories[].category` | string |
| `categories[].subcategory_id` | string \| null |
| `categories[].subcategory` | string \| null |
| `categories[].confidence` | integer |
| `categories[].keywords_found[]` | string[] |
| `categories[].signals[]` | object[] |
| `categories[].signals[]` | object |
| `categories[].signals[].source` | string |
| `categories[].signals[].evidence` | string |
| `primary_category_confidence` | string |
| `title` | string \| null |
| `description` | string \| null |
| `language` | string \| null |
| `language_confidence` | string |
| `adult_content` | boolean |
| `signals_used` | integer |
| `cached` | boolean |
| `total_time_ms` | integer |
| `checked_at` | string |
| `evidence_summary` | object |
| `evidence_summary.analysis_status` | string |
| `evidence_summary.content_observed` | boolean |
| `evidence_summary.content_source` | string |
| `evidence_summary.cache_status` | string |
| `evidence_summary.stale` | boolean |
| `evidence_summary.fetch_transport` | string \| null |
| `evidence_summary.response_status` | integer \| null |
| `evidence_summary.final_url` | string |
| `evidence_summary.redirect_count` | integer |
| `evidence_summary.body_truncated` | boolean |
| `evidence_summary.unavailable_reason` | string |
| `meta` | object |
| `meta.served_by` | string |
| `meta.cache_status` | string |

#### Example request

```bash
curl -H "X-API-Key: $DOMSCAN_API_KEY" "https://domscan.net/v1/categorize?url=https%3A%2F%2Fexample.com&domain=example.com&skip_cache=0&min_confidence=0"
```

```javascript
const response = await fetch("https://domscan.net/v1/categorize?url=https%3A%2F%2Fexample.com&domain=example.com&skip_cache=0&min_confidence=0", {
  headers: { "X-API-Key": process.env.DOMSCAN_API_KEY },
});
const data = await response.json();
console.log(data);
```

```python
import os
import requests

response = requests.get(
    "https://domscan.net/v1/categorize?url=https%3A%2F%2Fexample.com&domain=example.com&skip_cache=0&min_confidence=0",
    headers={"X-API-Key": os.environ["DOMSCAN_API_KEY"]},
)
print(response.json())
```

```go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest(http.MethodGet, "https://domscan.net/v1/categorize?url=https%3A%2F%2Fexample.com&domain=example.com&skip_cache=0&min_confidence=0", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Key", os.Getenv("DOMSCAN_API_KEY"))

```ruby
require "json"
require "net/http"

uri = URI("https://domscan.net/v1/categorize?url=https%3A%2F%2Fexample.com&domain=example.com&skip_cache=0&min_confidence=0")
request = Net::HTTP::Get.new(uri)
request["X-API-Key"] = ENV.fetch("DOMSCAN_API_KEY")

#### Example response

```json
{
  "url": "https://example.com",
  "primary_category": "SaaS & Cloud",
  "primary_category_id": "IAB25",
  "categories": [
    {
      "category_id": "IAB25",
      "category": "SaaS & Cloud",
      "subcategory_id": null,
      "subcategory": null,
      "confidence": 84,
      "keywords_found": [
        "platform",
        "dashboard",
        "enterprise"
      ],
      "signals": [
        {
          "source": "keyword_title",
          "evidence": "Matched platform and dashboard in the page title."
        }
      ]
    },
    {
      "category_id": "IAB19",
      "category": "Technology & Computing",
      "subcategory_id": null,
      "subcategory": null,
      "confidence": 72,
      "keywords_found": [
        "api",
        "developer",
        "automation"
      ],
      "signals": [
        {
          "source": "keyword_body",
          "evidence": "Developer-focused terms appear repeatedly in page copy."
        }
      ]
    }
  ],
  "primary_category_confidence": "high",
  "title": "Developer platform for AI apps",
  "description": "Build with APIs, models, and cloud workflows",
  "language": "en",
  "language_confidence": "high",
  "adult_content": false,
  "signals_used": 12,
  "cached": false,
  "total_time_ms": 412,
  "checked_at": "2026-04-18T21:00:00Z"
}
```

#### HTTP status codes

- `200` OK
- `400` Bad Request
- `401` Unauthorized
- `402` Payment Required
- `422` HTTP 422
- `429` Too Many Requests

## GET `/v1/categorize/taxonomy`

Operation: `getCategorizationTaxonomy`
Credits and authentication: Free
Authentication optional

GET /v1/categorize/taxonomy Credits: 0

#### Response fields

| Field | Type |
| --- | --- |
| `taxonomy` | string |
| `version` | string |
| `official_iab_taxonomy` | boolean |
| `inspired_by` | string |
| `category_count` | integer |
| `subcategory_count` | integer |
| `notes[]` | string[] |
| `categories[]` | object[] |
| `categories[]` | object |
| `categories[].category_id` | string |
| `categories[].category` | string |
| `categories[].taxonomy_name` | string |
| `categories[].ranked_category` | boolean |
| `categories[].subcategories[]` | object[] |
| `categories[].subcategories[]` | object |
| `categories[].subcategories[].subcategory_id` | string |
| `categories[].subcategories[].subcategory` | string |
| `meta` | object |

#### Example request

```bash
curl "https://domscan.net/v1/categorize/taxonomy"
```

```javascript
const response = await fetch("https://domscan.net/v1/categorize/taxonomy");
const data = await response.json();
console.log(data);
```

```python
import requests

response = requests.get(
    "https://domscan.net/v1/categorize/taxonomy",
)
print(response.json())
```

```go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, err := http.NewRequest(http.MethodGet, "https://domscan.net/v1/categorize/taxonomy", nil)
	if err != nil {
		panic(err)
	}

```ruby
require "json"
require "net/http"

uri = URI("https://domscan.net/v1/categorize/taxonomy")
request = Net::HTTP::Get.new(uri)

#### Example response

```json
{
  "taxonomy": "domscan-iab-inspired",
  "version": "v1",
  "official_iab_taxonomy": false,
  "inspired_by": "IAB Tech Lab Content Taxonomy 3.x",
  "category_count": 35,
  "subcategory_count": 134,
  "notes": [
    "DomScan returns IAB-style IDs from its own IAB-inspired taxonomy.",
    "The category field matches the value returned by /v1/categorize for backward compatibility.",
    "IAB29 Adult is primarily exposed through the adult_content boolean in categorization responses."
  ],
  "categories": [
    {
      "category_id": "IAB22",
      "category": "E-commerce",
      "taxonomy_name": "Shopping & E-commerce",
      "ranked_category": true,
      "subcategories": [
        {
          "subcategory_id": "IAB22-1",
          "subcategory": "Online Retail"
        },
        {
          "subcategory_id": "IAB22-2",
          "subcategory": "Deals & Coupons"
        }
      ]
    },
    {
      "category_id": "IAB25",
      "category": "SaaS & Cloud",
      "taxonomy_name": "SaaS & Cloud",
      "ranked_category": true,
      "subcategories": [
        {
          "subcategory_id": "IAB25-3",
          "subcategory": "Developer Tools"
        }
      ]
    }
  ]
}
```

#### HTTP status codes

- `200` OK
- `429` Too Many Requests

## POST `/v1/categorize/bulk`

Operation: `categorizeWebsiteBulk`
Credits and authentication: 3
Authentication required

POST /v1/categorize/bulk Credits: 3/item

#### Query parameters

| Parameter | Type | required |
| --- | --- | --- |
| dry_run | string Allowed values `true` | optional |

#### Body parameters

| Parameter | Type | required |
| --- | --- | --- |
| urls | string[] | required |

#### Response fields

| Field | Type |
| --- | --- |
| `results[]` | unknown[] |
| `meta` | object |
| `meta.total` | integer |
| `meta.succeeded` | integer |
| `meta.failed` | integer |
| `meta.cached` | integer |
| `meta.stale` | integer |
| `meta.duration_ms` | integer |

#### Example request

```bash
curl -X POST "https://domscan.net/v1/categorize/bulk" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $DOMSCAN_API_KEY" \
  -d '{
  "urls": [
    "https://example.com",
    "https://example.org"
  ]
}'
```

```javascript
const response = await fetch("https://domscan.net/v1/categorize/bulk", {
  method: "POST",
  headers: { "X-API-Key": process.env.DOMSCAN_API_KEY, "Content-Type": "application/json" },
  body: JSON.stringify({
    "urls": [
      "https://example.com",
      "https://example.org"
    ]
  }),
});
const data = await response.json();
console.log(data);
```

```python
import os
import requests

response = requests.post(
    "https://domscan.net/v1/categorize/bulk",
    headers={"X-API-Key": os.environ["DOMSCAN_API_KEY"]},
    json={
        "urls": [
            "https://example.com",
            "https://example.org",
        ],
    },
)
print(response.json())
```

```go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

func main() {
	body := strings.NewReader(`{
	  "urls": [
	    "https://example.com",
	    "https://example.org"
	  ]
	}`)
	req, err := http.NewRequest(http.MethodPost, "https://domscan.net/v1/categorize/bulk", body)
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Key", os.Getenv("DOMSCAN_API_KEY"))
	req.Header.Set("Content-Type", "application/json")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	data, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	fmt.Println(resp.Status, string(data))
}
```

```ruby
require "json"
require "net/http"

uri = URI("https://domscan.net/v1/categorize/bulk")
request = Net::HTTP::Post.new(uri)
request["X-API-Key"] = ENV.fetch("DOMSCAN_API_KEY")
request["Content-Type"] = "application/json"
request.body = JSON.generate({
  "urls" => [
    "https://example.com",
    "https://example.org"
  ]
})

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end
puts JSON.pretty_generate(JSON.parse(response.body))
```

#### Example response

```json
{
  "results": [],
  "meta": {
    "total": 1,
    "succeeded": 1,
    "failed": 1,
    "cached": 1,
    "stale": 1,
    "duration_ms": 1
  }
}
```

#### HTTP status codes

- `200` OK
- `400` Bad Request
- `401` Unauthorized
- `402` Payment Required
- `409` HTTP 409
- `422` HTTP 422
- `429` Too Many Requests

## Reference resources

[OpenAPI 3.0](https://domscan.net/v1/openapi.json)
[Postman](https://domscan.net/v1/postman.json)
[MCP](https://domscan.net/mcp-domain-checker)
