API Documentation

Integrate WorkForm with your applications using our RESTful API. Perfect for automation tools like Zapier, Make, and custom integrations.

Quick Start

Base URL

https://app.getworkform.com/api/v1

Authentication

All API requests must include your API key in the request headers:

X-API-Key: workform_your_api_key_here

Getting Your API Key

  1. Navigate to Workspace Settings
  2. Go to API Keys section
  3. Click "Create New API Key"
  4. Select required permissions
  5. Copy and securely store the key
Forms API
GET
/api/v1/forms

List all forms in your workspace

Query Parameters

pagePage number (default: 1)
limitResults per page (default: 20, max: 100)
statusFilter by status (draft, published, archived)

Required Permission

forms:read

Example Response

{
  "success": true,
  "data": [
    {
      "id": "507f1f77bcf86cd799439011",
      "publicId": "abc123",
      "title": "Contact Form",
      "description": "Main contact form",
      "type": "standard-form",
      "formStatus": {
        "status": "published",
        "isPublic": true
      },
      "createdAt": "2024-01-01T00:00:00.000Z",
      "updatedAt": "2024-01-02T00:00:00.000Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 45,
    "totalPages": 3
  }
}
POST
/api/v1/responses

Submit a new form response programmatically

Required Permission

responses:write

Request Body

{
  "formId": "abc123",
  "responses": {
    "email": "user@example.com",
    "name": "John Doe",
    "message": "Hello from API!"
  }
}

Example Response

{
  "success": true,
  "message": "Response created successfully.",
  "data": {
    "id": "507f1f77bcf86cd799439011",
    "responseId": "resp_abc123",
    "formId": "abc123",
    "status": "completed",
    "createdAt": "2024-01-01T00:00:00.000Z"
  }
}
GET
/api/v1/forms/{formId}

Get details of a specific form

Path Parameters

formIdThe form's public ID or MongoDB _id

Required Permission

forms:read

Example Response

{
  "success": true,
  "data": {
    "_id": "507f1f77bcf86cd799439011",
    "publicId": "abc123",
    "title": "Contact Form",
    "description": "Main contact form",
    "formType": "standard",
    "formStatus": { "status": "published" },
    "design": { ... },
    "settings": { ... },
    "createdAt": "2024-01-01T00:00:00.000Z"
  }
}
POST
/api/v1/forms

Create a new form

Required Permission

forms:write

Request Body

{
  "title": "Contact Form",
  "description": "Main contact form",
  "formType": "standard"
}

Example Response

{
  "success": true,
  "data": {
    "_id": "507f1f77bcf86cd799439011",
    "publicId": "abc123",
    "title": "Contact Form",
    "formType": "standard",
    "createdAt": "2024-01-01T00:00:00.000Z"
  }
}
PATCH
/api/v1/forms/{formId}

Update an existing form

Required Permission

forms:write

Allowed Update Fields

titleForm title
descriptionForm description
formStatusForm status object
settingsForm settings

Request Body

{
  "title": "Updated Contact Form",
  "description": "Updated description",
  "formStatus": {
    "status": "published",
    "isPublic": true
  }
}

Example Response

{
  "success": true,
  "message": "Form updated successfully.",
  "data": {
    "publicId": "abc123",
    "title": "Updated Contact Form",
    "description": "Updated description",
    "formStatus": {
      "status": "published",
      "isPublic": true
    },
    "updatedAt": "2024-01-02T00:00:00.000Z"
  }
}
DELETE
/api/v1/forms/{formId}

Delete a form

Required Permission

forms:delete

Example Response

{
  "success": true,
  "message": "Form deleted successfully"
}
Responses API

Historical Accuracy with Question Metadata

All response endpoints return question details (title, description, type) as they were at the time of submission. This is stored in the questionMetadata field and ensures data accuracy even if you later modify or delete questions from your form.

GET
/api/v1/responses

List all form responses

Query Parameters

formIdFilter by form ID or public ID
pagePage number (default: 1)
limitResults per page (default: 50, max: 100)
statusFilter by status (completed, partial)
startDateFilter by start date (ISO 8601)
endDateFilter by end date (ISO 8601)

Required Permission

responses:read

Example Response

{
  "success": true,
  "data": [
    {
      "id": "507f1f77bcf86cd799439011",
      "responseId": "resp_abc123",
      "form": {
        "id": "abc123",
        "title": "Contact Form"
      },
      "responses": [
        {
          "questionId": "q1_email",
          "question": {
            "id": "q1_email",
            "title": "Email Address",
            "description": "Please provide your email",
            "type": "email"
          },
          "answer": "user@example.com"
        },
        {
          "questionId": "q2_name",
          "question": {
            "id": "q2_name",
            "title": "Full Name",
            "description": "",
            "type": "short-text"
          },
          "answer": "John Doe"
        }
      ],
      "status": "completed",
      "submittedAt": "2024-01-01T00:00:00.000Z",
      "ipAddress": "192.168.1.1",
      "deviceType": "Desktop",
      "completionTime": 120,
      "createdAt": "2024-01-01T00:00:00.000Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 50,
    "total": 156,
    "totalPages": 4
  }
}
GET
/api/v1/forms/{ formId}/responses

Get all responses for a specific form with enriched question details

Question Metadata

Responses include question metadata as it was at submission time. This ensures you see the correct question titles and descriptions even if the form was later modified or questions were deleted.

Path Parameters

formIdThe form's MongoDB _id or publicId

Query Parameters

pagePage number (default: 1)
limitResults per page (default: 50, max: 100)
statusFilter by status (completed, incomplete)
startDateFilter by start date (ISO 8601)
endDateFilter by end date (ISO 8601)

Required Permission

responses:read

Example Response

{
  "success": true,
  "data": {
    "form": {
      "id": "abc123",
      "title": "Contact Form",
      "description": "Get in touch with us",
      "type": "standard-form"
    },
    "responses": [
      {
        "id": "507f1f77bcf86cd799439011",
        "responseId": "resp_abc123",
        "formId": "abc123",
        "formTitle": "Contact Form",
        "responses": [
          {
            "questionId": "q1_email",
            "question": {
              "id": "q1_email",
              "title": "Email Address",
              "description": "Please provide your email",
              "type": "email"
            },
            "answer": "user@example.com"
          },
          {
            "questionId": "q2_name",
            "question": {
              "id": "q2_name",
              "title": "Full Name",
              "description": "",
              "type": "short-text"
            },
            "answer": "John Doe"
          },
          {
            "questionId": "q3_message",
            "question": {
              "id": "q3_message",
              "title": "Your Message",
              "description": "Tell us how we can help",
              "type": "long-text"
            },
            "answer": "I'd like to discuss a project"
          }
        ],
        "status": "completed",
        "submittedAt": "2024-01-01T00:00:00.000Z",
        "ipAddress": "192.168.1.1",
        "deviceType": "Desktop",
        "completionTime": 120,
        "createdAt": "2024-01-01T00:00:00.000Z"
      }
    ],
    "pagination": {
      "page": 1,
      "limit": 50,
      "total": 42,
      "totalPages": 1
    }
  }
}

Path Parameters

responseIdThe response's MongoDB _id or responseId

Required Permission

responses:read

Example Response

{
  "success": true,
  "data": {
    "id": "507f1f77bcf86cd799439011",
    "responseId": "resp_abc123",
    "form": {
      "id": "507f1f77bcf86cd799439012",
      "publicId": "abc123",
      "title": "Contact Form"
    },
    "responses": [
      {
        "questionId": "q1_email",
        "question": {
          "id": "q1_email",
          "title": "Email Address",
          "description": "Please provide your email",
          "type": "email"
        },
        "answer": "user@example.com"
      },
      {
        "questionId": "q2_name",
        "question": {
          "id": "q2_name",
          "title": "Full Name",
          "description": "",
          "type": "short-text"
        },
        "answer": "John Doe"
      },
      {
        "questionId": "q3_message",
        "question": {
          "id": "q3_message",
          "title": "Your Message",
          "description": "Tell us how we can help",
          "type": "long-text"
        },
        "answer": "Hello!"
      }
    ],
    "status": "completed",
    "startedAt": "2023-12-31T23:55:00.000Z",
    "submittedAt": "2024-01-01T00:00:00.000Z",
    "ipAddress": "192.168.1.1",
    "userAgent": "Mozilla/5.0...",
    "browser": { "name": "Chrome", "version": "120.0", "os": "macOS" },
    "deviceType": "Desktop",
    "language": "en-US",
    "completionTime": 120,
    "createdAt": "2024-01-01T00:00:00.000Z",
    "updatedAt": "2024-01-01T00:00:00.000Z"
  }
}
DELETE
/api/v1/responses/{responseId}

Delete a response

Required Permission

responses:delete
Webhooks API

Complete Webhooks Guide

For detailed webhook documentation including payload structure, security, retry logic, and troubleshooting, see the Webhooks Documentation.

GET
/api/v1/webhooks

List all webhooks

Query Parameters

formIdFilter by form ID

Required Permission

webhooks:read
POST
/api/v1/webhooks

Create a new webhook

Required Permission

webhooks:write

Request Body

{
  "formId": "abc123",
  "url": "https://your-app.com/webhook",
  "events": ["form.submitted"],
  "active": true
}
PUT
/api/v1/webhooks/{webhookId}

Update a webhook

Required Permission

webhooks:write
DELETE
/api/v1/webhooks/{webhookId}

Delete a webhook

Required Permission

webhooks:delete
Error Handling

The API uses standard HTTP status codes and returns errors in a consistent format:

Error Response Format

{
  "success": false,
  "error": "Error message here",
  "code": "ERROR_CODE"
}

Common Status Codes

200
Success
201
Created
400
Bad Request - Invalid parameters
401
Unauthorized - Invalid or missing API key
403
Forbidden - Insufficient permissions
404
Not Found - Resource doesn't exist
429
Too Many Requests - Rate limit exceeded
500
Server Error - Something went wrong
Rate Limits

API requests are rate-limited to ensure fair usage:

  • 100 requests per minute per API key
  • 1000 requests per hour per API key

Rate limit headers are included in all responses:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1640995200
API Permissions

When creating an API key, you can grant specific permissions:

Forms Permissions

forms:read
forms:write
forms:delete

Responses Permissions

responses:read
responses:delete

Webhooks Permissions

webhooks:read
webhooks:write
webhooks:delete

Analytics Permissions

analytics:read
Code Examples
// Fetch all forms
const response = await fetch('https://app.getworkform.com/api/v1/forms', {
  headers: {
    'X-API-Key': 'workform_your_api_key_here',
    'Content-Type': 'application/json'
  }
});

const data = await response.json();
console.log(data);