Equipo Editorial ProFix

Documentación de la API de ProFix Directory — 73 endpoints, 15 esquemas, CC-BY-4.0

Documentación de referencia en español para cada endpoint público de la especificación OpenAPI 3.1 de ProFix Directory — agrupada por tag (agents, data, geo, verification, assets), con parámetros, ejemplos de respuesta y snippets curl / JavaScript / Python listos para copiar. Sin API key. CC-BY-4.0.

Sin API keyOpenAPI 3.1.084 endpoints18 esquemasCC-BY-4.0
Resumen rápido

Cinco cosas antes de llamar la API

  • 84 endpoints públicos agrupados en 5 tags — agents, data, geo, verification, assets.
  • Sin auth para lectura. Cada endpoint JSON / CSV / SVG / feed está abierto y con CORS. Las únicas superficies con auth son Stripe checkout y los webhooks.
  • OpenAPI 3.1 + MCP. Especificación en /api/openapi.json y /api/openapi.yaml. Servidor MCP con 16+ herramientas en /api/mcp.
  • CC-BY-4.0. Atribuye a "ProFix Directory" y lánzalo — uso comercial bienvenido.
  • 18 esquemas en components.schemas — Pro, ProList, City, State, CostGuide, LicenseGuide, BuyerGuide, FAQ, SearchResponse, CorrectionSubmission, ErrorResponse, ProDossier, ProPhotos, MatchResponse, ProPermits.

Convenciones de la API

Autenticación

