Skip to guide
Beluga Developer guide

Beluga developer guide

Connect your website. Keep your setup clear.

Beluga receives enquiries from the website you already have and gives your team a private place to review them. Use these guides to connect a website, connect an AI agent, or fix a setup issue.

Quick start

What you need before you begin

  1. A Beluga website entry. A workspace owner or admin adds the website in the Beluga dashboard.
  2. A private site key. In Websites, open the website’s Integration setup. Copy the key once and store it in your hosting provider’s secret settings. Replacing a key invalidates the old one.
  3. A server-side connection. The website’s server or platform function sends the enquiry to Beluga after the site has validated it.
  4. A Preview test. Test with Preview settings and an approved test inbox before enabling Production.

A Beluga site key identifies one website. It is not a CMS login, an admin token, or a key for reading the Beluga Inbox.

Website integration

Connect a website

Beluga’s website connection is server to server. Keep the Beluga key on the server; do not put it in browser JavaScript, page source, a public environment variable, or a repository.

  1. Keep your current form validation and server-verified bot protection.
  2. After those checks pass, send the approved fields from a server endpoint to Beluga.
  3. Show success only after Beluga confirms it saved the submission and any required visitor confirmation.
Server-side JavaScript example
const response = await fetch("https://api.usebeluga.app/v1/submissions", {
  method: "POST",
  redirect: "manual",
  headers: {
    Authorization: `Bearer ${env.BELUGA_SITE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": requestId,
    "Beluga-Environment": "preview",
  },
  body: JSON.stringify({
    email: form.email,
    name: form.name,
    message: form.message,
    form_id: "contact",
  }),
});

const receipt = await response.json();
if (!response.ok || receipt.saved !== true) {
  throw new Error(receipt.error || "Beluga did not confirm the submission.");
}

Only the email field is required. Beluga also accepts name, phone, message, a form ID and extra fields. The complete JSON request must be no larger than 32 KiB. See API basics for response codes.

How-to · Astro and Cloudflare Pages

Set up a Cloudflare Pages site

Use a Pages Function or another server endpoint to forward submissions. A static form cannot safely hold the Beluga site key by itself.

  1. In Beluga, open your workspace, then Websites → your website → Integration setup. Copy the Preview site key.
  2. In Cloudflare, open your Pages project’s Settings → Variables and Secrets. Add BELUGA_SITE_KEY as an encrypted secret for Preview.
  3. In the Pages Function, read the key from the server environment and call the Beluga endpoint after existing validation and Turnstile Siteverify checks succeed.
  4. Allow the Preview hostname in Turnstile, deploy a Preview build, and submit one clearly identified test enquiry to an inbox you control.
  5. After Preview passes, configure the Production key and hostnames, check notification and confirmation settings, then deploy and verify Production.

The Turnstile site key may be public on the page. Its secret belongs in the server environment and the token must be verified by the server. A visible “Verification failed” message means to check that verification path, hostname and matching environment secrets.

AI agent connection

Connect an AI agent with MCP

Beluga provides a remote MCP server over Streamable HTTP. It uses the same site key as a website integration; it does not use GitHub OAuth or a CMS account.

Server URLhttps://api.usebeluga.app/mcp
Authentication headerAuthorization: Bearer <BELUGA_SITE_KEY>
TransportStreamable HTTP

In the Beluga dashboard, go to your workspace → Websites → select the website → Integration setup → Connect an agent. Store the displayed key in the MCP client’s private secret or header settings. Client configuration screens differ, but the server URL and header above stay the same.

Generic remote MCP configuration
{
  "url": "https://api.usebeluga.app/mcp",
  "headers": {
    "Authorization": "Bearer ${BELUGA_SITE_KEY}"
  }
}

This is the connection shape, not a universal client config file. Use your MCP client’s documented secret-variable syntax. Do not paste the real key into shared prompts, source files or public settings.

Tools the agent can use

get_site_setup
Checks the connection and returns setup details for the authenticated website. It does not return credentials or submissions. This is the safe connection test.
submit_enquiry
Creates a real enquiry for that website. It requires a payload, an idempotency key, an environment (preview or production) and a confirmation choice.

The site key only submits enquiries for one website. MCP cannot read or search the Inbox, rotate keys, change email settings, edit the CMS, or access a repository or Cloudflare account.

API basics

Submission endpoint and responses

Method and URLPOST https://api.usebeluga.app/v1/submissions
Required headersAuthorization · Content-Type · Idempotency-Key
Environment headerBeluga-Environment: preview | production

Send a JSON object containing an email and any form fields you want to preserve. Make the request from your server; browser submissions are not enabled.

Response What it means What to do
201 New enquiry saved Show success after checking the receipt.
200 Same request already saved Use the original receipt; this is a safe retry.
400, 415, 422 Request or fields are invalid Fix the request before retrying.
401 Site key is missing or invalid Check the private server secret.
409 Idempotency key reused with changed data Investigate; do not retry with a new payload under that key.
413 Request is too large Keep the JSON body under 32 KiB.
429 Rate limit reached Wait for Retry-After, then retry the same request.
503 or timeout Completion is unconfirmed Keep the form values and retry with the same key and payload.

A 503 can happen after the enquiry has been saved if a configured notification is still pending. Idempotency makes a retry safe.

Email delivery

Restaurant notifications and visitor confirmations

Restaurant notifications and visitor confirmations are separate settings for each website and environment. Owners and admins manage them in the Beluga dashboard. An empty notification recipient list disables those emails while Beluga can still save submissions.

  • Send Beluga-Environment: preview or production so the right recipients and settings apply.
  • To require a Beluga visitor confirmation, send Beluga-Confirmation: required. The website should show success only when the response confirms both saving and sending.
  • Visitor confirmations require an enabled setting and a verified sending domain. A key for website submissions cannot change email settings.
  • A provider accepting an email is not the same as proof it reached the recipient’s inbox. Check a real approved test address during setup.

Troubleshooting

Common setup problems

Turnstile says “Verification failed”

Check that the server verifies the token with Siteverify, that the hostname is allowed for the correct site key, and that the secret is set in the environment serving this build. Showing the widget is not enough: the server must verify its token.

Beluga returns 401

Check the Authorization: Bearer … header and the secret named BELUGA_SITE_KEY. If a key was replaced in Beluga, update the hosting secret too; replacement immediately invalidates the old key.

Beluga returns 409

The same idempotency key was already used for different request data or settings. Keep a key stable for retries of one enquiry; create a new key only for a genuinely new enquiry.

Beluga returns 429

Wait for the Retry-After response header. Then retry the identical payload with the same idempotency key.

Beluga returns 503 or the form times out

Do not discard the form values or claim success. Retry with the same key and payload. If notifications or a required confirmation are configured, check those settings and their delivery status.

The MCP client cannot connect

Use https://api.usebeluga.app/mcp, choose the client’s remote Streamable HTTP option, and add the site key as a private Bearer header. Browser-only MCP transports are not supported. Call get_site_setup before trying a submission.

The enquiry saved but an email did not arrive

Check the correct environment’s recipient and confirmation settings, then inspect provider delivery and the recipient’s spam folder. Beluga’s saved receipt and email delivery have separate outcomes.

Still stuck? Open Beluga and ask a workspace owner or admin to check the website’s integration settings.