How to Get a Website's Category in PHP

November 07, 2026
How to Get a Website's Category in PHP

You’re building a PHP workflow that needs a website’s category to make a decision in real time—whether to block “news” traffic for an ad placement, enrich a signup with company details and a logo, or flag domains for brand-safety review. By the end of this guide, you’ll be able to call Klazify’s categorize endpoint from PHP, read its category fields (including IAB mappings), and wire the result into your pipeline with caching, fallbacks, and taxonomy mapping.

Why Klazify is a great fit for categorizing websites from PHP

When your logic depends on a site’s category, you need accurate signal, low latency, and a clean path into your PHP code. Klazify’s API helps you classify domains directly from URLs and provides the extra context (logo, company fields, social detection, and technologies) you can use to drive product features and safety checks.

Illustration: How to Get a Website's Category in PHP
  • Accurate website categorization using AI: Klazify analyzes on-page content, not just metadata, which is crucial for PHP apps that must decide whether to allow, block, or enrich based on the actual subject matter.
  • Global coverage: Works across multiple languages, important for international signups or traffic filtering in global PHP deployments.
  • Real-time classification: Get up-to-date categorizations, rather than relying on static databases that drift. This matters when you gate access or enforce policies in real time.
  • Industry-level categories: Categories map to IAB taxonomy, which is ideal when your PHP logic ties into ad tech or brand safety policies.
  • Simple API integration: A single POST to a REST endpoint (with Bearer auth) returns categories, IAB mappings, logo URL, company data, social, tech stack and more.
  • Compliance and filtering: Use consistent categories to enforce allowlists/denylists across signup enrichment, ad placements, network filtering, and content moderation.

You can get started quickly with a free account. Starter is $39.99/mo with a 7-day trial, and failed or unreachable calls are not billed. Create an account here: Register. Explore the API details in the Documentation and governance in MCP.

The endpoint you’ll use

Klazify exposes one primary endpoint for this job:

  • Endpoint: https://www.klazify.com/api/categorize
  • Method: POST
  • Auth: Bearer token in the Authorization header
  • Body: JSON containing the url field

Requesting categorization by URL enables page-level or domain-level signals depending on what you pass. The response includes:

  • domain.categories: An array of categories; each has name and optional IAB taxonomy mapping plus a confidence score.
  • domain.logo_url: A direct logo URL you can display in your UI or CRM.
  • domain.social_media: Social signals when present.
  • objects.company: Company details inferred from the domain.
  • domain_registration_data and similar_domains: Additional domain signals.

Quickstart: cURL request for categorization

Here is a complete, copy-pasteable request you can run from the terminal. Replace YOUR_API_KEY with your token. This example uses the domain shown in the docs fixture.

curl -X POST "https://www.klazify.com/api/categorize" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://cbsnews.com"}'

In the documentation fixture, this domain is categorized under /News with a confidence of 0.97. Your actual response may include additional fields described below (logo, social, company, tech).

PHP: call the API and extract the category

The snippet below shows a minimal PHP implementation using cURL to request a category and parse the top result. You can adapt this inside a controller, job, or middleware depending on your use case.

<?php
$apiUrl = 'https://www.klazify.com/api/categorize';
$payload = json_encode(['url' => 'https://cbsnews.com']); // Example URL from docs fixture

$ch = curl_init($apiUrl);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer YOUR_API_KEY',
    'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error    = curl_error($ch);
curl_close($ch);

if ($response === false || $httpCode < 200 || $httpCode >= 300) {
    // Not billed when failed or unreachable
    // Log and fallback to cached result if available
    error_log('Klazify request failed: ' . ($error ?: ('HTTP ' . $httpCode)));
    // $category = $cache->get($domain) ?? null;
    exit;
}

$data = json_decode($response, true);

// Extract top category name and confidence if present
$categoryName = null;
$confidence   = null;
$iabMapping   = null;

if (isset($data['domain']['categories'][0])) {
    $first = $data['domain']['categories'][0];
    $categoryName = $first['name'] ?? null;
    $confidence   = $first['confidence'] ?? null;

    // Some categories also include IAB mapping keys (example: "IAB-632-596")
    foreach ($first as $key => $value) {
        if (strpos($key, 'IAB-') === 0) {
            $iabMapping = $value;
            break;
        }
    }
}

$logoUrl = $data['domain']['logo_url'] ?? null;

// Use the fields in your application logic
// Example: block if News, otherwise allow
if ($categoryName === '/News') {
    // Block or route to review
} else {
    // Allow or enrich CRM record
}
?>

