Skip to content

IngestItem — the universal content model

IngestItem is the canonical unit of content in bAInquet. Every connector — WordPress, Shopify, Ghost, Django, a hand-rolled REST connector — produces IngestItem objects and pushes them via the ingestion API. bAInquet normalises, deduplicates, and assembles these items into the knowledge graph.

The model is designed to represent any content type from any website: a blog post, a product page, a service listing, a portfolio entry, an event, a restaurant menu item, a help-centre article — anything. It is simultaneously compact (only type, id, url, checksum are required) and extensible (the json payload carries an open bag of structured sub-schemas).

Contract version: 0.4.0 — the ingestion server validates every item against this schema.

Top-level fields

FieldRequiredTypeNotes
typeSourceTypeContent category
idstringStable connector-scoped id, e.g. post:412
urlstring (URI)Canonical public URL; host must match X-Site-Domain
checksumstringsha256:<hex> computed by the SDK; dedup key
canonical_urlstring (URI)Alternate canonical if different from url
titlestring (≤1024)Human-readable heading
excerptstring (≤4096)Short summary; connectors populate this from the CMS excerpt / short description
htmlstringFull body HTML
textstringPlain-text version (derived from html when absent)
jsonJsonPayloadStructured sub-schemas: SEO, images, price, author, etc.
languagestring (BCP-47)e.g. en, fr-FR
updated_atstring (RFC3339)Last-modified timestamp in UTC
attributesRecord<string, unknown>Arbitrary per-connector metadata bag

At least one of html, text, or json must be present.

SourceType

The type field classifies the content:

ValueUse for
pageGeneric web pages, CMS pages
postBlog posts, articles, news items
productE-commerce products
categoryTaxonomy terms, collections used as categories
collectionCMS collections, product collections
faqFAQ entries
reviewCustomer / editorial reviews
eventTime-bounded events
locationPhysical locations
profileAuthor, team member, business profiles
docTechnical documentation, help articles
mediaStandalone media items (video, audio, image pages)
serviceService offerings (booking services, SaaS features)
customAny type that doesn't fit the above; use attributes.subtype to sub-classify

JsonPayload

json is an open object — connectors may add any keys. bAInquet recognises a set of canonical sub-schemas that all normalisation pipelines understand. When connectors populate these canonical keys, the knowledge graph extracts richer structured data with higher confidence.

json.images[] — ImageObject

json
{
  "images": [
    {
      "src": "https://example.com/img/hero.jpg",
      "alt": "A product photo",
      "caption": "Available in three colours",
      "width": 1200,
      "height": 800,
      "mime": "image/jpeg"
    }
  ]
}
FieldRequiredNotes
srcAbsolute image URL
altAlt text
captionCaption / title
widthPixel width
heightPixel height
mimeMIME type, e.g. image/jpeg

json.seo{} — SeoObject

json
{
  "seo": {
    "title": "Buy Widgets | Acme Shop",
    "description": "Best widgets on the internet.",
    "canonical_url": "https://acme.com/widgets",
    "focus_keyword": "widgets",
    "keywords": "widget, buy widget, cheap widget",
    "robots": "index, follow",
    "og_title": "Acme Widgets",
    "og_description": "Best widgets on the internet.",
    "og_image": "https://acme.com/img/og.jpg",
    "og_type": "product",
    "twitter_title": "Acme Widgets",
    "twitter_description": "Best widgets on the internet.",
    "twitter_image": "https://acme.com/img/twitter.jpg",
    "twitter_card": "summary_large_image",
    "schema_markup": "{\"@context\":\"https://schema.org\",...}",
    "provenance_method": "seo_meta"
  }
}

All fields are optional. provenance_method must always be "seo_meta" when present.

Populated by: WordPress (Yoast + RankMath), Shopify, Ghost, Drupal (metatag module), Magento, Joomla, Webflow, Wix, and all framework connectors.

