# Keys & secrets

Keep the API keys your app uses as secrets or public values, out of your code and the chat. Before anything goes live, each publish checks your site for your secrets.

Your app may need keys to use other services, like Stripe for payments, Resend for email or OpenAI for AI features. **Keys & secrets** is where those keys live. Your app's code reads each one by its name, so the value never has to go in a file or a message.

## Is it a secret or a public value?

| Kind         | Who can read the value                                                       | Names                                                      | Example                       |
| ------------ | ---------------------------------------------------------------------------- | ---------------------------------------------------------- | ----------------------------- |
| Secret       | Only your app's server                                                       | Can't start with `VITE_`                                   | `STRIPE_SECRET_KEY`           |
| Public value | Anyone who opens your app, because it's built into the pages people download | Start with `VITE_` so your app's browser code can see them | `VITE_STRIPE_PUBLISHABLE_KEY` |

If a service calls something secret, private or a password, keep it as a secret. Only use a public value for a key the service says is safe to show, like Stripe's publishable key.

## Before you start

- To add, change or reveal a secret, you'll need Admin access to the project. Builders can see the names and the public values. Viewers can't open Keys & secrets.
- Use a test key while you build, since your preview and your published site use the same keys.

## Add a key

1. Open **Tools**, then select **Keys & secrets** under Connect.
2. Select **Add secret**, or **Add public value**.
3. Enter the name the service or WebDIY gave you, like `RESEND_API_KEY`, and paste in the value.
4. Save the key.

   > **What you should see:** The key shows up in its list. Your app restarts in the Preview and picks up the new value within a few seconds.
5. Let WebDIY know in the chat which key you added and what it's for. For example: "I've added RESEND\_API\_KEY. Send a confirmation email when someone books."

Names can use letters, digits and `_`, can't start with a digit and can be up to 128 characters long. Names that start with `WEBDIY_` are kept for WebDIY. A project can hold up to 100 secrets.

> **Warning:** Because the Preview and your published site share keys, a live payment key charges real cards in the Preview. Use test keys while you build, and switch to live keys once you're ready to take real payments.

## Why keys don't belong in your code or the chat

Anyone who opens your app can read the code that runs in their browser, and every file is kept in your project's saved versions and in Download Code. So a key written into a file can leak.

- Don't paste a key into the chat. Add it in Keys & secrets instead, then tell WebDIY its name.
- If a key has already been pasted or written into a file, add it in Keys & secrets, then make a new key at the service and replace the value, because the old one has been seen.
- Stored values are hidden. In the chat, the terminal and the logs, a secret's value shows as `[redacted:NAME]`, even if your app prints it.

> **Note:** Local key files named `.env.local`, `.dev.vars` or `.env.<name>.local` are never saved in your project's versions or in Download Code. A plain `.env` file is saved like any other file. If the **Security** screen finds a key file in your project, it offers **Move to Keys & secrets**.

## How publishing checks for secrets

Every publish checks the built site for the value of each of your secrets. If it finds one, the release is **Blocked** before it goes live, and nothing changes on your live site. The release tells you which secret it found, and in which file.

- Public values aren't checked, because they're meant to be public.
- The check only knows about keys stored in Keys & secrets. It can't find a key that's written into your code and never stored, which is one more reason to store every key.

See [Publish your app](https://web.diy/docs/publish/publish-your-app#when-a-publish-is-blocked-or-fails).

## Reveal, edit or delete a key

- **Reveal** shows a secret's value to project Admins, and each reveal is recorded in the project's audit log.
- The menu (**⋯**) on a key has **Edit…**, **Copy name** and **Delete…**.

Keys under **From Database** are set by your app's database. WebDIY looks after them, so you don't need to change them.

## Services with ready-made key names

Open **Tools**, then **Integrations**, to see 12 services and the keys each one needs: Stripe, Resend, OpenAI, Claude, Slack, Google Sheets, Google Calendar, Google Drive, Notion, Airtable, HubSpot and Discord. A service shows **Connected** once every key it needs has a value. From there, WebDIY writes the code that uses it.
