Skip to main content
Your coding agent adds and wires the SDK during the setup. This page is for you or a developer who wants to know what the code does, or wants to change it later.
The SDK never blocks your app. If everydeck cannot be reached, your app works unchanged. If the address, the key or the manifest digest is missing, the SDK switches itself off and says so at start.

Packages

The SDK has no runtime dependencies.

Install

Your agent installs the exact version everydeck names, with your app’s package manager:
In a Supabase Edge Function or in Deno, import it with the version in the address:
If your tool only installs packages that are at least one day old, your agent gets the newest such version by itself.

The three settings every client needs

Where each key goes is on Going live.

Browser

Browser options

Only these options are documented. Leave out the ones you do not need. The web page also keeps up to 300 rejected events in the browser until the next visit. Turn that off with persist: false.

What the browser SDK captures without code

  • Unhandled errors and rejected promises.
  • Errors written with console.error.
  • Every failed request made with fetch or XMLHttpRequest, also outside a flow. To your own hosts: network errors, 4xx and 5xx. A 401 counts only while a person is signed in. To other hosts: only 5xx.
  • Visits and sign-ins, once you tell the SDK who is signed in.
  • Page speed. See Source maps and page speed.
It never sends request bodies, headers, form values, query strings, cookies or the page content.

People: setSubject and reset

Call setSubject where the browser learns who is signed in, and reset where the person signs out.
  • setSubject(null) while the session is still loading is fine. It is no sign-out.
  • A reload with the same person is no new sign-in.
  • Without setSubject, every visit stays anonymous and Live shows A visitor.
  • If your app does not call reset at sign-out, a new sign-in of the same person on the same device is not reported.
The person you set in the browser is a claim. Your server’s identity stays the source that counts.

Flows in the browser: actions

Wrap each user action you want to follow in action. Name it after the flow in your app map.
  • The SDK reports start, end and failed requests of the action. It never claims a business success by itself.
  • Use ctx.fetch for the requests of the action. For a data client like supabase-js, pass ctx.fetch as its global.fetch.
  • Non-2xx answers, network errors and timeouts inside an action count as a failure, even if your app catches them.
  • operationId and attemptId let browser and server share one run. A retry is a new attempt.

Expected answers

Some non-2xx answers are normal, like a 404 before a record exists. Declare them, so they open no case:
If your code throws after an expected answer, that throw counts as its own failure. Handle the expected answer inside the action instead. When your app wraps a failed response in its own error, pass it on: throw new Error(message, { cause: response }). Then everydeck knows it is the same failure.

A result that ends in the browser

If a flow ends in the browser, with no server and no database write in between, send the result from inside the action:
The app map must mark this signal with "source": "browser". everydeck accepts it from the public browser key only with this mark. A result from the server for the same run wins. If only the browser confirmed a fix, the case page and the protocol say so.

Requests that never answer

If a request of a flow waits 30 seconds without an answer, the SDK reports it as hung. It never cancels or changes your request. See Flows and journeys.

CORS

Inside an action, the SDK adds three headers to captured requests: x-everydeck-operation-id, x-everydeck-attempt-id and x-everydeck-session-id. A request to another origin then sends a CORS preflight. Your API must allow these headers in Access-Control-Allow-Headers. Or exclude the address with correlate: (url) => false: the request is still captured, only without the link to your server. Check this before you go live.

Screens in apps without URL routing

  • Expo Router: call everydeck.screen(pathname) with usePathname() on each change.
  • Apps without routes: call everydeck.screen("Checkout") with a fixed screen name. Never put a name, id or input into it.

Server

If your server already talks to Supabase with the service key, everydeckFromSupabase(…) reads these settings from your Supabase project instead. Then you set nothing at your host.

Server options

Results of flows: signal

Send a signal after your database committed the change:
  • The role of the step in your app map decides how a run ends, never the name of the signal.
  • Use the same run id as the browser. It comes in the request header x-everydeck-operation-id.
  • When a signal names a record, everydeck reads exactly that record again right after.

Errors

Your agent wires the central error path of your server, the place that turns an exception into a 500:
  • The error class is short, lowercase and stable, like type_error or http_500.
  • With exc, the SDK sends the stack and, for up to 5 frames in your own code, the line and 5 lines before and after. Libraries get no code lines.
  • The message must not contain personal data or secrets. The SDK also removes keys, tokens and e-mail addresses.
There are also one-line helpers that report every 500 and every unhandled exception of a request:
The setup does not add these one-line helpers by itself yet. Your agent wires the error path instead. Errors outside a request, like in a background job or at start, need your own everydeck.error(…).

Short-lived runtimes

In Edge Functions and serverless handlers, wait for the SDK before you answer:
false means the events were not delivered.

Payments

Send payment events from your server, after your app stored the change. Only a server key may report payments.
  • total is in the main unit of the currency. Divide cents by 100, except for currencies without decimals like JPY or IDR.
  • currency is an ISO 4217 code.
  • orderId (or checkoutId) is required and counts once per event, so a webhook that arrives twice is safe.
  • Without a person and an organization, the payment counts for nobody, and the SDK warns. In a webhook nobody is signed in: take them from what your app stored with the checkout.
See Money and AI costs.

AI calls

Wrap each AI client where your app creates it. The wrapper returns the same client.
For an AI API without such a client, report the numbers after each call:
everydeck never stores the prompt, the answer or your provider key.

Heartbeats

Every part of your app that must keep running sends a heartbeat. Without a number, the SDK uses 300 seconds:
A scheduled job sends its heartbeat at the end of each run that worked, with its id from the app map:
Heartbeats never count toward your monthly events. See App parts and heartbeats for schedules in SQL and GitHub Actions.

Messages and usage

  • everydeck.messageSent({ conversationType, conversationRef, senderRef, text, appHosts }) sends only metadata: a checksum of the text and whether it holds a phone number, a foreign link or a payment request. The text never leaves your app. See Moderation.
  • everydeck.usage(kind, type, ref) counts views, saves, contacts, impressions and clicks of a record. kind is view, save, contact, impression or click.
  • everydeck.search(group, results) counts searches per group, like an area. Never pass the search text.

Versions: release key “auto”

Let the SDK find the version of your app. Use releaseKey: "auto" on the server. In the browser, pass the value your server found, or resolve it at build time with resolveReleaseKey() if your app has no server (for example in Vite’s define). The rule:
  1. EVERYDECK_RELEASE_KEY, if it is set to something other than auto.
  2. Otherwise the commit of the deploy, from your host or CI (for example GITHUB_SHA, VERCEL_GIT_COMMIT_SHA, RENDER_GIT_COMMIT, CF_PAGES_COMMIT_SHA, COMMIT_REF, SOURCE_VERSION, CI_COMMIT_SHA), as git: and the first 12 characters.
  3. Otherwise your local git commit, with +dirty. and a short hash when there are uncommitted changes.
So a fix shows up as a new version after a restart. Do not set a fixed EVERYDECK_RELEASE_KEY. Keep your app’s runtime files, like logs, ignored by git, or they change the version.

Updating the SDK

Ask your agent to raise the versions to the ones everydeck names. Restart a running dev server afterwards, because it may still hold the old module. Never patch SDK files.

Limits in the SDK

The SDK keeps at most 500 events in memory and drops events over 8 KiB. What it drops arrives as a data gap. All values are on Limits and plans.