Skip to main content

Vertical factory

  • Sells as: the vertical-factory product (a product-scoped API key). This capability has no separate product-face contract — its public product route reuses the capability contract below; see the Edge route table's Product face row.

Vertical-factory capability — the generic engine that registers, spins up and lifecycles a content vertical from a VerticalDefinition, and runs domain-pack DETECTION + field EXTRACTION over content. Extracted from vagary-platform's vertical registry + domain-pack machinery so any content product can provision verticals over one shared engine instead of re-implementing the registry/detect/extract plumbing. The DURABLE registry (VerticalDefinitions) is core-owned (Postgres, I4). Domain-PACKS (the per-vertical extraction IP) stay product-local and are supplied as INPUT to detect/extract — never persisted here. The org-tier company-creator (Paperclip) is a different tier and is untouched (I2).

  • Group: Content & media
  • Contract: contracts/vertical-factory/v1/openapi.yaml
  • Console: Manage the vertical-factory product in the console →
  • Runbook: operational checklist for vertical-factoryinternal (Vagary Labs ops; not part of this public site): docs/runbooks/capability-operations.md#vertical-factory
  • Public base: https://api.vagarylabs.com (the consolidated API gateway — one host, per-brand sibling api.<zone>)
  • Auth: a product API key (vgk_…) issued from the console — Authorization: Bearer vgk_…
  • Product face (customer-keyed):
    • https://api.vagarylabs.com/product/v1/verticals

Edge route table

The routes this capability actually serves on the public edge — live-synced from GET https://api.vagarylabs.com/product/v1/_meta/catalog (snapshot v1). The metric is the request-granularity billing counter; the scope is the key permission required.

Product face (customer-keyed)

MethodPathMetricScope
POST/product/v1/verticalsvertical_operationswrite

Endpoints

MethodPathSummary
POST/v1/vertical-factory/verticalsRegister (upsert) a VerticalDefinition — spin up / lifecycle a content vertical
GET/v1/vertical-factory/verticalsList registered VerticalDefinitions (org-scoped)
GET/v1/vertical-factory/verticals/&#123;vertical_id&#125;Get a VerticalDefinition (or 404)
PATCH/v1/vertical-factory/verticals/&#123;vertical_id&#125;Partially update a VerticalDefinition (builtins reject id/is_builtin changes)
DELETE/v1/vertical-factory/verticals/&#123;vertical_id&#125;Delete a VerticalDefinition (builtins cannot be deleted → 409)
GET/v1/vertical-factory/verticals/&#123;vertical_id&#125;/collectionResolve the storage collection name for a vertical (falls back to news_articles)
POST/v1/vertical-factory/packsRegister a DomainPack into the EPHEMERAL org-scoped in-memory cache (NON-DURABLE, per-replica, cleared on restart). Convenience so /detect + /extract can be called by vertical_id without re-shipping the pack. The pack is NEVER written to Postgres — its durable home stays in the product.
GET/v1/vertical-factory/packsList vertical_ids currently in the ephemeral in-memory pack cache (org-scoped)
POST/v1/vertical-factory/detectDetect which verticals are relevant for content. Packs are supplied INLINE in packs (canonical, stateless) or, if packs is omitted, the org's ephemeral in-memory cache is used. Zero persistence.
POST/v1/vertical-factory/extractExtract vertical-specific fields from content using a DomainPack's regex FieldSpecs + generic format validators. The pack is supplied INLINE in pack, or resolved by vertical_id from the ephemeral in-memory cache. Zero persistence.
GET/healthLiveness + role + store state
GET/metricsPrometheus exposition (BFT fail-open)

Schemas

VerticalDefinition

The canonical vertical-lifecycle definition (converged from the platform's rich, Mongo-persisted VerticalDefinition). Identity + storage + discovery + enrichment + scoring + addons + UI. This is the ONLY object the core store persists. domain_pack is an OPTIONAL back-reference to the pack's identity — the engine treats pack CONTENT as opaque and never persists it (see DomainPack).

FieldTypeDescription
vertical_idstring
display_namestring
descriptionstring
collection_namestringstorage collection; defaults to <vertical_id>s
content_schemaobjectrequired/optional field-name lists (storage schema hints — NOT extraction regex)
discovery_strategiesarray
enrichment_pipelinearrayordered enrichment step names; extraction is one such step, run over the vertical's DomainPack (data, not owned here)
scoring_weightsobject
addon_idsarray
ui_configobject
is_builtinboolean
enabledboolean
created_atnumber
updated_atnumber

ScoringWeights

FieldTypeDescription
freshnessnumber
relevancenumber
qualitynumber
engagementnumber
source_trustnumber

UIConfig

FieldTypeDescription
card_layoutstring
detail_layoutstring
primary_colorstring
iconstring
show_sentimentboolean
show_trendingboolean
addon_slotsarray

DomainPack

The per-vertical extraction IP (the platform's VerticalConfig, subsumed here as a sibling of the definition and back-referenced by vertical_id). Supplied as INPUT to /detect + /extract, or cached ephemerally in RAM. NEVER persisted by core — its durable home stays in the product (I5).

FieldTypeDescription
vertical_idstring
display_namestring
descriptionstring
extraction_fieldsarray
category_keywordsarray
relevance_termsarray
min_relevance_termsinteger

VerticalFieldSpec

FieldTypeDescription
namestring
patternstringregex used for extraction
requiredboolean
validatorstringname of a generic format validator (numeric_amount

ExtractionResult

FieldTypeDescription
vertical_idstring
extracted_fieldsobject
relevance_scorenumber
validation_errorsarray
matched_keywordsarray
is_relevantboolean

VerticalRef

FieldTypeDescription
vertical_idstring
display_namestring

Error

FieldTypeDescription
errorstring

Generated by scripts/gen-capability-docs.py from contracts/vertical-factory/v1/openapi.yaml — the contract IS the source of truth; edit the contract, not this page. The Edge route table section is synced from the live edge catalog snapshot (v1) — re-sync with python3 scripts/sync-edge-catalog.py.