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
<form
  action="https://my.contactfire.com/api/form/submit"
  method="POST"
>
  <!-- Required: your embed token -->
  <input type="hidden" name="_token" value="cf_embed_your_token_here" />

  <!-- Optional: redirect after successful submission -->
  <input type="hidden" name="_redirect" value="https://yoursite.com/thank-you" />

  <!-- Your form fields -->
  <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>
Reserved field names

These names control ContactFire behaviour. Use any other name for your data fields.

Field namePurpose
_tokenYour embed token — required
_redirectURL to redirect to after a successful submission
_honeypotHidden spam trap — leave empty (ContactFire adds this automatically for embedded forms)

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 data = new FormData(form);
  data.append('_token', 'cf_embed_your_token_here');

  try {
    const res = await fetch('https://my.contactfire.com/api/form/submit', {
      method: 'POST',
      body: data,
    });

    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.message);
    }
  } catch (err) {
    console.error('Network error:', err);
  }
});
API response — success
{"status":"success","message":"Submission received","submissionId":"abc123"}
API response — error
{"status":"error","message":"Invalid token","code":"INVALID_TOKEN"}

Redirect after submit

For plain HTML forms (without JavaScript), add a _redirect hidden field. ContactFire redirects to that URL after a successful submission.

<input type="hidden" name="_redirect" value="https://yoursite.com/thank-you" />

If _redirect is not set and no JavaScript intercepts the submit, the browser stays on ContactFire's default confirmation page.

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 data = new FormData(e.target);
    data.append('_token', 'cf_embed_your_token_here');

    const res = await fetch('https://my.contactfire.com/api/form/submit', {
      method: 'POST',
      body: data,
    });

    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