v1.0 · Live

API Reference

A simple REST API to categorize any URL or block of text in seconds. One endpoint, a fixed 25-category taxonomy, a confidence score.

Overview

CategorizeAPI provides a single HTTP endpoint that accepts a URL or a block of text and returns a category, an optional subcategory, a confidence score, and a short reasoning. The API is designed to be minimal and predictable — one endpoint, JSON in, JSON out.

Base URL

Base URL https://categorizeapi.com/api

Key capabilities

Authentication

All requests must include a valid API key in the Authorization header using the Bearer scheme.

HTTP Header
Authorization: Bearer YOUR_API_KEY
🔑
Get your API key Create a free account at categorizeapi.com/signup — your API key is available immediately in the dashboard. Free tier includes 100 requests/month with no credit card required.

API key format

API keys follow the format sk_live_xxxxxxxxxxxxxxxxxxxxxxxx (production) or sk_test_xxxxxxxxxxxxxxxxxxxxxxxx (test environment). Keep your key secret — treat it like a password.

Quick Start

Send a POST request to /api/categorize with a URL or text. You'll get a category back in a couple of seconds.

# Install: curl is available on all platforms

curl -X POST https://categorizeapi.com/api/categorize \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"input": "https://example.com", "type": "auto"}'
const categorize = async (input) => {
  const res = await fetch('https://categorizeapi.com/api/categorize', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ input, type: 'auto' })
  });
  const data = await res.json();
  console.log(data.category, data.confidence);
};

categorize('https://example.com');
import requests

response = requests.post(
    "https://categorizeapi.com/api/categorize",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"input": "https://example.com", "type": "auto"}
)

data = response.json()
print(data["category"], data["confidence"])
<?php
$response = file_get_contents('https://categorizeapi.com/api/categorize', false,
    stream_context_create(['http' => [
        'method'  => 'POST',
        'header'  => "Authorization: Bearer YOUR_API_KEY\r\nContent-Type: application/json",
        'content' => json_encode(['input' => 'https://example.com', 'type' => 'auto'])
    ]])
);
$data = json_decode($response, true);
echo $data['category'];

Example response

JSON Response · 200 OK
{
  "success": true,
  "category": "Technology & Computing",
  "subcategory": "Web Services",
  "confidence": 0.93,
  "reasoning": "The page describes a software product and its documentation.",
  "input_type": "url",
  "processing_time": 1.14,
  "requests_remaining": 4997
}

Endpoint

The API exposes a single categorization endpoint.

POST /api/categorize

Categorizes the provided URL or text and returns a structured JSON response.

Request headers

HeaderValueRequired
Authorization Bearer YOUR_API_KEY Required
Content-Type application/json Required

Request Parameters

Send a JSON body with the following fields. Only input is required.

ParameterTypeDefaultDescription
input
required
string A URL (http:// or https://) or a block of text. Text input is capped at 7,500 characters.
type
optional
string auto How to interpret input.
auto — detect URL vs text automatically
url — force URL handling (errors if input isn't a valid URL)
text — force plain-text handling, even if it looks like a URL

Full request example

JSON Request Body
{
  "input": "https://example.com/blog/electric-vehicles-2030",
  "type": "auto"
}
ℹ️
How URLs are fetchedFor type=url (or an auto-detected URL), the page is fetched server-side with an 8-second timeout, up to 3 redirects, and a ~300KB download cap. The title, meta description, and a content excerpt are extracted and classified — the raw HTML is never returned or stored.

Response Format

All responses are JSON. A successful request returns HTTP 200.

Success · 200 OK
{
  "success": true,
  "category": "News & Politics",
  "subcategory": "World News",
  "confidence": 0.87,
  "reasoning": "The text reports on an international diplomatic event.",
  "input_type": "text",
  "processing_time": 0.92,
  "requests_remaining": 4996
}

Response fields

FieldTypeDescription
successbooleanAlways true on success.
categorystringOne of the 25 top-level categories — see Categories.
subcategorystring | nullA more specific free-form label, when the model can be more precise. Not a fixed list.
confidencefloatModel confidence in the assigned category, from 0.0 to 1.0.
reasoningstringOne short sentence explaining why that category was chosen.
input_typestringEither url or text — how the input was actually interpreted.
processing_timefloatRequest duration in seconds.
requests_remainingintegerRemaining requests in the current billing period.

Categories

Every response's category field is exactly one of these 25 values, verbatim:

#Category
1Arts & Entertainment
2Automotive
3Business & Industrial
4Careers
5Education
6Family & Parenting
7Finance & Investing
8Food & Drink
9Gaming
10Health & Fitness
11Hobbies & Interests
12Home & Garden
13Law & Government
14News & Politics
15Pets & Animals
16Real Estate
17Science
18Shopping & Retail
19Society & Culture
20Sports
21Style & Fashion
22Technology & Computing
23Travel & Tourism
24Religion & Spirituality
25Adult Content
ℹ️
This list is fixed — it won't change without a version bump. Build your integration against these exact strings.

Errors

Error responses include an error field describing what went wrong. HTTP status codes follow standard conventions.

Error Response
{
  "error": "Invalid API key"
}
StatusErrorDescription
400 Invalid parameters Missing input, type not one of auto/url/text, text exceeds the character limit, or malformed JSON body.
401 Unauthorized Missing, expired, or invalid API key. Check the Authorization header.
405 Method not allowed Only POST requests are accepted.
422 URL fetch failed type=url was requested but the page could not be fetched — timed out, returned a non-2xx/3xx status, or had no extractable content.
429 Rate limit exceeded Monthly request quota or the 60 req/min burst limit was reached. Upgrade your plan or slow down.
500 Server error Both the primary and fallback models failed. Retry with exponential backoff. If the problem persists, contact support.

cURL Examples

Complete examples using curl — available on Linux, macOS, and Windows.

Categorize a URL

cURL
curl -X POST https://categorizeapi.com/api/categorize \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": "https://www.espn.com",
    "type": "url"
  }'

Categorize raw text

cURL
curl -X POST https://categorizeapi.com/api/categorize \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": "The Federal Reserve announced a quarter-point rate cut today, citing cooling inflation and a softening labor market.",
    "type": "text"
  }'

