From a server
Create submissions from a backend, script or integration with a secret API key.
Backends, cron jobs and integrations can post to the same endpoint as browsers. Add a secret API key so Ikiform knows the post is yours.
Create a secret key
- In the dashboard, open API keys and create a secret key.
- Give it the
submissions:writescope. Addsubmissions:readandforms:readonly if the same key also reads data from the REST API. - Copy the key. It starts with
ik_sk_and is shown once; Ikiform stores only its hash.
Send a submission
const response = await fetch("https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.IKIFORM_SECRET_KEY}`,
"Idempotency-Key": order.id,
},
body: JSON.stringify({ email: order.email, plan: order.plan }),
});
const result = await response.json();
if (!result.ok) throw new Error(`${result.error.code}: ${result.error.message} (${result.request_id})`);What a secret key changes
| Check | Without a key | With a secret key |
|---|---|---|
| Allowed domains | Checked against Origin or Referer | Skipped |
| Ikiform human check | Required when turned on | Skipped |
| Your own Turnstile keys | Token required | Token still required |
| Rate limits | Per visitor IP and form | Still apply, per your server's IP |
| Field validation and spam scoring | Run | Run |
A key from another workspace, a revoked key, or a secret key without submissions:write gets 403 forbidden. A malformed Authorization header is also refused rather than ignored, so a typo never silently downgrades to an anonymous post.
Publishable keys
Publishable keys (ik_pub_) are for browsers. They can only submit, and only from the domains you list on the key. A post with a publishable key from any other site gets 403 origin_not_allowed. They don't skip the human check or the form's own allowed domains.
Retries
Servers retry. Send an Idempotency-Key that is stable for the thing you are submitting, such as an order id, and a retry will replay the first response instead of creating a duplicate. See Idempotency.