Drıftstack docs
Docs

Usage

/v1/usage exposes the calling account’s current calendar-month (UTC) totals + tier quotas. /v1/usage/series returns a daily-bucketed sparkline for the last N days.

Both endpoints honor the X-Driftstack-Account header (Team RBAC): when set to a team owner’s account id, the response covers the OWNER’s usage rather than the calling member’s. The owner’s tier is the quota-cap source — being on a team doesn’t bump a member’s personal cap.

Current period summary

GET /v1/usage

Response (200):

{
  "period_start": "2026-05-01T00:00:00.000Z",
  "period_end": "2026-06-01T00:00:00.000Z",
  "tier": "pro_v3",
  "totals": {
    "session_minute": 1234,
    "navigate": 56789,
    "interact": 12345,
    "wait": 6789,
    "state_capture": 234,
    "screenshot_capture": 78
  },
  "quotas": {
    "session_minute": null,
    "navigate": null,
    "interact": null,
    "wait": null,
    "state_capture": null,
    "screenshot_capture": null
  }
}

Fields

  • period_start / period_end — UTC ISO 8601. The current calendar month bounds (period_end is exclusive — the first second of the next month).
  • tier — the account’s billing tier. The tier determines the quota caps below.
  • totals.* and quotas.* use the same key set — the UsageRecordType enum (singular): session_minute, navigate, interact, wait, state_capture, screenshot_capture. Both maps always carry all six keys.
  • totals.session_minute — wall-clock minutes sessions were active, summed across the calendar month. No paid plan caps it. The Trial has a 120-minute total for the whole trial, shown in quotas.session_minute below.
  • totals.navigate / interact / wait — count of each session action you invoked. Free on all tiers; shown for your information.
  • totals.state_capture / screenshot_capture — count of state reads + screenshot endpoint hits. Same: count-only, no per-tier cap.
  • quotas.session_minute — null on every PAID plan, and 120 on the Trial. Paid plans are priced on concurrent sessions only, so they carry no cap on minutes; the field is preserved on them (rather than removed) so the response shape stays stable. On the Trial the figure is the session time the WHOLE trial includes, and it is enforced. It is counted from the day the trial starts, across every session the account runs — not per calendar month like the totals here — so on a trial that crosses a month boundary, totals.session_minute shows only the current month’s part.
  • quotas.<other> is null for record types that are unmetered (the operation-count meters are free / count-only). A non-null value here would mean a hard cap exists; cross-check against totals.<same-key> to see how much headroom remains.

quotas.session_minute is null on every paid plan: no paid plan meters session minutes or has a monthly total of hours. A single session still ends on its own: at 4 hours when it was started in manual mode (every POST /v1/sessions session through a proxy, every profile launch, and manual sessions from the desktop app), and no later than about 12 hours after it was created in every other case. A session left unused closes sooner. The Trial has a total and a shorter session limit: it includes 120 minutes of session time in total, and a single trial session is closed after 20 minutes. A new trial session runs for 20 minutes or for what is left of the total, whichever is shorter. A session still running when the total runs out is closed with closed_reason: "trial_time_used", and once none is left, creating a session is refused with 429 tier-limit (code: "trial_session_time_used").

This endpoint does not surface the concurrent-sessions cap or the profile-count cap — those are tier-table values enforced at create time. See /reference/rate-limits for the full per-tier configuration.

Daily series

GET /v1/usage/series?days=30

Response (200):

{
  "from_date": "2026-04-09",
  "to_date": "2026-05-09",
  "buckets": [
    {
      "date": "2026-04-09",
      "totals": {
        "session_minute": 42,
        "navigate": 1200,
        "interact": 350,
        "wait": 75,
        "state_capture": 8,
        "screenshot_capture": 3
      }
    }
  ]
}

totals is a record keyed by record type (singular form, matching the UsageRecordType enum + the field names on the current_period totals). days parameter: 1-90, default 30. The series is right-aligned on “yesterday” (the most-recent fully-closed UTC day); today’s partial bucket is intentionally not surfaced — the dashboard’s sparkline renders cleaner without a half-empty trailing bucket.

Empty days are included in the series (not omitted from the response) so the dashboard can render an empty-state without client-side date-fill logic, but their totals is an empty object {} — treat a missing counter key as 0. (The current-period summary, by contrast, zero-fills every counter.)

SDK usage:

const series = await client.usage.series({ days: 30 });
for (const b of series.buckets) {
  console.log(b.date, b.totals.session_minute, b.totals.navigate);
}
series = client.usage.series(days=30)
for b in series["buckets"]:
    print(b["date"], b["totals"].get("session_minute", 0))
series, _ := client.Usage.Series(ctx, 30)
for _, b := range series.Buckets {
    fmt.Println(b.Date, b.Totals["session_minute"], b.Totals["navigate"])
}

Quota / tier caps

Each plan has a fixed limit on concurrent sessions and saved profiles (the public @driftstack/api-types package also exports them as TIER_CONCURRENT_SESSION_LIMITS and PROFILES_PER_TIER):

Plan Tier id Concurrent sessions Profiles
Trial trial 1 1
Starter starter_v3 1 25
Pro pro_v3 3 100
Team team_v3 6 300
Scale scale_v3 12 1,000
Enterprise enterprise 20+ Unlimited

Enterprise limits are set by contract.

The earlier plans, no longer offered, keep their limits for the accounts that hold them:

Plan Tier id Concurrent sessions Profiles
Personal solo_manual 1 10
Team team_manual 3 50
Agency agency_manual 8 200
API Starter api_starter 2 25
API Builder api_builder 8 100
API Scale api_scale 24 500

Paid plans are priced on how many sessions run at once. There is no monthly total of session hours (fair use), no session-minute meter and no per-meter overage billing. One session does not run for ever: a session started in manual mode ends at 4 hours, and any session still open about 12 hours after it was created is closed. The Trial includes 2 hours of session time in total, counted from the day it starts, and caps a single session at 20 minutes; both are enforced. The operation counters (navigate / interact / wait / state_capture / screenshot_capture) are shown for your information and are never charged.

Auth + scoping

Both endpoints accept any valid bearer (API key OR web session) with read scope. The X-Driftstack-Account header is honored for team scopes — member roles read the owner’s usage.

Errors

Status Body type When
401 unauthorized Missing / invalid bearer
403 forbidden X-Driftstack-Account points at an account the caller isn’t a member of
400 validation-failed days outside [1, 90] on /series

Historical data

Usage history starts from the date usage tracking launched. Days before that show as zero in the dashboard and in /series results. This is expected and does not mean data is missing.