> ## Documentation Index
> Fetch the complete documentation index at: https://docs.useautumn.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Track Usage

> Records usage for a customer feature and returns updated balances.

Use this after an action happens to decrement usage, or send a negative value to credit balance back.

export const DynamicResponseExample = ({json, statusCode = "200"}) => {
  const toCamelCase = str => {
    return str.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
  };
  const convertKeysToCamelCase = obj => {
    if (Array.isArray(obj)) {
      return obj.map(item => convertKeysToCamelCase(item));
    }
    if (obj !== null && typeof obj === "object") {
      return Object.keys(obj).reduce((acc, key) => {
        const camelKey = toCamelCase(key);
        acc[camelKey] = convertKeysToCamelCase(obj[key]);
        return acc;
      }, {});
    }
    return obj;
  };
  const [isTypeScript, setIsTypeScript] = useState(() => {
    if (typeof window !== "undefined") {
      try {
        const lang = localStorage.getItem("code");
        return JSON.parse(lang) === "typescript";
      } catch {
        return true;
      }
    }
    return true;
  });
  useEffect(() => {
    const onMintlifyStorage = event => {
      if (event.detail?.key === "code") {
        try {
          const value = JSON.parse(event.detail.value);
          setIsTypeScript(value === "typescript");
        } catch {}
      }
    };
    const pollInterval = setInterval(() => {
      try {
        const lang = localStorage.getItem("code");
        const value = JSON.parse(lang);
        setIsTypeScript(value === "typescript");
      } catch {}
    }, 300);
    document.addEventListener("mintlify-localstorage", onMintlifyStorage);
    return () => {
      document.removeEventListener("mintlify-localstorage", onMintlifyStorage);
      clearInterval(pollInterval);
    };
  }, []);
  const camelCaseJson = useMemo(() => convertKeysToCamelCase(json), [json]);
  const snakeCaseString = JSON.stringify(json, null, 2);
  const camelCaseString = JSON.stringify(camelCaseJson, null, 2);
  return <ResponseExample>
			{isTypeScript ? <CodeBlock language="json" filename={statusCode}>
					{camelCaseString}
				</CodeBlock> : <CodeBlock language="json" filename={statusCode}>
					{snakeCaseString}
				</CodeBlock>}
		</ResponseExample>;
};

export const DynamicResponseField = ({children, name, ...props}) => {
  const convertToCamelCase = str => {
    if (typeof str !== "string") return str;
    return str.replace(/[_-](\w)/g, (_, c) => c.toUpperCase());
  };
  const [lang, setLang] = useState(() => {
    if (typeof window !== "undefined") {
      const stored = localStorage.getItem("code");
      return stored || '"typescript"';
    }
    return '"typescript"';
  });
  useEffect(() => {
    const onMintlifyStorage = event => {
      const key = event.detail?.key;
      if (key === "code") {
        setLang(event.detail.value);
      }
    };
    const pollInterval = setInterval(() => {
      const current = localStorage.getItem("code");
      if (current && current !== lang) {
        setLang(current);
      }
    }, 500);
    document.addEventListener("mintlify-localstorage", onMintlifyStorage);
    return () => {
      document.removeEventListener("mintlify-localstorage", onMintlifyStorage);
      clearInterval(pollInterval);
    };
  }, [lang]);
  const resolvedName = useMemo(() => {
    try {
      const value = JSON.parse(lang);
      const useCamelCase = value === "typescript";
      return useCamelCase ? convertToCamelCase(name) : name;
    } catch {
      return name;
    }
  }, [name, lang]);
  return <ResponseField name={resolvedName} {...props}>
			{children}
		</ResponseField>;
};

export const DynamicParamField = ({children, body, path, ...props}) => {
  const convertToCamelCase = str => {
    if (typeof str !== "string") return str;
    return str.replace(/[_-](\w)/g, (_, c) => c.toUpperCase());
  };
  const [lang, setLang] = useState(() => {
    if (typeof window !== "undefined") {
      const stored = localStorage.getItem("code");
      return stored || '"typescript"';
    }
    return '"typescript"';
  });
  useEffect(() => {
    const onMintlifyStorage = event => {
      const key = event.detail?.key;
      if (key === "code") {
        setLang(event.detail.value);
      }
    };
    const pollInterval = setInterval(() => {
      const current = localStorage.getItem("code");
      if (current && current !== lang) {
        setLang(current);
      }
    }, 500);
    document.addEventListener("mintlify-localstorage", onMintlifyStorage);
    return () => {
      document.removeEventListener("mintlify-localstorage", onMintlifyStorage);
      clearInterval(pollInterval);
    };
  }, [lang]);
  const resolvedBody = useMemo(() => {
    try {
      const value = JSON.parse(lang);
      const useCamelCase = value === "typescript";
      return useCamelCase ? convertToCamelCase(body) : body;
    } catch {
      return body;
    }
  }, [body, lang]);
  const resolvedPath = useMemo(() => {
    try {
      const value = JSON.parse(lang);
      const useCamelCase = value === "typescript";
      return useCamelCase ? convertToCamelCase(path) : path;
    } catch {
      return path;
    }
  }, [path, lang]);
  return <ParamField body={resolvedBody} path={resolvedPath} {...props}>
			{children}
		</ParamField>;
};

<Note>
  Track records usage events to decrement a customer's balance. Use this to meter feature consumption like API calls, messages sent, or credits used.
</Note>

### Common Use Cases

<CodeGroup>
  ```typescript Track single usage theme={null}
  await autumn.track({
    customerId: "cus_123",
    featureId: "ai_messages",
    value: 1
  });
  ```

  ```typescript Track with idempotency theme={null}
  await autumn.track({
    customerId: "cus_123",
    featureId: "api_calls",
    value: 1,
    idempotencyKey: "request_abc123" // Prevents duplicate tracking on retry
  });
  ```

  ```typescript Credit balance (negative value) theme={null}
  await autumn.track({
    customerId: "cus_123",
    featureId: "seats",
    value: -1 // Increases balance when removing a seat
  });
  ```

  ```typescript Async (fire-and-forget) theme={null}
  await autumn.track({
    customerId: "cus_123",
    featureId: "ai_messages",
    value: 1,
    async: true // Returns 202 immediately; usage processed in the background
  });
  ```
