Skip to main content
DRIFTSTACK

What changed.

Customer-facing changes, in reverse-chronological order. SDK releases, pricing changes, security posture updates, self-hosted-tier adjustments. Internal engineering changes (code restructuring, test tooling, monitoring work) are tracked in our internal logs, not here.

For what lands next, see the roadmap.

  1. launch

    A clearer driftstack.dev

    The public site has been redesigned. Plainer language on every page — what each thing does first, with the precise technical claims kept in the small print. A rebuilt homepage shows the desktop app and the fleet of open iPhone sessions it drives. The site now ships its brand typography (self-hosted, no third-party requests), the groundwork for an accessible light theme is in place, and shared links get a fresh preview card. Prices, plans, and the API are unchanged.

  2. launch

    Route sessions through your own proxies

    You can now register your own SOCKS5 proxies against your account and run a session through one, so websites see your proxy's address as where the browsing comes from (your egress IP). Manage them in the desktop app under Proxies (set one as a profile default and launching routes through it automatically) or via the API at /v1/account/me/proxies — list, create, update, delete, and test reachability. Pass proxy_id when creating a session to choose the exit (egress) per run. Proxy passwords are stored encrypted while saved on our servers (encrypted at rest) under your account's own key and are never shown back to anyone, and hosts pointed at private or internal addresses are rejected. Documented at docs.driftstack.dev/api/proxies.

  3. launch

    Deleted profiles go to a recycle bin

    Deleting a profile is now reversible. A deleted profile moves to a recycle bin — hidden from your list and freeing up its name for reuse, but restorable for 30 days, after which it is permanently purged. Restore from the Trash view in the desktop app, or via the API: GET /v1/profiles/trash to list trashed profiles and POST /v1/profiles/:id/restore to bring one back. Documented at docs.driftstack.dev/api/profiles.

  4. launch

    Desktop app: the session viewer is now a real phone browser

    The live session view in the desktop app grew up: an editable address bar with reload, browser-style tabs (each tab is one of your concurrent sessions — sessions started from the dashboard or API appear automatically), an iPhone-style device frame that matches your session’s real screen shape (toggleable for pixel-level debugging), a page-loading bar, and honest page-error overlays (DNS, TLS, HTTP status, timeout) with one-click retry. Launching a profile now always lands you in a working viewer: deployments without live video streaming fall back to the direct viewer automatically, and an empty stream room says so instead of showing a black screen. The Dev Logs panel now also captures every failing API call and every visible error, so self-hosted debugging no longer needs devtools.

  5. sdk

    Sensitive-field typing + page lifecycle on session state

    Two additive API surfaces. (1) The type action accepts sensitive: true for card numbers, OTPs and PINs — the human-typing simulation then makes no visible corrections while typing them, so per-keystroke validation and auto-submit-on-length can't misfire (password fields get this automatically; the flag covers values the DOM can't reveal). All three SDKs carry it. (2) GET /v1/sessions/:id/state now includes page_state — the page lifecycle as the browser sees it (loading / loaded / errored, with error kind and HTTP status on failures) — so pollers can render loading and error states without screenshot guesswork. Both are documented at docs.driftstack.dev/api/sessions.

  6. self-hosted

    Self-hosted: sessions no longer require a proxy

    On self-hosted deployments, sessions reach the internet from your own machine — so requiring a proxy on every session-create made no sense there. The new SESSION_PROXY_REQUIRED environment variable makes the egress safeguard explicit: leave it unset to keep today's automatic behavior (a proxy is required whenever a proxy system — an egress backend — is connected, which is how our cloud runs), set false on self-hosted boxes to create sessions proxy-free, or true to force-require. One env var, no code change.

  7. launch

    Rate-limit caps now visible on the dashboard

    The /usage page gained a Rate limits card showing every request allowance ('token bucket') your account draws from — how many requests it holds (capacity), how fast the allowance refills (refill rate), and whether the value is your tier default or a staff-granted override (with the date the override automatically expires). Previously this data was only reachable by calling GET /v1/account/rate-limits from the SDK or curl. The endpoint stays available for programmatic reads.

  8. sdk

    IETF-standard RateLimit response headers

    Every rate-limited response now carries the IETF draft-standard ratelimit-limit / ratelimit-remaining / ratelimit-reset headers alongside the existing x-ratelimit-* set, so gateways and generic client libraries that read the un-prefixed names work out of the box. One semantic to note: ratelimit-reset is relative seconds-from-now per the draft, while x-ratelimit-reset stays an absolute unix timestamp. Purely additive — the x- set is unchanged and remains canonical. Details at docs.driftstack.dev/reference/rate-limits.

  9. docs

    Error reference site: every API error explained at errors.driftstack.dev

    Every Driftstack API error is an RFC 9457 problem+json body whose type URI now resolves to a live explainer page at errors.driftstack.dev — 32 problem types, each with what it means, how to fix it, and Related links to sibling errors (e.g. invalid-key → revoked-key / expired-key). The index groups errors by HTTP status class. Hit an error in production, click the type URL in the response, land on the fix.

  10. launch

    AI agent sessions: resume after a solved challenge + key-press actions

    Two agent-session upgrades. POST /v1/agent-sessions/{id}/resume lets you resume a paused agent run after a bot-challenge is resolved (pass the challenge_id from the session.challenge_detected webhook, or call it bare for a manual resume) — available in all three SDKs as resume()/Resume(). And the agent intent vocabulary gained press: the agent can now press a key (Enter to submit a form, Escape to dismiss a dialog) instead of only typing text. Both are additive; existing integrations are unaffected.

  11. security

    MFA sign-in on the web dashboard

    Accounts with two-factor enabled can now complete sign-in directly on app.driftstack.dev — the login page gained the authenticator-code step (with a recovery-code fallback for a lost device). Previously MFA-enrolled accounts had to sign in via the API.

  12. pricing

    Manual-ladder plans renamed: Personal, Team, Agency

    The three Manual-ladder plans now have clearer names — Personal (formerly Solo Manual), Team (formerly Team Manual), and Agency (formerly Agency Manual) — so the personal-vs-team distinction reads at a glance. Prices, profile counts, concurrent caps, and the underlying tier identifiers are unchanged: this is a display-name change only, so existing subscriptions and API tier ids (solo_manual / team_manual / agency_manual) are unaffected. The API ladder (API Starter / Builder / Scale) and Enterprise keep their names.

  13. pricing

    Perpetual free tier replaces the one-time trial pack

    The entry tier is now a perpetual free tier: $0 forever, one persistent profile, one concurrent session, manual sessions up to 20 minutes each, driven from the desktop GUI client, no card required. It is manual-only — programmatic API/SDK access comes with the paid tiers. There is no expiry, no credit to run out, and no usage metering. This replaces the previous one-time $2.99 trial pack entirely.

  14. pricing

    Crypto checkout is live via NowPayments

    The crypto payment option (the crypto rail) we postponed at launch is now live. Self-serve paid tiers ($79/mo and up) can pay with cryptocurrency (BTC, LTC, USDT, USDC, ETH, XMR) through NowPayments — open the crypto checkout from the billing dashboard, send the displayed amount, and the order moves pending → confirming → paid as on-chain confirmations land. crypto.order.paid and crypto.order.failed are emitted and subscribable via POST /v1/webhooks. Stripe remains the default way to pay (the default rail); Enterprise pays by bank wire. Crypto payments are non-refundable. Full reference at docs.driftstack.dev/api/billing-crypto.

  15. launch

    Account notification stream (SSE) — cost / incident / audit / session events

    Your account now has a single live event feed — real-time alerts your code or the desktop app can listen to — via the new GET /v1/account/me/notifications Server-Sent Events (SSE) endpoint. Four kinds in v0: cost.threshold_alert (fires on tier-spend transitions; warn / critical / resolved), incident.broadcast (customer-visible status incidents with minor / major / outage severity), audit.high_severity (selective republish for high-severity audit actions like api_key.revoked / byok_anthropic.key_set / team.member_removed), and session.errored (driver-terminal errors before customer destroy). Each event is labelled by kind (the SSE event: header), so code can listen for only the kinds it cares about — EventSource.addEventListener('cost.threshold_alert', ...). The desktop GUI client ships with the wired panel: subscribeNotifications + useNotifications hook + NotificationToastStack overlay component already mounted at the App shell. First version: if the connection drops it reconnects itself after ~3 seconds (native EventSource auto-reconnect), but events sent while you were disconnected aren't replayed yet (in-memory bus, no Last-Event-ID resume). Full reference at docs.driftstack.dev/api/account-notifications.

  16. launch

    Antidetect-browser-style profile launch (one-shot)

    POST /v1/sessions now accepts an optional profile_id field; cross-account profile_id returns 404 (anti-enumeration). New POST /v1/profiles/:id/launch wraps the sessions.create path into a single round-trip — server inherits the profile's archetype, stamps {profile_id, profile_name} into session metadata, and bumps the profile's last_used_at fire-and-forget. The dashboard /profiles page gains a per-row Launch primary CTA placed before Clone/Export/Snapshot/Delete; the desktop GUI client already exposed Launch since the earlier antidetect-browser hub restructure. SDK helpers shipped in all three languages: client.profiles.launch(id, body?) in TypeScript + Python (sync + async); ProfilesResource.Launch(ctx, profileID, body) in Go. Full reference at docs.driftstack.dev/api/profiles#launch.

  17. launch

    Live video for agent sessions (LiveKit WebRTC)

    Every Mac in the Driftstack fleet now runs its own LiveKit server; agent sessions publish their browser video stream into a per-session room. POST /v1/agent-sessions/{id}/livekit-token mints a 24-hour subscriber JWT; session-create auto-populates the same join info inline on the response so clients connect immediately. The desktop GUI client gains AgentSessionPanel (livekit-client subscriber) + LivekitConnectionBadge (live/reconnecting/error state) + DataChannel input forwarding (keyboard + mouse → Quartz CGEvents on the Mac) + dev-mode RTT measurement. Full reference at docs.driftstack.dev/api/agent-sessions.

  18. launch

    Agent sessions: natural-language automation with AI / manual / pair modes

    Tell any session what to do in plain language (a chat-style decompose-and-execute loop layered on top of any driver session). Send a user message ("open https://example.com and capture a screenshot"); the server's decomposer translates it into concrete browser steps — structured intents (navigate, interact, wait, capture) — and the runtime executes them. Three operational modes: AI (default — every message goes through decompose), manual (pass-through for clients driving via their own UI), and pair (interactive takeover state machine — AI drives by default, the customer can take over and hand back). Live transcript via Server-Sent Events on /v1/agent-sessions/{id}/transcript with Last-Event-ID resume. Full reference at docs.driftstack.dev/api/agent-sessions.

  19. launch

    BYOK Anthropic API keys + bundled-LLM rail for agent sessions

    Two ways to power the agent-session decomposer. BYOK — bring your own Anthropic key via PUT /v1/account/me/byok-anthropic-key (AES-256-GCM at rest; never echoed in responses; rotate / clear / test-connection endpoints all live; the dashboard form lands at v1.1). Bundled LLM — opt in via PATCH /v1/account/me/bundled-llm-settings and the decomposer falls back to a deployment-managed Anthropic budget (monthly soft cap surfaced in the dashboard read-only as used / remaining / refused; the opt-in toggle lands at v1.1). Per-request override via x-byok-anthropic-api-key on /v1/agent-sessions/{id}/message. Full references at docs.driftstack.dev/api/byok-anthropic and docs.driftstack.dev/api/bundled-llm.

  20. sdk

    Cross-SDK parity for typed pair-mode + LLM error fields

    TypeScript, Python, and Go SDKs gain PairModeStateInvalidTransitionError (carries from + transition for state-machine conflict recovery), ByokAnthropicRequiredError (502 when no BYOK + no bundled-LLM consent), BundledLlmBudgetExhaustedError (402 with reset_at), and BundledLlmConsentRequiredError (402 with consent_url). isRetryable() returns the same boolean across all three languages. Full reference at docs.driftstack.dev/reference/errors.

  21. launch

    Sign in with Google or GitHub

    One-click sign-in + signup with Google or GitHub now live on /login and /signup. If the email already has a password account, we first send that address a confirmation email (single-use link, valid 60 minutes) — so the email Google or GitHub supplies (the identity provider, IDP) is proven to be yours before the two accounts are merged. Revoked IDP links surface a "re-link or sign in with password" prompt instead of silently failing. Avatar + display name pull from the first IDP linked and become user-overridable from /settings.

  22. launch

    Profile snapshots: immutable point-in-time copies

    Capture a snapshot of any saved profile from /profiles → Snapshot. Snapshots are frozen — the source profile keeps evolving but the snapshot does not. List snapshots per-profile or across the whole account, restore any snapshot into a new profile (tier cap and name uniqueness checked the same way as profile creation), or delete one when you no longer need it. Full reference at docs.driftstack.dev/api/profiles.

  23. launch

    Account region preference (US / EU / APAC)

    Set a stated infrastructure region preference from /settings → Region. The selector is informational for v1 — Driftstack runs on EU-jurisdiction infrastructure for every account today (full sub-processor list at /trust/sub-processors). Recording your preference now lets us route accounts to the matching region automatically once the multi-region rollout lands; nothing about your data location changes when you set it.

  24. security

    Two-factor authentication (TOTP) is live

    Optional TOTP-based two-factor on every account. Enroll from /settings → Two-factor authentication: scan the QR with any standard authenticator app, confirm the 6-digit code, and store your 10 single-use recovery codes. Sign-in then issues a challenge token instead of a session; the dashboard exchanges it for a session after the second factor lands. Disabling MFA requires a fresh second-factor proof (15-minute step-up window). Recovery codes can be regenerated at any time. Full reference at docs.driftstack.dev/api/mfa.

  25. security

    Webhook signing-secret rotation with 24-hour grace

    Rotate any webhook endpoint's signing secret from /webhooks → Rotate secret. The new plaintext is shown once; the old secret stays valid for 24 hours so you can roll the new value across your verifier infrastructure without dropped deliveries. Driftstack dual-signs every outbound delivery during the grace inside the single x-driftstack-signature header (t=…,v1=<new>,v1=<old>); SDK verifiers in TypeScript, Python, and Go check every v1= entry and accept the delivery if either matches.

  26. security

    Active sign-ins list + per-session revoke

    See every browser session currently signed in to your account from /settings → Active sign-ins. Revoke any individual session, or sign out of every other session at once. IPs are intentionally omitted; user-agents are reduced to OS + browser bucket so the dashboard renders signal without surfacing fingerprintable strings.

  27. launch

    Account avatars + readable account handles

    Upload a 2 MB PNG/JPEG/WebP avatar from /settings (stored in private object storage; presigned read URLs). Set a lowercase a-z + 0-9 + hyphen account "slug" as a stable handle for support tickets, billing references, and audit entries. Per-vendor breakdown on /trust/sub-processors.

  28. launch

    Webhook test deliveries from the dashboard

    Click "Send test" on any webhook endpoint and Driftstack dispatches a synthetic test.ping event through the same delivery infrastructure as production events: HMAC-signed, retried on failure, audit-logged. Lets you confirm your handler signature-checks correctly before relying on it for real events. test.ping is delivery-side only — you can't subscribe to it.

  29. launch

    Profile cloning + audit-log filtering

    Clone any saved profile into a new copy from /profiles → Clone (server auto-derives "(copy)" / "(copy 2)" / ... naming). Filter the audit log by event type from /audit-log; the page now paginates with Load more across an unlimited backlog.

  30. security

    Team roles end-to-end: members can act on the owner's account (RBAC)

    A member of a team can scope any /v1/* request to the owner's resources by passing the X-Driftstack-Account header. Read endpoints accept both member and admin roles; write endpoints (POST/PATCH/DELETE/api-keys rotate) require admin role. Customer dashboard adds an "Acting as" picker in the sidebar; the active selection injects the header into every request automatically. Full reference at docs.driftstack.dev/api/team.

  31. sdk

    PlaywrightDriver added for self-hosted local development

    Set DRIVER=playwright + PLAYWRIGHT_BROWSER=webkit|chromium|firefox to run end-to-end smoke tests against a real browser without waiting for the WebKit fork to integrate. Dev/E2E only — production stays on DRIVER=webkit (the modified WebKit fork). Self-hosted Mac runbook at docs/runbooks/self-hosted-mac-local.md walks through the entire local-stack setup; npm run dev:all starts every surface concurrently.

  32. sdk

    Team RBAC, API key rotation, and webhook replay land in all three SDKs

    TypeScript, Python, and Go SDKs gain client.team.{invite,listMembers,listInvites,acceptInvite,removeMember}, client.apiKeys.rotate (24-hour grace on the prior key), and client.webhooks.replayDelivery (one delivery, fresh attempt, same idempotency key). Documentation at docs.driftstack.dev/api/team, /api/api-keys, /webhooks/replay.

  33. launch

    Public status page at status.driftstack.dev

    Live system status, incident history, and a 30-day SLA panel. Subscribe by email for incident notifications (double-opt-in, per-email unsubscribe link). The site is independent of api.driftstack.dev so a control-plane outage does not take the status page down.

  34. security

    GDPR Article 20 portability — full audit log export

    Customers can now export their complete account audit log as CSV or JSON via /v1/account/audit-log/export from the dashboard. 10K-row ceiling per export with cursor pagination beyond.

  35. sdk

    Pagination iterators land in TypeScript + Python SDKs

    sessions.iterate(), profiles.iterate(), and webhooks.iterateDeliveries() walk every page of a cursor-paginated list automatically. Sync + async parity in Python.

  36. pricing

    Two-ladder pricing live

    Manual ($79/mo Solo / $249/mo Team / $699/mo Agency) and API ($149/mo Starter / $499/mo Builder / $1,499/mo Scale + custom Enterprise). A free entry tier sits below both ladders.

  37. security

    Crypto payment rail deferred to post-launch

    Coinbase Commerce closed for non-US/Singapore merchants 2026-03-31. Stripe is sole launch payment rail (fiat-only). Crypto re-evaluates against actual transaction volume.

Want changelog entries delivered?

Email [email protected] to get added to the customer changelog list. Roughly one email every 2-4 weeks; only material changes (no internal-noise spam).

See docs →