Forms

Forms are the core resource in formdata.dev. Each form gets a unique public key (pk_ prefix) used in the ingestion URL.

All form endpoints require the x-tenant-key header.

List Forms

Request

GET /v1/admin/forms x-tenant-key: sk_live_abc123...

Example

curl https://api.formdata.dev/v1/admin/forms \
  -H "x-tenant-key: sk_live_abc123..."

Response (200)

{
  "ok": true,
  "forms": [
    {
      "id": "f1234567-89ab-cdef-0123-456789abcdef",
      "organization_id": "a1b2c3d4-...",
      "name": "Contact Form",
      "slug": "contact-form",
      "public_key": "pk_abc123...",
      "allowed_origins": ["https://example.com"],
      "verify_captcha": 0,
      "captcha_secret": null,
      "is_enabled": 1,
      "created_at": "2026-03-18T12:00:00.000Z",
      "updated_at": "2026-03-18T12:00:00.000Z"
    }
  ]
}

Create Form

Request

POST /v1/admin/forms Content-Type: application/json x-tenant-key: sk_live_abc123...

Schema

Field Type Required Default Constraints Description
name string Yes 2 - 120 chars Display name
slug string Yes 2 - 80 chars, ^[a-z0-9-]+$ URL-safe identifier
allowedOrigins string[] No [] Each must be a valid URL Origins allowed to submit; empty = allow all
verifyCaptcha boolean No false Enable captcha verification
captchaSecret string Conditional min 8 chars Required when verifyCaptcha is true
isEnabled boolean No true Whether the form accepts submissions

Example

curl -X POST https://api.formdata.dev/v1/admin/forms \
  -H "Content-Type: application/json" \
  -H "x-tenant-key: sk_live_abc123..." \
  -d '{
    "name": "Contact Form",
    "slug": "contact-form",
    "allowedOrigins": ["https://example.com"],
    "verifyCaptcha": false,
    "isEnabled": true
  }'

Response (200)

{
  "ok": true,
  "form": {
    "id": "f1234567-89ab-cdef-0123-456789abcdef",
    "publicKey": "pk_abc123...",
    "organizationId": "a1b2c3d4-...",
    "name": "Contact Form",
    "slug": "contact-form",
    "allowedOrigins": ["https://example.com"],
    "verifyCaptcha": false,
    "isEnabled": true
  }
}
Public Key

The publicKey field is what you use in the ingestion URL: POST /v1/f/pk_abc123...

Errors

Status Error Cause
400 Validation error Missing or invalid fields
400 captchaSecret is required when verifyCaptcha is true Captcha enabled without a secret

Get Form

Returns a single form along with all of its configured destinations.

Request

GET /v1/admin/forms/:id x-tenant-key: sk_live_abc123...

Example

curl https://api.formdata.dev/v1/admin/forms/f1234567-89ab-cdef-0123-456789abcdef \
  -H "x-tenant-key: sk_live_abc123..."

Response (200)

{
  "ok": true,
  "form": {
    "id": "f1234567-89ab-cdef-0123-456789abcdef",
    "organization_id": "a1b2c3d4-...",
    "name": "Contact Form",
    "slug": "contact-form",
    "public_key": "pk_abc123...",
    "allowed_origins": ["https://example.com"],
    "verify_captcha": 0,
    "captcha_secret": null,
    "is_enabled": 1,
    "created_at": "2026-03-18T12:00:00.000Z",
    "updated_at": "2026-03-18T12:00:00.000Z"
  },
  "destinations": [
    {
      "id": "d1234567-...",
      "form_id": "f1234567-...",
      "type": "webhook",
      "config": {
        "url": "https://hooks.slack.com/...",
        "method": "POST",
        "headers": {}
      },
      "is_enabled": 1,
      "created_at": "2026-03-18T12:00:00.000Z",
      "updated_at": "2026-03-18T12:00:00.000Z"
    }
  ]
}

Errors

Status Error Cause
404 Form not found Invalid form ID or belongs to another organization

Update Form

Supports partial updates. Only include the fields you want to change.

Request

PUT /v1/admin/forms/:id Content-Type: application/json x-tenant-key: sk_live_abc123...

Schema

Field Type Required Constraints Description
name string No 2 - 120 chars Display name
allowedOrigins string[] No Each must be a valid URL Allowed origins
verifyCaptcha boolean No Toggle captcha
captchaSecret string No min 8 chars Captcha secret
isEnabled boolean No Enable or disable the form

Example

curl -X PUT https://api.formdata.dev/v1/admin/forms/f1234567-89ab-cdef-0123-456789abcdef \
  -H "Content-Type: application/json" \
  -H "x-tenant-key: sk_live_abc123..." \
  -d '{
    "name": "Updated Contact Form",
    "isEnabled": false
  }'

Response (200)

{
  "ok": true,
  "form": {
    "id": "f1234567-89ab-cdef-0123-456789abcdef",
    "organization_id": "a1b2c3d4-...",
    "name": "Updated Contact Form",
    "slug": "contact-form",
    "public_key": "pk_abc123...",
    "allowed_origins": ["https://example.com"],
    "verify_captcha": 0,
    "captcha_secret": null,
    "is_enabled": 0,
    "created_at": "2026-03-18T12:00:00.000Z",
    "updated_at": "2026-03-18T14:00:00.000Z"
  }
}

Errors

Status Error Cause
400 No fields to update Request body contains no recognized fields
404 Form not found Invalid form ID or belongs to another organization

Delete Form

Deletes the form and all of its destinations. Also removes the form's KV entry so the public key stops accepting submissions immediately.

Request

DELETE /v1/admin/forms/:id x-tenant-key: sk_live_abc123...

Example

curl -X DELETE https://api.formdata.dev/v1/admin/forms/f1234567-89ab-cdef-0123-456789abcdef \
  -H "x-tenant-key: sk_live_abc123..."

Response (200)

{
  "ok": true
}

Errors

Status Error Cause
404 Form not found Invalid form ID or belongs to another organization