Skip to main content
Available on request β€” The Autumn Lakehouse is provisioned per customer. Contact us at hey@useautumn.com to get access.
Every object is delivered as a table named v2_3_<object>, grouped below by lane. The one exception is events: the event log is immutable and unversioned, delivered as events (not v2_3_events) β€” see Events.

Type legend

Types below are engine-neutral. How each engine surfaces them:
  • Timestamps are epoch-milliseconds (number (epoch ms)), not native datetimes β€” convert before use. See Querying β†’ Timestamps. The one exception is events.timestamp, which is a real timestamp.
  • JSON columns are stored as strings β€” parse them with JSONExtract* (ClickHouse).

Keys

  • ⭐ marks the stable, immutable key for a table β€” join and filter on this.
  • πŸ”— marks a stable foreign key (internal_customer_id, internal_feature_id, internal_product_id, internal_entity_id, internal_reward_id) β€” join to the matching internal_id.
  • External ids (customer_id, plan_id, feature_id, entity_id, id, …) are mutable β€” convenient for display, but don’t rely on them as stable keys. See Querying β†’ Use internal ids.
  • org_id is your tenant id (constant across your tables); env is sandbox or live (not production β€” filtering env = 'production' silently returns zero rows).

Catalog

Your pricing model: features, plans, plan items, rewards, and referral programs.

Subjects

Who your plans apply to: customers and entities (sub-customers).

States

Active customer–product relationships: recurring subscriptions and one-off purchases.

Balances

Feature balances, their per-entitlement breakdowns, and boolean feature flags.
These tables do not behave like a clean relational schema. They are denormalized snapshots of Autumn’s read-time balance computation, and they include every customer_entitlement row β€” across superseded product versions and past reset cycles β€” with no active-status or current-cycle filter. A naive SELECT ... FROM v2_3_balances therefore double- and triple-counts. Before you query balances, breakdowns, or overage, read Working with balances β€” it explains what each column means, why usage/granted/remaining don’t form a closed arithmetic triple, where overage comes from (it is not stored), and the active + current-cycle filter you must apply.
Balances, breakdowns, and flags carry both pooled (customer-level) rows β€” where entity_id is null β€” and per-entity rows. For customer-level totals, keep only the pooled rows with coalesce(entity_id, '') = '' to avoid double counting. (Use coalesce, not entity_id IS NULL β€” IS NULL throws on these Iceberg columns; see Querying β†’ Pooled vs per-entity.)
granted / remaining / usage are not a closed arithmetic triple β€” remaining β‰  granted βˆ’ usage. Each is aggregated over every entitlement row for this customer Γ— feature Γ— scope, including superseded product versions and past cycles, so a single row routinely sums many lifetimes of usage. remaining is floored per-entitlement, manual β€œSet Balance” decouples balance from grant, and rollover/unused are layered in. There is no overage column β€” it is derived. Always read Working with balances and apply the active + current-cycle filter before trusting these numbers.
v2_3_breakdowns has no status / is_active / is_current column and mixes rows from superseded/cancelled product versions, past reset cycles, and pre-seeded future cycles. To get the rows the API would use, join internal_product_id to active subscription status and pick the current cycle (earliest upcoming reset_resets_at); one_off rows are always live. See Working with balances β†’ The active + current-cycle filter.

Invoices

Invoices and their line items.

Events

The append-only usage event log. This is the highest-volume table and is append-only (no updates).
The events table is events, not v2_3_events. Events are immutable and unversioned β€” they are not subject to the v2_3 schema versioning that every other object uses. Address it as `<catalog>`.`<namespace>.events`. Querying v2_3_events returns Unknown table expression identifier because that table does not exist.
Unlike every other table, events.timestamp is a native timestamp β€” no epoch-ms conversion needed. created_at is still epoch-ms.