Vertical factory
This capability is granted by an API key scoped to the `` product (product face). See the product reference below.
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 - Public base:
https://api.vagarylabs.com(the consolidated API gateway — one host, per-brand siblingapi.<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
Endpoints
| Method | Path | Summary |
|---|---|---|
POST | /v1/vertical-factory/verticals | Register (upsert) a VerticalDefinition — spin up / lifecycle a content vertical |
GET | /v1/vertical-factory/verticals | List registered VerticalDefinitions (org-scoped) |
GET | /v1/vertical-factory/verticals/{vertical_id} | Get a VerticalDefinition (or 404) |
PATCH | /v1/vertical-factory/verticals/{vertical_id} | Partially update a VerticalDefinition (builtins reject id/is_builtin changes) |
DELETE | /v1/vertical-factory/verticals/{vertical_id} | Delete a VerticalDefinition (builtins cannot be deleted → 409) |
GET | /v1/vertical-factory/verticals/{vertical_id}/collection | Resolve the storage collection name for a vertical (falls back to news_articles) |
POST | /v1/vertical-factory/packs | Register 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/packs | List vertical_ids currently in the ephemeral in-memory pack cache (org-scoped) |
POST | /v1/vertical-factory/detect | Detect 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/extract | Extract 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 | /health | Liveness + role + store state |
GET | /metrics | Prometheus 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).
| Field | Type | Description |
|---|---|---|
vertical_id | string | |
display_name | string | |
description | string | |
collection_name | string | storage collection; defaults to <vertical_id>s |
content_schema | object | required/optional field-name lists (storage schema hints — NOT extraction regex) |
discovery_strategies | array | |
enrichment_pipeline | array | ordered enrichment step names; extraction is one such step, run over the vertical's DomainPack (data, not owned here) |
scoring_weights | object | |
addon_ids | array | |
ui_config | object | |
is_builtin | boolean | |
enabled | boolean | |
created_at | number | |
updated_at | number |
ScoringWeights
| Field | Type | Description |
|---|---|---|
freshness | number | |
relevance | number | |
quality | number | |
engagement | number | |
source_trust | number |
UIConfig
| Field | Type | Description |
|---|---|---|
card_layout | string | |
detail_layout | string | |
primary_color | string | |
icon | string | |
show_sentiment | boolean | |
show_trending | boolean | |
addon_slots | array |
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).
| Field | Type | Description |
|---|---|---|
vertical_id | string | |
display_name | string | |
description | string | |
extraction_fields | array | |
category_keywords | array | |
relevance_terms | array | |
min_relevance_terms | integer |
VerticalFieldSpec
| Field | Type | Description |
|---|---|---|
name | string | |
pattern | string | regex used for extraction |
required | boolean | |
validator | string | name of a generic format validator (numeric_amount |
ExtractionResult
| Field | Type | Description |
|---|---|---|
vertical_id | string | |
extracted_fields | object | |
relevance_score | number | |
validation_errors | array | |
matched_keywords | array | |
is_relevant | boolean |
VerticalRef
| Field | Type | Description |
|---|---|---|
vertical_id | string | |
display_name | string |
Error
| Field | Type | Description |
|---|---|---|
error | string |
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.