JavaScript Examples

Works in Node.js 18+ (built-in fetch) and all modern browsers.

class CategorizeAPIClient {
  constructor(apiKey, baseURL = 'https://categorizeapi.com/api') {
    this.apiKey = apiKey;
    this.baseURL = baseURL;
  }

  async categorize(input, type = 'auto') {
    const res = await fetch(`${this.baseURL}/categorize`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${this.apiKey}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ input, type })
    });
    if (!res.ok) {
      const err = await res.json();
      throw new Error(err.error || 'API error');
    }
    return res.json();
  }
}

// Usage
const client = new CategorizeAPIClient('YOUR_API_KEY');

const result = await client.categorize('https://example.com');
console.log('Category:', result.category);
console.log('Confidence:', Math.round(result.confidence * 100) + '%');
// npm install axios
const axios = require('axios');

const client = axios.create({
  baseURL: 'https://categorizeapi.com/api',
  headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
});

async function categorize(input, type = 'auto') {
  const { data } = await client.post('/categorize', { input, type });
  return data;
}

categorize('https://example.com')
  .then(r => console.log(r.category, r.confidence))
  .catch(e => console.error(e.response?.data?.error || e.message));

Python Examples

Works with Python 3.7+. Uses the requests library (pip install requests).

import requests

class CategorizeAPIClient:
    def __init__(self, api_key: str, base_url: str = "https://categorizeapi.com/api"):
        self.api_key = api_key
        self.base_url = base_url

    def categorize(self, input: str, type: str = "auto") -> dict:
        response = requests.post(
            f"{self.base_url}/categorize",
            headers={"Authorization": f"Bearer {self.api_key}"},
            json={"input": input, "type": type},
            timeout=30
        )
        response.raise_for_status()
        return response.json()

# Usage
client = CategorizeAPIClient("YOUR_API_KEY")
result = client.categorize("https://example.com")

print(f"Category: {result['category']}")
print(f"Confidence: {round(result['confidence'] * 100)}%")
import aiohttp
import asyncio

async def categorize(api_key: str, input: str, type: str = "auto") -> dict:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://categorizeapi.com/api/categorize",
            headers={"Authorization": f"Bearer {api_key}"},
            json={"input": input, "type": type}
        ) as resp:
            return await resp.json()

# Usage
result = asyncio.run(categorize(
    "YOUR_API_KEY",
    "https://example.com"
))
print(result["category"])

PHP Examples

Works with PHP 7.4+. Uses cURL (enabled by default in most PHP installations).

<?php

class CategorizeAPIClient {
    private string $apiKey;
    private string $baseUrl = 'https://categorizeapi.com/api';

    public function __construct(string $apiKey) {
        $this->apiKey = $apiKey;
    }

    public function categorize(string $input, string $type = 'auto'): array {
        $payload = json_encode(['input' => $input, 'type' => $type]);
        $ch = curl_init($this->baseUrl . '/categorize');
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST           => true,
            CURLOPT_POSTFIELDS     => $payload,
            CURLOPT_HTTPHEADER     => [
                'Authorization: Bearer ' . $this->apiKey,
                'Content-Type: application/json'
            ],
            CURLOPT_TIMEOUT        => 30
        ]);
        $body     = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode !== 200) {
            $err = json_decode($body, true);
            throw new \RuntimeException($err['error'] ?? 'API error');
        }
        return json_decode($body, true);
    }
}

// Usage
$client = new CategorizeAPIClient('YOUR_API_KEY');

$result = $client->categorize('https://example.com');

echo $result['category'] . PHP_EOL;
echo $result['confidence'] . PHP_EOL;
<?php
// composer require guzzlehttp/guzzle
use GuzzleHttp\Client;

$client = new Client([
    'base_uri' => 'https://categorizeapi.com/api/',
    'headers'  => ['Authorization' => 'Bearer YOUR_API_KEY']
]);

$response = $client->post('categorize', [
    'json' => [
        'input' => 'https://example.com',
        'type'  => 'auto'
    ]
]);

$data = json_decode($response->getBody(), true);
echo $data['category'];

Rate Limits

Monthly request limits are enforced per calendar month and reset on the 1st of each month. A separate burst limit of 60 requests/minute applies to every plan.

PlanRequests / monthAPI access
Free 100 Full API access
Professional — $5/mo 5,000 Full API access + priority processing
Business — $14/mo Unlimited Full API access + dedicated support + SLA 99.9%

When you exceed your monthly limit, the API returns HTTP 429. The requests_remaining field in every successful response lets you track usage programmatically.

ℹ️
When you exceed your monthly limit, upgrade to a paid plan to continue using the API without interruption.

Changelog

2026-07
v1.0 Latest
  • Initial public release
  • REST API with JSON request/response
  • URL and text input, auto-detected
  • 25-category fixed taxonomy with confidence + reasoning
  • Automatic fallback to a secondary model/provider
  • API key authentication
  • Free tier — 100 requests/month

Have a feature request or found a bug? Contact us — we read every message.