# description
Lyrenth AIDocument v2 response shape: the canonical envelope served by POST /v1/aidocument. One stable shape per URL; cached once, served to every agent.

# properties.schema.properties.version.description
Schema version this response conforms to. Bumped only on incompatible layout changes.

# properties.schema.properties.ref.description
Content-addressed identifier of the document fingerprint (url + canonical_url + title + description + language + content_type + markdown + headings + links + images + structured_data). Stable across cache states and re-crawls of an unchanged page. Format: aidoc:sha256:<32 hex chars>.

# properties.source.description
What was fetched, how it was rendered, and which freshness policy the caller requested. Even on a cache hit, these fields describe the underlying snapshot.

# properties.source.properties.canonical_url.description
Page-declared canonical URL when present (e.g. <link rel=canonical>).

# properties.source.properties.fetched_at.description
RFC 3339 UTC timestamp of the underlying snapshot. Omitted on documents predating the field.

# properties.source.properties.render_mode.description
How the page was rendered. "static" for a direct HTTP fetch; "rendered" when JS execution was required.

# properties.source.properties.status_code.description
HTTP status from the origin at fetch time.

# properties.source.properties.freshness_policy.description
The policy the CALLER requested, not the outcome. Outcome lives in cache.status.

# properties.cache.description
What happened on the Lyrenth side for this specific call. Status is the coarse label; the two booleans are the precise truth.

# properties.cache.properties.status.description
hit = cached snapshot served. miss = cache_first policy missed, body fetched from origin. refreshed = force_refresh policy, body fetched from origin. stale_revalidated = origin returned 304 Not Modified.

# properties.identity.properties.language.description
BCP 47 language tag (e.g. en, en-US, fr).

# properties.identity.properties.content_type.description
Inferred page-content classification (e.g. article, product, listing, profile).

# properties.content.description
The cleaned page body. Markdown is the canonical agent-readable form.

# properties.structure.description
Extracted page structure. Every field is optional; a single-paragraph article may legitimately have no links and no images.

# properties.structure.properties.links.items.properties.internal.description
true when the link's host matches the page's host.

# properties.structure.properties.links.items.properties.rel.description
rel attribute as declared (e.g. nofollow, ugc, sponsored).

# properties.structure.properties.media.description
Embedded audio/video the page declares directly: native <video>/<audio> (with <source> mime and poster), media-file links, and og:video/og:audio tags. References only: Lyrenth records URLs and metadata, not the media files. Iframe embeds (YouTube, Vimeo) are not represented.

# properties.structure.properties.contacts.description
Contact points the page publishes: emails and phone numbers, including those in mailto:/tel: links and the page footer. Emails are restricted to the site's own registrable domain (role or named, e.g. press@ or founder@example.com); off-domain and free-provider personal addresses are excluded for privacy. Phones come from tel: links.

# properties.structure.properties.contacts.items.properties.label.description
Coarse role hint for emails, derived from the local-part. Empty for a named personal-business address.

# properties.structure.properties.structured_data.description
Merged schema.org / JSON-LD payload from <script type="application/ld+json"> blocks on the page. Keys depend on the page; we do not enumerate them here.

# properties.signals.description
Per-call quality projection derived from the AIDocument structure. Cheap, deterministic, no DB lookup. Audit-derived scores from page_audits may be unioned into this block in a later schema version.

# properties.signals.properties.has_json_ld.description
True if the page declared any application/ld+json structured data.

# properties.signals.properties.heading_hierarchy_ok.description
True if there is at least one heading, the first is h1 or h2, and no adjacent levels jump by more than 1.

# properties.economics.description
Token + USD savings of consuming the AIDocument markdown vs the raw HTML. Omitted on pre-MF3.5 cached documents that predate the economics block.