API Reference
Rowform provides a REST API for integrations like Zapier. All endpoints are hosted at https://rowform.io/api/zapier/.
Authentication
All API requests require an API key passed via the X-API-Key header.
X-API-Key: rk_live_your_api_key_hereGenerate API keys from Organization Settings > API Keys in your Rowform dashboard.
Rate Limits
All endpoints are rate-limited to 60 requests per hour per API key per endpoint. Exceeding this returns 429 Too Many Requests.
Endpoints
Test Authentication
Verify that your API key is valid.
GET /api/zapier/authHeaders:
| Header | Required | Description |
|---|---|---|
X-API-Key | Yes | Your Rowform API key |
Response (200):
{
"id": "user-uuid",
"email": "user@example.com",
"name": "John Doe",
"key_name": "My API Key",
"scopes": ["read:forms", "read:responses", "write:webhooks"]
}Errors:
| Status | Description |
|---|---|
| 401 | Invalid, expired, or disabled API key |
| 429 | Rate limit exceeded |
List Forms
Returns all forms belonging to the authenticated user.
GET /api/zapier/formsHeaders:
| Header | Required | Description |
|---|---|---|
X-API-Key | Yes | Your Rowform API key |
Response (200):
[
{
"id": "form-uuid",
"title": "Customer Feedback Survey",
"description": "Collect feedback from customers",
"is_published": true,
"created_at": "2026-01-15T10:00:00.000Z",
"updated_at": "2026-02-01T14:30:00.000Z",
"label": "Customer Feedback Survey"
}
]Draft forms include (Draft) in the label field.
Get Form Responses
Fetch recent responses for a specific form. This is the primary endpoint used by the Zapier integration’s polling trigger.
GET /api/zapier/responses?formId={formId}Headers:
| Header | Required | Description |
|---|---|---|
X-API-Key | Yes | Your Rowform API key |
Query Parameters:
| Parameter | Required | Default | Description |
|---|---|---|---|
limit | No | 25 | Number of responses to return (max 100) |
Response (200):
[
{
"id": "response-uuid",
"form_id": "form-uuid",
"form_title": "Customer Feedback Survey",
"submitted_at": "2026-02-20T12:00:00.000Z",
"respondent_email": "respondent@example.com",
"answers": [
{
"question_id": "q1",
"question_label": "How satisfied are you?",
"question_type": "rating",
"value": 5
},
{
"question_id": "q2",
"question_label": "Any feedback?",
"question_type": "long_text",
"value": "Great service!"
}
],
"raw_answers": {
"q1": 5,
"q2": "Great service!",
"hf_abc123": "google",
"hf_def456": "partner"
}
}
]Errors:
| Status | Description |
|---|---|
| 401 | Invalid API key |
| 403 | Form does not belong to authenticated user |
| 404 | Form not found |
Subscribe Webhook
Register a webhook URL to receive events. These endpoints are used for custom webhook integrations — the official Zapier app uses polling instead.
POST /api/zapier/hooksHeaders:
| Header | Required | Description |
|---|---|---|
X-API-Key | Yes | Your Rowform API key |
Content-Type | Yes | application/json |
Request Body:
{
"hookUrl": "https://hooks.zapier.com/hooks/catch/123456/abcdef/",
"event": "form.response.created",
"formId": "form-uuid"
}| Field | Required | Description |
|---|---|---|
hookUrl | Yes | The URL to receive webhook POST requests |
event | Yes | Event type (see below) |
formId | No | Specific form ID, or omit for all forms |
Supported Events:
| Event | Description |
|---|---|
form.response.created | A new response is submitted |
form.created | A new form is created |
form.updated | A form is updated |
form.published | A form is published |
Response (200):
{
"id": "webhook-uuid",
"message": "Webhook subscription created"
}Unsubscribe Webhook
Remove a webhook subscription.
DELETE /api/zapier/hooks?id={webhookId}Headers:
| Header | Required | Description |
|---|---|---|
X-API-Key | Yes | Your Rowform API key |
Response (200):
{
"message": "Webhook unsubscribed"
}List Webhooks
List all webhook subscriptions for the authenticated user.
GET /api/zapier/hooksHeaders:
| Header | Required | Description |
|---|---|---|
X-API-Key | Yes | Your Rowform API key |
Response (200):
[
{
"id": "webhook-uuid",
"form_id": "form-uuid",
"target_url": "https://hooks.zapier.com/hooks/catch/123456/abcdef/",
"event_type": "form.response.created",
"is_active": true,
"created_at": "2026-02-20T10:00:00.000Z"
}
]Webhook Delivery
When an event fires, Rowform sends an HTTP POST to your webhook URL with the following headers:
| Header | Description |
|---|---|
Content-Type | application/json |
User-Agent | Rowform-Webhook/1.0 |
X-Rowform-Event | The event type (e.g., form.response.created) |
X-Rowform-Delivery | Unique delivery ID |
X-Rowform-Signature | HMAC-SHA256 signature (if secret is configured) |
Failure Handling
- Webhooks are retried via a scheduled dispatch process.
- After 5 consecutive failures (non-2xx responses), the webhook is automatically disabled.
- The account owner receives an email notification when a webhook is disabled.
- Re-enable disabled webhooks from the Integrate tab in the form builder.
Security
- API keys are hashed with SHA-256 before storage. Plain-text keys are never stored.
- Webhook signatures use HMAC-SHA256 for payload verification.
- All communication is over HTTPS.