</CodeGroup>

### Body Parameters

<DynamicParamField body="customer_id" type="string" required>
  The ID of the customer.
</DynamicParamField>

<DynamicParamField body="feature_id" type="string">
  The ID of the feature to track usage for. Required if event\_name is not provided.
</DynamicParamField>

<DynamicParamField body="entity_id" type="string">
  The ID of the entity for entity-scoped balances (e.g., per-seat limits).
</DynamicParamField>

<DynamicParamField body="event_name" type="string">
  Event name to track usage for. Use instead of feature\_id when multiple features should be tracked from a single event.
</DynamicParamField>

<DynamicParamField body="value" type="number">
  The amount of usage to record. Defaults to 1. Use negative values to credit balance (e.g., when removing a seat).
</DynamicParamField>

<DynamicParamField body="properties" type="object">
  Additional properties to attach to this usage event.
</DynamicParamField>

<DynamicParamField body="timestamp" type="integer">
  Unix timestamp in milliseconds to use for the usage event. Defaults to the current time.
</DynamicParamField>

<DynamicParamField body="overage_behavior" type="'cap' | 'overflow'">
  How to handle usage that exceeds the available balance. "cap" (default) deducts only what fits, stopping at zero. "overflow" deducts the full value: the balance can go negative and usage limits do not clamp the deduction, though spend limits still apply.
</DynamicParamField>

<DynamicParamField body="async" type="boolean">
  If true, enqueue the event for asynchronous processing and return 204 immediately. The response will not include balance information.
</DynamicParamField>

<DynamicParamField body="lock" type="object">
  <Expandable title="properties">
    <DynamicParamField body="lock_id" type="string" required>
      A unique identifier for this lock. Used to finalize the lock later via balances.finalize.
    </DynamicParamField>

    <DynamicParamField body="enabled" type="any" required>
      Must be true to enable locking.
    </DynamicParamField>

    <DynamicParamField body="expires_at" type="number">
      Unix timestamp (ms) when the lock automatically expires and releases the held balance.
    </DynamicParamField>
  </Expandable>
</DynamicParamField>

### Response

<DynamicResponseField name="customer_id" type="string">
  The ID of the customer whose usage was tracked.
</DynamicResponseField>

<DynamicResponseField name="entity_id" type="string">
  The ID of the entity, if entity-scoped tracking was performed.
</DynamicResponseField>

<DynamicResponseField name="event_name" type="string">
  The event name that was tracked, if event\_name was used instead of feature\_id.
</DynamicResponseField>

<DynamicResponseField name="value" type="number">
  The amount of usage that was recorded.
</DynamicResponseField>

