---
title: "The write key was rejected"
description: "What \"writeKey is not a write key\" and a 401 invalid_write_key mean, and how to get the right key into your build."
canonical: "https://www.togohq.ai/docs/troubleshooting/write-key"
applies_to: "@togohq/sdk-browser 1.x, @togohq/sdk-node 1.x"
updated: "2026-11-03T00:00:00Z"
---

# The write key was rejected

What "writeKey is not a write key" and a 401 invalid_write_key mean, and how to get the right key into your build.

## What you see

In the browser console or your server log, one of:

```text
writeKey is not a write key (togo_pkt_… or togo_pkl_…). Check for an unsubstituted environment variable. No events will be captured.
writeKey is a SECRET key, not a write key. …
… the write key was rejected (401). No events will be captured on this page. …
```

or, from the ingest endpoint, a `401` with `missing_write_key` or `invalid_write_key`.

## The usual causes

1. **The environment variable did not reach the build.** The most common one. The value is empty
   or still the literal `process.env.…` text. Frameworks only ship variables with their public
   prefix to the browser — `NEXT_PUBLIC_` in Next.js, `VITE_` in Vite — and only those set when the
   build ran. Set it in your hosting provider's settings for the right environment, then rebuild.
2. **A secret was pasted where the write key belongs.** Togo write keys start with `togo_pkt_`
   (test) or `togo_pkl_` (live). Anything else is not one — and if a secret key has shipped in a
   browser bundle, rotate it.
3. **The key was revoked.** A revoked key is refused. Find the project's current keys in its
   **Settings** in [app.togohq.ai](https://app.togohq.ai), or ask your agent to call
   `list_projects`.
4. **The key was created moments ago.** A new key can take a short while to be accepted
   everywhere. The browser SDK keeps queued events on the device and retries them on the next page
   load, so reload once.

## What happens to events meanwhile

The browser SDK stops sending for the rest of the page, keeps every `track()` call returning
normally, and keeps the events it had already queued for the next page load. Nothing is sent
under a key that was refused.

## Check the fix

Rebuild, reload, and send one event with the test key: it should appear in **Events → Live View**
within seconds ([Check that events arrive](/docs/verify)).
