Formular-ID

REST API

Lies Formulare und Einsendungen, verschiebe Einsendungen in den Spam und wieder heraus und lösche sie mit einem Secret Key.

Mit der REST-API kann dein Server Formulare und Einsendungen lesen, Einsendungen in den Spam und wieder heraus verschieben und sie löschen. Sie spricht JSON über HTTPS unter https://ikiform.com/api/v1. Das OpenAPI-3.1-Dokument liegt unter /api/v1/openapi.json.

Einsendungen erstellen gehört nicht zu /api/v1. Sende stattdessen mit einem Secret Key an den Formular-Endpunkt; siehe Von einem Server.

API-Schlüssel

Erstelle Schlüssel im Dashboard unter API keys. Ein Schlüssel gehört zu einem Workspace und sieht nur diesen Workspace. Der vollständige Schlüssel wird einmal angezeigt; Ikiform speichert nur seinen Hash.

ArtPräfixVerwende
Secretik_sk_Für Server. Ruft die REST-API mit den Scopes auf, die du wählst, und kann Einsendungen erstellen.
Publishableik_pub_Für Browser. Kann nur Formulare absenden, und nur von den Domains, die du beim Schlüssel einträgst.

Scopes

ScopeErlaubt
forms:readGET /forms, GET /forms/:formId
submissions:readGET /submissions, GET /submissions/:id
submissions:writeDELETE /submissions/:id, POST /submissions/:id/spam und /not-spam sowie das Senden an /f/:formId

Authentifizierung

Sende den Secret Key als Bearer-Token. Die API funktioniert nur von Server zu Server: Sie sendet keine CORS-Header und beantwortet Browser-Preflights mit 405, daher kann ein Secret Key nie von einer Webseite aus funktionieren.

Terminal
curl https://ikiform.com/api/v1/forms \
  -H "Authorization: Bearer $IKIFORM_SECRET_KEY"
  • Ein fehlender, fehlerhafter, unbekannter, widerrufener oder abgelaufener Schlüssel erhält 401 unauthorized mit WWW-Authenticate: Bearer.
  • Ein Publishable Key erhält 403 forbidden (Publishable keys can only submit forms.). Ein Schlüssel ohne den nötigen Scope erhält 403 forbidden, und die Meldung nennt den Scope.
  • Antworten werden mit Cache-Control: no-store gesendet.

Die SDK-Beispiele unten nutzen alle denselben Client:

ikiform.ts
import { createClient } from "@ikiform/sdk";

const ikiform = createClient({ apiKey: process.env.IKIFORM_SECRET_KEY! });

Request-Builder

Formular
Formular-ID
curl "https://ikiform.com/api/v1/submissions?form_id=frm_xxxxxxxxxxxxxxxx&status=received&limit=50" \
  -H "Authorization: Bearer $IKIFORM_SECRET_KEY"

Führ das auf deinem Server aus. Die REST API lehnt Browser-Requests ab, deshalb sendet diese Seite ihn nie.

Endpunkte

MethodePfadScopeGibt zurück
GET/formsforms:readFormulare auflisten
GET/forms/:formIdforms:readEin Formular abrufen
GET/submissionssubmissions:readEinsendungen auflisten
GET/submissions/:idsubmissions:readEine Einsendung abrufen
POST/submissions/:id/spamsubmissions:writeAls Spam markieren
POST/submissions/:id/not-spamsubmissions:writeAls kein Spam markieren
DELETE/submissions/:idsubmissions:writeEine Einsendung löschen
GET/openapi.jsonKeinerDas OpenAPI-Dokument
GET/healthKeiner{ "ok": true }

Formulare auflisten

GET /forms mit dem Scope forms:read.

  • Neueste zuerst. Akzeptiert limit (1 bis 100, Standard 25) und cursor.
curl "https://ikiform.com/api/v1/forms?limit=10" \
  -H "Authorization: Bearer $IKIFORM_SECRET_KEY"

Ein Formular abrufen

GET /forms/:formId mit dem Scope forms:read.

  • Eine Formular-ID aus einem anderen Workspace gibt 404 zurück, genau wie eine, die nicht existiert.
curl https://ikiform.com/api/v1/forms/frm_xxxxxxxxxxxxxxxx \
  -H "Authorization: Bearer $IKIFORM_SECRET_KEY"

Einsendungen auflisten

GET /submissions mit dem Scope submissions:read.

ParameterWerteDefault
form_idEine Formular-IDAlle Formulare im Workspace
statusreceived oder spamBeide
limit1 bis 10025
cursornext_cursor von der vorherigen SeiteDie erste Seite
  • Neueste zuerst. Eine form_id aus einem anderen Workspace gibt statt eines Fehlers eine leere Liste zurück, sodass sich IDs nicht ausprobieren lassen.
curl "https://ikiform.com/api/v1/submissions?form_id=frm_xxxxxxxxxxxxxxxx&status=received&limit=50" \
  -H "Authorization: Bearer $IKIFORM_SECRET_KEY"