<DynamicResponseField name="balance" type="object | null">
  The updated balance for the tracked feature. Null if tracking by event\_name that affects multiple features.

  <Expandable title="properties">
    <DynamicResponseField name="feature_id" type="string">
      The feature ID this balance is for.
    </DynamicResponseField>

    <DynamicResponseField name="feature" type="object">
      The full feature object if expanded.

      <Expandable title="properties">
        <DynamicResponseField name="id" type="string">
          The unique identifier for this feature, used in /check and /track calls.
        </DynamicResponseField>

        <DynamicResponseField name="name" type="string">
          Human-readable name displayed in the dashboard and billing UI.
        </DynamicResponseField>

        <DynamicResponseField name="type" type="'boolean' | 'metered' | 'credit_system' | 'ai_credit_system'">
          Feature type: 'boolean' for on/off access, 'metered' for usage-tracked features, 'credit\_system' for unified credit pools, 'ai\_credit\_system' for model-based token pricing.
        </DynamicResponseField>

        <DynamicResponseField name="consumable" type="boolean">
          For metered features: true if usage resets periodically (API calls, credits), false if allocated persistently (seats, storage).
        </DynamicResponseField>

        <DynamicResponseField name="event_names" type="string[]">
          Event names that trigger this feature's balance. Allows multiple features to respond to a single event.
        </DynamicResponseField>

        <DynamicResponseField name="credit_schema" type="object[]">
          For credit\_system features: maps metered features to their credit costs.

          <Expandable title="properties">
            <DynamicResponseField name="metered_feature_id" type="string">
              ID of the metered feature that draws from this credit system.
            </DynamicResponseField>

            <DynamicResponseField name="credit_cost" type="number">
              Credits consumed per unit of the metered feature.
            </DynamicResponseField>
          </Expandable>
        </DynamicResponseField>

        <DynamicResponseField name="model_markups.{key}" type="object | null">
          Per-model markup overrides for AI credit systems.

          <Expandable title="properties">
            <DynamicResponseField name="markup" type="number" />

            <DynamicResponseField name="input_cost" type="number" />

            <DynamicResponseField name="output_cost" type="number" />
          </Expandable>
        </DynamicResponseField>

        <DynamicResponseField name="default_markup" type="number">
          Default percentage markup for AI credit systems. Use -100 to make usage free.
        </DynamicResponseField>

        <DynamicResponseField name="provider_markups.{key}" type="object | null">
          Per-provider default markup percentages for AI credit systems.

          <Expandable title="properties">
            <DynamicResponseField name="markup" type="number" />
          </Expandable>
        </DynamicResponseField>

        <DynamicResponseField name="display" type="object">
          Display names for the feature in billing UI and customer-facing components.

          <Expandable title="properties">
            <DynamicResponseField name="singular" type="string | null">
              Singular form for UI display (e.g., 'API call', 'seat').
            </DynamicResponseField>

            <DynamicResponseField name="plural" type="string | null">
              Plural form for UI display (e.g., 'API calls', 'seats').
            </DynamicResponseField>
          </Expandable>
        </DynamicResponseField>

        <DynamicResponseField name="archived" type="boolean">
          Whether the feature is archived and hidden from the dashboard.
        </DynamicResponseField>
      </Expandable>
    </DynamicResponseField>

    <DynamicResponseField name="granted" type="number">
      Total balance granted (included + prepaid).
    </DynamicResponseField>

    <DynamicResponseField name="remaining" type="number">
      Remaining balance available for use.
    </DynamicResponseField>

    <DynamicResponseField name="usage" type="number">
      Total usage consumed in the current period.
    </DynamicResponseField>

    <DynamicResponseField name="unlimited" type="boolean">
      Whether this feature has unlimited usage.
    </DynamicResponseField>

    <DynamicResponseField name="overage_allowed" type="boolean">
      Whether usage beyond the granted balance is allowed (with overage charges).
    </DynamicResponseField>

    <DynamicResponseField name="max_purchase" type="number | null">
      Maximum quantity that can be purchased as a top-up, or null for unlimited.
    </DynamicResponseField>

    <DynamicResponseField name="next_reset_at" type="number | null">
      Timestamp when the balance will reset, or null for no reset.
    </DynamicResponseField>

    <DynamicResponseField name="breakdown" type="object[]">
      Detailed breakdown of balance sources when stacking multiple plans or grants.

      <Expandable title="properties">
        <DynamicResponseField name="id" type="string">
          The unique identifier for this balance breakdown.
        </DynamicResponseField>

        <DynamicResponseField name="plan_id" type="string | null">
          The plan ID this balance originates from, or null for standalone balances.
        </DynamicResponseField>

        <DynamicResponseField name="included_grant" type="number">
          Amount granted from the plan's included usage.
        </DynamicResponseField>

        <DynamicResponseField name="prepaid_grant" type="number">
          Amount granted from prepaid purchases or top-ups.
        </DynamicResponseField>

        <DynamicResponseField name="remaining" type="number">
          Remaining balance available for use.
        </DynamicResponseField>

        <DynamicResponseField name="usage" type="number">
          Amount consumed in the current period.
        </DynamicResponseField>

        <DynamicResponseField name="unlimited" type="boolean">
          Whether this balance has unlimited usage.
        </DynamicResponseField>

        <DynamicResponseField name="reset" type="object | null">
          Reset configuration for this balance, or null if no reset.

          <Expandable title="properties">
            <DynamicResponseField name="interval" type="'one_off' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'">
              The reset interval (hour, day, week, month, etc.) or 'multiple' if combined from different intervals.
            </DynamicResponseField>

            <DynamicResponseField name="interval_count" type="number">
              Number of intervals between resets (eg. 2 for bi-monthly).
            </DynamicResponseField>

            <DynamicResponseField name="resets_at" type="number | null">
              Timestamp when the balance will next reset.
            </DynamicResponseField>
          </Expandable>
        </DynamicResponseField>

        <DynamicResponseField name="price" type="object | null">
          Pricing configuration if this balance has usage-based pricing.

          <Expandable title="properties">
            <DynamicResponseField name="amount" type="number">
              The per-unit price amount.
            </DynamicResponseField>

            <DynamicResponseField name="tiers" type="object[]">
              Tiered pricing configuration if applicable.

              <Expandable title="properties">
                <DynamicResponseField name="to" type="number" />

                <DynamicResponseField name="amount" type="number" />

                <DynamicResponseField name="flat_amount" type="number" />
              </Expandable>
            </DynamicResponseField>

            <DynamicResponseField name="tier_behavior" type="'graduated' | 'volume'">
              How tiers are applied: graduated (split across bands) or volume (flat rate for the matched tier).
            </DynamicResponseField>

            <DynamicResponseField name="billing_units" type="number">
              The number of units per billing increment (eg. \$9 / 250 units).
            </DynamicResponseField>

            <DynamicResponseField name="billing_method" type="'prepaid' | 'usage_based'">
              Whether usage is prepaid or billed pay-per-use.
            </DynamicResponseField>

            <DynamicResponseField name="max_purchase" type="number | null">
              Maximum quantity that can be purchased, or null for unlimited.
            </DynamicResponseField>
          </Expandable>
        </DynamicResponseField>

        <DynamicResponseField name="expires_at" type="number | null">
          Timestamp when this balance expires, or null for no expiration.
        </DynamicResponseField>
      </Expandable>
    </DynamicResponseField>

    <DynamicResponseField name="rollovers" type="object[]">
      Rollover balances carried over from previous periods.

      <Expandable title="properties">
        <DynamicResponseField name="balance" type="number">
          Amount of balance rolled over from a previous period.
        </DynamicResponseField>

        <DynamicResponseField name="expires_at" type="number">
          Timestamp when the rollover balance expires.
        </DynamicResponseField>
      </Expandable>
    </DynamicResponseField>
  </Expandable>
</DynamicResponseField>