json.author{} — AuthorObject

json
{
  "author": {
    "id": "wp:42",
    "name": "Jane Smith",
    "url": "https://example.com/author/jane",
    "avatar": "https://gravatar.com/avatar/abc",
    "provenance_method": "cms_field"
  }
}

json.authors[]

Array of AuthorObject for multi-author content (e.g. Ghost posts with multiple authors).

json.tags[]

Array of tag name strings:

json
{ "tags": ["javascript", "performance", "tutorial"] }

json.categories[]

Array of category name strings (or IDs when names unavailable):

json
{ "categories": ["Tech", "Tutorials"] }

json.excerpt

Plain-text excerpt string (mirrors the top-level excerpt field; useful for JSON-only consumers):

json
{ "excerpt": "A short summary of the article content..." }

json.price{} — TypedPrice

json
{
  "price": {
    "value": 49.99,
    "unit": "currency",
    "currency": "EUR"
  }
}

unit is always the literal "currency". Never use concatenated price strings.

Connector-namespaced extensions

Connectors add their own namespaced sub-objects alongside canonical keys:

json
{
  "json": {
    "images": [...],
    "seo": {...},
    "wp": { "post_type": "product", "post_status": "publish" },
    "acf": { "hero_cta_text": "Shop now" },
    "product": { "sku": "WGT-001", "price": { "value": 49.99, "unit": "currency", "currency": "USD" } }
  }
}

Canonical keys (images, seo, author, authors, tags, categories, excerpt, price) are always at the top level of json. Connector-specific data goes in a namespace key (wp, shopify, ghost, wix, acf, custom, etc.).

Provenance ladder

When multiple extractors produce the same fact, confidence is determined by the provenance method:

MethodConfidenceSource
cms_field0.98Directly from a CMS field (highest trust)
schema_org0.95JSON-LD / structured data in HTML
seo_meta0.85SEO plugin meta fields
text_extraction0.75Derived from body text (lowest trust)

Full example

A WordPress product post with ACF, Yoast SEO, and WooCommerce data:

json
{
  "type": "product",
  "id": "product:1042",
  "url": "https://acme.com/products/blue-widget",
  "canonical_url": "https://acme.com/products/blue-widget",
  "title": "Blue Widget Pro",
  "excerpt": "The professional-grade widget for serious makers.",
  "html": "<p>The professional-grade widget...</p>",
  "text": "The professional-grade widget for serious makers.",
  "language": "en",
  "updated_at": "2026-06-20T14:30:00Z",
  "checksum": "sha256:a3b2c1d4...",
  "json": {
    "images": [
      { "src": "https://acme.com/img/blue-widget.jpg", "alt": "Blue Widget Pro", "width": 800, "height": 800 }
    ],
    "seo": {
      "title": "Buy Blue Widget Pro | Acme Shop",
      "description": "The best blue widget for professionals.",
      "focus_keyword": "blue widget pro",
      "og_image": "https://acme.com/img/og-blue-widget.jpg",
      "provenance_method": "seo_meta"
    },
    "author": { "id": "wp:3", "name": "Admin", "provenance_method": "cms_field" },
    "tags": ["widgets", "professional"],
    "categories": ["Hardware", "Pro Tools"],
    "price": { "value": 49.99, "unit": "currency", "currency": "USD" },
    "product": {
      "sku": "BW-PRO-001",
      "in_stock": true,
      "stock_quantity": 42,
      "variations": [
        { "id": "variant:2001", "sku": "BW-PRO-S", "attributes": { "size": "Small" }, "price": { "value": 39.99, "unit": "currency", "currency": "USD" } }
      ]
    },
    "acf": {
      "hero_cta_text": "Order now",
      "warranty_years": "2"
    },
    "wp": {
      "post_id": 1042,
      "post_type": "product",
      "post_status": "publish"
    }
  }
}

Owner-controlled structured data for AI.