For AI agents: a documentation index is available at the root level at /llms.txt and /llms-full.txt. Append /llms.txt to any URL for a page-level index, or .md for the markdown version of any page.
SupportDashboard
Getting StartedAPI ReferenceRoadmapBlog
Getting StartedAPI ReferenceRoadmapBlog
  • Getting Started
    • Overview
    • What is Schematic?
    • Concepts
  • Using Schematic
    • Who Uses Schematic
  • Quickstart
    • Quickstart
    • Account Setup
    • Entitling a Feature
    • Tracking Usage
    • Components
    • Identifying Users
    • Setup the SDK
  • Using Feature Flags
    • Overview
    • Flags
    • Features
    • Tracking Feature Usage
    • Company Overrides
    • Feature Types
  • Building Your Catalog
    • Overview
    • Plans
    • Managing Company Plans
    • Configuring the Catalog
    • Add Ons
    • Trials
  • AI Tooling
    • For Developers
  • Setting Up Billing
    • Overview
    • Usage Based Billing Models
    • Seat Based Billing Models
    • Credit burndown
  • Using UI Components
    • Overview
  • Developer Resources
    • Concepts
    • Key Management
    • Environments
    • Entity Relationship Diagram
  • Production Readiness
    • Availability
    • Observability & Support
    • Security
  • Integrations
    • Segment Integration
    • Clerk Integration
    • WorkOS Integration
    • Salesforce Integration
    • Hubspot Integration
  • Playbooks
    • Overview
    • Creating a metered feature
    • Backfills and usage corrections
    • Rolling out beta functionality with Flags
    • Handling customer exceptions and feature trials
    • Automatically provision customers using Stripe
    • Build a slack webhook
LogoLogo
SupportDashboard
On this page
  • When to use which mode
  • trusted_client_clock
  • backfill
  • Behavior matrix
  • SDK example
  • Retention
  • Validation errors
  • Related
Playbooks

Backfills and usage corrections

Was this page helpful?
Previous

Rolling out beta functionality with Flags

Next
Built with

By default, Schematic stamps every event with the time it was received. Two optional flags on the track-event payload let you override that and submit an event with the time it actually happened:

  • trusted_client_clock — use the client-provided sent_at as the event’s effective timestamp. Billing side effects still fire (against the logical timestamp). Best for correcting recent usage that arrived late or with a bad timestamp.
  • backfill — analytics-only mode for importing historical usage. Events are stored at their logical time but skip all billing side effects.

Both flags require a secret API key (sch_ prefix) and a sent_at value on the event. See Authentication for key types.

When to use which mode

You want to…Use
Record usage that just happened (normal flow)Neither flag — server time is used
Correct an event that happened yesterday or earlier today, including billing impacttrusted_client_clock
Import months of historical usage for analytics, without re-billing customersbackfill

trusted_client_clock

When true, Schematic uses the sent_at you provide as the event’s effective timestamp (captured_at) instead of server receipt time.

Requirements for setting sent_at:

  • No more than 5 minutes in the future
  • No more than 34 days in the past

The 34-day past bound sits one day inside Stripe’s meter-event 35-day cap, to absorb wall-clock skew between Schematic and Stripe. For older events, use backfill.

All normal processing still happens — billing impact, webhooks, and activity updates fire as usual — just anchored to the logical timestamp instead of the receipt time. Feature usage counters only count the event toward periods that the logical timestamp falls within, so an event timestamped yesterday won’t show up in today’s daily counter.

1{
2 "api_key": "sch_secret_...",
3 "type": "track",
4 "sent_at": "2026-05-17T14:30:00Z",
5 "trusted_client_clock": true,
6 "body": {
7 "event": "api-call",
8 "company": { "your-company-key": "value" },
9 "quantity": 50
10 }
11}

backfill

backfill: true implies trusted_client_clock — sent_at is the effective timestamp — but all billing side effects are skipped. Use this when you want historical usage to appear in analytics without re-running billing.

Requirements for setting sent_at when backfill: true:

  • No more than 5 minutes in the future
  • No more than 365 days in the past

Skipped:

  • Billing impact (credit consumption, Stripe meter reporting, auto-topup)
  • Webhooks
  • last_seen_at bumps on companies and users (historical events shouldn’t shift present-time activity)

Still happens:

  • The event is stored at its logical timestamp and shows up in analytics there.
  • Feature usage counters reflect the event for periods the logical timestamp falls within.
  • Companies and users referenced by the event are still created or linked from the event keys — their last_seen_at just isn’t touched.
1{
2 "api_key": "sch_secret_...",
3 "type": "track",
4 "sent_at": "2025-10-15T09:00:00Z",
5 "backfill": true,
6 "body": {
7 "event": "api-call",
8 "company": { "your-company-key": "value" },
9 "quantity": 1000
10 }
11}

Behavior matrix

BehaviorNormaltrusted_client_clockbackfill
Effective captured_atserver timesent_atsent_at
Billing impactYes (current time)Yes (logical time)No
WebhooksYesYesNo
Feature usage countersYes (all periods)Period-filteredPeriod-filtered
Company/user create or linkYesYesYes
Company/user last_seen_at bumpYesYesNo

SDK example

1import { SchematicClient } from "@schematichq/schematic-typescript-node";
2
3const client = new SchematicClient({ apiKey: process.env.SCHEMATIC_SECRET_KEY });
4
5// Usage correction: an api-call from yesterday that we missed
6await client.track({
7 event: "api-call",
8 company: { "your-company-key": "value" },
9 quantity: 50,
10 sentAt: new Date("2026-05-17T14:30:00Z"),
11 trustedClientClock: true,
12});
13
14// Historical backfill: import a month-old event for analytics only
15await client.track({
16 event: "api-call",
17 company: { "your-company-key": "value" },
18 quantity: 1000,
19 sentAt: new Date("2025-10-15T09:00:00Z"),
20 backfill: true,
21});

Retention

Events are retained for 365 days, measured from the event’s effective captured_at. A backfill submitted near the 365-day past bound therefore lands with very little remaining retention — by design. Aggregated feature usage is preserved separately on the same logical-period anchor, so usage charts and entitlement counters stay intact even after the underlying event expires.

Validation errors

ConditionError
trusted_client_clock or backfill with a publishable keytrusted_client_clock and backfill require a secret API key
trusted_client_clock or backfill without sent_atsent_at is required when trusted_client_clock or backfill is true
sent_at more than 5 minutes in the futuresent_at cannot be more than 5 minutes in the future
trusted_client_clock with sent_at more than 34 days in the pastsent_at cannot be more than 34 days in the past for trusted_client_clock; for older events use backfill (analytics-only, no billing side effects)
backfill with sent_at more than 365 days in the pastsent_at cannot be more than 365 days in the past

Related

  • Creating a metered feature
  • Negative quantities (usage adjustments)
  • The Event object