<DynamicResponseField name="balances.{key}" type="object | null">
  Map of feature\_id to updated balance for the tracked feature and any related features (e.g. linked credit systems). Value is null when the customer has no balance for that feature.

  <Expandable title="properties">
    <DynamicResponseField name="feature_id" type="string">
      The feature ID this balance is for.
    </DynamicResponseField>

    <DynamicResponseField name="feature" type="object">
      The full feature object if expanded.

      <Expandable title="properties">
        <DynamicResponseField name="id" type="string">
          The unique identifier for this feature, used in /check and /track calls.
        </DynamicResponseField>

        <DynamicResponseField name="name" type="string">
          Human-readable name displayed in the dashboard and billing UI.
        </DynamicResponseField>

        <DynamicResponseField name="type" type="'boolean' | 'metered' | 'credit_system' | 'ai_credit_system'">
          Feature type: 'boolean' for on/off access, 'metered' for usage-tracked features, 'credit\_system' for unified credit pools, 'ai\_credit\_system' for model-based token pricing.
        </DynamicResponseField>

        <DynamicResponseField name="consumable" type="boolean">
          For metered features: true if usage resets periodically (API calls, credits), false if allocated persistently (seats, storage).
        </DynamicResponseField>

        <DynamicResponseField name="event_names" type="string[]">
          Event names that trigger this feature's balance. Allows multiple features to respond to a single event.
        </DynamicResponseField>

        <DynamicResponseField name="credit_schema" type="object[]">
          For credit\_system features: maps metered features to their credit costs.

          <Expandable title="properties">
            <DynamicResponseField name="metered_feature_id" type="string">
              ID of the metered feature that draws from this credit system.
            </DynamicResponseField>

            <DynamicResponseField name="credit_cost" type="number">
              Credits consumed per unit of the metered feature.
            </DynamicResponseField>
          </Expandable>
        </DynamicResponseField>

        <DynamicResponseField name="model_markups.{key}" type="object | null">
          Per-model markup overrides for AI credit systems.

          <Expandable title="properties">
            <DynamicResponseField name="markup" type="number" />

            <DynamicResponseField name="input_cost" type="number" />

            <DynamicResponseField name="output_cost" type="number" />
          </Expandable>
        </DynamicResponseField>

        <DynamicResponseField name="default_markup" type="number">
          Default percentage markup for AI credit systems. Use -100 to make usage free.
        </DynamicResponseField>

        <DynamicResponseField name="provider_markups.{key}" type="object | null">
          Per-provider default markup percentages for AI credit systems.

          <Expandable title="properties">
            <DynamicResponseField name="markup" type="number" />
          </Expandable>
        </DynamicResponseField>

        <DynamicResponseField name="display" type="object">
          Display names for the feature in billing UI and customer-facing components.

          <Expandable title="properties">
            <DynamicResponseField name="singular" type="string | null">
              Singular form for UI display (e.g., 'API call', 'seat').
            </DynamicResponseField>

            <DynamicResponseField name="plural" type="string | null">
              Plural form for UI display (e.g., 'API calls', 'seats').
            </DynamicResponseField>
          </Expandable>
        </DynamicResponseField>

        <DynamicResponseField name="archived" type="boolean">
          Whether the feature is archived and hidden from the dashboard.
        </DynamicResponseField>
      </Expandable>
    </DynamicResponseField>

    <DynamicResponseField name="granted" type="number">
      Total balance granted (included + prepaid).
    </DynamicResponseField>

    <DynamicResponseField name="remaining" type="number">
      Remaining balance available for use.
    </DynamicResponseField>

    <DynamicResponseField name="usage" type="number">
      Total usage consumed in the current period.
    </DynamicResponseField>

    <DynamicResponseField name="unlimited" type="boolean">
      Whether this feature has unlimited usage.
    </DynamicResponseField>

    <DynamicResponseField name="overage_allowed" type="boolean">
      Whether usage beyond the granted balance is allowed (with overage charges).
    </DynamicResponseField>

    <DynamicResponseField name="max_purchase" type="number | null">
      Maximum quantity that can be purchased as a top-up, or null for unlimited.
    </DynamicResponseField>

    <DynamicResponseField name="next_reset_at" type="number | null">
      Timestamp when the balance will reset, or null for no reset.
    </DynamicResponseField>

    <DynamicResponseField name="breakdown" type="object[]">
      Detailed breakdown of balance sources when stacking multiple plans or grants.

      <Expandable title="properties">
        <DynamicResponseField name="id" type="string">
          The unique identifier for this balance breakdown.
        </DynamicResponseField>

        <DynamicResponseField name="plan_id" type="string | null">
          The plan ID this balance originates from, or null for standalone balances.
        </DynamicResponseField>

        <DynamicResponseField name="included_grant" type="number">
          Amount granted from the plan's included usage.
        </DynamicResponseField>

        <DynamicResponseField name="prepaid_grant" type="number">
          Amount granted from prepaid purchases or top-ups.
        </DynamicResponseField>

        <DynamicResponseField name="remaining" type="number">
          Remaining balance available for use.
        </DynamicResponseField>

        <DynamicResponseField name="usage" type="number">
          Amount consumed in the current period.
        </DynamicResponseField>

        <DynamicResponseField name="unlimited" type="boolean">
          Whether this balance has unlimited usage.
        </DynamicResponseField>

        <DynamicResponseField name="reset" type="object | null">
          Reset configuration for this balance, or null if no reset.

          <Expandable title="properties">
            <DynamicResponseField name="interval" type="'one_off' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'">
              The reset interval (hour, day, week, month, etc.) or 'multiple' if combined from different intervals.
            </DynamicResponseField>

            <DynamicResponseField name="interval_count" type="number">
              Number of intervals between resets (eg. 2 for bi-monthly).
            </DynamicResponseField>

            <DynamicResponseField name="resets_at" type="number | null">
              Timestamp when the balance will next reset.
            </DynamicResponseField>
          </Expandable>
        </DynamicResponseField>

        <DynamicResponseField name="price" type="object | null">
          Pricing configuration if this balance has usage-based pricing.

          <Expandable title="properties">
            <DynamicResponseField name="amount" type="number">
              The per-unit price amount.
            </DynamicResponseField>

            <DynamicResponseField name="tiers" type="object[]">
              Tiered pricing configuration if applicable.

              <Expandable title="properties">
                <DynamicResponseField name="to" type="number" />

                <DynamicResponseField name="amount" type="number" />

                <DynamicResponseField name="flat_amount" type="number" />
              </Expandable>
            </DynamicResponseField>

            <DynamicResponseField name="tier_behavior" type="'graduated' | 'volume'">
              How tiers are applied: graduated (split across bands) or volume (flat rate for the matched tier).
            </DynamicResponseField>

            <DynamicResponseField name="billing_units" type="number">
              The number of units per billing increment (eg. \$9 / 250 units).
            </DynamicResponseField>

            <DynamicResponseField name="billing_method" type="'prepaid' | 'usage_based'">
              Whether usage is prepaid or billed pay-per-use.
            </DynamicResponseField>

            <DynamicResponseField name="max_purchase" type="number | null">
              Maximum quantity that can be purchased, or null for unlimited.
            </DynamicResponseField>
          </Expandable>
        </DynamicResponseField>

        <DynamicResponseField name="expires_at" type="number | null">
          Timestamp when this balance expires, or null for no expiration.
        </DynamicResponseField>
      </Expandable>
    </DynamicResponseField>

    <DynamicResponseField name="rollovers" type="object[]">
      Rollover balances carried over from previous periods.

      <Expandable title="properties">
        <DynamicResponseField name="balance" type="number">
          Amount of balance rolled over from a previous period.
        </DynamicResponseField>

        <DynamicResponseField name="expires_at" type="number">
          Timestamp when the rollover balance expires.
        </DynamicResponseField>
      </Expandable>
    </DynamicResponseField>
  </Expandable>