La mayoría de los endpoints son públicos. Sin API key, sin OAuth. CORS permisivo (Access-Control-Allow-Origin: *). Los endpoints de Stripe checkout y webhook aceptan el header Stripe-Signature. Las rutas administrativas en /api/admin/* requieren un token bearer del editor en el header Authorization: Bearer.

Límites de tasa

No publicamos un límite por API key — las lecturas públicas están cacheadas en el borde y no cuestan nada en repetir. Los endpoints POST de leads, claim y correcciones tienen una compuerta suave por IP (~20 req/min) para frenar abusos. Por encima devolvemos HTTP 429 con Retry-After. Las descargas masivas de /api/all.json deberían cachearse al menos 1 hora.

Cache headers y ETags

Las lecturas usan Cache-Control: public, max-age=3600, s-maxage=86400, stale-while-revalidate=604800. Next.js adjunta un ETag derivado del cuerpo — devuélvelo como If-None-Match en peticiones posteriores y respondemos 304 Not Modified cuando el snapshot no cambió.

Envelope de respuesta

Las respuestas JSON comparten una envoltura estándar: { ok: true, license: "CC-BY-4.0", generated_at, ...payload }. Los errores son { ok: false, error, message } — ver el esquema ErrorResponse. Los CSV siguen RFC 4180 con fila de encabezado.

Descubrimiento agent-native

  • Servidor MCP en /api/mcp — HTTP streamable, 16+ herramientas tipadas: find_pros, get_pro, triage_symptom, get_cost_estimate, list_guides, get_active_storm_events y más.
  • Manifiesto ai-plugin en /.well-known/ai-plugin.json — manifiesto de plugin ChatGPT / conector Anthropic que apunta a esta OpenAPI.
  • ai.txt + llms.txt en /.well-known/ai.txt y /llms.txt — política de acceso para agentes y mapa de contenido para LLMs.

Agentes y descubrimiento

Servidor MCP, espejo OpenAPI/YAML, manifiesto ai-plugin, llms.txt, ai.txt — las superficies que cualquier agente autónomo o motor de IA toca primero.

15 endpoints
get/.well-known/ai-plugin.json

ChatGPT plugin manifest

ChatGPT plugin / Anthropic connector manifest pointing at this OpenAPI spec. Schema version `v1`, auth `none`, API type `openapi`.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Plugin manifest JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/.well-known/ai-plugin.json"
javascript
const res = await fetch("https://profixdirectory.com/.well-known/ai-plugin.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/.well-known/ai-plugin.json", timeout=10)
res.raise_for_status()
print(res.json())
get/.well-known/ai.txt

AI agent access policy

Plain-text AI-agent access policy mirroring robots.txt — Spawning.ai ai.txt draft + llmstxt.org convention. Lists allowed agents, disallowed paths, and discovery pointers (llms.txt, MCP, OpenAPI, dataset).

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(ai.txt plain text)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/.well-known/ai.txt"
javascript
const res = await fetch("https://profixdirectory.com/.well-known/ai.txt");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/.well-known/ai.txt", timeout=10)
res.raise_for_status()
print(res.json())
get/api/all

Discovery index — every machine-readable surface in one document

Single-fetch agent-discovery payload aggregating the bulk dataset, every JSON/CSV/RSS/iCal feed (via /api/feeds-index.json), the canonical site graph, and every relevant content map. Useful for AI engines that want one URL to crawl. CC-BY-4.0, 1h cache, CORS-enabled.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Discovery index JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/all"
javascript
const res = await fetch("https://profixdirectory.com/api/all");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/all", timeout=10)
res.raise_for_status()
print(res.json())
get/api/changelog

Git-derived product changelog — paginated JSON (last 90 days)

Paginated, machine-readable feed of every user-facing change (feat/fix/perf) sourced from the live git log over a rolling 90-day window. 50 entries per page, ETag + Cache-Control, scope-aware url hints, and HEAD support. Personal git authors are dropped — every entry is published under the ProFix Editorial Team banner. Paginate with ?page=1..N. Companion HTML pages: /changelog (EN), /es/registro-cambios (ES). CC-BY-4.0.

Parámetros

  • page (query)tipo: integer
    1-indexed page number. Defaults to 1.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Changelog JSON page)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/changelog"
javascript
const res = await fetch("https://profixdirectory.com/api/changelog");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/changelog", timeout=10)
res.raise_for_status()
print(res.json())
get/api/changelog.json

Newsroom changelog — machine-readable

JSON companion to /newsroom. Every entry has date, type (research/feature/data/api/design), headline, body, optional url. Sorted newest-first. CC-BY-4.0.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Changelog JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/changelog.json"
javascript
const res = await fetch("https://profixdirectory.com/api/changelog.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/changelog.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/emergency-playbook/{slug}.json

Emergency playbook JSON companion

Minimal JSON mirror of /emergency/playbooks/{slug}. Returns immediate steps, shutoff guidance, do-not list, who-to-call list, damage mitigation, typical cost band, insurance note, and prevention guidance. CC-BY-4.0. CORS-enabled, 1h cache.

Parámetros

  • slug (path)requeridotipo: string
    Emergency playbook slug, for example burst-pipe-inside.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Emergency playbook JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/emergency-playbook/miller-plumbing-toledo.json"
javascript
const res = await fetch("https://profixdirectory.com/api/emergency-playbook/miller-plumbing-toledo.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/emergency-playbook/miller-plumbing-toledo.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/jsonld/{type}

Open JSON-LD feeds — full Schema.org graphs by type

First-class structured-data feeds for AI engines, partners, and structured-data tooling. Supported types: `pros` (LocalBusiness graph for every pro), `cost-guides` (Article graph), `faq` (combined FAQPage), `organization` (ProFix Directory entity), `local-business-index` (top-100 ItemList), `faq-trade-{trade}` (per-trade FAQPage), `breadcrumb-coverage` (BreadcrumbList for /coverage). No auth, 1h CDN cache + 1d stale-while-revalidate.

Parámetros

  • type (path)requeridotipo: string
    JSON-LD feed identifier (see description for valid values)

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(JSON-LD graph)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/jsonld/organization"
javascript
const res = await fetch("https://profixdirectory.com/api/jsonld/organization");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/jsonld/organization", timeout=10)
res.raise_for_status()
print(res.json())
get/api/markdown-corpus

Paginated index of every Markdown-exportable route

JSON metadata listing every available `/api/markdown/{slug}` URL grouped by content type. Pages capped at 5000 entries via `?cursor=` (offset). Use `?type=<contentType>` to filter. Every entry is CC-BY-4.0 sourced from the ProFix Editorial Team.

Parámetros

  • type (query)tipo: string
    Optional content type filter.
  • cursor (query)tipo: integer
    Zero-based offset for pagination.
  • limit (query)tipo: integer
    Page size. Hard-capped at 5000.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Paginated corpus index JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/markdown-corpus"
javascript
const res = await fetch("https://profixdirectory.com/api/markdown-corpus");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/markdown-corpus", timeout=10)
res.raise_for_status()
print(res.json())
get/api/markdown/{slug}

Markdown export of a single editorial route

Returns CC-BY-4.0 Markdown with YAML frontmatter for any (contentType, slug) pair covered by the corpus. Use `?type=<contentType>` to disambiguate when a slug exists across multiple types; otherwise the route auto-infers. Strong ETag + Cache-Control. Designed for AI training pipelines and content aggregators.

Parámetros

  • slug (path)requeridotipo: string
    The route slug (e.g. `plumber`, `furnace-tune-up-cost-toledo`).
  • type (query)tipo: string
    Content type. Optional — auto-inferred from slug when omitted.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Markdown text/plain with YAML frontmatter)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/markdown/miller-plumbing-toledo"
javascript
const res = await fetch("https://profixdirectory.com/api/markdown/miller-plumbing-toledo");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/markdown/miller-plumbing-toledo", timeout=10)
res.raise_for_status()
print(res.json())
get/api/mcp

Model Context Protocol server

Streamable HTTP MCP server exposing 46 tools for AI agents (Claude, ChatGPT, Perplexity): find_pros, find_pros_by_neighborhood, get_pro, list_taxonomy, get_emergency_contacts, get_cost_estimate, list_cost_guides, list_guides, get_guide, triage_symptom, get_methodology, get_active_storm_events, get_verification_feed, get_county_coverage_stats, find_emergency_pros, get_trade_pricing, get_trade_guide, get_trade_faq, list_emergency_playbooks, get_emergency_playbook, estimate_cost, list_research_articles, get_research_article, verify_contractor, and national state/pro/license matching tools. Use when your agent supports MCP; otherwise prefer the REST endpoints.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(MCP handshake)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/mcp"
javascript
const res = await fetch("https://profixdirectory.com/api/mcp");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/mcp", timeout=10)
res.raise_for_status()
print(res.json())
get/api/newsroom.rss

Newsroom RSS 2.0 feed

RSS feed combining changelog entries + published research articles. Subscribe in any RSS reader to track ProFix's product + editorial milestones. CC-BY-4.0.

Respuesta de ejemplo

json
# RSS XML
# Feed en texto plano (RSS / Atom / iCal).

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/newsroom.rss"
javascript
const res = await fetch("https://profixdirectory.com/api/newsroom.rss");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/newsroom.rss", timeout=10)
res.raise_for_status()
print(res.json())
get/api/trade-guide/{trade}.json

Trade encyclopedia JSON companion

Minimal JSON mirror of /trades/{trade}/guide. Returns the Wave 64 trade encyclopedia entry: troubleshooting, maintenance schedule, cost components, hiring red flags, contract checklist, and warranty norms. CC-BY-4.0. CORS-enabled, 1h cache.

Parámetros

  • trade (path)requeridotipo: string
    Canonical trade slug, for example plumber, hvac, electrician, roofing.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Trade guide JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/trade-guide/plumber.json"
javascript
const res = await fetch("https://profixdirectory.com/api/trade-guide/plumber.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/trade-guide/plumber.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/voice/{q}

Voice assistant single-question Q&A

GET endpoint for Alexa skills / Google Actions. Takes a URL-encoded natural-language question as a path segment and returns a 25-40 word voice-friendly answer in both English and Spanish, plus the canonical source URL and source type. Deterministic — no LLM call. Reuses the same search-query-expander + voice-answer collapse pipeline that powers /faq and /api/ask. Strong ETag; Cache-Control public max-age=3600, s-maxage=86400. No auth required.

Parámetros

  • q (path)requeridotipo: string
    URL-encoded natural-language question (e.g. `how%20much%20does%20a%20plumber%20cost`).

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Voice answer JSON.)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/voice/example"
javascript
const res = await fetch("https://profixdirectory.com/api/voice/example");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/voice/example", timeout=10)
res.raise_for_status()
print(res.json())
get/llms-full.txt

Full LLM content dump

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Plain-text full content map)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/llms-full.txt"
javascript
const res = await fetch("https://profixdirectory.com/llms-full.txt");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/llms-full.txt", timeout=10)
res.raise_for_status()
print(res.json())
get/llms.txt

LLM content map (llmstxt.org spec)

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Plain-text content map)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/llms.txt"
javascript
const res = await fetch("https://profixdirectory.com/llms.txt");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/llms.txt", timeout=10)
res.raise_for_status()
print(res.json())

Feeds de datos

Feeds JSON / CSV por recurso — profesionales, permisos, leads, deltas de verificación, reportes de costos, glosario, búsqueda, autocompletar y el recuperador determinístico /api/answer.

64 endpoints
post/api/answer

Deterministic ProFix answer retrieval

Accepts a homeowner or agent question and returns top grounded matches from ProFix research, buyer guides, glossary, and cost guides. Pure deterministic text retrieval; no LLM call.

Cuerpo de ejemplo

json
{
  "question": "¿Cómo encuentro un plomero licenciado en Toledo con historial reciente de permisos?",
  "context": [
    "toledo",
    "plumbing"
  ]
}

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Grounded deterministic matches)"
}

Ejemplos de código

curl
curl -X POST "https://profixdirectory.com/api/answer" \
  -H 'Content-Type: application/json' \
  -d '{
  "question": "¿Cómo encuentro un plomero licenciado en Toledo con historial reciente de permisos?",
  "context": [
    "toledo",
    "plumbing"
  ]
}'
javascript
const res = await fetch("https://profixdirectory.com/api/answer", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    "question": "¿Cómo encuentro un plomero licenciado en Toledo con historial reciente de permisos?",
    "context": [
      "toledo",
      "plumbing"
    ]
  }),
});
const data = await res.json();
console.log(data);
python
import requests

payload = {
  "question": "¿Cómo encuentro un plomero licenciado en Toledo con historial reciente de permisos?",
  "context": [
    "toledo",
    "plumbing"
  ]
}

res = requests.post("https://profixdirectory.com/api/answer", json=payload, timeout=10)
res.raise_for_status()
print(res.json())
get/api/ask

Natural-language Q&A endpoint

GET version of the answer engine. Accepts a single `q` parameter and returns a structured response with intent detection, a best_answer, related_answers, and related_routes pulled deterministically from FAQs, cost guides, license guides, glossary, buyer guides, and comparison guides. No LLM. Always returns 200 — when no match is found, intent is `unknown` and `match_status` is `no_answer`. Strong ETag; Cache-Control: public, max-age=3600.

Parámetros

  • q (query)tipo: string
    Natural-language question (URL-encoded).

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Structured answer JSON.)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/ask"
javascript
const res = await fetch("https://profixdirectory.com/api/ask");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/ask", timeout=10)
res.raise_for_status()
print(res.json())
get/api/autocomplete

Lightweight typeahead

Typeahead-shaped variant of /api/search — same scoring, smaller payload, strong ETag, designed for header search bars and agent prefix queries.

Parámetros

  • q (query)requeridotipo: string
  • limit (query)tipo: integer

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Autocomplete suggestions JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/autocomplete"
javascript
const res = await fetch("https://profixdirectory.com/api/autocomplete");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/autocomplete", timeout=10)
res.raise_for_status()
print(res.json())
get/api/badge/{slug}.svg

Embeddable 'ProFix Verified' trust badge SVG

Per-contractor 240×80 SVG badge displaying current ProFix trust tier (Elite/Solid/Starter/Minimal), 0-100 composite Trust Score, and recent permit count when > 0. Pure inline SVG using system fonts — no external assets. Designed to be embedded with a single `<img>` tag on a contractor's own website, Slack channel, or email signature. CORS-enabled. CC-BY-4.0; keep the wordmark visible. Returns a 404 SVG fallback for unknown slugs. 1h CDN cache.

Parámetros

  • slug (path)requeridotipo: string
    Pro slug (see /api/jsonld/local-business-index for the canonical list)

Respuesta de ejemplo

json
<!-- SVG badge -->
<svg xmlns="http://www.w3.org/2000/svg" ...>...</svg>

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/badge/miller-plumbing-toledo.svg"
javascript
const res = await fetch("https://profixdirectory.com/api/badge/miller-plumbing-toledo.svg");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/badge/miller-plumbing-toledo.svg", timeout=10)
res.raise_for_status()
print(res.json())
get/api/brand-assets.json

Brand assets feed — logo URLs, color palette, fonts, attribution

Programmatic feed of ProFix Directory brand assets — logo SVG + icon SVG URLs, the brand color palette (primary, accent, background, foreground, neutral), font stack, and short/long/HTML attribution strings. Designed for partner integrations (Slack apps, Discord embeds, Zapier templates, widget hosts) that want a branded card. CC-BY-4.0 for editorial use; brand marks remain ProFix Directory LLC trademarks. 1h cache, CORS-enabled.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Brand assets JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/brand-assets.json"
javascript
const res = await fetch("https://profixdirectory.com/api/brand-assets.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/brand-assets.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/buyers-guides.json

Buyer's guide index

Machine-readable index of every ProFix Directory buyer's guide — slug, title, summary, trade, last-reviewed date, and canonical URL. CC-BY-4.0, 1h cache, CORS-enabled.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Buyer's guides JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/buyers-guides.json"
javascript
const res = await fetch("https://profixdirectory.com/api/buyers-guides.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/buyers-guides.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/changelog.atom

Newsroom changelog — Atom 1.0 mirror of /api/newsroom.rss

Atom 1.0 feed of every public ProFix Directory changelog entry. Same data the RSS feed exposes, served in the Atom envelope for readers and AI engines that prefer Atom over RSS. CC-BY-4.0, 1h cache, CORS-enabled.

Respuesta de ejemplo

json
# Changelog Atom 1.0
# Feed en texto plano (RSS / Atom / iCal).

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/changelog.atom"
javascript
const res = await fetch("https://profixdirectory.com/api/changelog.atom");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/changelog.atom", timeout=10)
res.raise_for_status()
print(res.json())
get/api/changelog.csv

Newsroom changelog — CSV mirror of /api/changelog.json

RFC 4180 CSV mirror of /api/changelog.json. One row per CHANGELOG entry. Columns: `date,type,headline,slug,url`. Use when you want to drop the changelog into Excel/Sheets/pandas. CC-BY-4.0, 1h cache, CORS-enabled.

Respuesta de ejemplo

json
# Respuesta CSV — RFC 4180. La primera fila es el encabezado.
# Changelog CSV
slug,name,city,county,state,phone,verification_tier
miller-plumbing-toledo,Miller Plumbing,Toledo,Lucas,OH,419-555-0144,license-linked

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/changelog.csv"
javascript
const res = await fetch("https://profixdirectory.com/api/changelog.csv");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/changelog.csv", timeout=10)
res.raise_for_status()
print(res.json())
get/api/changelog.ics

Newsroom changelog — iCal (RFC 5545) calendar feed

iCal subscription of every ProFix Directory changelog milestone as an all-day VEVENT. Subscribe in Apple Calendar, Google Calendar, or Outlook via webcal://profixdirectory.com/api/changelog.ics. Each event carries SUMMARY, DESCRIPTION, URL, CATEGORIES, and a stable UID. CC-BY-4.0, 1h cache, CORS-enabled.

Respuesta de ejemplo

json
# iCal calendar
# Feed en texto plano (RSS / Atom / iCal).

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/changelog.ics"
javascript
const res = await fetch("https://profixdirectory.com/api/changelog.ics");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/changelog.ics", timeout=10)
res.raise_for_status()
print(res.json())
get/api/compare

Side-by-side contractor comparison

Normalized side-by-side comparison feed for up to three ProFix contractors. Pass `?pros=slug1,slug2,slug3` (comma-separated, ≤3 slugs). Returns each pro's Trust Score + tier, permit count over the last 12 months, license status + license number, rating + review count, insurance-verified flag, tenure, specialties, service area, photo count, featured flag, Spanish-speaking flag, profile URL, evidence-page URL, and last-verified date. Unknown slugs are silently dropped; `requested_slugs` echoes what was asked for. Same JSON shape powers the interactive /compare page. CC-BY-4.0, CORS-enabled, 1h cache.

Parámetros

  • pros (query)requeridotipo: string
    Comma-separated pro slugs (e.g. `miller-plumbing-toledo,atlas-butler-heating-cooling-columbus`). At most 3 slugs; returns 400 otherwise.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Comparison JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/compare"
javascript
const res = await fetch("https://profixdirectory.com/api/compare");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/compare", timeout=10)
res.raise_for_status()
print(res.json())
get/api/contractors/by-county/{county}.csv

Bulk contractor feed — CSV mirror of /api/contractors/by-county/{county}.json

RFC 4180 CSV mirror of the per-county contractor JSON feed. Same row set, byte-different envelope for spreadsheet + pandas workflows. CC-BY-4.0.

Parámetros

  • county (path)requeridotipo: string
    One of the 88 ProFix Ohio county slugs

Respuesta de ejemplo

json
# Respuesta CSV — RFC 4180. La primera fila es el encabezado.
# Contractor CSV
slug,name,city,county,state,phone,verification_tier
miller-plumbing-toledo,Miller Plumbing,Toledo,Lucas,OH,419-555-0144,license-linked

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/contractors/by-county/lucas.csv"
javascript
const res = await fetch("https://profixdirectory.com/api/contractors/by-county/lucas.csv");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/contractors/by-county/lucas.csv", timeout=10)
res.raise_for_status()
print(res.json())
get/api/contractors/by-county/{county}.json

Bulk contractor feed for a single Ohio county

All public ProFix contractors who serve the given county. Pre-rendered for all 88 Ohio county slugs. Each row carries slug, name, trade + trades[], city, county, phone, rating + review_count, trust_score + trust_tier, permit_count_12mo, license_status + license_number, url, and evidence_url. CC-BY-4.0, 1h cache, CORS-enabled.

Parámetros

  • county (path)requeridotipo: string
    One of the 88 ProFix Ohio county slugs (lucas, cuyahoga, franklin, hamilton, …)

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Contractor feed JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/contractors/by-county/lucas.json"
javascript
const res = await fetch("https://profixdirectory.com/api/contractors/by-county/lucas.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/contractors/by-county/lucas.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/contractors/by-trade/{trade}.csv

Bulk contractor feed — CSV mirror of /api/contractors/by-trade/{trade}.json

RFC 4180 CSV mirror of the per-trade contractor JSON feed. Same row set, byte-different envelope for spreadsheet + pandas workflows. CC-BY-4.0.

Parámetros

  • trade (path)requeridotipo: string
    One of the 37 ProFix trade slugs

Respuesta de ejemplo

json
# Respuesta CSV — RFC 4180. La primera fila es el encabezado.
# Contractor CSV
slug,name,city,county,state,phone,verification_tier
miller-plumbing-toledo,Miller Plumbing,Toledo,Lucas,OH,419-555-0144,license-linked

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/contractors/by-trade/plumber.csv"
javascript
const res = await fetch("https://profixdirectory.com/api/contractors/by-trade/plumber.csv");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/contractors/by-trade/plumber.csv", timeout=10)
res.raise_for_status()
print(res.json())
get/api/contractors/by-trade/{trade}.json

Bulk contractor feed for a single trade (statewide)

All public ProFix contractors whose declared trade list includes the given slug, statewide. Pre-rendered for all 37 ProFix trade slugs. Same row shape as /api/contractors/by-county/{county}.json. CC-BY-4.0, 1h cache, CORS-enabled.

Parámetros

  • trade (path)requeridotipo: string
    One of the 37 ProFix trade slugs (plumber, hvac, electrician, appliance-repair, gas-tech, concrete, roofing, tree-service, restoration, lead-abatement, fire-protection, water-well, septic-system, tech-repair, pest-control, landscaping, painting, foundation-repair, garage-door, deck-builder, patio-installer, pool-installer, fence-contractor, shed-builder, siding-contractor, window-door-installer, gutter-installer, pressure-washing, lawn-care, sealcoat, outdoor-lighting, solar-installer, ev-charger-installer, heat-pump-installer, insulation-contractor, general-contractor, handyman)

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Contractor feed JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/contractors/by-trade/plumber.json"
javascript
const res = await fetch("https://profixdirectory.com/api/contractors/by-trade/plumber.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/contractors/by-trade/plumber.json", timeout=10)
res.raise_for_status()
print(res.json())
post/api/corrections

Submit a correction to the editorial team

Public corrections submission endpoint. Accepts JSON or form-encoded payloads with `pro_slug` (optional), `field`, `correction`, and `evidence_url`. Returns 200 with a thank-you acknowledgement. No PII required.

Cuerpo de ejemplo

json
{
  "pro_slug": "miller-plumbing-toledo",
  "field": "phone",
  "correction": "Teléfono comercial actualizado tras verificación por buzón de voz.",
  "evidence_url": "https://example.com/captura-buzon.png",
  "contact_email": "informante@example.com"
}

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Acknowledged)"
}

Ejemplos de código

curl
curl -X POST "https://profixdirectory.com/api/corrections" \
  -H 'Content-Type: application/json' \
  -d '{
  "pro_slug": "miller-plumbing-toledo",
  "field": "phone",
  "correction": "Teléfono comercial actualizado tras verificación por buzón de voz.",
  "evidence_url": "https://example.com/captura-buzon.png",
  "contact_email": "informante@example.com"
}'
javascript
const res = await fetch("https://profixdirectory.com/api/corrections", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    "pro_slug": "miller-plumbing-toledo",
    "field": "phone",
    "correction": "Teléfono comercial actualizado tras verificación por buzón de voz.",
    "evidence_url": "https://example.com/captura-buzon.png",
    "contact_email": "informante@example.com"
  }),
});
const data = await res.json();
console.log(data);
python
import requests

payload = {
  "pro_slug": "miller-plumbing-toledo",
  "field": "phone",
  "correction": "Teléfono comercial actualizado tras verificación por buzón de voz.",
  "evidence_url": "https://example.com/captura-buzon.png",
  "contact_email": "informante@example.com"
}

res = requests.post("https://profixdirectory.com/api/corrections", json=payload, timeout=10)
res.raise_for_status()
print(res.json())
get/api/cost-report.csv

Cost guide aggregate — CSV companion to /api/cost-report.json

RFC 4180 CSV mirror of the cost report JSON. One row per benchmark. CC-BY-4.0.

Respuesta de ejemplo

json
# Respuesta CSV — RFC 4180. La primera fila es el encabezado.
# Cost report CSV
slug,name,city,county,state,phone,verification_tier
miller-plumbing-toledo,Miller Plumbing,Toledo,Lucas,OH,419-555-0144,license-linked

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/cost-report.csv"
javascript
const res = await fetch("https://profixdirectory.com/api/cost-report.csv");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/cost-report.csv", timeout=10)
res.raise_for_status()
print(res.json())
get/api/cost-report.json

Cost guide aggregate (Toledo + Findlay 2026 research)

Aggregate Toledo + Findlay home-services cost benchmarks from the 2026 NW Ohio cost research — 60 cost benchmarks across 8 trades with median + range + Findlay-vs-Toledo variance. CC-BY-4.0. CSV mirror at /api/cost-report.csv.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Cost report JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/cost-report.json"
javascript
const res = await fetch("https://profixdirectory.com/api/cost-report.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/cost-report.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/coverage-stats.csv

Coverage snapshot — CSV companion to /api/coverage-stats.json

RFC 4180 CSV with one row per Ohio county (slug, name, region, pro_count). CC-BY-4.0.

Respuesta de ejemplo

json
# Respuesta CSV — RFC 4180. La primera fila es el encabezado.
# Coverage stats CSV
slug,name,city,county,state,phone,verification_tier
miller-plumbing-toledo,Miller Plumbing,Toledo,Lucas,OH,419-555-0144,license-linked

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/coverage-stats.csv"
javascript
const res = await fetch("https://profixdirectory.com/api/coverage-stats.csv");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/coverage-stats.csv", timeout=10)
res.raise_for_status()
print(res.json())
get/api/coverage-stats.json

Coverage snapshot — pro counts by county / region / trade

Static aggregate of verified contractor counts grouped by Ohio county, region (Cleveland/Columbus/Cincinnati/Dayton/Toledo/Findlay/etc.), and trade. Completes the public-data trio (lead-feed + quality-stats + coverage-stats). 1h cache, CC-BY-4.0.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Coverage stats JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/coverage-stats.json"
javascript
const res = await fetch("https://profixdirectory.com/api/coverage-stats.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/coverage-stats.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/data-studies/{slug}.csv

Data study — CSV download

RFC 4180-style CSV companion for a generated ProFix data-study route at /data-studies/{slug}. Uses rowGroup to distinguish primary and secondary row sets. CC-BY-4.0, CORS-enabled.

Parámetros

  • slug (path)requeridotipo: string
    Data-study slug, for example contractor-density-by-state-2026.

Respuesta de ejemplo

json
# Respuesta CSV — RFC 4180. La primera fila es el encabezado.
# Data-study CSV payload
slug,name,city,county,state,phone,verification_tier
miller-plumbing-toledo,Miller Plumbing,Toledo,Lucas,OH,419-555-0144,license-linked

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/data-studies/miller-plumbing-toledo.csv"
javascript
const res = await fetch("https://profixdirectory.com/api/data-studies/miller-plumbing-toledo.csv");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/data-studies/miller-plumbing-toledo.csv", timeout=10)
res.raise_for_status()
print(res.json())
get/api/data-studies/{slug}.json

Data study — JSON companion

Machine-readable JSON companion for a generated ProFix data-study route at /data-studies/{slug}. Includes methodology, limitations, source files, primary rows, download URLs, and CC-BY-4.0 attribution.

Parámetros

  • slug (path)requeridotipo: string
    Data-study slug, for example contractor-density-by-state-2026.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Data-study JSON payload)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/data-studies/miller-plumbing-toledo.json"
javascript
const res = await fetch("https://profixdirectory.com/api/data-studies/miller-plumbing-toledo.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/data-studies/miller-plumbing-toledo.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/embed/{slug}.json

Partner embed feed — top 5 pros for a trade × city pair

Returns the top 5 verified pros for a `{trade}-{city}` slug pair (e.g. `plumber-toledo`, `hvac-cleveland`). Designed for one-line third-party embeds — blogs, newsletters, HOA sites. Includes name, phone, rating, verification tier, and permit count. CC-BY-4.0. 1h cache.

Parámetros

  • slug (path)requeridotipo: string
    Slug format `{trade}-{city}` (e.g. plumber-toledo)

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Embed JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/embed/miller-plumbing-toledo.json"
javascript
const res = await fetch("https://profixdirectory.com/api/embed/miller-plumbing-toledo.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/embed/miller-plumbing-toledo.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/feeds-index.json

Feeds index — catalog of every JSON/CSV/RSS/iCal feed with metadata

Catalog of every public ProFix Directory feed (JSON, CSV, RSS, iCal). Each entry carries `path`, absolute `url`, `format`, `category`, `description`, `license`, `refresh_cadence` (live / hourly / daily / weekly / monthly / static), `cors`, and an optional `openapi_id` cross-reference. Enumerated from the same `PUBLIC_API_FEED_PATHS` list that powers /sitemap.xml — a single fetch tells an agent every machine-readable surface ProFix exposes. CC-BY-4.0, 1h cache, CORS-enabled.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Feeds index JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/feeds-index.json"
javascript
const res = await fetch("https://profixdirectory.com/api/feeds-index.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/feeds-index.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/glossary.json

Bilingual glossary — EN + ES home-services terminology

Programmatic feed of every glossary term in the ProFix bilingual reference: trade jargon, licensing (OCILB, EPA 608), permits, manufacturer certifications, legal terms, and pricing concepts. Each entry has term, slug, English + Spanish definitions, category, and optional related-term cross-refs. CC-BY-4.0. 1h cache. CORS-enabled.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Glossary JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/glossary.json"
javascript
const res = await fetch("https://profixdirectory.com/api/glossary.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/glossary.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/graph/coverage.jsonld

Ohio coverage Schema.org graph

Connected JSON-LD graph for Ohio, covered metros, counties, cities, ProFix Directory as LocalBusiness, and one Service node per trade. Built for Google Dataset Search and AI knowledge graph ingestion.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Coverage JSON-LD)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/graph/coverage.jsonld"
javascript
const res = await fetch("https://profixdirectory.com/api/graph/coverage.jsonld");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/graph/coverage.jsonld", timeout=10)
res.raise_for_status()
print(res.json())
get/api/health

Liveness + dependency probe

Returns directory load status (pro count, county count) plus presence flags for Stripe, Supabase, PostHog, Resend env vars. Public — useful for monitors and partner status pages.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Service healthy)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/health"
javascript
const res = await fetch("https://profixdirectory.com/api/health");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/health", timeout=10)
res.raise_for_status()
print(res.json())
get/api/jsonld/dataset

Dataset JSON-LD — Google Dataset Search registration document

Top-level Schema.org Dataset document describing the 21,898-record ProFix Ohio Home-Services Pros dataset. Names creator + publisher (ProFix Directory / ProFix Directory LLC), declares CC-BY-4.0 license, lists three DataDownload distributions (JSON, CSV, Hugging Face), Ohio spatialCoverage as a GeoShape, 2026/.. temporalCoverage, and five variableMeasured PropertyValue entries (license status, permit count, verification tier, trust score, review aggregate). Designed for Google Dataset Search registration + academic-search tooling that crawl JSON-LD Dataset shapes. Daily revalidate. CORS open.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Dataset JSON-LD)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/jsonld/dataset"
javascript
const res = await fetch("https://profixdirectory.com/api/jsonld/dataset");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/jsonld/dataset", timeout=10)
res.raise_for_status()
print(res.json())
get/api/lead-feed.csv

Lead feed — CSV companion to /api/lead-feed.json

Long-format CSV (window_days, bucket, key, value) for lead aggregate metrics — pivot-friendly. Zero PII. CC-BY-4.0.

Respuesta de ejemplo

json
# Respuesta CSV — RFC 4180. La primera fila es el encabezado.
# Lead feed CSV
slug,name,city,county,state,phone,verification_tier
miller-plumbing-toledo,Miller Plumbing,Toledo,Lucas,OH,419-555-0144,license-linked

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/lead-feed.csv"
javascript
const res = await fetch("https://profixdirectory.com/api/lead-feed.csv");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/lead-feed.csv", timeout=10)
res.raise_for_status()
print(res.json())
get/api/lead-feed.json

Lead volume + quality-tier aggregate feed

30-day rolling aggregate of homeowner lead submissions, grouped by trade, quality tier (premium/standard/low/needs_review), urgency, and counties with active demand. Zero PII. Refreshes hourly. Useful for sizing local home-services market or summarizing demand signals.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Lead feed JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/lead-feed.json"
javascript
const res = await fetch("https://profixdirectory.com/api/lead-feed.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/lead-feed.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/license-revocations.json

Anonymized license-status change patterns

Programmatic feed behind /license-watch. Returns anonymized contractor license, registration, and credential status-change patterns across ProFix trades: id, trade, status_change, pattern, reason_category, date_of_change, county, and homeowner_action. No business names, personal names, license numbers, addresses, or docket numbers. CC-BY-4.0 editorial assembly, 1h cache, CORS-enabled.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(License revocations and suspensions JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/license-revocations.json"
javascript
const res = await fetch("https://profixdirectory.com/api/license-revocations.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/license-revocations.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/match/{trade}/{state}

Agent-native ranked pro matching for (trade, state)

Returns up to 50 gold-tier contractors (combined `national_gold` + `regional_gold` — national gold = confidence ≥ 80 with multi-source aggregation; regional gold = single-source + license + phone-state exact match) for a (trade, state) query, sorted by confidence descending. Same per-pro dossier shape as /api/pro/{slug} — no PII beyond what's on the public profile. Validates trade against TRADES and state against SUPPORTED_STATES (case-insensitive). 400 on invalid input. 404 when the state isn't supportedByDirectory OR the (trade, state) pool has fewer than 3 pros. Optional filters: `?limit=` (default 10, max 50), `?city=` (case-insensitive), `?emergency=true` (24/7 pros only). Strong ETag covers the full filter set + a pool snapshot hash so deploys that refresh the seed bust the cache. 1h browser / 24h CDN / 7d SWR. CORS-enabled. CC-BY-4.0.

Parámetros

  • trade (path)requeridotipo: string
    Trade slug (e.g. 'plumber', 'hvac', 'electrician'). See TRADES.
  • state (path)requeridotipo: string
    Two-letter postal code (e.g. 'OH'). Case-insensitive.
  • limit (query)tipo: integer
    Max number of pros to return (1-50, default 10).
  • city (query)tipo: string
    Filter to a single city (case-insensitive).
  • emergency (query)tipo: boolean
    When true, only return pros flagged emergency24h.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Ranked match payload)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/match/plumber/OH"
javascript
const res = await fetch("https://profixdirectory.com/api/match/plumber/OH");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/match/plumber/OH", timeout=10)
res.raise_for_status()
print(res.json())
get/api/metrics.json

Directory growth metrics — totals, per-trade, per-metro

Machine-readable mirror of /metrics. Build-time aggregate of total contractors, license-linked share, permit pulls in the last 12 months, trades / counties / cities covered, research articles, buyer's guides, glossary terms, public API endpoints, data sources, plus per-trade and per-metro rows. CC-BY-4.0, CORS-enabled, 1h cache.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Metrics JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/metrics.json"
javascript
const res = await fetch("https://profixdirectory.com/api/metrics.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/metrics.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/openapi.yaml

OpenAPI 3.1 spec — YAML mirror of /api/openapi.json

YAML serialization of the canonical OpenAPI 3.1 document at /api/openapi.json. Same spec object, byte-different envelope — for partners and AI tooling that prefer YAML over JSON. CC-BY-4.0, 24h cache, CORS-enabled.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(OpenAPI 3.1 YAML)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/openapi.yaml"
javascript
const res = await fetch("https://profixdirectory.com/api/openapi.yaml");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/openapi.yaml", timeout=10)
res.raise_for_status()
print(res.json())
get/api/outage-status

Active utility outage status

Real-time-ish outage status for major Ohio utilities serving NW Ohio.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Outage status JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/outage-status"
javascript
const res = await fetch("https://profixdirectory.com/api/outage-status");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/outage-status", timeout=10)
res.raise_for_status()
print(res.json())
get/api/permit-leaderboard.csv

Permit-pull leaderboard — CSV companion to /api/permit-leaderboard.json

RFC 4180 CSV mirror of the permit leaderboard JSON feed. Same query-param filtering (`?trade=&county=&window=&top=`). One row per leaderboard entry. CC-BY-4.0.

Parámetros

  • trade (query)tipo: string
  • county (query)tipo: string
  • window (query)tipo: integer
  • top (query)tipo: integer

Respuesta de ejemplo

json
# Respuesta CSV — RFC 4180. La primera fila es el encabezado.
# Permit leaderboard CSV
slug,name,city,county,state,phone,verification_tier
miller-plumbing-toledo,Miller Plumbing,Toledo,Lucas,OH,419-555-0144,license-linked

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/permit-leaderboard.csv"
javascript
const res = await fetch("https://profixdirectory.com/api/permit-leaderboard.csv");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/permit-leaderboard.csv", timeout=10)
res.raise_for_status()
print(res.json())
get/api/permit-leaderboard.json

Permit-pull leaderboard — pro rankings by verified building permits

Ranks Ohio contractors by VERIFIED public building permits pulled in the last 365 days (proof of work, not stars). Per-trade, per-county leaderboards across Lucas / Cuyahoga / Franklin / Hamilton counties. Filter via query params: `?trade=<slug>&county=<slug>|ohio&window=<days>&top=<n>`. Use `county=ohio` for statewide aggregates. CC-BY-4.0. 1h cache.

Parámetros

  • trade (query)tipo: string
    Filter to a single trade slug (plumber, hvac, etc.)
  • county (query)tipo: string
    Filter to a single county slug, or `ohio` for statewide aggregates
  • window (query)tipo: integer
    Days back to count permits (max 1095)
  • top (query)tipo: integer
    Top N entries per leaderboard (max 100)

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Permit leaderboard JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/permit-leaderboard.json"
javascript
const res = await fetch("https://profixdirectory.com/api/permit-leaderboard.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/permit-leaderboard.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/permits.json

Permit office directory (Toledo + Findlay metros)

Permit-issuing offices with phone, hours, and per-trade guidance. Currently scoped to Toledo + Findlay metros (other Ohio metros forthcoming).

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Permits JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/permits.json"
javascript
const res = await fetch("https://profixdirectory.com/api/permits.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/permits.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/permits/by-county/{county}.json

Rolling 365-day permit feed for a single Ohio county

Public building permits over the last 365 days attributed to contractors who serve the given Ohio county. Pre-rendered for all 88 county slugs. Each row carries permit_id, issued_date, contractor_slug, address, trade, value_usd, url. CC-BY-4.0, 1h cache, CORS-enabled.

Parámetros

  • county (path)requeridotipo: string
    One of the 88 ProFix Ohio county slugs

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Permit feed JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/permits/by-county/lucas.json"
javascript
const res = await fetch("https://profixdirectory.com/api/permits/by-county/lucas.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/permits/by-county/lucas.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/permits/by-trade/{trade}.json

Rolling 365-day permit feed for a single trade (statewide)

Public building permits over the last 365 days attributed to contractors whose declared trade list includes the given slug, statewide. Pre-rendered for all 37 trade slugs. Same row shape as /api/permits/by-county/{county}.json. CC-BY-4.0, 1h cache, CORS-enabled.

Parámetros

  • trade (path)requeridotipo: string
    One of the 37 ProFix trade slugs

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Permit feed JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/permits/by-trade/plumber.json"
javascript
const res = await fetch("https://profixdirectory.com/api/permits/by-trade/plumber.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/permits/by-trade/plumber.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/pro/{slug}

Structured per-pro dossier (gold-tier, national)

Structured JSON mirror of /state/{state}/pro/{slug} for every gold-tier contractor in the ProFix Directory. Gold-tier is the combined `national_gold` + `regional_gold` set: national gold is confidence >= 80 with multi-source aggregation; regional gold is single-source + license + phone-state exact match (single-source `verified` listings are not exposed here). Returns identity, trades, verification tier, license evidence + verify URL, evidence (confidence score + corroborating source count + program badges), photo manifest entry, permit footprint, and outbound source URLs. Phone is included and tagged as `phone_verification: "directory-verified" | "self-attested"`. No PII beyond what's on the public profile. Strong ETag + 1h browser / 24h CDN / 7d SWR cache. CORS-enabled. CC-BY-4.0.

Parámetros

  • slug (path)requeridotipo: string
    Gold-tier pro slug

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Pro JSON dossier)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/pro/miller-plumbing-toledo"
javascript
const res = await fetch("https://profixdirectory.com/api/pro/miller-plumbing-toledo");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/pro/miller-plumbing-toledo", timeout=10)
res.raise_for_status()
print(res.json())
get/api/pro/{slug}.json

Per-pro JSON dossier

Canonical per-contractor dossier as JSON. Returns name, location, license + verification details, source URLs, permit count + verified status, the read-only Google Places rating (source: google_places), and a first-party `reviews` block — count, mean, star histogram, and up to 5 recent snippets from APPROVED ProFix-moderated homeowner reviews (source: first_party_moderated). Zero PII beyond what /pro/{slug} already shows publicly. CC-BY-4.0. 1h cache.

Parámetros

  • slug (path)requeridotipo: string
    Pro slug (see /api/jsonld/local-business-index for the canonical list)

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Pro JSON dossier)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/pro/miller-plumbing-toledo.json"
javascript
const res = await fetch("https://profixdirectory.com/api/pro/miller-plumbing-toledo.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/pro/miller-plumbing-toledo.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/pro/{slug}/permits

Per-pro permit-pull history (rolling 365d)

Targeted child endpoint of /api/pro/{slug}: returns the permit-pull history for the given gold-tier pro. Each row carries issued_date, permit_type, jurisdiction, address, job_value_usd, source_url, and synthetic flag. Includes a summary block with `count_total`, `count_12mo`, and `permit_verified`. Strong ETag + 1h/24h/7d cache. CORS-enabled. CC-BY-4.0.

Parámetros

  • slug (path)requeridotipo: string
    Gold-tier pro slug

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Permit feed)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/pro/miller-plumbing-toledo/permits"
javascript
const res = await fetch("https://profixdirectory.com/api/pro/miller-plumbing-toledo/permits");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/pro/miller-plumbing-toledo/permits", timeout=10)
res.raise_for_status()
print(res.json())
get/api/pro/{slug}/photos

Per-pro photo manifest entry

Targeted child endpoint of /api/pro/{slug}: returns just the photo manifest entry for the given gold-tier pro (`photo_url`, `thumb_url`, `alt`, `source_type`, `trusted`). Returns `photo: null` (200) when the manifest has no entry. Strong ETag + 1h/24h/7d cache. CORS-enabled. CC-BY-4.0.

Parámetros

  • slug (path)requeridotipo: string
    Gold-tier pro slug

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Photo manifest entry)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/pro/miller-plumbing-toledo/photos"
javascript
const res = await fetch("https://profixdirectory.com/api/pro/miller-plumbing-toledo/photos");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/pro/miller-plumbing-toledo/photos", timeout=10)
res.raise_for_status()
print(res.json())
get/api/prompts.json

ProFix Prompt Library — copy-paste prompts for AI engines

Machine-readable mirror of the /prompts library. Returns 23 ready-to-ship prompts for ChatGPT, Claude, Perplexity, and Gemini that ground their answers in public ProFix endpoints. Each entry includes id, category (homeowner / developer / press), title, description, the literal prompt text, referenced endpoints, tags, and an anchor URL into /prompts. CC-BY-4.0. 1h cache, CORS-enabled.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Prompt library JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/prompts.json"
javascript
const res = await fetch("https://profixdirectory.com/api/prompts.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/prompts.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/pros.csv

Bulk dataset — every public pro as CSV

RFC 4180 CSV mirror of /api/pros.json. One row per published contractor. Use when you want to drop the dataset into Excel, Sheets, or pandas. CC-BY-4.0.

Respuesta de ejemplo

json
# Respuesta CSV — RFC 4180. La primera fila es el encabezado.
# Pros dataset CSV
slug,name,city,county,state,phone,verification_tier
miller-plumbing-toledo,Miller Plumbing,Toledo,Lucas,OH,419-555-0144,license-linked

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/pros.csv"
javascript
const res = await fetch("https://profixdirectory.com/api/pros.csv");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/pros.csv", timeout=10)
res.raise_for_status()
print(res.json())
get/api/pros.json

Bulk dataset — every public pro as JSON

Full ProFix Directory pro dataset as one JSON document. One entry per published contractor with the public-surface columns (slug, name, address, phone, trades, license, rating, verification, trust). Mirror of the Hugging Face dataset `Pisces89/ohio-home-services-pros`. CC-BY-4.0, 1h cache, CORS-enabled.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Pros dataset JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/pros.json"
javascript
const res = await fetch("https://profixdirectory.com/api/pros.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/pros.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/quality-stats.json

Lead-quality score histogram + median per trade

90-day rolling aggregate of lead-quality scores — histogram by 20-point buckets, tier breakdown, overall median, and median per trade (requires ≥3 scored leads per trade to avoid noise). Zero PII. Refreshes hourly. Companion to /api/lead-feed.json.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Quality stats JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/quality-stats.json"
javascript
const res = await fetch("https://profixdirectory.com/api/quality-stats.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/quality-stats.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/recently-verified.json

Recently-verified pros — rolling 30-day feed

Feed of pros whose verifiedAt timestamp falls within the last 30 days. Includes verification tier, permit-verified flag, and trust score. Useful for 'what's new' surfaces + partner freshness checks. CC-BY-4.0. 1h cache.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Recently-verified pros JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/recently-verified.json"
javascript
const res = await fetch("https://profixdirectory.com/api/recently-verified.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/recently-verified.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/reports/permits-this-month.json

Monthly recap — last 30 days of Ohio contractor permit activity

Machine-readable mirror of /reports/permits-this-month. Rolling 30-day window over the real matched permit-by-pro dataset (5,004 public permits joined to 554 contractors across 22 county jurisdictions; in Ohio: Cuyahoga, Franklin, Hamilton). Returns generated_at, license, window (start/end/days), top_pros (top 25 by permit count), by_trade (top 3 per trade), by_county (top 3 per county). Real public-record permits only. CC-BY-4.0. Daily refresh.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Permits-this-month recap JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/reports/permits-this-month.json"
javascript
const res = await fetch("https://profixdirectory.com/api/reports/permits-this-month.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/reports/permits-this-month.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/reports/this-week.json

Weekly recap — last 7 days of newsroom changelog + research publications

Machine-readable mirror of /reports/this-week. Rolling 7-day window over the public CHANGELOG and RESEARCH_ARTICLES datasets. Returns generated_at, license, window (start/end/days), changelog_entries (date/type/headline/url), research_published (slug/title/url/publishedAt), and counts. Honest about empty windows. CC-BY-4.0. Daily refresh.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(This-week recap JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/reports/this-week.json"
javascript
const res = await fetch("https://profixdirectory.com/api/reports/this-week.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/reports/this-week.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/research-publications.ics

Research publications — iCal (RFC 5545) calendar feed

iCal subscription of every ProFix Directory research-article publication date as an all-day VEVENT. Subscribe in Apple Calendar, Google Calendar, or Outlook via webcal://profixdirectory.com/api/research-publications.ics. Each event links to the canonical /research/<slug> URL. CC-BY-4.0, 1h cache, CORS-enabled.

Respuesta de ejemplo

json
# iCal calendar
# Feed en texto plano (RSS / Atom / iCal).

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/research-publications.ics"
javascript
const res = await fetch("https://profixdirectory.com/api/research-publications.ics");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/research-publications.ics", timeout=10)
res.raise_for_status()
print(res.json())
get/api/research.csv

Research articles — CSV mirror of /api/research.json

RFC 4180 CSV mirror of /api/research.json. One row per published research article. Columns: `slug,publishedAt,wordCount,title,summary,keywords,url` where `keywords` is `;`-joined since CSV cannot nest arrays. CC-BY-4.0, 1h cache, CORS-enabled.

Respuesta de ejemplo

json
# Respuesta CSV — RFC 4180. La primera fila es el encabezado.
# Research CSV
slug,name,city,county,state,phone,verification_tier
miller-plumbing-toledo,Miller Plumbing,Toledo,Lucas,OH,419-555-0144,license-linked

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/research.csv"
javascript
const res = await fetch("https://profixdirectory.com/api/research.csv");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/research.csv", timeout=10)
res.raise_for_status()
print(res.json())
get/api/research.json

Research articles — JSON index

Machine-readable index of authored ProFix Directory research articles. Returns slug, title, publishedAt, wordCount, summary, keywords, and canonical URL for each /research/{slug} article. Generated data-study Markdown entries are exposed through /api/markdown-corpus?type=research when the data-studies seed exists. CC-BY-4.0, 1h cache, CORS-enabled.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Research article JSON index)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/research.json"
javascript
const res = await fetch("https://profixdirectory.com/api/research.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/research.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/reviews/aggregates.json

First-party review aggregates — every reviewed pro

Corpus-wide aggregates of APPROVED, ProFix-moderated homeowner reviews: one row per pro with count, mean rating, star histogram, and newest-review timestamp, plus a corpus summary (rated_pros, total_reviews, volume-weighted corpus_average). Aggregate-only, zero PII. DISTINCT from the read-only Google Places rating the directory surfaces — those are never re-emitted as ProFix aggregates. Per-pro recent review snippets live on /api/pro/{slug}.json. 1h cache, CORS-open, CC-BY-4.0.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(First-party review aggregates JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/reviews/aggregates.json"
javascript
const res = await fetch("https://profixdirectory.com/api/reviews/aggregates.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/reviews/aggregates.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/site-graph.json

Site graph — major sections with their pages + data endpoints

High-level link graph of ProFix Directory grouped into 10 sections (trust, permits, research, buyer's guides, trades, metros, agent-native, transparency, Spanish, tools). Each section bundles canonical HTML hub URLs with their machine-readable data endpoints, plus a top-level `agent_discovery` block pointing at llms.txt, llms-full.txt, OpenAPI, MCP, and the sitemap index. Designed for AI engines and partners that want to understand the site structure without crawling 20K+ pages. CC-BY-4.0, 1h cache, CORS-enabled.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Site graph JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/site-graph.json"
javascript
const res = await fetch("https://profixdirectory.com/api/site-graph.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/site-graph.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/sources.json

Data source registry — provenance index for every external source ProFix uses

Programmatic mirror of /sources. Returns the canonical registry of every external data source ProFix Directory uses to assemble its Ohio home-services contractor directory — licensing (Ohio eLicense, OCILB, ODH, SFM), permits (Lucas, Cuyahoga, Franklin, Hamilton county portals), reviews (Google Business Profiles, BBB), profiles (Google Places API), cost guides (primary research, U.S. BLS), local content (NOAA storm events, county building departments, ARPA lead-line programs), and open data (U.S. Census Geocoder, ACS). Each entry includes id, category, URL, license, optional license URL, refresh cadence, fields used, an explicit 'what we don't pull' list, and a stable /sources anchor. CC-BY-4.0 editorial assembly; underlying sources retain their own licenses. 1h cache, CORS-enabled.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Sources registry JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/sources.json"
javascript
const res = await fetch("https://profixdirectory.com/api/sources.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/sources.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/storm-events.json

Ohio storm events historical feed

Programmatic feed of ProFix's illustrative Ohio storm-event registry for 2020-2026. Returns date, type, severity, affected metros/counties, description, NOAA/NWS source URL, and canonical /storm-history/{slug} URL for each event. Editorial assembly is CC-BY-4.0; NOAA/NWS records retain public-domain source status. 1h cache, CORS-enabled.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Storm events JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/storm-events.json"
javascript
const res = await fetch("https://profixdirectory.com/api/storm-events.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/storm-events.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/trades.json

Trade taxonomy — 37 canonical home-services trades

Public registry of the 37 canonical trades ProFix Directory tracks. Per trade: slug, English + Spanish label, federal NAICS codes that crosswalk to it, CSLB classes (California), the 2-letter state codes where at least one gold-tier pro offers the trade, and the national pro count. Strong ETag. CC-BY-4.0. 1h browser / 24h CDN / 7d SWR.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Trades registry JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/trades.json"
javascript
const res = await fetch("https://profixdirectory.com/api/trades.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/trades.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/trust-scores.json

ProFix Trust Score aggregate — every pro's composite 0-100 score + tier

Bulk feed of every pro's ProFix Trust Score (0-100) and tier (elite/solid/starter/minimal). Composite of verification tier, license status, rating × review count, photos/hours/specialties/tenure, permit-verified flag. Methodology at /methodology. Zero PII. CC-BY-4.0. 1h cache.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Trust scores JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/trust-scores.json"
javascript
const res = await fetch("https://profixdirectory.com/api/trust-scores.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/trust-scores.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/verification-feed.json

Verification deltas feed

Live JSON feed of license-status changes, new permits, and audit deltas. Refreshed hourly.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Verification feed JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/verification-feed.json"
javascript
const res = await fetch("https://profixdirectory.com/api/verification-feed.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/verification-feed.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/voice-answers.json

Voice assistant Q&A answers

Short spoken contractor answers for Alexa, Google Assistant, Siri, and other voice systems. Each answer is capped for spoken delivery and includes speakable JSON-LD.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Voice answer feed)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/voice-answers.json"
javascript
const res = await fetch("https://profixdirectory.com/api/voice-answers.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/voice-answers.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/widgets.json

Widget catalog — every embeddable trade × city slug

Programmatic catalog of every ProFix partner widget slug. Returns `TRADES × ALL_CITIES` entries with `{trade}-{city}` slug, JavaScript embed URL, and matching `/api/embed/{slug}.json` data URL. CC-BY-4.0. 1h cache. CORS-enabled for partner discovery.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Widget catalog JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/widgets.json"
javascript
const res = await fetch("https://profixdirectory.com/api/widgets.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/widgets.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/zip/{zipcode}.json

ZIP-level Ohio coverage lookup

Returns city, county, nearest metro, utility contacts, permit office, and top five pros by trade for a covered Ohio ZIP code. Designed for AI agents that start from a homeowner ZIP.

Parámetros

  • zipcode (path)requeridotipo: string
    Five-digit Ohio ZIP code, for example 43615.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(ZIP coverage match)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/zip/43615.json"
javascript
const res = await fetch("https://profixdirectory.com/api/zip/43615.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/zip/43615.json", timeout=10)
res.raise_for_status()
print(res.json())

Taxonomía geográfica

Estados, ciudades, cobertura por código postal y registro de taxonomía urbana.

3 endpoints
get/api/cities.json

City registry — every incorporated place + CDP nationally

Paginated public registry of every U.S. city ProFix Directory has loaded into its national taxonomy (15,614 records sourced from Census ACS Places). Use `?cursor=<slug>&limit=<n>` to walk large pulls (default limit 500, max 5000). Returns next_cursor null when exhausted. Each city carries: state, English + (optional) Spanish name, slug, 7-digit FIPS code, population, primary county, and the gold-tier pro count for the city. Strong ETag. CC-BY-4.0. 1h browser / 24h CDN / 7d SWR.

Parámetros

  • cursor (query)tipo: string
    Opaque cursor (slug of the last city emitted on the previous page).
  • limit (query)tipo: integer
    Page size — defaults to 500, capped at 5000.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(Cities registry JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/cities.json"
javascript
const res = await fetch("https://profixdirectory.com/api/cities.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/cities.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/city-taxonomy.json

City taxonomy

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(City taxonomy JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/city-taxonomy.json"
javascript
const res = await fetch("https://profixdirectory.com/api/city-taxonomy.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/city-taxonomy.json", timeout=10)
res.raise_for_status()
print(res.json())
get/api/states.json

State registry — 50 states + DC + 5 territories

Public registry of every U.S. state ProFix Directory tracks. Per entry: 2-letter code, English + Spanish name, launched flag, gold-tier pro count, total pro count, distinct cities covered, top 5 metros (by population), and the primary licensing-board name + URL. Strong ETag (`W/"states-…"`) supports If-None-Match short-circuiting. CC-BY-4.0. 1h browser / 24h CDN / 7d SWR.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(States registry JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/states.json"
javascript
const res = await fetch("https://profixdirectory.com/api/states.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/states.json", timeout=10)
res.raise_for_status()
print(res.json())

Verificación

Comprobaciones cruzadas contra fuentes oficiales e índices de evidencia.

1 endpoint
get/api/license-evidence.json

License evidence index

Per-pro license evidence: license number, source URL, last verified.

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(License evidence JSON)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/license-evidence.json"
javascript
const res = await fetch("https://profixdirectory.com/api/license-evidence.json");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/license-evidence.json", timeout=10)
res.raise_for_status()
print(res.json())

Activos generados

Insignias SVG por profesional e imágenes de tarjeta compartibles.

1 endpoint
get/api/pro-card/{slug}

Generated pro card SVG

Parámetros

  • slug (path)requeridotipo: string

Respuesta de ejemplo

json
{
  "ok": true,
  "license": "CC-BY-4.0",
  "generated_at": "2026-06-08T00:00:00Z",
  "example": "(SVG image)"
}

Ejemplos de código

curl
curl -sL "https://profixdirectory.com/api/pro-card/miller-plumbing-toledo"
javascript
const res = await fetch("https://profixdirectory.com/api/pro-card/miller-plumbing-toledo");
if (!res.ok) throw new Error(`ProFix ${res.status}`);
const data = await res.json();
console.log(data);
python
import requests

res = requests.get("https://profixdirectory.com/api/pro-card/miller-plumbing-toledo", timeout=10)
res.raise_for_status()
print(res.json())

Esquemas de componentes

18 esquemas reutilizables definidos en components.schemas. Inspecciona cualquiera en JSON crudo en /api/openapi.json.

  • Pro
  • ProList
  • City
  • State
  • CostGuide
  • LicenseGuide
  • BuyerGuide
  • FAQ
  • ResearchArticle
  • TradeGuide
  • EmergencyPlaybook
  • SearchResponse
  • CorrectionSubmission
  • ErrorResponse
  • ProDossier
  • ProPhotos
  • MatchResponse
  • ProPermits
Emergencia