Authentication

Embed tokens and API keys

ContactFire uses two token types so you never have to expose a secret in frontend code. The right token depends on where your submission code runs.

Two token types

Embed token
cf_embed_...
  • Public-safe: ship in HTML and JavaScript
  • Locked to allowed domains
  • Used by the JS embed snippet
  • Used by the Astro component
  • Used by plain HTML forms
API key
cf_api_...
  • Server-only: never put in frontend code
  • Used in x-api-key header
  • For server-to-server submissions
  • No domain restriction (server already trusted)

Which one to use

Your scenarioUse
Plain HTML form on a static siteEmbed token
JS embed snippet on any pageEmbed token
Astro componentEmbed token
React / Vue / Svelte frontendEmbed token
WordPress, Webflow, SquarespaceEmbed token
Next.js / Nuxt / Remix server actionAPI key
Node.js or Python backend scriptAPI key
Server-to-server form submissionAPI key

Embed tokens

Create an embed token

  1. In your dashboard, click Embed Tokens
  2. Click Create token
  3. Name it (e.g., "Main website" or "Contact page")
  4. Optionally set allowed domains
  5. Click Create
  6. Copy the full token starting with cf_embed_

Use an embed token

In the JS embed script attribute (recommended: the script handles submission automatically):

<script
  src="https://my.contactfire.com/api/embed-script"
  data-token="cf_embed_your_token_here"
  data-form-id="your_form_id"
  async
></script>

In a plain HTML form (add data-contactfire-token; embed script intercepts the submit):

<script src="https://my.contactfire.com/api/embed-script" async></script>

<form data-contactfire-token="cf_embed_your_token_here">
  <input type="text" name="name" />
  <input type="email" name="email" />
  <button type="submit">Send</button>
</form>

In a fetch request (send as JSON with X-Embed-Token header):

await fetch('https://my.contactfire.com/api/form/submit', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-Embed-Token': 'cf_embed_your_token_here',
  },
  body: JSON.stringify({
    formData: {
      name: 'Alice',
      email: 'alice@example.com',
    },
  }),
});

API keys

Never put an API key in frontend code. API keys appear in network requests and can be extracted from browser DevTools. If exposed, rotate it immediately.

Create an API key

  1. In your dashboard, click API Keys
  2. Click Create key
  3. Name it (e.g., "Backend integration")
  4. Click Create
  5. Copy the full key: it is only shown once

Use an API key

Send the key in the x-api-key header:

// Node.js example
const res = await fetch('https://my.contactfire.com/api/form/submit', {
  method: 'POST',
  headers: {
    'x-api-key': process.env.CONTACTFIRE_API_KEY, // cf_api_...
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    formData: {
      name: 'Alice',
      email: 'alice@example.com',
      message: 'Hello from the backend',
    },
  }),
});

const result = await res.json();
// { message: 'Form submission received successfully', submissionId: 'abc123xyz', status: 'accepted', usage: {...} }

Domain restrictions (embed tokens)

Restrict an embed token to specific domains. Submissions from unlisted origins are rejected with a 403 response.

Format
  • One domain per line: yoursite.com
  • Include www separately if needed: www.yoursite.com
  • Wildcard subdomains supported: *.yoursite.com
  • Leave blank to allow all origins (not recommended for production)

Recipient overrides

Both token types support custom notification recipients. Useful when different tokens are used for different departments or clients.

Recipient precedence (highest to lowest)
  1. Per-form notification recipients (Form Studio โ†’ Settings)
  2. Embed token recipient override
  3. API key recipient override
  4. Account notification email (Settings โ†’ Notifications)
  5. Account email

Rotating and revoking

Rotate (embed token)

Create a new token, update your site, then delete the old token. No downtime: both tokens are valid until the old one is deleted.

Revoke immediately

Delete a token from the dashboard to revoke it instantly. Submissions using that token are rejected immediately.

Previous: Chat widget Next: API Reference