Eine Einsendung abrufen

GET /submissions/:id mit dem Scope submissions:read.

  • IDs aus einem anderen Workspace geben 404 zurück, genau wie IDs, die nicht existieren.
curl https://ikiform.com/api/v1/submissions/sub_01k7v2c9t3e8m5q4x6z0a1b2c3 \
  -H "Authorization: Bearer $IKIFORM_SECRET_KEY"

Als Spam markieren

POST /submissions/:id/spam mit dem Scope submissions:write.

  • Verschiebt eine empfangene Einsendung in den Spam, senkt den submission_count des Formulars und bricht ihre ausstehenden Webhook-Zustellungen ab.
  • Bei einer Einsendung, die schon Spam ist, wird sie unverändert zurückgegeben.
curl -X POST https://ikiform.com/api/v1/submissions/sub_01k7v2c9t3e8m5q4x6z0a1b2c3/spam \
  -H "Authorization: Bearer $IKIFORM_SECRET_KEY"

Als kein Spam markieren

POST /submissions/:id/not-spam mit dem Scope submissions:write.

  • Verschiebt sie zurück zu „empfangen“, löscht ihren Spam-Score und die Gründe und sendet submission.created an jeden passenden Webhook-Endpunkt.
  • Bei einer empfangenen Einsendung wird sie unverändert zurückgegeben.
curl -X POST https://ikiform.com/api/v1/submissions/sub_01k7v2c9t3e8m5q4x6z0a1b2c3/not-spam \
  -H "Authorization: Bearer $IKIFORM_SECRET_KEY"

Eine Einsendung löschen

DELETE /submissions/:id mit dem Scope submissions:write.

  • Entfernt die Einsendung und ihre Webhook-Zustellungen dauerhaft. Das lässt sich nicht rückgängig machen. Erneutes Löschen gibt 404 zurück.
curl -X DELETE https://ikiform.com/api/v1/submissions/sub_01k7v2c9t3e8m5q4x6z0a1b2c3 \
  -H "Authorization: Bearer $IKIFORM_SECRET_KEY"

Objekte

Objekte sind JSON in snake_case mit einem Feld object. Zeitstempel sind ISO 8601 in UTC mit Millisekunden. Einsendungs-IDs sind zeitlich geordnet (sub_ plus 26 Zeichen); Formular-IDs sind zufällig (frm_ plus 16 Zeichen).

FormularfeldBeschreibung
statusactive, paused oder disabled
submission_countEmpfangene Einsendungen, kein Spam
EinsendungsfeldBeschreibung
statusreceived oder spam
fieldsDie gespeicherten Werte
metauser_agent, origin, referrer, country, subject, reply_to. Jeder Schlüssel ist vorhanden und jeder Wert kann null sein. Der IP-Hash wird nie zurückgegeben
spam.score, spam.reasonsDer Spam-Score und die Gründe, etwa honeypot oder origin_mismatch

Paginierung

Listen sind nach Neuesten zuerst sortiert und nutzen opake Cursor.

  1. Sende den Request ohne Cursor.
  2. Wenn has_more true ist, sende next_cursor als cursor mit denselben Filtern.
  3. Hör auf, wenn next_cursor null ist.

Seiten bleiben stabil, während neue Einsendungen eintreffen: Neue erscheinen auf der ersten Seite, nie als Duplikate weiter unten. Baue oder parse Cursor nicht selbst; ein ungültiger gibt 400 invalid_request zurück.

for await (const submission of ikiform.submissions.iterate({ formId: "frm_xxxxxxxxxxxxxxxx" })) {
  console.log(submission.id, submission.fields);
}

Fehler

Fehler nutzen dieselbe Hülle wie Formular-Einsendungen. Jede Antwort hat einen Header X-Request-Id, den Fehler als request_id wiederholen.

403 Forbidden
{
  "ok": false,
  "error": { "code": "forbidden", "message": "This API key is missing the forms:read scope." },
  "request_id": "req_01k7v2c9t3e8m5q4x6z0a1b2c3"
}
StatusCodeWann
400invalid_requestlimit, status, form_id oder cursor ist ungültig; die Meldung nennt den Parameter
401unauthorizedFehlender oder ungültiger Schlüssel
403forbiddenPublishable Key oder fehlender Scope
404not_foundUnbekannte Route oder ID, oder eine ID in einem anderen Workspace
405method_not_allowedEin Browser-Preflight
429rate_limitedRate-Limit pro Schlüssel überschritten
500server_errorBei uns ist etwas fehlgeschlagen; gib die request_id an

Rate-Limit

Jeder Schlüssel kann 100 Requests pro 60 Sekunden senden. Über dem Limit gibt die API 429 rate_limited mit einem Header Retry-After in Sekunden zurück. Das SDK stellt ihn als error.retryAfter bereit.