AI-generated app in the browser

WhatsApp in Bolt: database Secrets, a server function and a check before sending

Bolt generates and publishes apps from a conversation. Bolt's support documentation (read on 2026-11-11) describes the database Secrets tab: the value is available only to server functions, is not shown again after saving and is not written into the project files or the published site. That is the right vault for the ZapZap key.

Updated on

Why connect

You ask Bolt for a contact form, an orders panel or an appointment reminder. The part that talks to WhatsApp has to run on the server. The safest flow, and the one this example shows, is to check with POST /chat/check whether the number is on WhatsApp before sending, which avoids errors and lost sends. ZapZap connects numbers through an unofficial channel: WhatsApp may limit or block any number, so pacing, consent and warm-up matter. It costs R$15 per active number per month, prepaid, with no per-message fee, and you start with a welcome credit when you verify your phone, subject to the current campaign.

Step by step

  1. 1

    Connect a database to the project

    In the documentation, the Secrets tab requires a database connected to the project. Connect the database before continuing.

  2. 2

    Save the keys in Secrets

    Click the database icon in the top menu, open Secrets, and save ZAPZAP_API_KEY, ZAPZAP_API_SECRET and ZAPZAP_INSTANCE_ID. The name is case-sensitive. On an individual account only the owner sees the secrets; on a team account, the owner, co-owners and admins. Keys at Settings > API on app.zapzapapi.com.

  3. 3

    Ask for the server function

    Prompt: "Create a server function that receives number and text, calls ZapZap POST /chat/check with numbers: [number], and only if the number exists calls POST /send/text. Read ZAPZAP_API_KEY, ZAPZAP_API_SECRET and ZAPZAP_INSTANCE_ID from the secrets. The frontend only calls this function."

  4. 4

    Review what Bolt generated

    Look for three common mistakes: a key written into the code, a call made from a frontend component and a send without validating the number. Fix them by asking Bolt, and compare with the example on this page.

  5. 5

    Test with your own number and look at the instance status

    Call the function with your phone, check the response and query GET /{instanceId}/instance/status. If the instance is disconnected, reconnect by QR code in the dashboard.

Example

// Server function (Deno edge function): check the number first, then send. Secrets: ZAPZAP_API_KEY, ZAPZAP_API_SECRET, ZAPZAP_INSTANCE_ID
const BASE = "https://api.zapzapapi.com/api/v1/" + Deno.env.get("ZAPZAP_INSTANCE_ID");
const headers = {
  "Content-Type": "application/json",
  "x-api-key": Deno.env.get("ZAPZAP_API_KEY") ?? "",
  "x-api-secret": Deno.env.get("ZAPZAP_API_SECRET") ?? "",
};

Deno.serve(async (req: Request) => {
  const { number, text } = await req.json();
  const check = await fetch(BASE + "/chat/check", { method: "POST", headers, body: JSON.stringify({ numbers: [number] }) });
  if (!check.ok) return new Response("check failed: " + check.status, { status: 502 });
  const found = JSON.stringify(await check.json());
  if (!found.includes(number)) return new Response("number not found", { status: 404 });
  const send = await fetch(BASE + "/send/text", { method: "POST", headers, body: JSON.stringify({ number, text }) });
  return new Response(await send.text(), { status: send.status });
});

Illustrative. The exact fields and endpoints are in the documentation.

Why check the number before sending

POST /{instanceId}/chat/check takes numbers and tells you which are on WhatsApp. Sending only to numbers that exist reduces errors and keeps history clean. It is not a guarantee against blocking: the channel is unofficial and WhatsApp may limit numbers, so send only to people who have a relationship with you and keep a human pace.

Frequently asked questions

Where do I keep the key in Bolt?

In Secrets, through the database icon. According to Bolt's documentation (2026-11-11), the value is available only to server functions and does not go into the project files or the published site.

Can I call the API from a frontend component?

No. The key would sit in every visitor's browser. Call the server function and let only it talk to ZapZap.

Does Bolt's documentation cover incoming webhooks?

The page I read covers secrets. To receive messages, create another server function, register its URL with PUT /instances/{id}/webhook and validate the X-ZapZap-Signature.

Do I need a paid Bolt plan?

The documentation I read does not say; check Bolt's plans page.

What does ZapZap cost?

It costs R$15 per active number per month, prepaid, with no per-message fee, and you start with a welcome credit when you verify your phone, subject to the current campaign.

Start now

Create your account, connect a number in minutes and test the API with warm-up and anti-ban. R$15 per active number/month, prepaid, no lock-in.