Skip to main content
These endpoints require your login session: the ff_token cookie, or the same JWT sent as Authorization: Bearer <token>. Integrations belong to a form, and each form has at most one integration of each type. Integration configs are encrypted at rest with AES-256-GCM. Secrets (apiKey, webhook secret, Google refreshToken) are masked as •••••••• whenever a config is returned.

List a form’s integrations

Create an integration

Types: EMAIL, WEBHOOK, GOOGLE_SHEETS. Posting a type the form already has replaces that integration’s config. Returns 201 with { "integration": { "id", "type", "name", "enabled", "createdAt" } }.

EMAIL config

WEBHOOK config

GOOGLE_SHEETS config

Google Sheets is connected through Google OAuth from the form’s Integrations tab, not with this endpoint. See Google Sheets.

Get an integration

Returns { "integration": { "_id", "type", "name", "enabled", "config", "createdAt", "updatedAt" } } with secrets masked.

Update an integration

Updatable fields: name, enabled, config. config replaces the stored config, so send the complete object. To keep an existing webhook secret without resending it, pass "secret": "__KEEP_EXISTING__".

Delete an integration

Returns { "success": true }.

Test an integration

Runs the integration once with sample data (Test User, [email protected], and a few more fields). No submission is created.
If the integration fails, you get 400 with { "error": "Test failed", "message": "<provider error>" }.

Integration status

Returns type, name, and enabled. For Google Sheets it also returns connectedEmail, spreadsheetId, spreadsheetUrl, and sheetName. Per-submission success or failure is in the integration logs.