API Reference

Complete API reference for Transactional Forms

Forms API Reference

Complete reference for all Forms API endpoints.

Authentication

All API requests require an API key passed in the X-API-Key header:

curl -X GET https://api.usetransactional.com/v1/forms \
  -H "X-API-Key: your-api-key"

Base URL

https://api.usetransactional.com/v1

Forms

List Forms

GET /forms

Query parameters:

ParameterTypeDescription
pagenumberPage number (default: 1)
limitnumberItems per page (default: 20, max: 100)
statusstringFilter by status: DRAFT, LIVE, PAUSED, CLOSED, ARCHIVED
searchstringSearch by title

Response:

{
  "data": [
    {
      "id": 1,
      "uuid": "form-uuid-here",
      "title": "Contact Form",
      "slug": "contact-form",
      "status": "LIVE",
      "createdAt": "2024-01-15T10:00:00Z",
      "updatedAt": "2024-01-15T10:00:00Z",
      "publishedAt": "2024-01-15T10:30:00Z"
    }
  ],
  "meta": {
    "page": 1,
    "limit": 20,
    "total": 45,
    "totalPages": 3
  }
}

Get Form

GET /forms/:formId

Response:

{
  "data": {
    "id": 1,
    "uuid": "form-uuid-here",
    "title": "Contact Form",
    "slug": "contact-form",
    "description": "Get in touch with us",
    "status": "LIVE",
    "settings": {
      "accessType": "PUBLIC"
    },
    "theme": {
      "preset": "MODERN",
      "colors": {
        "primary": "#3B82F6",
        "background": "#F8FAFC",
        "text": "#1E293B"
      }
    },
    "fields": [
      {
        "id": 1,
        "type": "SHORT_TEXT",
        "label": "Name",
        "required": true,
        "order": 0
      }
    ],
    "analytics": {
      "views": 1500,
      "submissions": 800,
      "completionRate": 0.53
    },
    "createdAt": "2024-01-15T10:00:00Z",
    "updatedAt": "2024-01-15T10:00:00Z"
  }
}

Create Form

POST /forms

Request body:

{
  "title": "Contact Form",
  "slug": "contact-form",
  "description": "Get in touch with us",
  "settings": {
    "accessType": "PUBLIC"
  },
  "theme": {
    "preset": "MODERN"
  },
  "fields": [
    {
      "type": "SHORT_TEXT",
      "label": "Name",
      "required": true,
      "order": 0
    },
    {
      "type": "EMAIL",
      "label": "Email",
      "required": true,
      "order": 1
    }
  ]
}

Response: 201 Created

{
  "data": {
    "id": 1,
    "uuid": "form-uuid-here",
    "title": "Contact Form",
    "status": "DRAFT"
  }
}

Update Form

PUT /forms/:formId

Request body:

{
  "title": "Updated Contact Form",
  "description": "New description",
  "theme": {
    "preset": "BOLD"
  }
}

Response: 200 OK

Delete Form

DELETE /forms/:formId

Archives the form (soft delete).

Response: 204 No Content

Publish Form

POST /forms/:formId/publish

Changes form status to LIVE.

Response:

{
  "data": {
    "id": 1,
    "status": "LIVE",
    "publishedAt": "2024-01-15T10:30:00Z"
  }
}

Unpublish Form

POST /forms/:formId/unpublish

Changes form status to PAUSED.

Duplicate Form

POST /forms/:formId/duplicate

Creates a copy of the form with all fields.

Response:

{
  "data": {
    "id": 2,
    "uuid": "new-form-uuid",
    "title": "Contact Form (Copy)",
    "status": "DRAFT"
  }
}

Fields

Add Field

POST /forms/:formId/fields

Request body:

{
  "type": "LONG_TEXT",
  "label": "Message",
  "placeholder": "Your message here...",
  "required": true,
  "order": 2,
  "settings": {
    "minLength": 10,
    "maxLength": 500
  }
}

Update Field

PUT /forms/:formId/fields/:fieldId

Request body:

{
  "label": "Your Message",
  "required": false
}

Delete Field

DELETE /forms/:formId/fields/:fieldId

Reorder Fields

POST /forms/:formId/fields/reorder

Request body:

{
  "fieldOrder": [3, 1, 2, 4]
}

Submissions

List Submissions

GET /forms/:formId/submissions

Query parameters:

ParameterTypeDescription
pagenumberPage number
limitnumberItems per page
statusstringpartial or complete
startDatestringISO date string
endDatestringISO date string

Get Submission

GET /forms/:formId/submissions/:submissionId

Delete Submission

DELETE /forms/:formId/submissions/:submissionId

Export Submissions

