Destinations

Where accepted submissions go, to webhooks, notification emails and contacts.

An accepted submission (at once, after the submitter confirmed, or released by you) goes to every destination the form has. Each is retried on its own if it fails.

Webhooks

Your environment's webhook endpoints subscribed to them get:

{
  "id": "evt_01k…",
  "object": "event",
  "type": "form.submission.received",
  "api_version": "2026-10-10",
  "created_at": "2026-10-29T10:00:00.100Z",
  "data": {
    "form_id": "form_01k…",
    "form_name": "Contact us",
    "submission_id": "fsub_01k…",
    "status": "accepted",
    "data": { "name": "Ada Lovelace", "email": "ada@example.com", "message": "Hello!" },
    "submitter_email": "ada@example.com",
    "files": [],
    "spam_reason": null,
    "sandbox": false,
    "occurred_at": "2026-10-29T10:00:00.000Z"
  }
}

The payload carries what was submitted; uploaded files are listed, never included: download them with coss.forms.submissions.file(). Treat submitted values as untrusted input.

Notification emails

notifications.recipients (up to 5) get an email for each accepted submission, with every field and a link to it in the dashboard, replying to the submitter. In live environments, recipients must be members of your organization or addresses on its verified domains.

They come from notifications.from when you set one (an address on a verified domain), else from coss.com as <form name> via coss.com. Opens and clicks aren't tracked, and coss.com doesn't keep their bodies once sent.

Contacts

With contacts.enabled, the submitter becomes a contact of the environment (source: "form"), added to contacts.audience_ids and opted into contacts.topics:

await ..({
  : "Newsletter",
  : [
    { : "email", : "email", : true },
    { : "first_name", : "text" },
    { : "company", : "text" },
  ],
  : {
    : true,
    : [],
    : ["newsletter"],
    : "first_name",
    // Contact property key → the field it takes its value from.
    : { : "company" },
    : true,
  },
});

Property values are converted to the property's type (numbers, true/on/yes/1 for booleans, dates); one that doesn't fit is left out. Double opt-in decides whether new contacts are subscribed or pending.