Skip to content

Forms ​

Collect contact requests, quotes or sign-ups from your site without exposing an API token. Build the form in Forms, share it as a link, an iframe or a snippet, and read the answers in the dashboard.

Under the hood a form is a blueprint of type Form: its fields are the questions, and every submission is an entry of that blueprint.

Compared to posting with your own token, a form endpoint is safe to use from a public page: it can only create submissions, it checks where they come from, and it filters spam before anything is stored.

Create a form ​

  1. Click Forms in the sidebar, then New form
  2. Pick a starting point (Contact, Newsletter, Quote request or Blank) and name it
  3. In Questions, add, edit and reorder the questions; the live preview on the right shows what visitors see. Mark a question required to make it required
  4. In Share, copy the link, the iframe or the snippet for your site
  5. In Settings, set the success message, email alerts (on by default, to you) and spam protection

Click N submissions in the builder, or on the Forms list, to read the answers, newest first. You can edit a submission (to fill an internal field such as a status) and delete it, but not create one from the dashboard.

Forms do not appear in the content list of the sidebar. A form blueprint created another way (Settings › Blueprints, the JSON import or the API) shows up in Forms all the same.

Fields a visitor sees ​

These field types appear in the form:

Field typeRendered asValue sent
textsingle-line inputstring, 2,000 characters max
rich-textmulti-line text areaplain text, 20,000 characters max. Stored as escaped HTML paragraphs
emailemail inputvalid email address
linkURL inputvalid URL
numbernumber inputnumber, within the field's min and max
enumselectone of the field's options
multi-enumcheckboxesarray of options
booleancheckboxtrue / false (a required one must be checked)
datedate pickerYYYY-MM-DD
datetimedate and time pickerany date the server can parse

Fields of other types (image, file, relation, user, page builder…) stay internal: visitors never see them, values posted for them are ignored, and your team can use them on each submission in the dashboard. A Status choice field or an Assignee user field are common.

Add it to your site ​

Every form has a public key (frm_…). The Share tab gives the code for each method, built from your questions.

https://api.diggama.com/f/frm_… is a page with just the form: send it by email, put it in a social post or behind a QR code. No website needed.

Iframe ​

html
<iframe src="https://api.diggama.com/f/frm_xxxxxxxxxxxxxxxxxxxxxxxx?embed=1" title="Contact" style="width:100%;border:0;height:640px" loading="lazy"></iframe>
<!-- Optional: resizes the iframe to the form's height -->
<script src="https://api.diggama.com/forms/embed.js" defer></script>

Works in WordPress, Webflow, Wix, Framer or any HTML block. With the script line, the iframe takes the form's exact height, also after sending. ?embed=1 drops the page's title and background.

With allowed domains set, only those sites can show the iframe.

Embed ​

Paste two lines where the form should appear:

html
<div data-diggama-form="frm_xxxxxxxxxxxxxxxxxxxxxxxx"></div>
<script src="https://api.diggama.com/forms/embed.js" defer></script>

The script renders the fields, validates them, shows errors next to each field and the success message after sending. It includes the anti-spam fields on its own, and the Turnstile widget when the form has Turnstile keys.

It inherits your site's font and takes its look from CSS variables:

css
.dgf {
  --dgf-accent: #e11d48;   /* button, focus ring */
  --dgf-border: #d4d4d8;
  --dgf-bg: #fff;          /* inputs */
  --dgf-error: #dc2626;
  --dgf-radius: 4px;
  --dgf-font: inherit;
}

Several forms can share a page. For a form added after the page loads (a modal, a single-page app), call window.DiggamaForms.mount(element). After a successful submission the container fires a diggama:submitted event.

HTML form ​

Write your own markup and post it to the form endpoint. Input names are the field slugs:

html
<form action="https://api.diggama.com/forms/frm_xxxxxxxxxxxxxxxxxxxxxxxx" method="POST">
  <input name="name" required>
  <input name="email" type="email" required>
  <textarea name="message"></textarea>
  <input name="_gotcha" tabindex="-1" autocomplete="off" style="display:none">
  <button>Send</button>
</form>

After sending, the visitor is redirected to the form's redirect URL, or sees a small thank-you page with a link back to your site. If something is invalid, that page lists the errors.

Keep the _gotcha field: it is the honeypot (see below).

JavaScript ​

js
const response = await fetch("https://api.diggama.com/forms/frm_xxxxxxxxxxxxxxxxxxxxxxxx", {
  method: "POST",
  headers: { "Content-Type": "application/json", Accept: "application/json" },
  body: JSON.stringify({ name, email, message }),
});
StatusBody
201{ "ok": true, "message": "…", "redirect_url": null }
422{ "error": { "code": "VALIDATION_ERROR", "details": { "email": ["…"] } } }, or captcha_failed
403forbidden_origin (domain not allowed) or form_closed
404Unknown form key
429Too many submissions, retry later

GET /forms/{key} returns the form's public description (fields with their label, type, required flag and options; button label; success message; Turnstile site key), to build your own rendering.

Spam protection ​

Always on, with nothing to set up:

  • Rate limits: 5 submissions per minute per visitor and form, 30 per hour per visitor across forms, and 500 per hour per form, so a wave of spam from many addresses cannot flood one inbox.
  • Honeypot: the _gotcha field is hidden from people, so only bots fill it.
  • Minimum fill time: the embed sends the time the form appeared (_ts, in milliseconds); a form sent in under 3 seconds was filled by a script. Custom forms may leave it out.

A bot caught by the honeypot or the fill time gets the normal success answer and nothing is stored, so it has no signal to adapt to.

To set up:

  • Allowed domains: only browsers on these domains (and their subdomains) can post, and only these sites can show the form in an iframe. The form's own page (the link) always works. Leave it empty to accept any site, including scripts running outside a browser.
  • Cloudflare Turnstile: a free, mostly invisible check that stops bots driving a real browser. Create a widget for your domain in the Cloudflare dashboard, then paste its site key and secret key in Settings. The embed shows the widget on its own; a custom form must render it and send its token as cf-turnstile-response. The secret key is stored encrypted and never shown again. The link and the iframe show the widget too.
  • New key: if a form is targeted anyway, generate a new key. The old one stops working at once; update the code on your site.

To stop a form without deleting it, turn off Accept submissions: it then answers form_closed and stores nothing.

After a submission ​

  • Success message and redirect URL: what the visitor sees. A redirect URL takes precedence.
  • Email alerts: each accepted submission is emailed to the addresses you list, with every answer. Replying answers the visitor (the first email field of the form).
  • Workflows: a submission is a new entry of the blueprint, so workflows on that blueprint run, e.g. to send it to a webhook, Slack or a CRM.
  • API: submissions are drafts, so they are private. A token reads them with preview on the form's blueprint, and can export them as CSV.

Diggama Documentation