GET /forms/:formId/submissions/export

Query parameters:

ParameterTypeDescription
formatstringcsv or json
startDatestringISO date string
endDatestringISO date string

Analytics

Get Form Analytics

GET /forms/:formId/analytics

Query parameters:

ParameterTypeDescription
startDatestringISO date string
endDatestringISO date string
groupBystringday, week, month

Response:

{
  "data": {
    "summary": {
      "views": 1500,
      "starts": 1200,
      "completions": 800,
      "completionRate": 0.667
    },
    "daily": [
      {
        "date": "2024-01-15",
        "views": 150,
        "starts": 120,
        "completions": 80
      }
    ]
  }
}

Public Endpoints

These endpoints are used for form rendering and submission. By default, they don't require authentication, but forms can be configured to require API key authentication.

API Key Authentication for Submissions

Forms can be configured to require API key authentication for submissions. When requireApiKey is enabled in form settings:

  • Web form submissions are disabled
  • API submissions must include X-API-Key header with a valid organization API key
curl -X POST https://api.usetransactional.com/v1/f/form-uuid/submit \
  -H "Content-Type: application/json" \
  -H "X-API-Key: org_your_api_key" \
  -d '{"answers": [...]}'

Get Form for Rendering

GET /f/:formUuid

Returns form data for public rendering. Use form UUID or slug.

Response:

{
  "data": {
    "uuid": "abc-123-uuid",
    "title": "Contact Form",
    "description": "Get in touch with us",
    "fields": [
      {
        "ref": "field_a1b2c3d4",
        "type": "SHORT_TEXT",
        "label": "Name",
        "required": true
      },
      {
        "ref": "field_e5f6g7h8",
        "type": "EMAIL",
        "label": "Email",
        "required": true
      }
    ],
    "settings": {
      "requiresAuth": false,
      "hasPassword": false
    }
  }
}

Track View Event

POST /f/:formUuid/view

Request body:

{
  "sessionId": "session-uuid",
  "visitorHash": "visitor-fingerprint",
  "referrer": "https://example.com"
}

Submit Form

POST /f/:formUuid/submit

Submit form responses. Use field ref values from the form definition to identify fields.

Request body:

{
  "answers": [
    {
      "fieldRef": "field_a1b2c3d4",
      "value": "John Doe"
    },
    {
      "fieldRef": "field_e5f6g7h8",
      "value": "john@example.com"
    },
    {
      "fieldRef": "field_i9j0k1l2",
      "value": "Hello, this is my message!"
    }
  ],
  "respondentEmail": "john@example.com",
  "metadata": {
    "source": "api",
    "referrer": "https://example.com",
    "utm": {
      "source": "google",
      "medium": "cpc",
      "campaign": "spring-2024"
    }
  }
}

Response:

{
  "data": {
    "submissionId": "submission-uuid",
    "status": "COMPLETED",
    "redirectUrl": "https://example.com/thank-you"
  }
}

Answer Field Types

Field TypeValue Format
SHORT_TEXT, LONG_TEXT, EMAIL, URL, PHONE"value": "string"
NUMBER, RATING, NPS, SLIDER"valueNumber": 42
DATE, DATE_TIME"valueDate": "2024-01-15T10:00:00Z"
SELECT, MULTI_SELECT, CHECKBOX"valueJson": ["option1", "option2"]
FILE"fileUrl": "...", "fileName": "...", "fileSize": 1234

Save Partial Progress

POST /f/:formUuid/partial

Save partial submission for resuming later.

Request body:

{
  "submissionId": "optional-existing-submission-uuid",
  "respondentEmail": "john@example.com",
  "lastFieldId": 2,
  "answers": [
    {
      "fieldRef": "field_a1b2c3d4",
      "value": "John Doe"
    }
  ]
}

Response:

{
  "data": {
    "submissionId": "partial-submission-uuid"
  }
}

Error Responses

All endpoints return errors in this format:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid field type",
    "details": {
      "field": "type",
      "received": "INVALID_TYPE",
      "expected": ["SHORT_TEXT", "LONG_TEXT", "EMAIL", "..."]
    }
  }
}

Error Codes

CodeHTTP StatusDescription
UNAUTHORIZED401Invalid or missing API key
FORBIDDEN403Access denied
NOT_FOUND404Resource not found
VALIDATION_ERROR400Invalid request data
RATE_LIMITED429Too many requests
INTERNAL_ERROR500Server error

Rate Limits

Endpoint TypeRate Limit
Management APIs100 req/min
Public APIs1000 req/min
Submission10 req/min per IP

Webhooks

See Webhooks documentation for webhook configuration.

Next Steps