Entwickler
API-Methoden
Vollständige Referenz für alle Methoden der formbase REST API. Jede Methode zeigt ihre Parameter, Beispielanfragen und Antwortstrukturen.
Ein Endpunkt, viele Methoden
Jede Methode ist POST https://api.formbase.so/api/v1 mit einem JSON-Body
{"method": "...", "params": {...}} und einem Authorization: Bearer fb_…-Header. Siehe
API-Übersicht für Authentifizierung und Fehlerbehandlung, und
API-Tokens für das Token selbst.
Konventionen
paramskann weggelassen werden; es ist standardmäßig{}. Eine unbekannte Methode ergibt404 METHOD_NOT_FOUND.Ein Token ist an einen Workspace gebunden. Einen anderen Workspace zu nennen, oder ein Formular darin, ergibt
403 FORBIDDEN— selbst wenn du zu beiden gehörst.Paginierung. List-Methoden liefern
{ items, nextCursor, hasMore }; die meisten liefern außerdemcanPaginate, dasfalseist, wennhasMorezwartrueist, sich aber mit keinem Cursor fortsetzen lässt (unscharfe Suche). GibnextCursoralscursorzurück.limitliegt bei 1–100, Standard 20 — außer beirequests.list, dessen Standard 25 ist.Rate-Limits. 120 Aufrufe pro Minute pro Token, gemeinsam genutzt mit dem MCP-Server;
requests.createhat ein eigenes Limit von 60 pro Minute. Fehlgeschlagene Authentifizierung wird separat begrenzt, 30 pro 15 Minuten pro IP, danach sehen ungültige TokenRATE_LIMITEDstattUNAUTHORIZED.Body-Größe. 1 MiB. Größere Bodys werden mit
VALIDATION_ERRORabgelehnt.Versionierung. Der Pfad trägt die Version. Breaking Changes erscheinen als
/api/v2; neue Methoden und neue Antwortfelder nicht.
Formulare
forms.list
Formulare in einem Workspace auflisten. Unterstützt Cursor-Paginierung und optionale unscharfe Namenssuche.
workspaceIdstringrequired
workspaceIdstringrequiredWorkspace-ID.
folderIdstring | nulloptional
folderIdstring | nulloptionalNach Ordner filtern. null übergeben für nur Formulare auf Root-Ebene. Weglassen, um alle aufzulisten.
querystringoptional
querystringoptionalUnscharfe Namenssuche. Ergebnisse auf limit begrenzt; keine Cursor-Paginierung.
limitnumberoptionaldefault: 20
limitnumberoptionaldefault: 20Seitengröße (1–100).
cursorstringoptional
cursorstringoptionalPaginierungs-Cursor aus einer vorherigen Antwort.
curl -X POST https://api.formbase.so/api/v1 \
-H "Authorization: Bearer fb_..." \
-H "Content-Type: application/json" \
-d '{
"method": "forms.list",
"params": { "workspaceId": "ws_abc123" }
}'{
"ok": true,
"data": {
"items": [
{
"id": "frm_abc123",
"name": "Contact Form",
"folderId": null,
"workspaceId": "ws_abc123",
"isPublished": true,
"publishedAt": 1714041851000,
"unpublishedAt": null,
"createdAt": 1714041800000,
"lastEditedAt": 1714042000000,
"emoji": null
}
],
"nextCursor": null,
"hasMore": false,
"canPaginate": false
}
}forms.get
Vollständige Details für ein einzelnes Formular abrufen, einschließlich Fragen, Cover, Logo und einer Vorschau-URL.
formIdstringrequired
formIdstringrequiredFormular-ID.
curl -X POST https://api.formbase.so/api/v1 \
-H "Authorization: Bearer fb_..." \
-H "Content-Type: application/json" \
-d '{
"method": "forms.get",
"params": { "formId": "frm_abc123" }
}'{
"ok": true,
"data": {
"id": "frm_abc123",
"name": "Event Feedback",
"folderId": null,
"workspaceId": "ws_abc123",
"isPublished": true,
"publishedAt": 1714041851000,
"unpublishedAt": null,
"createdAt": 1714041800000,
"lastEditedAt": 1714042000000,
"emoji": null,
"questions": [
{
"id": "q_1",
"type": "email-input",
"inputType": "email",
"title": "Your email",
"metadata": null
},
{
"id": "q_2",
"type": "rating-input",
"inputType": "rating",
"title": "Overall experience",
"metadata": { "kind": "rating", "maxStars": 5 }
}
],
"hasContent": true,
"cover": null,
"logo": null,
"isDeleted": false,
"trashedAt": null,
"previewUrl": "https://formbase.so/preview/abc..."
}
}forms.create
Ein neues leeres Formular erstellen. Gibt das Formular und eine Vorschau-URL zurück.
namestringrequired
namestringrequiredFormularname (1–255 Zeichen).
workspaceIdstringrequired
workspaceIdstringrequiredWorkspace-ID.
folderIdstringoptional
folderIdstringoptionalDas Formular in einem Ordner ablegen. Weglassen, um es im Workspace-Root zu erstellen.
curl -X POST https://api.formbase.so/api/v1 \
-H "Authorization: Bearer fb_..." \
-H "Content-Type: application/json" \
-d '{
"method": "forms.create",
"params": {
"name": "Contact",
"workspaceId": "ws_abc123"
}
}'const res = await fetch('https://api.formbase.so/api/v1', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.FORMBASE_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
method: 'forms.create',
params: { name: 'Contact', workspaceId: 'ws_abc123' },
}),
})
const { ok, data } = await res.json()import os, requests
res = requests.post(
"https://api.formbase.so/api/v1",
headers={"Authorization": f"Bearer {os.environ['FORMBASE_TOKEN']}"},
json={
"method": "forms.create",
"params": {
"name": "Contact",
"workspaceId": "ws_abc123",
},
},
)
data = res.json(){
"ok": true,
"data": {
"id": "frm_new123",
"name": "Contact",
"workspaceId": "ws_abc123",
"folderId": null,
"isPublished": false,
"createdAt": 1714041851000,
"previewUrl": "https://formbase.so/preview/abc..."
}
}forms.update
Formular-Metadaten aktualisieren: Name, Ordner, Emoji, Cover oder Logo. Aktualisiert nicht den Formularinhalt (dafür die Editor-Tools verwenden).
formIdstringrequired
formIdstringrequiredFormular-ID.
namestringoptional
namestringoptionalNeuer Formularname (1–255 Zeichen).
folderIdstring | nulloptional
folderIdstring | nulloptionalFormular in einen Ordner verschieben. null übergeben, um es in den Workspace-Root zu verschieben.
emojistring | nulloptional
emojistring | nulloptionalFormular-Emoji (max. 10 Zeichen). null übergeben, um es zu entfernen.
coverobjectoptional
coverobjectoptionalCover. {"type": "color", "color": "#ffffff"}, {"type": "image", "url": "https://...", "offsetY": 50} (
offsetY 0–100, Standard 50), oder {"type": "none"} zum Entfernen. Bild-URLs müssen http(s)
oder eine data:image-URI sein.
logoobjectoptional
logoobjectoptionalLogo. {"type": "icon", "name": "HeartIcon"}, {"type": "image", "url": "https://..."} oder
{"type": "none"} zum Entfernen. Icon-Namen sind fest: QuestionMarkIcon, ListBulletsIcon,
ChartBarIcon, ClockCountdownIcon, HeartIcon, LightbulbIcon,
CheckCircleIcon, MagnifyingGlassIcon, TrendUpIcon, EnvelopeIcon,
PhoneIcon, CalendarIcon, LinkIcon, UsersIcon.
Übergib mindestens eines der fünf aktualisierbaren Felder. Das ändert nicht den Formularinhalt — nutze dafür die MCP-Editor-Tools.
curl -X POST https://api.formbase.so/api/v1 \
-H "Authorization: Bearer fb_..." \
-H "Content-Type: application/json" \
-d '{
"method": "forms.update",
"params": {
"formId": "frm_abc123",
"name": "Updated Name",
"emoji": "📋"
}
}'{
"ok": true,
"data": {
"id": "frm_abc123",
"name": "Updated Name",
"folderId": null,
"emoji": "📋"
}
}cover und logo kommen nur zurück, wenn du sie mitgeschickt hast. Ein Payload, der bei jedem skalaren Feld dem
aktuellen Zustand entsprach, ergänzt noChange: true.
forms.publish
Ein Formular veröffentlichen, damit es Antworten entgegennehmen kann, und seine Feldschlüssel in einem neuen
Snapshot einfrieren. Idempotent: ein bereits veröffentlichtes Formular liefert Erfolg mit alreadyPublished: true, und ein
depubliziertes Formular wird aus seinem letzten Snapshot erneut veröffentlicht.
formIdstringrequired
formIdstringrequiredFormular-ID.
Ein Formular mit Inhaltsblöcken, aber ohne Fragen, wird mit einer Warnung veröffentlicht. Ein Formular ganz ohne Inhalt lässt sich nicht veröffentlichen. Veröffentlichen erzeugt keine öffentliche URL — rufe dafür shareLinks.create auf.
forms.unpublish
Ein Formular offline nehmen. Ausfüllende können es nicht mehr öffnen. Idempotent — ein Formular, das nicht veröffentlicht ist, liefert
alreadyUnpublished: true. Umkehrbar mit forms.publish.
formIdstringrequired
formIdstringrequiredFormular-ID.
forms.delete
Ein Formular in den Papierkorb verschieben. Seine aktiven Freigabelinks werden widerrufen, ihre öffentlichen URLs liefern also nichts mehr aus.
formIdstringrequired
formIdstringrequiredFormular-ID.
Wiederherstellen bringt die Links nicht zurück
forms.restore liefert das Formular zurück, aber die Freigabelinks, die es widerrufen hat, bleiben widerrufen. Erstelle neue
mit shareLinks.create. Ein Formular, das schon im Papierkorb liegt, liefert alreadyTrashed: true und behält
sein ursprüngliches Papierkorb-Datum.
forms.restore
Ein Formular aus dem Papierkorb wiederherstellen.
formIdstringrequired
formIdstringrequiredFormular-ID.
folderIdstring | nulloptional
folderIdstring | nulloptionalWohin es wiederhergestellt wird. Weglassen für den ursprünglichen Ordner, null für den Workspace-Root, oder eine Ordner-ID.
Ein Formular, das nicht im Papierkorb liegt, liefert alreadyRestored: true.
formSettings.get
Die Verhaltenseinstellungen eines Formulars lesen.
formIdstringrequired
formIdstringrequiredFormular-ID.
Liefert { settings, isDefault, availableEmailDomains, defaultFromAddress, payment }. isDefault ist wahr,
wenn das Formular noch keine gespeicherte Einstellungszeile hat und du die Standardwerte siehst. availableEmailDomains
enthält die verifizierten Domain-IDs, die du als emailDomainId übergeben kannst, und payment meldet, ob Stripe
verbunden ist (das Verbinden selbst ist ein Dashboard-Schritt).
formSettings.update
Die Verhaltenseinstellungen eines Formulars aktualisieren. Ein partielles Update: nur die gesendeten Felder werden geschrieben.
formIdstringrequired
formIdstringrequiredFormular-ID.
Accessgroupoptional
Accessgroupoptionallanguage (BCP-47, Standard “en”), requireAuthentication, showBranding,
captchaEnabled, passwordEnabled, password (4 Zeichen oder mehr; ein String setzt implizit
passwordEnabled: true, null entfernt die Sperre).
Owner notificationsgroupoptional
Owner notificationsgroupoptionalnotifyOnSubmission, notificationEmails (Array), selfNotificationSubject,
selfNotificationEmailBody, pdfGenerationEnabled, showViewSubmissionButton. E-Mails an den
Formularinhaber sind nicht übersetzbar — schreibe sie in der Sprache, die du willst.
Respondent notificationsgroupoptional
Respondent notificationsgroupoptionalrespondentNotificationEnabled, respondentNotificationTo (die Feld-ID einer E-Mail-Frage, oder
null), respondentNotificationSubject, respondentNotificationBody,
respondentNotificationPdfEnabled.
Remindersgroupoptional
RemindersgroupoptionalrespondentReminderEnabled, respondentReminderTo, respondentReminderSubject,
respondentReminderBody, respondentReminderRequiredFieldIds, und reminderSteps — Leerlauf-Abstände
wie [“1d”,“3d”,“1w”], maximal 5, beim Speichern sortiert und dedupliziert, [] für keine. Der Zeitplan gilt
gleichermaßen für abgebrochene Antworten über den öffentlichen Link und für Requests. Pro.
After submitgroupoptional
After submitgroupoptionalredirectUrl (http(s); null oder “” entfernt sie), redirectQueryParams (
[{ paramName, fieldId }]), allowAnotherResponse (schließt sich mit einer Weiterleitung gegenseitig aus),
maxSubmissionsPerRespondent (0 = unbegrenzt, max. 1000), editAfterSubmit, maxEdits (max. 3; 0
bedeutet unbegrenzt bei Pro und Business, 3 bei Free).
Retentiongroupoptional
RetentiongroupoptionaldraftRetentionDays und submissionRetentionDays (0–36500, null setzt auf den Standard zurück).
Aufbewahrung von Einreichungen ist Business, und sie zu setzen entfernt ein festes Löschdatum, das im Builder konfiguriert wurde.
emailDomainIdstring | nulloptional
emailDomainIdstring | nulloptionalEine verifizierte E-Mail-Domain-ID aus formSettings.get, für eine benutzerdefinierte Absenderadresse. null
setzt auf den Standardabsender zurück.
Betreffzeilen und Texte sind Klartext und akzeptieren {{variable}}-Platzhalter; Zeilenumbrüche werden zu Absätzen. Einen
Betreff oder Text für die ausfüllende Person anzupassen macht ihn übersetzbar, seine Schlüssel erscheinen also sofort in
translations.listEntries.
Einreichungen
submissions.list
Die Einreichungen eines Formulars auflisten, neueste Seite zuerst, mit Cursor-Paginierung.
formIdstringrequired
formIdstringrequiredFormular-ID.
includeDraftsbooleanoptionaldefault: true
includeDraftsbooleanoptionaldefault: trueAntworten einschließen, die begonnen, aber nie abgesendet wurden. Entwürfe sind eine Pro-Funktion: im Free-Plan werden nur abgeschlossene Einreichungen aufgelistet.
translationLanguagestringoptional
translationLanguagestringoptionalGespeicherte KI-Übersetzungen der Antworten unter items[].translation.display anhängen, mit denselben Schlüsseln wie
display. items[].answers und items[].display bleiben immer das Original.
limitnumberoptionaldefault: 20
limitnumberoptionaldefault: 20Seitengröße (1–100).
cursorstringoptional
cursorstringoptionalPaginierungs-Cursor aus einer vorherigen Antwort.
{
"ok": true,
"data": {
"formId": "frm_abc123",
"formName": "Event Feedback",
"items": [
{
"id": "sub_xyz789",
"submittedAt": "2026-05-18 18:02:28",
"isCompleted": true,
"createdAt": "2026-05-18 18:02:19",
"answers": {
"email": "user@example.com",
"plan": "pro",
"contacts": [{ "name": "Ada" }, { "name": "Grace" }]
},
"display": {
"email": "user@example.com",
"plan": "Pro",
"contacts": "Ada, Grace"
}
}
],
"nextCursor": null,
"hasMore": false,
"canPaginate": false
}
}Dieselben Antworten wie bei Webhooks und Callbacks
Jedes Element trägt answers, indiziert nach Feldschlüssel, und display
mit denselben Schlüsseln in lesbarem Text — die Form, die ein Webhook-Payload, ein
Request-Callback und requests.get tragen. Eine Auswahlantwort ist ihr
Optionsschlüssel, eine Wiederholungsgruppe ein Array von Instanzen. Ruf fields.list für Titel und Optionsbeschriftungen
jedes Schlüssels auf. Diese Methode liefert keine Summen.
submissions.pdf
Einen Link zum PDF einer Einreichung abrufen. Für den Zapier-Connector gebaut: Es liefert nur dann ein Ergebnis, wenn das Formular eine aktive Zapier-Integration hat, die so konfiguriert ist, dass sie das PDF einschließt, und das PDF aufbewahrt wurde.
formIdstringrequired
formIdstringrequiredFormular-ID.
submissionIdstringrequired
submissionIdstringrequiredEinreichungs-ID. Muss zu diesem Formular gehören und abgeschlossen sein.
{
"ok": true,
"data": {
"url": "https://api.formbase.so/api/storage/...",
"filename": "formbase-submission-sub_xyz789.pdf",
"contentType": "application/pdf",
"byteLength": 148213
}
}submissions.sample
Ein Beispiel-Payload für die Einreichung eines Formulars bauen, ohne echte Daten. Es hat exakt die Form, die die Zustellung einer
Einreichung über den öffentlichen Link trägt, Connectors nutzen es also für die Felderkennung; eine aus einem Request entstandene
Einreichung erreicht ein Abonnement stattdessen als request.completed — das Beispiel dafür liefert
requests.sample. data.form.snapshotId ist die aktuell veröffentlichte Version des Formulars,
dieselbe ID, die Live-Events tragen, oder null, solange das Formular unveröffentlicht ist.
formIdstringrequired
formIdstringrequiredFormular-ID.
{
"ok": true,
"data": {
"id": "evt_example000000000000",
"type": "submission.completed",
"createdAt": "2026-05-18T19:00:00.000Z",
"apiVersion": "2026-09-24",
"test": true,
"data": {
"form": { "id": "frm_abc123", "name": "Event Feedback", "snapshotId": "js7abc123" },
"submission": {
"id": "sub_example000000000000",
"respondentEmail": "respondent@example.com",
"submittedAt": "2026-05-18T19:00:00.000Z",
"updatedAt": null,
"editCount": 0,
"pdfUrl": null,
"language": "en"
},
"answers": { "your_email": "john@example.com" },
"display": { "your_email": "john@example.com" }
}
}
}Feld- und Payload-Semantik sind einmalig dokumentiert, in der Webhooks-Referenz.
Freigabe-Links
Felder
fields.list
Jedes Feld der aktuell veröffentlichten Version eines Formulars auflisten, mit dem Schlüssel, über den es angesprochen wird. Vor
requests.create aufrufen, statt Schlüssel fest im Code zu hinterlegen. Siehe Feldschlüssel.
formIdstringrequired
formIdstringrequiredFormular-ID. Ein Formular, das noch nie veröffentlicht wurde, hat noch keine Feldschlüssel und liefert published: false
ohne Einträge zurück.
curl -X POST https://api.formbase.so/api/v1 \
-H "Authorization: Bearer fb_..." \
-H "Content-Type: application/json" \
-d '{
"method": "fields.list",
"params": { "formId": "j57..." }
}'{
"ok": true,
"data": {
"published": true,
"items": [
{ "key": "company_name", "type": "text", "title": "Company", "required": true, "prefillable": true },
{
"key": "company_size", "type": "select", "title": "Company size", "required": false, "prefillable": true,
"options": [
{ "key": "1_50", "label": "1–50" },
{ "key": "51_200", "label": "51–200" }
]
},
{
"key": "satisfaction", "type": "matrix", "title": "How did we do?", "required": false, "prefillable": true,
"rows": [{ "key": "delivery_speed", "label": "Delivery speed" }],
"columns": [{ "key": "very_good", "label": "Very good" }, { "key": "poor", "label": "Poor" }]
},
{ "key": "case_id", "type": "hidden", "title": "Case", "required": false, "prefillable": false, "context": true },
{ "key": "total", "type": "number", "title": "Total", "required": false, "prefillable": false, "calculated": true }
],
"hasMore": false
}
}Die Flags lesen
context: true ist ein verstecktes Feld — sein Wert gehört in context, niemals in prefill.
prefillable: false markiert ein Feld, für das niemand einen Wert liefern kann (Datei, Signatur, Zahlung, Termin,
Dokumente). Bei einer Auswahlfrage den Schlüssel der Option senden, nicht ihr Label; eine Matrix listet ihre
rows und columns auf dieselbe Weise auf und nimmt { "row_key": "column_key" }.
calculated: true ist ein berechnetes Feld: Das Formular ermittelt seinen Wert, du liest ihn in answers zurück,
und nichts kann ihn senden.
Eine Wiederholungsgruppe ist type: “group” mit repeating: true und einem members-Array. Ein
Dokumente-Block ist type: “documents” und trägt documents: [{ name }], die vom Autor hinterlegten Dateien,
die jede ausfüllende Person bereits sieht.
Requests
Ein Request weist ein veröffentlichtes Formular einer Person zu und ruft dich zurück, wenn er endet. Die konzeptionelle Anleitung steht in Eine Anfrage erstellen; hier folgt die Parameterliste.
requests.create
Einen Request erstellen. Verbraucht eine Einheit des monatlichen Kontingents des Workspace, unabhängig davon, ob die empfangende Person antwortet.
formIdstringrequired
formIdstringrequiredDas zu vergebende veröffentlichte Formular.
recipientobjectoptional
recipientobjectoptional{ email?, name? }. Eine E-Mail ist erforderlich, wenn delivery gleich “email” ist;
andernfalls identifiziert sie die Person nur auf der Requests-Seite und bei ihren Antworten.
prefillobjectoptional
prefillobjectoptionalErste Antworten nach Feldschlüssel. Die empfangende Person sieht sie und kann sie ändern.
readonlystring[]optional
readonlystring[]optionalVorausgefüllte Schlüssel, die die empfangende Person nicht ändern kann. Jeder Schlüssel hier muss auch in prefill
erscheinen, und ein gesperrtes Pflichtfeld muss mit einem nicht-leeren Wert vorausgefüllt sein.
contextobjectoptional
contextobjectoptionalWerte für die versteckten Felder des Formulars, nach Feldschlüssel. Vertrauenswürdig, unveränderlich und im Callback zurückgegeben. Ein
unbekannter Schlüssel wird mit UNKNOWN_FIELD_KEY abgelehnt.
metadataobjectoptional
metadataobjectoptionalDeine eigene Buchführung. Erreicht das Formular nie; kommt in Callbacks und Abfragen zurück.
languagestringoptional
languagestringoptionalEine der veröffentlichten Sprachen des Formulars. Standardmäßig die Standardsprache des Formulars.
deliverystringoptionaldefault: none
deliverystringoptionaldefault: none“email”, damit formbase die Einladung sendet (braucht eine E-Mail der empfangenden Person sowie Pro oder Business oder eine
der 10 kostenlosen Einladungen eines Free-Kontos), oder “none”, um den Link selbst auszuliefern.
remindersstring[]optional
remindersstring[]optionalÜberschreibt den Erinnerungsplan des Formulars für diesen Request. Ein leeres Array schaltet Erinnerungen ab.
expiresAtnumberoptional
expiresAtnumberoptionalEpoch-Millisekunden. Standardmäßig 30 Tage später; 365 Tage ist das Maximum.
callbackUrlstringoptional
callbackUrlstringoptionalWohin formbase den Callback per POST sendet, wenn der Request endet. Nur HTTPS, und der Host muss auf eine öffentliche Adresse auflösen.
externalIdstringoptional
externalIdstringoptionalDeine eigene ID für diesen Request. Filterbar in requests.list.
idempotencyKeystringoptional
idempotencyKeystringoptionalWiederholung mit demselben Body gibt den ursprünglichen Request mit deduplicated: true zurück. Ein anderer Body wird
abgelehnt. Schlüssel leben 30 Tage.
domainIdstringoptional
domainIdstringoptionalDen Link auf einer deiner benutzerdefinierten Domains erzeugen. Nur über die REST API.
documentsobject[]optional
documentsobject[]optional[{ documentId, field?, name? }] — Dateien, die dieser einen empfangenden Person übergeben werden, zuvor mit
documents.create hochgeladen.
testbooleanoptionaldefault: false
testbooleanoptionaldefault: falseEin Testlauf: Es wird nichts per E-Mail gesendet, der Callback trägt “test”: true, und die Einreichung zählt nirgends. Der
Link schließt sich innerhalb von 24 Stunden, und auf Free darf ein Workspace 10 Testanfragen pro Tag erstellen.
curl -X POST https://api.formbase.so/api/v1 \
-H "Authorization: Bearer fb_..." \
-H "Content-Type: application/json" \
-d '{
"method": "requests.create",
"params": {
"formId": "j57...",
"recipient": { "email": "ada@acme.com", "name": "Ada" },
"prefill": { "company_name": "Acme" },
"readonly": ["company_name"],
"context": { "case_id": "CASE-9" },
"delivery": "email",
"externalId": "run-42",
"callbackUrl": "https://automation.example/webhook/resume-abc",
"idempotencyKey": "run-42"
}
}'{
"ok": true,
"data": {
"id": "kd7...",
"status": "pending",
"url": "https://form.formbase.so/r/rq_...",
"deliveryStatus": "queued",
"expiresAt": 1794787200000,
"createdAt": 1789379200000,
"externalId": "run-42",
"deduplicated": false
}
}Behalte die url
url trägt das einmalige Token. requests.get kann sie meist rekonstruieren, aber sie kommt als
null zurück für einen Request, der erstellt wurde, bevor das Deployment einen Request-Token-Schlüssel hatte. Wenn du den
Link selbst ausgibst, speichere ihn bei der Erstellung.
deliveryStatus ist not_requested, bis eine Einladung eingereiht wird, dann queued →
sent oder failed, und bounced, sobald der Mail-Anbieter einen Hard Bounce oder eine Beschwerde
meldet.
requests.get
Einen Request vollständig abrufen: Status, Ergebnis, was vorausgefüllt wurde, seine Timeline und — sobald abgeschlossen — answers und display nach Feldschlüssel, dieselben zwei Maps, die auch der Callback trägt.
requestIdstringrequired
requestIdstringrequiredRequest-ID.
{
"ok": true,
"data": {
"id": "kd7...",
"formId": "j57...",
"status": "completed",
"outcome": "approve",
"isTest": false,
"recipient": { "email": "ada@acme.com", "name": "Ada" },
"language": "en",
"externalId": "run-42",
"metadata": null,
"context": { "case_id": "CASE-9" },
"prefill": { "company_name": "Acme" },
"readonlyKeys": ["company_name"],
"delivery": "email",
"deliveryStatus": "sent",
"hasCallback": true,
"callbackFailedAt": null,
"submissionId": "kp2...",
"url": "https://form.formbase.so/r/rq_...",
"answers": { "company_name": "Acme", "decision": "approve" },
"display": { "company_name": "Acme", "decision": "Approve" },
"timeline": [
{ "id": "kd7...:created", "type": "created", "at": 1789379200000 },
{ "id": "kd7...:completed", "type": "completed", "at": 1789465600000 }
],
"expiresAt": 1794787200000,
"completedAt": 1789465600000
}
}outcome vs. status
status sagt, ob der Request abgeschlossen ist; outcome sagt, wie die empfangende Person entschieden hat —
approve, decline, changes, oder null bei allem außer einem abgeschlossenen Request,
dessen empfangende Person eine der drei Optionen gewählt hat — auch bei einem Formular ohne
Entscheidungsfrage. Die Callback-URL selbst wird nie zurückgegeben;
hasCallback sagt nur, ob eine gesetzt ist.
Das Beispiel oben ist gekürzt. Eine vollständige Antwort trägt außerdem workspaceId, formSnapshotId,
createdVia, documents, reminderStep, remindersSent, reminderDueAt,
dataPurgedAt und den Rest der Zeitstempel (updatedAt, openedAt, startedAt,
lastActivityAt, expiredAt, canceledAt, canceledBy, cancelReason).
Zwei Felder sagen dir, wann die Kopie vor dir die einzige ist. callbackFailedAt ist gesetzt, während der Callback dieses
Requests keine Versuche mehr übrig hat, und wird geleert, sobald einer durchkommt oder du ihn erneut sendest. dataPurgedAt
ist gesetzt, sobald die Aufbewahrung den Request gestrippt hat: context, prefill und metadata
kommen leer zurück, readonlyKeys und documents sind [], und submissionId,
answers und display sind null.
timeline ist abgeleitet, älteste zuerst. Jeder Eintrag hat eine id, ein at und einen
type — created, invitation, reminder, opened, started,
completed, expired, canceled, callback. Zustellungs-Einträge ergänzen
deliveryStatus und attemptCount, und Callbacks ergänzen eventType. Zustellungszeilen bleiben 30
Tage erhalten, ältere Timelines dünnen also auf die Zeitstempel aus.
requests.list
Requests in einem Workspace oder zu einem Formular auflisten, neueste zuerst. Testanfragen bleiben außen vor, sofern du nicht danach fragst.
workspaceIdstringoptional
workspaceIdstringoptionalAuf einen Workspace eingrenzen. Dies oder formId angeben.
formIdstringoptional
formIdstringoptionalAuf ein Formular eingrenzen.
statusstringoptional
statusstringoptionalpending, completed, expired oder canceled.
outcomestringoptional
outcomestringoptionalapprove, decline oder changes. Impliziert nur abgeschlossene Requests.
externalIdstringoptional
externalIdstringoptionalDeine eigene ID, um den Request zu finden, den ein Lauf erstellt hat.
includeTestbooleanoptionaldefault: false
includeTestbooleanoptionaldefault: falseMit test: true erstellte Requests einschließen.
limitnumberoptionaldefault: 25
limitnumberoptionaldefault: 25Seitengröße (1–100).
cursorstringoptional
cursorstringoptionalPaginierungs-Cursor aus einer vorherigen Antwort.
{
"ok": true,
"data": {
"items": [
{
"id": "kd7...",
"formId": "j57...",
"status": "pending",
"outcome": null,
"recipient": { "email": "ada@acme.com", "name": "Ada" },
"externalId": "run-42",
"deliveryStatus": "sent",
"expiresAt": 1794787200000,
"createdAt": 1789379200000
}
],
"nextCursor": null,
"hasMore": false
}
}Listeneinträge tragen dieselben Felder wie requests.get, minus url, answers, display
und timeline, und jeder trägt isTest. Gib workspaceId oder formId an — keines von
beiden ergibt 400 VALIDATION_ERROR mit dem Grund SCOPE_REQUIRED. outcome hat Vorrang vor
status, denn nur ein abgeschlossener Request hat ein Urteil.
requests.cancel
Einen ausstehenden Request zurückziehen. Der Link funktioniert nicht mehr, die empfangende Person sieht einen Hinweis auf den Rückzug, und
ein request.canceled-Callback wird ausgelöst.
requestIdstringrequired
requestIdstringrequiredRequest-ID.
reasonstringoptional
reasonstringoptionalDeine Notiz zum Warum, wird am Request gespeichert und im Callback gesendet.
requests.remind
Die empfangende Person jetzt per E-Mail erreichen, ohne den Erinnerungsplan anzurühren. Braucht eine E-Mail der empfangenden Person und einen Pro- oder Business-Plan.
requestIdstringrequired
requestIdstringrequiredRequest-ID. Muss noch ausstehend sein und darf keine Testanfrage sein.
Zwei Untergrenzen gelten: mindestens 10 Minuten zwischen manuellen Erinnerungen, und höchstens 8 Erinnerungen pro Request insgesamt,
manuelle und geplante zusammengerechnet. Der automatische Zeitplan bleibt unberührt — reminderStep und
reminderDueAt bleiben, wo sie waren.
requests.replayCallback
Den Callback, den ein Request bei seinem Ende ausgelöst hat, erneut senden — gleiche Payload, gleiche Event-ID, sodass ein Empfänger, der ihn bereits verarbeitet hat, dedupliziert. Nach dem Beheben eines defekten Endpunkts verwenden.
requestIdstringrequired
requestIdstringrequiredRequest-ID. Muss abgeschlossen, abgelaufen oder storniert sein.
{
"ok": true,
"data": { "dispatchId": "kf9...", "eventId": "evt_kf9..." }
}requests.sample
Ein Beispiel-Request-Ereignis für ein Formular bauen, ohne echten Request. Es ist genau der Umschlag, den ein mit
webhooks.create erstelltes request_*-Abonnement empfängt, Connectors nutzen es also für die Felderkennung. Ein
abgeschlossenes Beispiel trägt dieselben Beispielantworten, die submissions.sample zeigt; ein abgelaufenes
oder storniertes Beispiel trägt nur den Request-Block.
formIdstringrequired
formIdstringrequiredFormular-ID.
eventTypestringrequired
eventTypestringrequiredWelches Ende als Beispiel dient, in der Schreibweise von webhooks.create. Das type des Umschlags ist die
gepunktete Form.
request_completedrequest_expiredrequest_canceled{
"ok": true,
"data": {
"id": "evt_example000000000000",
"type": "request.completed",
"createdAt": "2026-05-18T19:00:00.000Z",
"apiVersion": "2026-09-24",
"test": true,
"data": {
"request": {
"id": "req_example000000000000",
"externalId": "order-1234",
"status": "completed",
"language": "en",
"recipient": { "email": "recipient@example.com", "name": "Sample Recipient" },
"metadata": { "source": "sample" },
"context": {},
"createdAt": "2026-05-18T18:00:00.000Z",
"completedAt": "2026-05-18T19:00:00.000Z"
},
"form": { "id": "frm_abc123", "name": "Event Feedback", "snapshotId": "js7abc123" },
"submission": {
"id": "sub_example000000000000",
"respondentEmail": "respondent@example.com",
"submittedAt": "2026-05-18T19:00:00.000Z",
"updatedAt": null,
"editCount": 0,
"pdfUrl": null,
"language": "en"
},
"answers": { "your_email": "john@example.com" },
"display": { "your_email": "john@example.com" }
}
}
}Der Request-Block und das Ergebnis sind auf der Callbacks-Seite dokumentiert; die
Einreichungshälfte in der Webhooks-Referenz. Beispiel-IDs sind die oben gezeigten
festen Platzhalter, und test ist true, sodass ein Empfänger ein Beispiel von einem Live-Ereignis unterscheiden
kann.
documents.create
Einen Upload für eine Datei reservieren, die du einer empfangenden Person über den Dokumente-Block des
Formulars übergibst. Bytes wandern nie durch diese API: Du bekommst ein vorsigniertes PUT, lädst hoch, und requests.create prüft das
Objekt, bevor der Request existiert.
formIdstringrequired
formIdstringrequiredDas Formular, dessen Dokumente-Block die Datei zeigt. Bindet den Upload an diesen Workspace.
namestringrequired
namestringrequiredAnzeigename, den die empfangende Person sieht (1–200 Zeichen). Pro Request überschreibbar.
contentTypestringrequired
contentTypestringrequiredapplication/pdf oder ein Bildtyp: image/png, image/jpeg, image/webp,
image/gif, image/svg+xml, image/avif, image/bmp, image/tiff.
Office-Dokumente werden nicht akzeptiert.
sizenumberrequired
sizenumberrequiredExakte Byte-Länge. Maximum 25 MB (26.214.400).
sha256stringoptional
sha256stringoptionalHex-Digest der Bytes. Wird nach dem Upload verifiziert, wenn angegeben.
{
"ok": true,
"data": {
"id": "kn7...",
"name": "Lease contract draft",
"contentType": "application/pdf",
"size": 412000,
"uploadUrl": "https://...",
"expiresAt": 1792198800000
}
}PUTe die rohen Bytes innerhalb einer Stunde an uploadUrl, mit Content-Type auf den deklarierten Typ
gesetzt, und referenziere dann die ID von requests.create aus:
{
"method": "requests.create",
"params": {
"formId": "j57...",
"documents": [
{ "documentId": "kn7...", "name": "Your lease contract" },
{ "documentId": "kn8...", "field": "attachments" }
]
}
}fieldist der Feldschlüssel des Dokumente-Blocks. Optional, wenn das Formular genau einen Block hat; erforderlich bei zwei oder mehr.- Die vom Autor hinterlegten Dokumente des Blocks bleiben; deine erscheinen darunter, nur für diese eine empfangende Person.
Obergrenzen: 25 MB pro Dokument, 100 MB Dokumente pro Request, 20 pro Block angezeigte Dokumente einschließlich der vom Autor hinterlegten.
Ein Upload kann von beliebig vielen Requests referenziert werden. Ein Upload, den niemand referenziert, läuft irgendwann aus. Bytes zählen gegen den Speicher des Workspace-Inhabers, bis der letzte Request, der sie referenziert, von der Aufbewahrung gestrippt wird.
Jeder Fehler hier ist 400 VALIDATION_ERROR mit einem details.reason: DOCUMENT_TYPE_NOT_ALLOWED,
DOCUMENT_TOO_LARGE, INVALID_DOCUMENT_NAME oder INVALID_DOCUMENT_SHA256 von dieser Methode, und
DOCUMENT_NOT_FOUND, DOCUMENT_NOT_UPLOADED (du hast das PUT übersprungen),
DOCUMENT_INVALID, INVALID_DOCUMENT_TARGET, DOCUMENTS_TOO_LARGE oder DOCUMENTS_TOO_MANY
von requests.create.
Webhooks
webhooks.list
Webhook-Abonnements für ein Formular auflisten.
formIdstringrequired
formIdstringrequiredFormular-ID.
{
"ok": true,
"data": {
"items": [
{
"subscriptionId": "int_abc123",
"formId": "frm_abc123",
"provider": "zapier",
"targetUrl": "https://hooks.zapier.com/...",
"eventType": "submission_created",
"status": "active",
"createdAt": 1714041851000
}
],
"hasMore": false
}
}webhooks.create
Eine URL für Formularereignisse abonnieren: neue oder abgebrochene Einreichungen, oder Requests, die auf dem Formular enden. Die URL muss HTTPS verwenden.
formIdstringrequired
formIdstringrequiredFormular-ID.
targetUrlstringrequired
targetUrlstringrequiredHTTPS-URL zum Empfangen von Webhook-Payloads.
providerstringrequired
providerstringrequiredZu welchem Tool das Abonnement gehört. Das ist nur ein Label für deine eigene Buchführung — es gibt keine Marketplace-App zu installieren, und jeder Anbieter verhält sich gleich.
zapiermaken8neventTypestringoptionaldefault: submission_created
eventTypestringoptionaldefault: submission_createdEreignistyp, der abonniert werden soll. Die drei submission_-Typen liefern das Einreichungs-Payload:
-Typen liefern das passende
Request-Ereignis, wann immer ein Request auf dem Formular so endet, signiert mit dem
Geheimnis dieses Abonnements; Testanfragen erreichen kein Abonnement.submission_created für eine erste Einreichung, submission_updated für eine Bearbeitung durch die empfangende
Person, und submission_abandoned für einen inaktiven Entwurf. Die drei request_
submission_createdsubmission_updatedsubmission_abandonedrequest_completedrequest_expiredrequest_canceledidleWindowstringoptional
idleWindowstringoptionalErforderlich, wenn eventType gleich submission_abandoned ist; abgelehnt bei jedem anderen Typ.
12h1d3d1wsigningSecretstringoptional
signingSecretstringoptionalOptionales HMAC-Signing-Secret, 32–255 Zeichen. Wenn angegeben, enthalten Zustellungen X-formbase-Signature. Das Secret
wird gespeichert, aber nie von der API zurückgegeben.
curl -X POST https://api.formbase.so/api/v1 \
-H "Authorization: Bearer fb_..." \
-H "Content-Type: application/json" \
-d '{
"method": "webhooks.create",
"params": {
"formId": "frm_abc123",
"targetUrl": "https://hooks.zapier.com/hooks/catch/...",
"provider": "zapier",
"eventType": "submission_created",
"signingSecret": "whsec_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
}
}'{
"ok": true,
"data": {
"subscriptionId": "int_new123",
"formId": "frm_abc123",
"provider": "zapier",
"targetUrl": "https://hooks.zapier.com/hooks/catch/...",
"eventType": "submission_created"
}
}Abonnements für abgebrochene Einreichungen liefern das gewählte idleWindow sowohl von webhooks.create als auch
von webhooks.list zurück. Jedes andere Abonnement lässt es aus.
Ein Request-Abonnement hört dieselben Ereignisse wie ein Callback, aber als eigene Zustellung: eigene
Event-ID, eigene Signatur und ein eigenes Wiederholungsbudget von fünf Versuchen, nach dem das Abonnement pausiert. Ein Request, der mit
einer callbackUrl auf einem Formular mit einem request_completed-Abonnement erstellt wurde, feuert deshalb
zweimal, einmal an jeden Empfänger. requests.replayCallback sendet nur den Callback erneut. Verwende
requests.sample, um das Payload zu sehen, bevor irgendein Request geendet hat.
webhooks.delete
Ein Webhook-Abonnement entfernen.
subscriptionIdstringrequired
subscriptionIdstringrequiredAbonnement-ID aus webhooks.list oder webhooks.create.
{
"ok": true,
"data": {
"subscriptionId": "int_abc123",
"deleted": true
}
}Analysen
analytics.get
Aggregierte Analysekennzahlen für ein Formular abrufen. Unterstützt Datumsbereich, Gerät, Verkehrsquelle und Länderfilter.
Analysen sind eine Pro-Funktion, und die Regel richtet sich nach dem Tarif des Workspace-Eigentümers, genau wie der Analytics-Tab im Dashboard. Ist der Eigentümer nicht auf Pro, gibt der Aufruf UPGRADE_REQUIRED zurück — auch für Verlaufsdaten aus der Zeit davor. Ein Free-Mitglied im Workspace eines Pro-Eigentümers erhält die Daten.
formIdstringrequired
formIdstringrequiredFormular-ID.
fromnumberoptional
fromnumberoptionalBeginn des Datumsbereichs als Unix-Zeitstempel in Millisekunden. Muss kleiner oder gleich to sein, wenn beide gesetzt sind.
tonumberoptional
tonumberoptionalEnde des Datumsbereichs als Unix-Zeitstempel in Millisekunden. Beide weglassen für die gesamte Zeit — period kommt dann als
{ "from": null, "to": null } zurück.
devicestringoptionaldefault: all
devicestringoptionaldefault: allNach Gerätetyp filtern.
alldesktopmobiletablettrafficSourcestringoptional
trafficSourcestringoptionalNach Verkehrsquelle filtern (z. B. “Direct”, “Google”).
countrystringoptional
countrystringoptionalNach 2-Buchstaben-Ländercode filtern (z. B. “US”, “DE”).
includeEventsbooleanoptionaldefault: false
includeEventsbooleanoptionaldefault: falseAuch die bereinigten Analyse-Events hinter den Kennzahlen zurückgeben, für deine eigene Auswertung. Keine Besucher-IDs.
Raten sind Zahlen von 0 bis 100, Zählungen sind Ganzzahlen, und totalEvents ist die rohe Event-Zeilenzahl vor der
Deduplizierung zu eindeutigen Besuchern.
{
"ok": true,
"data": {
"formId": "frm_abc123",
"period": { "from": null, "to": null },
"totalEvents": 17,
"metrics": {
"views": 7,
"uniqueVisitors": 7,
"engaged": 6,
"submissions": 4,
"engagementRate": 86,
"completionRate": 57,
"bounceRate": 14
},
"breakdown": {
"byBrowser": { "Chrome": 17 },
"byCountry": { "US": 10, "DE": 7 },
"byDevice": { "desktop": 14, "mobile": 3 },
"bySource": { "Direct": 12, "Google": 5 }
}
}
}Workspaces
workspaces.list
Die Workspaces auflisten, die dein Token erreichen kann. Keine Parameter.
Ein API-Token ist an einen Workspace gebunden, liefert also genau diesen einen zurück — auch wenn dein Konto zu mehreren gehört.
{
"ok": true,
"data": {
"items": [
{
"id": "ws_abc123",
"name": "Acme Inc",
"createdAt": 1714041800000,
"role": "owner"
}
],
"nextCursor": null,
"hasMore": false,
"canPaginate": false
}
}workspaces.createInvite
Einen Einladungslink für einen Workspace erstellen.
workspaceIdstringrequired
workspaceIdstringrequiredWorkspace-ID.
expiresAtnumberoptional
expiresAtnumberoptionalAblauf als zukünftiger Unix-Zeitstempel in Millisekunden.
maxUsesnumberoptional
maxUsesnumberoptionalMaximale Anzahl der Verwendungen der Einladung.
{
"ok": true,
"data": {
"id": "inv_abc123",
"workspaceId": "ws_abc123",
"code": "aBcDeFgH",
"expiresAt": null,
"maxUses": null,
"uses": 0,
"createdAt": 1714041851000
}
}workspaces.getInvite
Eine einzelne Workspace-Einladung abrufen. Liefert dieselbe Form wie workspaces.createInvite.
inviteIdstringrequired
inviteIdstringrequiredEinladungs-ID.
workspaces.updateInvite
Eine bestehende Workspace-Einladung aktualisieren. Gib mindestens eines von expiresAt oder maxUses an, sonst
wird der Aufruf abgelehnt. Liefert die aktualisierte Einladung.
inviteIdstringrequired
inviteIdstringrequiredEinladungs-ID.
expiresAtnumberoptional
expiresAtnumberoptionalNeuer Ablaufzeitstempel in Millisekunden.
maxUsesnumberoptional
maxUsesnumberoptionalNeues maximales Nutzungslimit.
workspaces.revokeInvite
Eine Workspace-Einladung dauerhaft widerrufen.
inviteIdstringrequired
inviteIdstringrequiredEinladungs-ID.
{
"ok": true,
"data": {
"inviteId": "inv_abc123",
"revoked": true
}
}Ordner
folders.list
Ordner in einem Workspace auflisten.
workspaceIdstringrequired
workspaceIdstringrequiredWorkspace-ID.
limitnumberoptionaldefault: 20
limitnumberoptionaldefault: 20Seitengröße (1–100).
cursorstringoptional
cursorstringoptionalPaginierungs-Cursor.
{
"ok": true,
"data": {
"items": [
{
"id": "fld_abc123",
"name": "Customer Feedback",
"workspaceId": "ws_abc123",
"parentId": null,
"createdAt": 1714041800000
}
],
"nextCursor": null,
"hasMore": false,
"canPaginate": false
}
}folders.create
Einen Ordner in einem Workspace erstellen. Idempotent — gibt den bestehenden Ordner zurück, wenn bereits ein Ordner mit demselben Namen existiert.
workspaceIdstringrequired
workspaceIdstringrequiredWorkspace-ID.
namestringrequired
namestringrequiredOrdnername (1–255 Zeichen).
parentIdstring | nulloptional
parentIdstring | nulloptionalÜbergeordnete Ordner-ID für Verschachtelung. Für Root-Ebene weglassen.
{
"ok": true,
"data": {
"id": "fld_new123",
"name": "Customer Feedback",
"workspaceId": "ws_abc123",
"parentId": null,
"createdAt": 1714041851000,
"alreadyExisted": false
}
}folders.update
Einen Ordner umbenennen oder in einen anderen übergeordneten Ordner verschieben.
folderIdstringrequired
folderIdstringrequiredOrdner-ID.
namestringoptional
namestringoptionalNeuer Ordnername (1–255 Zeichen).
parentIdstring | nulloptional
parentIdstring | nulloptionalNeuer übergeordneter Ordner. null übergeben, um in den Root zu verschieben.
folders.delete
Einen Ordner und seinen gesamten Inhalt (Unterordner und Formulare) dauerhaft löschen.
folderIdstringrequired
folderIdstringrequiredOrdner-ID.
Destruktive Aktion
Diese Aktion löscht dauerhaft alle Unterordner und Formulare im Ordner. Sie kann nicht rückgängig gemacht werden.
{
"ok": true,
"data": {
"folderId": "fld_abc123",
"deletedFolderIds": ["fld_abc123"],
"deletedFormIds": ["frm_in_folder"],
"message": "Folder and 1 form deleted."
}
}Übersetzungen
translations.listLanguages
Alle für ein Formular konfigurierten Sprachen auflisten.
formIdstringrequired
formIdstringrequiredFormular-ID.
{
"ok": true,
"data": {
"formId": "frm_abc123",
"items": [
{
"language": "es",
"completion": { "total": 15, "current": 12, "outdated": 2, "missing": 1, "suggested": 0 },
"lastUpdatedAt": 1714041851000
}
],
"nextCursor": null,
"hasMore": false,
"canPaginate": false
}
}translations.addLanguage
Eine Sprache auf einem Formular registrieren. Jede andere Übersetzungsmethode schlägt mit 404 NOT_FOUND fehl, bis du das getan hast.
formIdstringrequired
formIdstringrequiredFormular-ID.
languagestringrequired
languagestringrequiredBCP-47-Sprachtag (z. B. “es”, “pt-BR”).
{
"ok": true,
"data": {
"formId": "frm_abc123",
"language": "es",
"rowId": "tl_new123"
}
}translations.removeLanguage
Eine Sprache und alle ihre Übersetzungen aus einem Formular entfernen.
formIdstringrequired
formIdstringrequiredFormular-ID.
languagestringrequired
languagestringrequiredBCP-47-Sprachtag.
translations.listEntries
Jeden Quellschlüssel für eine Sprache in einem Formular auflisten, mit seinem aktuellen Zustand. So findest du die key-Werte, die
translations.setEntry erwartet.
formIdstringrequired
formIdstringrequiredFormular-ID.
languagestringrequired
languagestringrequiredBCP-47-Sprachtag. Muss bereits auf dem Formular sein.
{
"ok": true,
"data": {
"formId": "frm_abc123",
"language": "es",
"completion": { "total": 15, "current": 12, "outdated": 2, "missing": 1, "suggested": 0 },
"items": [
{
"key": "block_q_1.title",
"status": "current",
"value": "[{\"text\":\"Tu correo electrónico\"}]",
"sourceFragment": "[{\"text\":\"Your email\"}]",
"updatedAt": 1714041851000,
"block": { "id": "q_1", "type": "email-input", "label": "Your email" }
}
],
"hasMore": false
}
}status ist missing (nichts gespeichert), outdated (die Quelle hat sich seither geändert),
current, oder suggested (ein KI-Vorschlag, vorgemerkt, aber nicht übernommen). Schlüssel decken Formularinhalt
ab (block_<id>.) und, sobald ein Autor sie angepasst hat, die Bestätigungs- und Erinnerungs-E-Mails an die ausfüllende
Person (, email.confirmation.email.reminder.*).
translations.setEntry
Einen einzelnen Übersetzungseintrag setzen. Die Sprache muss zuvor über translations.addLanguage hinzugefügt worden sein.
formIdstringrequired
formIdstringrequiredFormular-ID.
languagestringrequired
languagestringrequiredBCP-47-Sprachtag.
keystringrequired
keystringrequiredEin Schlüssel aus translations.listEntries. Nicht von Hand konstruieren.
valuestringrequired
valuestringrequiredDas übersetzte Fragment, JSON-stringifiziert. Seine Markup-Struktur muss der des Quellfragments entsprechen.
curl -X POST https://api.formbase.so/api/v1 \
-H "Authorization: Bearer fb_..." \
-H "Content-Type: application/json" \
-d '{
"method": "translations.setEntry",
"params": {
"formId": "frm_abc123",
"language": "es",
"key": "block_q_1.title",
"value": "[{\"text\":\"Tu correo electrónico\"}]"
}
}'Schreiben hier ist live
Die API hat keinen Entwurf-dann-Veröffentlichen-Schritt: Ein setEntry oder deleteEntry erreicht Befragte
sofort. Das Dashboard und die MCP-Übersetzungstools nutzen stattdessen einen Entwurf.
Liefert { formId, language, key }.
translations.deleteEntry
Einen einzelnen Übersetzungseintrag löschen und diesen Schlüssel zur Standardsprache des Formulars zurücksetzen. Idempotent. Verschwindet der letzte Eintrag einer Sprache, fällt die Sprache aus den veröffentlichten Sprachen des Formulars.
formIdstringrequired
formIdstringrequiredFormular-ID.
languagestringrequired
languagestringrequiredBCP-47-Sprachtag.
keystringrequired
keystringrequiredZu löschender Übersetzungsschlüssel.
Konto
me.get
Informationen über den authentifizierten Benutzer abrufen.
{
"ok": true,
"data": {
"id": "usr_abc123",
"email": "you@example.com",
"name": "Jane Doe"
}
}Meta
methods.list
Jeden Methodennamen auflisten, den dieses Deployment bereitstellt, sortiert. Die maßgebliche Antwort, wenn diese Seite und der Server sich widersprechen.
{
"ok": true,
"data": {
"methods": [
"methods.list",
"analytics.get",
"folders.create",
"folders.delete",
"folders.list",
"folders.update",
"formSettings.get",
"formSettings.update",
"forms.create",
"forms.delete",
"forms.get",
"forms.list",
"..."
]
}
}Fehlerreferenz
Jede Fehlerantwort hat dieselbe Form. Das Set der obersten code-Werte ist absichtlich geschlossen: Ein neuer Fehlerfall fügt nie einen
Code hinzu, sondern einen reason. Verzweige nach code für das Ergebnis auf HTTP-Ebene und nach details.reason für die Behebung.
{
"ok": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "No field with key \"company\" on this form.",
"details": { "reason": "UNKNOWN_FIELD_KEY", "field": "prefill.company", "validKeys": ["company_name", "contacts"] }
}
}details ist immer vorhanden, wenn der Server die Ursache benennen kann. Neben reason kann es field
tragen (der problematische Parameter, mit Punkten für Verschachtelung), validKeys, validValues (die
Werte der Optionen, die eine Auswahlfrage akzeptiert), expectedType, feature (bei
UPGRADE_REQUIRED) und retryAfterMs (bei einem gedrosselten Aufruf). Gründe für die jeweilige Anfrage stehen bei
jeder Methode oben.
Das sind alle Codes:
VALIDATION_ERROR400optional
VALIDATION_ERROR400optionalUngültige oder fehlende Parameter in der Anfrage.
UNAUTHORIZED401optional
UNAUTHORIZED401optionalFehlendes oder ungültiges API-Token.
FORBIDDEN403optional
FORBIDDEN403optionalToken hat keinen Zugriff auf die angeforderte Ressource.
NOT_FOUND404optional
NOT_FOUND404optionalRessource existiert nicht.
METHOD_NOT_FOUND404optional
METHOD_NOT_FOUND404optionalUnbekannter Methodenname. methods.list verwenden, um verfügbare Methoden zu sehen.
CONFLICT409optional
CONFLICT409optionalDie Ressource ist nicht in einem Zustand, der diesen Aufruf erlaubt — ein Request, der nicht mehr aussteht, ein Idempotenzschlüssel, der mit einem anderen Body wiederverwendet wurde.
RATE_LIMITED429optional
RATE_LIMITED429optionalÜber 120 Aufrufe pro Minute auf diesem Token, über 60 requests.create-Aufrufe pro Minute, oder zu viele fehlgeschlagene
Authentifizierungen von dieser IP.
UPGRADE_REQUIRED402optional
UPGRADE_REQUIRED402optionalFunktion erfordert einen höheren Abonnement-Tarif, der Workspace hat sein monatliches Kontingent aufgebraucht (Grund
MONTHLY_ALLOWANCE_REACHED), oder ein Free-Konto hat seine 10 kostenlosen Einladungen aufgebraucht (Grund
FREE_INVITATIONS_USED).
INTERNAL_ERROR500optional
INTERNAL_ERROR500optionalUnerwarteter Serverfehler. Später erneut versuchen.