How to Get a Website's Tech Stack in PHP
Your product team needs to identify what powers a website—its CMS, analytics, CDN, frameworks, and ad networks—so you can enrich PHP signups, qualify leads, or enforce integration policies. By the end of this guide you’ll call a single API to fetch a site’s tech stack, parse the response in your PHP app, and wire the data into your enrichment, filtering, or analytics pipeline.
Why Klazify is the right API for discovering tech stacks you’ll use in PHP
When your goal is to detect technologies behind a website and act on them inside a PHP application, the data needs to be accurate, fresh, and easy to plug into your workflow. Klazify analyzes live website content, scripts, headers, and other signals to surface the stack components you care about.
- Accurate technology detection using AI: Klazify inspects page content and execution signals, which helps distinguish between lookalike tags and real deployments. That precision matters when deciding if a lead runs a supported CMS or analytics tool you integrate with.
- Global coverage: If your lead sources are multilingual or international, you still get consistent technology identifiers that don’t vary by language.
- Real-time analysis: You’re not relying on stale lookups. Your PHP backend can check a domain during signup and block, enrich, or route the submission in real time.
- Industry-level categories: If you also need to classify the site (e.g., for brand safety), Klazify maps content to IAB taxonomy so you can pair technology detection with compliant categories in a single provider.
- Simple API integration: A straightforward REST API with a dedicated endpoint for technology detection makes server-side PHP usage and cross-language pipelines uncomplicated.
- Compliance and filtering: Combine tech detection with content categorization to whitelist or filter sites based on toolchains (CMS, ad networks) and business rules.
Start with the technology stack endpoint for your PHP use case, and expand to categorization or company data when your workflow needs more context. Learn more at klazify.com.
Scenario: enrich and route PHP signups by stack
Imagine a user signs up with a domain email. You want to:
- Enrich the lead with the domain’s CMS and analytics tools to tailor onboarding.
- Auto-assign the account to the team that covers a specific framework or CDN.
- Flag domains that run unsupported ad networks to prevent downstream issues.
Your PHP backend will:
- Call Klazify’s technology endpoint with the domain URL.
- Read
objects.company.tech, a list of technology identifiers. - Map identifiers into your internal categories and trigger actions (enrichment, routing, or blocking).
The endpoint you’ll call for technology detection
Use the technology detection endpoint to identify a website’s stack:
- Method: POST
- URL:
https://www.klazify.com/api/domain_tech - Auth: Bearer token in the Authorization header
- Body (JSON):
{"url":"https://example.com"} - Response focus:
objects.company.tech(array of technology identifiers)
These identifiers include CMS, analytics, CDN, frameworks, and ad networks. You can integrate the same identifiers across your rules engine, CRM enrichment, or analytics tables.
Refer to the API reference for details on fields and structure: Documentation.
Quick start: cURL request you can paste
This example shows how to request a website’s technology stack. Replace YOUR_API_KEY with your token.
curl -X POST "https://www.klazify.com/api/domain_tech" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://cbsnews.com"}'
If the call fails or the target is unreachable, the request is not billed. You can safely retry according to your retry strategy.
JavaScript example: fetch tech identifiers and act on them
Below is a Node.js-style example. It sends the same payload, reads objects.company.tech, and demonstrates a simple mapping from identifiers to internal tags you might store in a CRM or event stream.
import fetch from "node-fetch";
const KLAZIFY_URL = "https://www.klazify.com/api/domain_tech";
const API_KEY = process.env.KLAZIFY_API_KEY; // set securely
// Map technology identifiers you care about into normalized labels for downstream usage
const TECH_MAP = {
"wordpress": "cms",
"drupal": "cms",
"joomla": "cms",
"shopify": "ecommerce",
"magento": "ecommerce",
"google_analytics": "analytics",
"omniture_adobe_analytics": "analytics",
"segment": "cdp",
"cloudflare": "cdn",
"fastly": "cdn",
"akamai": "cdn",
"react": "framework",
"vue_js": "framework",
"angular": "framework",
"next_js": "framework",
"gatsby": "framework",
"google_adsense": "ad_network",
"doubleclick": "ad_network"
};
async function fetchTech(url) {
const res = await fetch(KLAZIFY_URL, {
method: "POST",
headers: {
"Authorization": `Bearer ${API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({ url })
});
if (!res.ok) {
const text = await res.text();
throw new Error(`Klazify error ${res.status}: ${text}`);
}
const json = await res.json();
// Defensive checks: depending on the domain, some fields may be missing
const techList = json?.objects?.company?.tech || [];
// Normalize into a set of categories you route on
const normalized = new Set();
for (const t of techList) {
const key = t.toLowerCase();
if (TECH_MAP[key]) normalized.add(TECH_MAP[key]);
}
return {
rawTech: techList,
normalizedTags: Array.from(normalized)
};
}
// Example usage in a signup handler
(async () => {
const domainUrl = "https://example.com";
try {
const { rawTech, normalizedTags } = await fetchTech(domainUrl);
// Persist to your CRM or user profile
console.log("Raw tech identifiers:", rawTech);
console.log("Normalized tags:", normalizedTags);
// Route lead based on tech
if (normalizedTags.includes("cms")) {
// Assign to CMS specialists
}
if (normalizedTags.includes("ad_network")) {
// Trigger brand safety checks
}
} catch (e) {
console.error("Failed to fetch tech:", e.message);
// Apply fallback routing if needed
}
})();
PHP server-side snippet: integrate with your signup or enrichment job
While the example above uses JavaScript to satisfy cross-language pipelines, most readers here will wire this into a PHP backend. The snippet below shows how to call the same endpoint from PHP using cURL:
<?php
$apiKey = getenv("KLAZIFY_API_KEY");
$url = "https://www.klazify.com/api/domain_tech";
$target = "https://example.com";
$payload = json_encode(["url" => $target]);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . $apiKey,
"Content-Type: application/json"
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
$response = curl_exec($ch);
if ($response === false) {
$error = curl_error($ch);
curl_close($ch);
throw new Exception("cURL error: " . $error);
}
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode < 200 || $httpCode >= 300) {
throw new Exception("Klazify HTTP $httpCode: " . $response);
}
$data = json_decode($response, true);
// Safely access technology list
$tech = [];
if (isset($data["objects"]["company"]["tech"]) && is_array($data["objects"]["company"]["tech"])) {
$tech = $data["objects"]["company"]["tech"];
}
// Example: persist or route based on $tech
print_r($tech);
The official response shape and fields you’ll use
Below is an official Klazify response example. It includes categorization fields and, inside objects.company.tech, a sample of technology identifiers. Your technology lookup responses follow the same structural conventions, and the array of identifiers is what you’ll parse in PHP to power your enrichment and routing.
{
"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"
]
}
Key fields you will use:
objects.company.tech: Array of technology identifiers. These are the primary values to normalize, map, and store in your pipeline.domain.categories: If you’re also applying brand safety or content filters, these include names and IAB codes for integration with ad-tech rules.domain.logo_url: Helpful for CRM profile UIs or enrichment dashboards.success: Quick boolean check to verify a valid response body.
Map technology identifiers to your taxonomy
Technology detection returns identifiers that are consistent across domains. Most teams still map them to their own tags for routing, reporting, or restrictions. A simple approach is a dictionary look-up with a default bucket for unknown tools. Keep the mapping under version control so analytics and routing remain reproducible.
| Identifier examples | Internal tag | Action in pipeline |
|---|---|---|
| wordpress, drupal, joomla | cms | Route to CMS specialists; customize onboarding |
| google_analytics, omniture_adobe_analytics | analytics | Enable attribution integrations; pre-fill tracking docs |
| cloudflare, akamai, fastly | cdn | Adjust latency expectations; flag for edge config guidance |
| react, vue_js, angular, next_js | framework | Select compatible SDK; route to solution engineers |
| google_adsense, doubleclick | ad_network | Brand safety review; ad policy checks |
Operational guidance: scale, reliability, and costs
Batching and concurrency: If you are processing many domains, parallelize calls within your job runner or worker pool while respecting your account’s throughput. For very large lists, break them into chunks and backoff on non-2xx responses.
Caching: Cache results by registrable domain (e.g., example.com) with a TTL appropriate for your workflow. For onboarding and lead enrichment, a 7–30 day TTL is typical. Invalidate sooner for high-traffic properties where stacks change frequently.
Handling unknown or new domains: Some domains may return an empty tech array. Treat this as “unknown” and queue for retry later. Don’t block on enrichment in your signup path—defer to an async job and annotate the account once the data arrives.
Retries and non-billed errors: If a request fails due to temporary network issues or the target being unreachable, it is not billed. Implement exponential backoff and a max retry count. Record the final error state for observability.
Normalization and schema: Store both the raw identifier list and your normalized tags. This lets you reprocess historical data when your mapping changes.
Pairing with categorization: If you also need brand safety or content filters, call the main categorization endpoint (https://www.klazify.com/api/categorize) and combine its IAB categories with technology outcomes for richer policy checks.
Plans and trial: The Starter plan is $39.99/mo and includes a 7-day trial so you can validate coverage and integration. Create your key here: Register. Learn more about Klazify at klazify.com.
Putting it together in your PHP pipeline
1) When to call the endpoint
- Inline during signup: Quick enrichment to personalize onboarding. Use a short timeout and fall back to async processing.
- Async enrichment worker: Fetch technologies after account creation to avoid blocking user flows.
- Nightly audits: Re-scan existing customers or ad destinations to keep stack data fresh.
2) Where to store the data
- CRM fields: Persist raw identifiers (array) and normalized tags (array or join table).
- Data warehouse: One row per domain with an array column for
objects.company.tech, plus a flattened table for analysis. - Feature store: Derive boolean flags like
uses_cms,uses_cdn,uses_analyticsfor ML models.
3) How to act on the results
- Routing: Assign to owners based on detected frameworks or platforms.
- Configuration: Pre-select SDKs and edge settings for detected stacks.
- Policy: Block or queue for review if disallowed ad networks are present.
Troubleshooting and quality checks
- Empty
objects.company.tech: The site may be minimal, behind strict CSP, or scripts are deferred. Retry later; keep a “tech_unknown” tag. - Unexpected identifiers: Log the raw list. Update your mapping dictionary rather than discarding. This keeps historical data consistent.
- Timeouts: Use a reasonable client timeout and surface a non-blocking enrichment status in your UI or logs.
- International domains: The identifiers are language-agnostic, so downstream logic doesn’t need localization.
Security, governance, and auditability
- Secure keys: Store your API key in environment variables or your secrets manager.
- Audit trails: Keep request/response metadata (status code, timestamp, domain) for debugging and data lineage.
- Reproducibility: Version your mapping and transformation code so the same raw identifiers always yield the same tags.
If your organization uses a model control process or integration checklist, coordinate with your data platform owners. See MCP for programmatic governance details.
Adding categorization for brand safety (optional)
Many teams pair technology detection with content categories. For example, allow analytics but restrict ad placements on certain IAB categories. The categorization response provides a list of categories and an IAB-mapped code you can store alongside technologies for holistic policy decisions.
Practical tip: Store both fields together in the same enrichment record so ad policy checks and routing logic have a single source of truth.
Checklist before you ship
- Environment variable KLAZIFY_API_KEY set and not exposed in logs.
- Retry with exponential backoff for transient HTTP errors; note that unreachable calls are not billed.
- Cache results by domain with a TTL that matches your use case; include a manual refresh path.
- Store raw identifiers and normalized tags; version the mapping.
- Log enrichment status on account records so support can see the latest attempt.
FAQ
What’s the primary field for technology detection?
Use objects.company.tech, an array of technology identifiers. Normalize these to your taxonomy for routing and reporting.
Can I pair technology detection with content categories?
Yes. Use the main categorization endpoint (/api/categorize) to fetch IAB-mapped categories and store them with the technology list for combined policy checks.
How should I handle unknown or empty tech results?
Treat as “unknown,” set a short retry schedule, and do not block critical flows. Keep a tag like tech_unknown so analytics can segment these cases.
Do failed calls count against my usage?
Failed or unreachable calls are not billed. Implement retries with backoff and log final outcomes.
How do I get started and test without committing?
Use the Starter plan at $39.99/mo with a 7-day trial to validate your integration and coverage before rolling out.
Ready to enrich your PHP workflows with reliable technology detection and categorization? Create your API key now: Register. Explore more features and endpoints at klazify.com and the full Documentation.
Ready to use Klazify?
Start classifying websites, enriching company data, and exploring web intelligence.
Get Started Free