JavaScript: fetch and apply the same logic

If your stack also includes Node.js services or browser-based tooling (proxied via your backend for security), here’s a simple example:

import fetch from 'node-fetch';

async function categorize(url) {
  const res = await fetch('https://www.klazify.com/api/categorize', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ url })
  });

  if (!res.ok) {
    // Not billed when failed or unreachable
    throw new Error('Klazify request failed: ' + res.status);
  }

  const data = await res.json();

  // Extract top category name and confidence
  let categoryName = null;
  let confidence = null;
  let iab = null;

  const categories = data?.domain?.categories || [];
  if (categories.length > 0) {
    const first = categories[0];
    categoryName = first.name ?? null;
    confidence = first.confidence ?? null;

    for (const k of Object.keys(first)) {
      if (k.startsWith('IAB-')) {
        iab = first[k];
        break;
      }
    }
  }

  const logoUrl = data?.domain?.logo_url ?? null;

  return { categoryName, confidence, iab, logoUrl, raw: data };
}

(async () => {
  try {
    const result = await categorize('https://cbsnews.com');
    if (result.categoryName === '/News') {
      // Blocklist path
    } else {
      // Whitelist path
    }
    console.log(result);
  } catch (e) {
    console.error(e);
  }
})();

Understand the response you’ll receive

Below is an official JSON example. Use it to learn the shape and key fields you’ll parse in your code. Keep in mind that the endpoint can also return logo, social media, company, technology stack, domain registration data, and similar domains in addition to categories.


{
    "domain": {
        "categories": [
            {
                "confidence": 0.92,
                "name": "/Computers & Electronics/Consumer Electronics",
                "IAB-632-596": "Consumer Electronics/Technology & Computing/Consumer Electronics"
            },
            {
                "confidence": 0.89,
                "name": "/Internet & Telecom/Mobile & Wireless/Mobile Phones"
            }
        ],
        "social_media": null,
        "logo_url": "https://klazify.s3.amazonaws.com/2110787991611585019600ed5fb1d1300.04730104.png"
    },
    "success": true,
    "objects": {
        "company": {
            "url": "https://www.apple.com/",
            "name": "Apple",
            "city": "Cupertino",
            "stateCode": "CA",
            "countryCode": "US",
            "employeesRange": "100K+",
            "revenue": 274515000000,
            "raised": null,
            "tags": [
                "E-commerce",
                "Consumer Electronics",
                "Mobile",
                "B2C"
            ],
            "tech": [
                "omniture_adobe_analytics",
                "atlassian_confluence",
                "successfactors",
                "apache_apex",
                "talend",
                "oracle_peoplesoft",
                "salesforce",
                "stripe",
                "dell_boomi_atomsphere",
                "gigya",
                "sage_50cloud",
                "quickbooks",
                "webmethods",
                "apache_tomcat",
                "alteryx",
                "tibco_rendezvous",
                "atlassian_jira",
                "..."
            ]
        }
    },
    "domain_registration_data": {
        "domain_age_date": "1987-02-19",
        "domain_age_days_ago": "13026",
        "domain_expiration_date": "2030-02-20",
        "domain_expiration_days_left": "123"
    },
    "similar_domains": [
        "bestbuy.com",
        "icloud.com",
        "microsoft.com",
        "macrumors.com",
        "google.com",
        "samsung.com",
        "twitter.com",
        "hp.com",
        "bhphotovideo.com",
        "dell.com"
    ]
}

How to use these fields:

  • domain.categories: You’ll typically read categories[0].name and categories[0].confidence. If present, keys that start with IAB- contain IAB taxonomy mappings to use in ad tech and brand safety policies.
  • domain.logo_url: Display the logo in admin tools or CRM enrichment.
  • objects.company: Use name, location, employeesRange, revenue, and tags to augment leads or accounts.
  • objects.company.tech: Identify technology stack elements for scoring and segmentation.
  • domain_registration_data: Helpful for trust signals (e.g., domain age) in fraud checks.
  • similar_domains: Build related recommendations, find alternatives, or cluster prospects by similarity.

Plug categories into your PHP logic

1) Block, allow, or route to review

  • Blocklist: If the top category name matches a prohibited path (e.g., /News), block the request or mark for review.
  • Allowlist: For required content areas, only allow domains whose categories include these prefixes.
  • Confidence threshold: Act only when confidence ≥ a threshold your team sets; otherwise send to human review or secondary checks.

