Spectodocs

SDK reference

The script tag and the npm package (@spectosh/browser) share one recorder. This page lists everything you can configure and call.

Recording starts at once

The recorder captures from the moment it starts: errors, console output, requests and the page itself are held in memory while the project's settings load (one request, cached at the edge), then filtered by those settings and sent — or dropped, if the project is paused, sampled out or doesn't know the key. So start it as early as you can: the script tag first in <head>, startRecording() in your entry file before the app renders, or SpectoProvider at the root.

Keys know where they live

A key is all an install needs. pk_… belongs to the hosted service; a project in another region or on a self-hosted instance has a key that says so — pk_…@eu.specto.sh, pk_…@replay.example.com — and its Install page shows it that way. The settings request also confirms the key: a host that doesn't know it records nothing, and the console says why, so a key without its host never sends data to the wrong place.

Script tag

<script src="https://specto.sh/specto.js" data-key="pk_your_key" defer></script>
AttributeValuesEffect
data-keypk_…Required. The project’s publishable key (Settings → Install).
data-hosthostWhere the project lives. Defaults to the host that served the script (or the key's own @host).
data-endpointURLFull ingest URL (legacy; overrides data-host).
data-privacystrictMask all text, not only inputs; drop console text and the query strings of recorded URLs.
data-sample-rate0–1Fraction of sessions recorded, decided once per session.
data-consentrequiredRecord and store nothing until Specto.consent(true).
data-consolefalseSkip console capture.
data-detailsfalseSkip network request details (method, URL and status are still kept).
data-feedbacktrueAdd a floating feedback button wired to your inbox.
data-tracestrueSend a W3C traceparent header with same-origin requests, so backend traces join the replay.
data-trace-originsoriginsMore origins for that header, comma-separated (their CORS must allow it).

window.Specto

CallDoes
Specto.identify(id, traits)Attach your user id (up to 256 characters) and up to 25 flat traits (string, number or boolean; strings up to 256 characters) to the session. Use an opaque id rather than an email where you can.
Specto.track(name, props)Add a custom event to the timeline. String props are scrubbed and cut to 500 characters.
Specto.captureError(error)Report an error your app caught itself — it shows on the timeline and in Issues like an uncaught one.
Specto.consent(true | false)Consent mode: true starts recording (and remembers it); false stops and forgets it.
Specto.optOut()Stop now and never record this browser again.
Specto.optIn()Undo optOut() and start again.
Specto.sessionUrl()A link to this session’s replay — handy in support tickets.
Specto.stop()Stop capturing and restore everything the recorder patched.
Specto.sessionThe active recorder, or undefined when nothing is recording.
Specto.init(options)Start by hand when the script tag has no data-key (same options as below, plus feedback).

npm package

npm install @spectosh/browser
import { startRecording, identify, track } from '@spectosh/browser'

// in your entry file, before the app renders
const rec = startRecording({ key: 'pk_your_key' })
ExportDoes
startRecording(options)Start recording; returns the recorder. Calling it again while recording returns the same recorder.
identify(id, traits)As Specto.identify.
track(name, props)As Specto.track.
captureError(error, info)As Specto.captureError; info.componentStack rides along.
sessionUrl()As Specto.sessionUrl.
stopRecording()Stop the active recorder.
grantConsent()Consent mode: remember consent and start with the last options.
revokeConsent()Forget consent and stop.
optOut() / optIn()As on window.Specto.
hasConsent() / isOptedOut()Read the stored choice.
scrubText(text)The redaction the SDK applies to console lines and errors (emails, tokens, card-like numbers).
SDK_VERSIONThe package version.

TypeScript types ship with the package — for @spectosh/browser and @spectosh/browser/react.

Options

OptionDefaultMeaning
key—Required. pk_…, or pk_…@host for a project in another region or on a self-hosted instance (copy it from the Install page).
hostthe key'sWhere the project lives, overriding the key's — e.g. your own domain proxying to Specto.
endpoint—Full ingest URL (legacy; overrides host).
privacy'balanced''strict' masks all text, drops console text and keeps only the path of recorded URLs.
sampleRate1Fraction of sessions recorded.
consent'granted''required' waits for consent.
consoletrueCapture console output.
networkDetailstrueCapture request details (timing, sizes, a few response headers).
configUrlthe host's /api/sdk/configWhere the project's settings are fetched; false skips it (and the key check).
tracesfalseSend a traceparent header with same-origin requests (backend traces).
traceOrigins[]More origins to send it to.

The recorder

PropertyMeaning
rec.sessionIdThe current session id.
rec.sessionUrl()Link to the replay.
rec.flushNow()Upload what is buffered right away.
rec.stop()Stop and restore everything the recorder patched.
rec.disabled, rec.reasonSet when nothing is being recorded: dnt, opted-out, consent-required, not-sampled, recording-disabled, unknown-key (the host has no such project), unconfirmed (the hosted service couldn't be asked about a key without a host) or stopped.

React

@spectosh/browser/react starts the recorder from your app's root, catches the errors React swallows, and gives components a hook. React is a peer dependency (17 and later).

import { createRoot } from 'react-dom/client'
import { SpectoProvider, spectoErrorHandler } from '@spectosh/browser/react'

createRoot(document.getElementById('root'), {
  onCaughtError: spectoErrorHandler(),    // React 19
  onUncaughtError: spectoErrorHandler(),
}).render(
  <SpectoProvider apiKey="pk_your_key" user={user}>
    <App />
  </SpectoProvider>
)
ExportDoes
<SpectoProvider apiKey user …options>Starts recording during its first render — before any component's effects run, so the first requests of a page load are captured. Once per page: StrictMode, remounts and hot reloads reuse the running recorder, and unmounting never stops it. On the server it renders its children and nothing else. user ({ id, …traits }) is identified whenever it changes; every other prop is a startRecording option.
useSpecto()identify, track, captureError, sessionUrl, stop and the consent controls.
<SpectoErrorBoundary fallback>An error boundary that reports what it catches with the component stack. fallback is an element or ({ error, reset }) => …. The way to catch render errors on React 18.
spectoErrorHandler(next?)For React 19's createRoot options onCaughtError, onUncaughtError and onRecoverableError: reports the error, then calls next — or logs it, as React does by default.

An error reported by both a boundary and a root handler is recorded once. Next.js, Remix and the other frameworks: framework guides.

Project settings win when stricter

At start the SDK fetches the project's settings (Settings → Privacy, cached at the edge) — the same request confirms the key. The stricter of those and your options applies: the dashboard can pause recording, force strict privacy, turn off console or request details, or lower the sample rate without a redeploy. Ingest enforces the same settings server-side.

Sessions, storage and limits

A session continues across page loads in the same tab (each load is recorded as a navigation, so funnels see every page), ends after 30 minutes without interaction and rotates after 4 hours. Batches upload every few seconds from a Web Worker, are numbered so retries never duplicate data, and the tail goes out with sendBeacon when the page is hidden. A full DOM checkpoint every 5 minutes keeps a lost batch from ruining a replay.

StoredWhereWhy
the sessionsessionStoragecontinue the session across page loads in this tab
specto-vidlocalStoragea random visitor id for retention cohorts (no fingerprinting)
specto-consentlocalStoragethe visitor’s consent, in consent mode
specto-optoutlocalStoragethe visitor opted out

No cookies. Visitors with Do-Not-Track or Global Privacy Control turned on are never recorded. More: privacy controls, consent banners, troubleshooting.