</DynamicResponseField>

<DynamicResponseField name="deductions" type="object[]">
  Per-balance breakdown of what this event deducted. A single event can consume from multiple balance rows when credit systems or rollovers are involved; this surfaces each one so callers can build per-feature usage views without polling.

  <Expandable title="properties">
    <DynamicResponseField name="balance_id" type="string">
      ID of the underlying balance row that was deducted from (customer\_entitlement or rollover).
    </DynamicResponseField>

    <DynamicResponseField name="feature_id" type="string">
      The feature this balance belongs to.
    </DynamicResponseField>

    <DynamicResponseField name="plan_id" type="string | null">
      ID of the plan/product this balance belongs to. Null when the balance can't be attributed to a single plan (e.g. it spans multiple).
    </DynamicResponseField>

    <DynamicResponseField name="reset" type="object | null">
      Reset configuration for the balance this deduction came from, or null if the balance doesn't reset.

      <Expandable title="properties">
        <DynamicResponseField name="interval" type="'one_off' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'">
          The reset interval (hour, day, week, month, etc.) or 'multiple' if combined from different intervals.
        </DynamicResponseField>

        <DynamicResponseField name="interval_count" type="number">
          Number of intervals between resets (eg. 2 for bi-monthly).
        </DynamicResponseField>

        <DynamicResponseField name="resets_at" type="number | null">
          Timestamp when the balance will next reset.
        </DynamicResponseField>
      </Expandable>
    </DynamicResponseField>

    <DynamicResponseField name="value" type="number">
      Amount deducted from this balance. Positive when usage was consumed, negative when credit was restored (e.g. a refund via negative track value).
    </DynamicResponseField>
  </Expandable>
</DynamicResponseField>

<ResponseExample>
  ```json 200 theme={null}
  {
    "customer_id": "cus_123",
    "value": 1,
    "balance": {
      "feature_id": "messages",
      "granted": 100,
      "remaining": 72,
      "usage": 28,
      "unlimited": false,
      "overage_allowed": false,
      "max_purchase": null,
      "next_reset_at": 1773851121437,
      "breakdown": [
        {
          "id": "cus_ent_39qmLooixXLAqMywgXywjAz96rV",
          "plan_id": "pro_plan",
          "included_grant": 100,
          "prepaid_grant": 0,
          "remaining": 72,
          "usage": 28,
          "unlimited": false,
          "reset": {
            "interval": "month",
            "resets_at": 1773851121437
          },
          "price": null,
          "expires_at": null
        }
      ]
    },
    "deductions": [
      {
        "balance_id": "cus_ent_3DdSDoyFmoA9Neecl2a2Gc507X2",
        "feature_id": "messages",
        "plan_id": "pro",
        "reset": {
          "interval": "month",
          "resets_at": 1781288736881
        },
        "value": 1
      }
    ]
  }
  ```
</ResponseExample>


## OpenAPI

````yaml openapi POST /v1/balances.track
openapi: 3.1.0
info:
  title: Autumn API
  version: 2.3.0
servers:
  - url: https://api.useautumn.com
    description: Production server
security:
  - secretKey: []
