Integration guide

Add a ContactFire form to any site

Two ways to integrate. The JS snippet takes 30 seconds. The plain HTML form gives you full control over markup and styling.

Two integration approaches

JS embed snippet

Paste one <script> tag. ContactFire renders the full form for you, styled and ready. Best for most sites.

  • No custom HTML needed
  • Form updates without re-deploying your site
  • Auto-handles spam protection
Plain HTML form

Write a standard <form> tag and point the action at ContactFire. Full control over markup and CSS.

  • Use your own CSS
  • Works with any backend or static site
  • Needs a redirect URL for success handling

Get your embed token

Both approaches need an embed token. This is a public-safe credential: it is fine to ship it in client-side code.

  1. Log in to my.contactfire.com
  2. Go to Embed Tokens in the left sidebar
  3. Click Create token
  4. Give it a name (e.g., "My website") and optionally restrict it to your domain
  5. Copy the token: it starts with cf_embed_
Embed tokens (cf_embed_...) are safe in frontend code. API keys (cf_api_...) are for server-side use only. Learn the difference.

Option 1: JS embed snippet

Add two lines of HTML anywhere on your page. ContactFire loads the form asynchronously and renders it inside the #cf-form div.

HTML
<!-- Place this where you want the form to appear -->
<div id="cf-form"></div>

<!-- Load the ContactFire embed script -->
<script
  src="https://my.contactfire.com/api/embed-script"
  data-token="cf_embed_your_token_here"
  data-form-id="your_form_public_id"
  async
></script>
Script attributes
AttributeRequiredDescription
data-tokenYesYour embed token (starts with cf_embed_)
data-form-idYes12-character public form ID from Form Studio
asyncRecommendedLoad without blocking page render
Find your Form ID in Form Studio under Settings → Embed Code. It looks like abc123xyz789.

Option 2: Plain HTML form

Point a standard HTML form at the ContactFire submission endpoint. Use your own markup and CSS. Works on any static site, WordPress, Webflow, or server-rendered app.

HTML
<!-- Load the ContactFire embed script (once per page) -->
<script src="https://my.contactfire.com/api/embed-script" async></script>

<!-- Add data-contactfire-token to your form: the script handles submission -->
<form data-contactfire-token="cf_embed_your_token_here">

  <label for="name">Name</label>
  <input type="text" id="name" name="name" required />

  <label for="email">Email</label>
  <input type="email" id="email" name="email" required />

  <label for="message">Message</label>
  <textarea id="message" name="message" rows="4" required></textarea>

  <button type="submit">Send message</button>
</form>
How it works

When the embed script is loaded, it automatically intercepts the submit event of any form with a data-contactfire-token attribute, converts the field values to JSON, and posts them to ContactFire: no page reload required.

Find your embed token in your dashboard under Embed Tokens. It starts with cf_embed_.

Domain restrictions

Lock your embed token to specific domains so only your site can use it. This stops anyone else from submitting forms with your token.

  1. Go to Embed Tokens in your dashboard
  2. Edit your token
  3. Add your domain under Allowed domains (e.g., yoursite.com)
  4. Save: submissions from other origins are now rejected
Include both yoursite.com and www.yoursite.com if your site is accessible from both.

Handle responses with JavaScript

Submit via fetch to show an inline success message instead of a page redirect.

document.querySelector('#contact-form').addEventListener('submit', async (e) => {
  e.preventDefault();

  const form = e.target;
  const raw = new FormData(form);
  const formData = Object.fromEntries(raw.entries());

  try {
    const res = 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 }),
    });

    if (res.ok) {
      // Show your success message
      document.querySelector('#success').hidden = false;
      form.reset();
    } else {
      const err = await res.json();
      console.error('Submission failed:', err.error);
    }
  } catch (err) {
    console.error('Network error:', err);
  }
});
API response: success
{"message":"Form submission received successfully","submissionId":"abc123xyz","status":"accepted","usage":{"current":42,"limit":1000,"overage":0}}
API response: auth error
{"error":"No authentication token provided. Include X-API-Key header or X-Embed-Token header."}

Redirect after submit (Form Studio)

When using Form Studio (/api/public/forms/{formId}/submit), you can configure a redirect URL in the form's settings. After a successful submission the API returns a redirectUrl field in the response. The embed script follows it automatically.

For custom HTML forms using /api/form/submit, handle redirects in your JavaScript after receiving a successful response. The API does not perform HTTP redirects.

Custom fields

Every input name (except reserved names starting with _) becomes a field in the submission. Name your inputs to match how you want them to appear in the inbox.

<!-- These field names appear as-is in the ContactFire inbox -->
<input type="text"   name="full_name"    />
<input type="email"  name="work_email"   />
<input type="text"   name="company"      />
<select              name="budget_range" />
<textarea            name="project_brief" rows="5"></textarea>

Framework examples

React

import { useState } from 'react';

export default function ContactForm() {
  const [status, setStatus] = useState('idle');

  async function handleSubmit(e) {
    e.preventDefault();
    setStatus('loading');

    const raw = new FormData(e.target);
    const formData = Object.fromEntries(raw.entries());

    const res = 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 }),
    });

    setStatus(res.ok ? 'success' : 'error');
  }

  if (status === 'success') return <p>Message sent!</p>;

  return (
    <form onSubmit={handleSubmit}>
      <input name="name"    type="text"  required />
      <input name="email"   type="email" required />
      <textarea name="message" required />
      <button type="submit" disabled={status === 'loading'}>
        {status === 'loading' ? 'Sending…' : 'Send'}
      </button>
    </form>
  );
}

Astro

Download the pre-built Astro component from your dashboard: it includes Live Draft Saving and resume support out of the box.

---
// ContactFireForm.astro: download from Dashboard > Embed Code > Astro tab
import ContactFireForm from './ContactFireForm.astro';
---
<ContactFireForm token="cf_embed_your_token_here" formId="your_form_id" />
Get the Astro component file from Dashboard → Embed Code → Astro tab, or generate it from the API: GET /api/embed-code/{tokenId}?format=astro
Previous: Quick Start Next: Form Builder