2) Enrich signups and accounts

  • Store domain.logo_url and objects.company fields beside your user or account record.
  • Save category name(s), IAB mapping, and confidence for analytics and targeting.
  • Use objects.company.tech to power customer fit models.

3) Ad placement and brand safety

  • Use IAB mappings to match your ad inventory taxonomy. This ensures clean alignment with demand- and supply-side policies.
  • Fail-safe: If no confident category is present, avoid serving the ad or use a default safe placement.

Mapping Klazify categories to your taxonomy

Many teams maintain their own category vocabulary. Map Klazify fields to your internal values:

Klazify field Example value How to map
domain.categories[].name /Computers & Electronics/Consumer Electronics Exact string or prefix matching against your category tree.
domain.categories[].confidence 0.92 Set minimum thresholds. Store for auditability.
domain.categories[].IAB-... (if present) Consumer Electronics/Technology & Computing/Consumer Electronics Authoritative mapping for ad tech and brand safety pipelines.
domain.logo_url Direct PNG URL Cache locally or via CDN; display in admin/CRM.
objects.company.tags [ "E-commerce", "Mobile", ... ] Convert to internal tags; support multi-select fields.

Operational guidance for production

Caching strategy

  • Cache by normalized domain (e.g., registrable domain) to avoid repeat calls for the same site.
  • Use a TTL appropriate to your tolerance for drift (for many use cases, days or weeks). Invalidate early when decisions are sensitive.
  • On request failure, fall back to cache; failed or unreachable calls are not billed.

Batching and throughput

  • Batch at your application layer: queue domains and fetch in worker processes.
  • Respect rate limits described in the Documentation. If you’re near limits, implement exponential backoff and jitter.
  • De-duplicate within a short time window to avoid redundant classification attempts.

Handling unknown or new domains

  • New domains may have sparse signals. Check confidence and consider a human review path when it’s below your threshold.
  • Retry classification after a delay; content can change quickly, especially just after launch.
  • If critical, combine with domain_registration_data as an additional trust signal.

Error handling and observability

  • Log HTTP status and response bodies for unexpected formats.
  • Track error rates and category distribution shifts to detect integration issues.
  • Alert when the proportion of low-confidence results exceeds a baseline.

Extending beyond categories: logos, social, company, and tech

With a single call, you can enrich workflows beyond simple allow/deny:

  • Logos: Pull domain.logo_url for a cleaner UI and faster operator decisions.
  • Company data: Use objects.company fields to pre-fill CRM records or qualify signups automatically.
  • Technology detection: objects.company.tech informs ICP fits and routing rules.
  • Similar domains: Create discovery lists, power “compare to” widgets, or trigger outbound sequences.

All of this comes from the same POST request to /api/categorize, simplifying your integration surface.

Security, compliance, and governance

  • Store only what you use, and regularly sanitize or rotate caches that aren’t needed.
  • When decisions affect user rights (e.g., blocking), log inputs, outputs, and reasons (category name, confidence).
  • Use IAB mapping keys where available to align with standardized industry semantics.
  • Review the MCP page for policy and governance context.

Production checklist for your PHP deployment

  • Normalize and validate input URLs before sending to the API.
  • Implement a domain-level cache with a safe TTL and refresh policy.
  • Define a confidence threshold; route low-confidence cases to review.
  • Map category names and IAB mappings to your internal taxonomy.
  • Use logo_url and company fields to enrich user or account records.
  • Set up error handling, retries with backoff, and circuit breakers.
  • Unit test parsing paths for domain.categories, domain.logo_url, objects.company, and edge cases (missing fields).
  • Monitor call volume, error rates, and distribution of categories to catch anomalies early.

FAQ

What happens if the site is down when I call the API?
Failed or unreachable calls are not billed. Use cached data if available, and retry later.

How do I handle multiple categories in the response?
Start with domain.categories[0] as the primary category. Consider additional entries for secondary logic or analytics. Always check confidence per entry.

Can I rely on IAB mappings for ad placements?
Yes. When present, use the IAB-... mapping key in domain.categories[]. This standardizes category semantics for ad tech and brand safety.

Do I need to pass domains or full URLs?
Pass whichever you have. Using a full URL allows page-level context when a site spans diverse topics. Normalize when you plan to cache.

How should I set a confidence threshold?
Pick a threshold consistent with your risk tolerance. Store confidence alongside decisions so you can iterate without losing context.

Ready to integrate? Create a free account and start classifying domains in minutes: Register. For endpoint specifics, examples, and field definitions, head to the Documentation.

Ready to use Klazify?

Start classifying websites, enriching company data, and exploring web intelligence.

Get Started Free