paths:
  /v1/balances.track:
    post:
      description: >-
        Records usage for a customer feature and returns updated balances.


        Use this after an action happens to decrement usage, or send a negative
        value to credit balance back.
      operationId: track
      parameters:
        - name: x-api-version
          in: header
          required: true
          schema:
            type: string
            default: 2.3.0
          x-speakeasy-globals-hidden: true
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                customer_id:
                  type: string
                  description: The ID of the customer.
                feature_id:
                  type: string
                  description: >-
                    The ID of the feature to track usage for. Required if
                    event_name is not provided.
                entity_id:
                  type: string
                  description: >-
                    The ID of the entity for entity-scoped balances (e.g.,
                    per-seat limits).
                event_name:
                  type: string
                  minLength: 1
                  description: >-
                    Event name to track usage for. Use instead of feature_id
                    when multiple features should be tracked from a single
                    event.
                value:
                  type: number
                  description: >-
                    The amount of usage to record. Defaults to 1. Use negative
                    values to credit balance (e.g., when removing a seat).
                properties:
                  type: object
                  propertyNames:
                    type: string
                  additionalProperties: {}
                  description: Additional properties to attach to this usage event.
                timestamp:
                  type: integer
                  minimum: 0
                  maximum: 9007199254740991
                  exclusiveMinimum: 0
                  description: >-
                    Unix timestamp in milliseconds to use for the usage event.
                    Defaults to the current time.
                overage_behavior:
                  description: >-
                    How to handle usage that exceeds the available balance.
                    "cap" (default) deducts only what fits, stopping at zero.
                    "overflow" deducts the full value: the balance can go
                    negative and usage limits do not clamp the deduction, though
                    spend limits still apply.
                  enum:
                    - cap
                    - overflow
                  type: string
                async:
                  type: boolean
                  description: >-
                    If true, enqueue the event for asynchronous processing and
                    return 204 immediately. The response will not include
                    balance information.
                lock:
                  type: object
                  properties:
                    lock_id:
                      type: string
                      maxLength: 256
                      description: >-
                        A unique identifier for this lock. Used to finalize the
                        lock later via balances.finalize.
                    enabled:
                      const: true
                      description: Must be true to enable locking.
                    expires_at:
                      type: number
                      description: >-
                        Unix timestamp (ms) when the lock automatically expires
                        and releases the held balance.
                  required:
                    - lock_id
                    - enabled
              required:
                - customer_id
              title: TrackParams
              examples:
                - customer_id: cus_123
                  feature_id: messages
                  value: 1
            example:
              customer_id: cus_123
              feature_id: messages
              value: 1
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  customer_id:
                    type: string
                    description: The ID of the customer whose usage was tracked.
                  entity_id:
                    type: string
                    description: >-
                      The ID of the entity, if entity-scoped tracking was
                      performed.
                  event_name:
                    type: string
                    description: >-
                      The event name that was tracked, if event_name was used
                      instead of feature_id.
                  value:
                    type: number
                    description: The amount of usage that was recorded.
                  balance:
                    anyOf:
                      - $ref: '#/components/schemas/Balance'
                      - type: 'null'
                    description: >-
                      The updated balance for the tracked feature. Null if
                      tracking by event_name that affects multiple features.
                  balances:
                    type: object
                    propertyNames:
                      type: string
                    additionalProperties:
                      anyOf:
                        - $ref: '#/components/schemas/Balance'
                        - type: 'null'
                    description: >-
                      Map of feature_id to updated balance for the tracked
                      feature and any related features (e.g. linked credit
                      systems). Value is null when the customer has no balance
                      for that feature.
                  deductions:
                    type: array
                    items:
                      type: object
                      properties:
                        balance_id:
                          type: string
                          description: >-
                            ID of the underlying balance row that was deducted
                            from (customer_entitlement or rollover).
                        feature_id:
                          type: string
                          description: The feature this balance belongs to.
                        plan_id:
                          anyOf:
                            - type: string
                            - type: 'null'
                          description: >-
                            ID of the plan/product this balance belongs to. Null
                            when the balance can't be attributed to a single
                            plan (e.g. it spans multiple).
                        reset:
                          anyOf:
                            - type: object
                              properties:
                                interval:
                                  anyOf:
                                    - enum:
                                        - one_off
                                        - minute
                                        - hour
                                        - day
                                        - week
                                        - month
                                        - quarter
                                        - semi_annual
                                        - year
                                      type: string
                                    - const: multiple
                                  description: >-
                                    The reset interval (hour, day, week, month,
                                    etc.) or 'multiple' if combined from
                                    different intervals.
                                interval_count:
                                  type: number
                                  description: >-
                                    Number of intervals between resets (eg. 2
                                    for bi-monthly).
                                resets_at:
                                  anyOf:
                                    - type: number
                                    - type: 'null'
                                  description: Timestamp when the balance will next reset.
                              required:
                                - interval
                                - resets_at
                            - type: 'null'
                          description: >-
                            Reset configuration for the balance this deduction
                            came from, or null if the balance doesn't reset.
                        value:
                          type: number
                          description: >-
                            Amount deducted from this balance. Positive when
                            usage was consumed, negative when credit was
                            restored (e.g. a refund via negative track value).
                      required:
                        - balance_id
                        - feature_id
                        - plan_id
                        - reset
                        - value
                    description: >-
                      Per-balance breakdown of what this event deducted. A
                      single event can consume from multiple balance rows when
                      credit systems or rollovers are involved; this surfaces
                      each one so callers can build per-feature usage views
                      without polling.
                required:
                  - customer_id
                  - value
                  - balance
                examples:
                  - customer_id: cus_123
                    value: 1
                    balance:
                      feature_id: messages
                      granted: 100
                      remaining: 72
                      usage: 28
                      unlimited: false
                      overage_allowed: false
                      max_purchase: null
                      next_reset_at: 1773851121437
                      breakdown:
                        - id: cus_ent_39qmLooixXLAqMywgXywjAz96rV
                          plan_id: pro_plan
                          included_grant: 100
                          prepaid_grant: 0
                          remaining: 72
                          usage: 28
                          unlimited: false
                          reset:
                            interval: month
                            resets_at: 1773851121437
                          price: null
                          expires_at: null
                    deductions:
                      - balance_id: cus_ent_3DdSDoyFmoA9Neecl2a2Gc507X2
                        feature_id: messages
                        plan_id: pro
                        reset:
                          interval: month
                          resets_at: 1781288736881
                        value: 1
              example:
                customer_id: cus_123
                value: 1
                balance:
                  feature_id: messages
                  granted: 100
                  remaining: 72
                  usage: 28
                  unlimited: false
                  overage_allowed: false
                  max_purchase: null
                  next_reset_at: 1773851121437
                  breakdown:
                    - id: cus_ent_39qmLooixXLAqMywgXywjAz96rV
                      plan_id: pro_plan
                      included_grant: 100
                      prepaid_grant: 0
                      remaining: 72
                      usage: 28
                      unlimited: false
                      reset:
                        interval: month
                        resets_at: 1773851121437
                      price: null
                      expires_at: null
                deductions:
                  - balance_id: cus_ent_3DdSDoyFmoA9Neecl2a2Gc507X2
                    feature_id: messages
                    plan_id: pro
                    reset:
                      interval: month
                      resets_at: 1781288736881
                    value: 1
        '202':
          description: >-
            Accepted. Autumn is experiencing degraded service from a downstream
            provider, so the event was accepted for replay and will be tracked
            as soon as the service is restored.
          content:
            application/json:
              schema:
                type: object
                properties:
                  customer_id:
                    type: string
                    description: The ID of the customer whose usage was tracked.
                  entity_id:
                    type: string
                    description: >-
                      The ID of the entity, if entity-scoped tracking was
                      performed.
                  event_name:
                    type: string
                    description: >-
                      The event name that was tracked, if event_name was used
                      instead of feature_id.
                  value:
                    type: number
                    description: The amount of usage that was recorded.
                  balance:
                    anyOf:
                      - $ref: '#/components/schemas/Balance'
                      - type: 'null'
                    description: >-
                      The updated balance for the tracked feature. Null if
                      tracking by event_name that affects multiple features.
                  balances:
                    type: object
                    propertyNames:
                      type: string
                    additionalProperties:
                      anyOf:
                        - $ref: '#/components/schemas/Balance'
                        - type: 'null'
                    description: >-
                      Map of feature_id to updated balance for the tracked
                      feature and any related features (e.g. linked credit
                      systems). Value is null when the customer has no balance
                      for that feature.
                  deductions:
                    type: array
                    items:
                      type: object
                      properties:
                        balance_id:
                          type: string
                          description: >-
                            ID of the underlying balance row that was deducted
                            from (customer_entitlement or rollover).
                        feature_id:
                          type: string
                          description: The feature this balance belongs to.
                        plan_id:
                          anyOf:
                            - type: string
                            - type: 'null'
                          description: >-
                            ID of the plan/product this balance belongs to. Null
                            when the balance can't be attributed to a single
                            plan (e.g. it spans multiple).
                        reset:
                          anyOf:
                            - type: object
                              properties:
                                interval:
                                  anyOf:
                                    - enum:
                                        - one_off
                                        - minute
                                        - hour
                                        - day
                                        - week
                                        - month
                                        - quarter
                                        - semi_annual
                                        - year
                                      type: string
                                    - const: multiple
                                  description: >-
                                    The reset interval (hour, day, week, month,
                                    etc.) or 'multiple' if combined from
                                    different intervals.
                                interval_count:
                                  type: number
                                  description: >-
                                    Number of intervals between resets (eg. 2
                                    for bi-monthly).
                                resets_at:
                                  anyOf:
                                    - type: number
                                    - type: 'null'
                                  description: Timestamp when the balance will next reset.
                              required:
                                - interval
                                - resets_at
                            - type: 'null'
                          description: >-
                            Reset configuration for the balance this deduction
                            came from, or null if the balance doesn't reset.
                        value:
                          type: number
                          description: >-
                            Amount deducted from this balance. Positive when
                            usage was consumed, negative when credit was
                            restored (e.g. a refund via negative track value).
                      required:
                        - balance_id
                        - feature_id
                        - plan_id
                        - reset
                        - value
                    description: >-
                      Per-balance breakdown of what this event deducted. A
                      single event can consume from multiple balance rows when
                      credit systems or rollovers are involved; this surfaces
                      each one so callers can build per-feature usage views
                      without polling.
                required:
                  - customer_id
                  - value
                  - balance
                examples:
                  - customer_id: cus_123
                    value: 1
                    balance:
                      feature_id: messages
                      granted: 100
                      remaining: 72
                      usage: 28
                      unlimited: false
                      overage_allowed: false
                      max_purchase: null
                      next_reset_at: 1773851121437
                      breakdown:
                        - id: cus_ent_39qmLooixXLAqMywgXywjAz96rV
                          plan_id: pro_plan
                          included_grant: 100
                          prepaid_grant: 0
                          remaining: 72
                          usage: 28
                          unlimited: false
                          reset:
                            interval: month
                            resets_at: 1773851121437
                          price: null
                          expires_at: null
                    deductions:
                      - balance_id: cus_ent_3DdSDoyFmoA9Neecl2a2Gc507X2
                        feature_id: messages
                        plan_id: pro
                        reset:
                          interval: month
                          resets_at: 1781288736881
                        value: 1
              example:
                customer_id: cus_123
                value: 1
                balance:
                  feature_id: messages
                  granted: 100
                  remaining: 72
                  usage: 28
                  unlimited: false
                  overage_allowed: false
                  max_purchase: null
                  next_reset_at: 1773851121437
                  breakdown:
                    - id: cus_ent_39qmLooixXLAqMywgXywjAz96rV
                      plan_id: pro_plan
                      included_grant: 100
                      prepaid_grant: 0
                      remaining: 72
                      usage: 28
                      unlimited: false
                      reset:
                        interval: month
                        resets_at: 1773851121437
                      price: null
                      expires_at: null
                deductions:
                  - balance_id: cus_ent_3DdSDoyFmoA9Neecl2a2Gc507X2
                    feature_id: messages
                    plan_id: pro
                    reset:
                      interval: month
                      resets_at: 1781288736881
                    value: 1
      x-codeSamples:
        - lang: typescript
          label: Typescript (SDK)
          source: |-
            import { Autumn } from 'autumn-js'

            const autumn = new Autumn()

            const result = await autumn.track({
              customerId: "cus_123",
              featureId: "messages",
              value: 1,
            });
        - lang: python
          label: Python (SDK)
          source: |-
            from autumn_sdk import Autumn

            autumn = Autumn(secret_key="am_sk_test...")

            res = autumn.track(
                customer_id="cus_123",
                feature_id="messages",
                value=1,
            )
