Skip to content

Test and go live

View .md

Everything in Proof works in test mode, from the editor to agents and seals, so you can build and try your whole flow before any real user writes a word. This guide covers what’s different in test mode, then what to check before you switch to live keys.

Your platform has two sets of keys in the console: test (sk_test_…) and live (sk_live_…). Each sees only its own data. Users, documents, agents, seals and webhook endpoints made with a test key don’t exist for a live key, and the other way round.

In test mode:

  • The editor loads on http://localhost and http://127.0.0.1 on any port, as well as your embed origins.
  • Seals are marked. Codes start with T, such as TQ83KD0PA, and the seal page says Test seal at the top. Test seals don’t count toward billing.
  • Agents connect to a test address, https://mcp.proof.exalto.ai/acme/test, which uses the test consent URL you set in the console. It may be on localhost, since the person’s own browser opens it.
  • Webhooks go to test endpoints only. A test endpoint may be any URL, http://localhost:3000/proof/events included when Proof runs on your machine; otherwise point it at a tunnel such as cloudflared tunnel --url http://localhost:3000.

Test data is yours to clear: Delete test data in the console removes every test object at once.

Work through these with your live keys, in a staging copy of your app if you have one.

Load sk_live_… from your secret store or an environment variable, on the server only. It never belongs in the browser, in a mobile app, or in your repository. The browser only ever needs session tokens, which your server starts for one user and one document at a time.

Anyone holding your secret key can start a session as any of your users. That’s why seals name your platform as the one vouching for who wrote, and record which key was used.

List every origin your app serves the editor from, such as https://acme.com, under Embed origins. Leave out anything you don’t control. The editor won’t load anywhere else, which stops other sites from framing your users’ documents.

Set the live consent URL under Agents, or with PATCH /v1/platform and a live key, and connect a real agent to your live address, https://mcp.proof.exalto.ai/acme, from start to finish. See Connect agents.

Add the live endpoint, which must be https, and store its whsec_… secret apart from the test one. Check your server answers 2xx to a real event, such as a comment in a live document. See Send notifications.

Seal pages name your platform as where the text was written, which vouches for who wrote it. Make sure the name under Platform is the one your users know.

Rolling a key gives you a new one while the old one keeps working for a time you choose, up to seven days, so you can deploy the new key without downtime:

  1. In the console, choose Roll key and pick how long the old key keeps working.
  2. Deploy the new key.
  3. Check the console shows no recent requests with the old key, then expire it.

If a key may have leaked, choose Revoke now instead. Every request with it stops at once. Seals record the ids of the keys that started their writing sessions (attested_by.key_ids), so you can find every seal a leaked key had a hand in.

The API doesn’t limit requests yet. Even so, start one session per page load rather than one per action, and call users.upsert only when starting sessions or when a profile changes. When limits come, a request over them will get 429 with a Retry-After header, which the Node SDK already waits for and retries.

In the editor, people’s edits always go first, and each agent request gets a short slice of work at a time per document, so one busy agent never slows anyone’s typing.

Every error has a type and a code, so your code can branch on them:

try {
await proof.sessions.create({ user: "usr_9Tb3Wc1X", document: "doc_8Hq2Lm4R" });
} catch (error) {
if (error.type === "permission" && error.code === "no_access") showNoAccess();
else throw error;
}

The API overview lists every type.