API Quick Start
Make your first API call to Mobyform in minutes.
API Quick Start
This guide walks you through making your first Mobyform API call. In a few minutes, you will list your forms, create a new form, read submissions, and set up a webhook.
Requires Pro plan or above
Step 1: Generate an API Key
- Log in to Mobyform
- Go to "Settings" → "Developer"
- Click "Generate API Key"
- Give the key a descriptive name (e.g., "Backend Integration")
- Copy the key immediately — it will not be shown again
Store your API key securely. Never expose it in frontend code, public repositories, or client-side applications.
Step 2: Make Your First Request
Use the API key to list your forms. All requests use the base URL https://api.mobyform.com and require the Authorization header.
cURL
curl -X GET https://api.mobyform.com/api/forms \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json"JavaScript / Node.js
const response = await fetch('https://api.mobyform.com/api/forms', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
});
const data = await response.json();
console.log(data);Python
import requests
response = requests.get(
'https://api.mobyform.com/api/forms',
headers={
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
}
)
data = response.json()
print(data)Example Response
{
"data": [
{
"key": "abc123",
"title": "Customer Feedback",
"status": "published",
"createdAt": "2024-06-01T08:00:00Z",
"submissions": 142
},
{
"key": "def456",
"title": "Event Registration",
"status": "draft",
"createdAt": "2024-06-10T14:30:00Z",
"submissions": 0
}
],
"total": 2,
"page": 1,
"size": 20
}Step 3: Create a Form via API
Create a new form by sending a POST request with the form structure.
cURL
curl -X POST https://api.mobyform.com/api/forms \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Contact Form",
"fields": [
{
"type": "input",
"label": "Full Name",
"required": true
},
{
"type": "email",
"label": "Email Address",
"required": true
},
{
"type": "textarea",
"label": "Message",
"required": true,
"placeholder": "How can we help you?"
}
]
}'JavaScript / Node.js
const response = await fetch('https://api.mobyform.com/api/forms', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
title: 'Contact Form',
fields: [
{ type: 'input', label: 'Full Name', required: true },
{ type: 'email', label: 'Email Address', required: true },
{ type: 'textarea', label: 'Message', required: true, placeholder: 'How can we help you?' },
],
}),
});
const form = await response.json();
console.log('Created form:', form.key);Python
import requests
import json
response = requests.post(
'https://api.mobyform.com/api/forms',
headers={
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
data=json.dumps({
'title': 'Contact Form',
'fields': [
{'type': 'input', 'label': 'Full Name', 'required': True},
{'type': 'email', 'label': 'Email Address', 'required': True},
{'type': 'textarea', 'label': 'Message', 'required': True, 'placeholder': 'How can we help you?'},
],
})
)
form = response.json()
print('Created form:', form['key'])Example Response
{
"key": "ghi789",
"title": "Contact Form",
"status": "draft",
"createdAt": "2024-06-15T10:00:00Z",
"fields": [
{ "id": "field_1", "type": "input", "label": "Full Name", "required": true },
{ "id": "field_2", "type": "email", "label": "Email Address", "required": true },
{ "id": "field_3", "type": "textarea", "label": "Message", "required": true }
]
}Step 4: Read Form Submissions
Retrieve submissions for a specific form with pagination.
cURL
curl -X GET "https://api.mobyform.com/api/forms/abc123/data?page=1&size=10" \
-H "Authorization: Bearer YOUR_API_KEY"JavaScript / Node.js
const formKey = 'abc123';
const response = await fetch(
`https://api.mobyform.com/api/forms/${formKey}/data?page=1&size=10`,
{
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
},
}
);
const submissions = await response.json();
console.log(`Total: ${submissions.total} submissions`);
for (const item of submissions.data) {
console.log(item.id, item.fields);
}Python
import requests
form_key = 'abc123'
response = requests.get(
f'https://api.mobyform.com/api/forms/{form_key}/data',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
params={'page': 1, 'size': 10}
)
submissions = response.json()
print(f"Total: {submissions['total']} submissions")
for item in submissions['data']:
print(item['id'], item['fields'])Example Response
{
"data": [
{
"id": "data_001",
"fields": {
"Full Name": "Jane Smith",
"Email Address": "jane@example.com",
"Message": "I have a question about pricing."
},
"createdAt": "2024-06-15T12:00:00Z"
}
],
"total": 1,
"page": 1,
"size": 10
}Pagination Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page | number | 1 | Page number |
size | number | 20 | Items per page (max 100) |
sort | string | createdAt | Field to sort by |
order | string | desc | Sort direction (asc or desc) |
Step 5: Set Up a Webhook
Webhooks notify your server in real time when form events occur, so you do not need to poll the API.
Register a Webhook
curl -X POST https://api.mobyform.com/api/webhooks \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/webhook/mobyform",
"events": ["form_data_add", "form_data_update", "form_data_delete"],
"headers": {
"X-Webhook-Secret": "your-secret-value"
}
}'Webhook Events
| Event | Trigger |
|---|---|
form_data_add | A new submission is received |
form_data_update | A submission is modified |
form_data_delete | A submission is deleted |
Handle Webhook Events
Here is a minimal Node.js/Express handler for incoming webhook events:
const express = require('express');
const app = express();
app.use(express.json());
app.post('/webhook/mobyform', (req, res) => {
const secret = req.headers['x-webhook-secret'];
if (secret !== 'your-secret-value') {
return res.status(401).send('Unauthorized');
}
const { event, formKey, data } = req.body;
switch (event) {
case 'form_data_add':
console.log(`New submission on form ${formKey}:`, data.fields);
break;
case 'form_data_update':
console.log(`Updated submission ${data.id} on form ${formKey}`);
break;
case 'form_data_delete':
console.log(`Deleted submission ${data.id} on form ${formKey}`);
break;
}
res.status(200).send('OK');
});
app.listen(3000);Error Handling
When something goes wrong, the API returns a standard error response:
{
"error": {
"code": "INVALID_REQUEST",
"message": "Description of what went wrong"
}
}Common Error Codes
| HTTP Status | Error Code | Meaning | Solution |
|---|---|---|---|
400 | INVALID_REQUEST | Request body is malformed or missing required fields | Check your JSON structure and required parameters |
401 | UNAUTHORIZED | API key is missing or invalid | Verify the Authorization header and key |
403 | FORBIDDEN | API key lacks permission for this action | Check the key's permission scope in Settings |
404 | NOT_FOUND | The form or submission does not exist | Verify the form key or data ID |
429 | RATE_LIMITED | Too many requests | Reduce request frequency; see rate limits below |
500 | INTERNAL_ERROR | Server-side error | Retry after a short delay; contact support if persistent |
Rate Limits
| Plan | Monthly Limit |
|---|---|
| Pro | 1,000 requests |
| Business | 10,000 requests |
| Enterprise | Custom |
When you exceed the limit, the API returns 429 Too Many Requests. The response includes a Retry-After header indicating when you can make requests again.
Next Steps
- API Reference — Full API documentation with all endpoints
- Integrations — Use built-in integrations without writing code