components:
  schemas:
    Balance:
      type: object
      properties:
        feature_id:
          type: string
          description: The feature ID this balance is for.
        feature:
          type: object
          properties:
            id:
              type: string
              description: >-
                The unique identifier for this feature, used in /check and
                /track calls.
            name:
              type: string
              description: Human-readable name displayed in the dashboard and billing UI.
            type:
              enum:
                - boolean
                - metered
                - credit_system
                - ai_credit_system
              type: string
              description: >-
                Feature type: 'boolean' for on/off access, 'metered' for
                usage-tracked features, 'credit_system' for unified credit
                pools, 'ai_credit_system' for model-based token pricing.
            consumable:
              type: boolean
              description: >-
                For metered features: true if usage resets periodically (API
                calls, credits), false if allocated persistently (seats,
                storage).
            event_names:
              type: array
              items:
                type: string
              description: >-
                Event names that trigger this feature's balance. Allows multiple
                features to respond to a single event.
            credit_schema:
              type: array
              items:
                type: object
                properties:
                  metered_feature_id:
                    type: string
                    description: >-
                      ID of the metered feature that draws from this credit
                      system.
                  credit_cost:
                    type: number
                    description: Credits consumed per unit of the metered feature.
                required:
                  - metered_feature_id
                  - credit_cost
              description: >-
                For credit_system features: maps metered features to their
                credit costs.
            model_markups:
              anyOf:
                - type: object
                  propertyNames:
                    type: string
                  additionalProperties:
                    type: object
                    properties:
                      markup:
                        type: number
                        minimum: -100
                      input_cost:
                        type: number
                        minimum: 0
                      output_cost:
                        type: number
                        minimum: 0
                - type: 'null'
              description: Per-model markup overrides for AI credit systems.
            default_markup:
              type: number
              minimum: -100
              description: >-
                Default percentage markup for AI credit systems. Use -100 to
                make usage free.
            provider_markups:
              anyOf:
                - type: object
                  propertyNames:
                    type: string
                  additionalProperties:
                    type: object
                    properties:
                      markup:
                        type: number
                        minimum: -100
                    required:
                      - markup
                - type: 'null'
              description: Per-provider default markup percentages for AI credit systems.
            display:
              type: object
              properties:
                singular:
                  anyOf:
                    - type: string
                    - type: 'null'
                  description: Singular form for UI display (e.g., 'API call', 'seat').
                plural:
                  anyOf:
                    - type: string
                    - type: 'null'
                  description: Plural form for UI display (e.g., 'API calls', 'seats').
              description: >-
                Display names for the feature in billing UI and customer-facing
                components.
            archived:
              type: boolean
              description: Whether the feature is archived and hidden from the dashboard.
          required:
            - id
            - name
            - type
            - consumable
            - archived
          description: The full feature object if expanded.
        granted:
          type: number
          description: Total balance granted (included + prepaid).
        remaining:
          type: number
          minimum: 0
          description: Remaining balance available for use.
        usage:
          type: number
          description: Total usage consumed in the current period.
        unlimited:
          type: boolean
          description: Whether this feature has unlimited usage.
        overage_allowed:
          type: boolean
          description: >-
            Whether usage beyond the granted balance is allowed (with overage
            charges).
        max_purchase:
          anyOf:
            - type: number
            - type: 'null'
          description: >-
            Maximum quantity that can be purchased as a top-up, or null for
            unlimited.
        next_reset_at:
          anyOf:
            - type: number
            - type: 'null'
          description: Timestamp when the balance will reset, or null for no reset.
        breakdown:
          type: array
          items:
            type: object
            properties:
              id:
                type: string
                default: ''
                description: The unique identifier for this balance breakdown.
              plan_id:
                anyOf:
                  - type: string
                  - type: 'null'
                description: >-
                  The plan ID this balance originates from, or null for
                  standalone balances.
              included_grant:
                type: number
                description: Amount granted from the plan's included usage.
              prepaid_grant:
                type: number
                description: Amount granted from prepaid purchases or top-ups.
              remaining:
                type: number
                description: Remaining balance available for use.
              usage:
                type: number
                description: Amount consumed in the current period.
              unlimited:
                type: boolean
                description: Whether this balance has unlimited usage.
              reset:
                anyOf:
                  - type: object
                    properties:
                      interval:
                        anyOf:
                          - enum:
                              - one_off
                              - minute
                              - hour
                              - day
                              - week
                              - month
                              - quarter
                              - semi_annual
                              - year
                            type: string
                          - const: multiple
                        description: >-
                          The reset interval (hour, day, week, month, etc.) or
                          'multiple' if combined from different intervals.
                      interval_count:
                        type: number
                        description: >-
                          Number of intervals between resets (eg. 2 for
                          bi-monthly).
                      resets_at:
                        anyOf:
                          - type: number
                          - type: 'null'
                        description: Timestamp when the balance will next reset.
                    required:
                      - interval
                      - resets_at
                  - type: 'null'
                description: Reset configuration for this balance, or null if no reset.
              price:
                anyOf:
                  - type: object
                    properties:
                      amount:
                        type: number
                        description: The per-unit price amount.
                      tiers:
                        type: array
                        items:
                          type: object
                          properties:
                            to:
                              anyOf:
                                - type: number
                                - const: inf
                            amount:
                              type: number
                            flat_amount:
                              type: number
                          required:
                            - to
                            - amount
                        description: Tiered pricing configuration if applicable.
                      tier_behavior:
                        enum:
                          - graduated
                          - volume
                        type: string
                        description: >-
                          How tiers are applied: graduated (split across bands)
                          or volume (flat rate for the matched tier).
                      billing_units:
                        type: number
                        description: >-
                          The number of units per billing increment (eg. $9 /
                          250 units).
                      billing_method:
                        enum:
                          - prepaid
                          - usage_based
                        type: string
                        description: Whether usage is prepaid or billed pay-per-use.
                      max_purchase:
                        anyOf:
                          - type: number
                          - type: 'null'
                        description: >-
                          Maximum quantity that can be purchased, or null for
                          unlimited.
                    required:
                      - billing_units
                      - billing_method
                      - max_purchase
                  - type: 'null'
                description: Pricing configuration if this balance has usage-based pricing.
              expires_at:
                anyOf:
                  - type: number
                  - type: 'null'
                description: >-
                  Timestamp when this balance expires, or null for no
                  expiration.
            required:
              - plan_id
              - included_grant
              - prepaid_grant
              - remaining
              - usage
              - unlimited
              - reset
              - price
              - expires_at
          description: >-
            Detailed breakdown of balance sources when stacking multiple plans
            or grants.
        rollovers:
          type: array
          items:
            type: object
            properties:
              balance:
                type: number
                description: Amount of balance rolled over from a previous period.
              expires_at:
                type: number
                description: Timestamp when the rollover balance expires.
            required:
              - balance
              - expires_at
          description: Rollover balances carried over from previous periods.
      required:
        - feature_id
        - granted
        - remaining
        - usage
        - unlimited
        - overage_allowed
        - max_purchase
        - next_reset_at
      examples:
        - feature_id: messages
          granted: 100
          remaining: 72
          usage: 28
          unlimited: false
          overage_allowed: false
          max_purchase: null
          next_reset_at: 1773851121437
          breakdown:
            - id: cus_ent_39qmLooixXLAqMywgXywjAz96rV
              plan_id: pro_plan
              included_grant: 100
              prepaid_grant: 0
              remaining: 72
              usage: 28
              unlimited: false
              reset:
                interval: month
                resets_at: 1773851121437
              price: null
              expires_at: null
  securitySchemes:
    secretKey:
      type: http
      scheme: bearer
      bearerFormat: JWT

````