API Reference¶
FormVox provides a REST API for programmatic access to forms and responses.
Authentication¶
Internal API¶
For authenticated Nextcloud users: - Uses Nextcloud session cookies - Or basic authentication with app password
# Using app password
curl -u "username:app-password" \
https://your-nextcloud.com/apps/formvox/api/forms
Public API¶
For public form submissions: - No authentication required - Uses form's public hash
curl -X POST \
https://your-nextcloud.com/apps/formvox/api/public/HASH/submit \
-d '{"answers": {...}}'
Endpoints¶
Forms¶
List Forms¶
Response:
{
"forms": [
{
"id": "file-id",
"title": "Customer Survey",
"created": "2024-01-15T10:00:00Z",
"responseCount": 42
}
]
}
Get Form¶
Parameters:
| Name | Type | Description |
|------|------|-------------|
| fileId | integer | Nextcloud file ID |
Response:
{
"form": {
"id": "uuid",
"title": "Customer Survey",
"description": "...",
"questions": [ ... ],
"settings": { ... }
}
}
Create Form¶
Request Body:
Response:
Update Form¶
Request Body:
Delete Form¶
Questions¶
Add Question¶
Request Body:
Update Question¶
Delete Question¶
Reorder Questions¶
Request Body:
Responses¶
Get Responses¶
Query Parameters:
| Name | Type | Default | Description |
|------|------|---------|-------------|
| page | integer | 1 | Page number |
| limit | integer | 50 | Results per page |
| from | string | - | Start date (ISO 8601) |
| to | string | - | End date (ISO 8601) |
Response:
Get Single Response¶
Delete Response¶
Delete All Responses¶
Public Submission¶
Get Public Form¶
Returns form structure without responses.
Response:
Submit Response¶
Request Body:
Response:
With Password:
Export¶
Export Responses¶
Query Parameters:
| Name | Type | Options | Description |
|------|------|---------|-------------|
| format | string | csv, json, xlsx | Export format |
| from | string | - | Start date |
| to | string | - | End date |
Response: Returns file download with appropriate content type.
Sharing¶
Get Share Settings¶
Update Share Settings¶
Request Body:
Statistics¶
Get Form Statistics¶
Response:
{
"totalResponses": 142,
"responsesPerDay": [ ... ],
"averageCompletionTime": 180,
"questionStats": { ... }
}
Error Responses¶
All errors return JSON with consistent format:
Error Codes¶
| Code | HTTP Status | Description |
|---|---|---|
UNAUTHORIZED |
401 | Authentication required |
FORBIDDEN |
403 | No permission |
FORM_NOT_FOUND |
404 | Form doesn't exist |
INVALID_REQUEST |
400 | Bad request data |
VALIDATION_ERROR |
422 | Form validation failed |
RATE_LIMITED |
429 | Too many requests |
FORM_EXPIRED |
410 | Public link expired |
PASSWORD_REQUIRED |
401 | Form requires password |
Rate Limiting¶
Public endpoints are rate limited:
| Endpoint | Limit |
|---|---|
| Public form view | 60/minute |
| Public submission | 10/minute |
Authenticated endpoints: | Endpoint | Limit | |----------|-------| | All endpoints | 120/minute |
Rate limit headers:
Presence (Collaborative Editing)¶
Endpoints for real-time collaborative editing presence detection.
Send Presence Heartbeat¶
Registers the current user as actively editing the form. Should be called every 30 seconds as a heartbeat.
Response:
Get Active Editors¶
Returns a list of users currently editing the form (active within the last 60 seconds).
Response:
Notes:
- The current user is excluded from the editors list
- Users who haven't sent a heartbeat in 60 seconds are considered inactive
- myFirstSeen indicates when the current user first started editing (used for edit priority/locking)
External API & Webhooks¶
FormVox now supports an External API with API key authentication and webhooks for real-time notifications.
See the dedicated documentation: External API & Webhooks
Features:
- API key authentication (bcrypt-hashed storage)
- Configurable permissions per key
- CRUD operations on responses
- Webhook events: response.created, response.updated, response.deleted
- HMAC-SHA256 signed webhook payloads
Code Examples¶
Python¶
import requests
# Authentication
session = requests.Session()
session.auth = ('username', 'app-password')
# List forms
response = session.get('https://nc.example.com/apps/formvox/api/forms')
forms = response.json()['forms']
# Get responses
response = session.get(f'https://nc.example.com/apps/formvox/api/forms/{form_id}/responses')
responses = response.json()['responses']
# Export to CSV
response = session.get(
f'https://nc.example.com/apps/formvox/api/forms/{form_id}/export',
params={'format': 'csv'}
)
with open('responses.csv', 'wb') as f:
f.write(response.content)
JavaScript¶
// Using fetch
const BASE_URL = 'https://nc.example.com/apps/formvox/api';
async function getForms() {
const response = await fetch(`${BASE_URL}/forms`, {
credentials: 'include'
});
return response.json();
}
async function submitPublicForm(hash, answers) {
const response = await fetch(`${BASE_URL}/public/${hash}/submit`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ answers })
});
return response.json();
}
cURL¶
# List forms
curl -u "user:app-password" \
https://nc.example.com/apps/formvox/api/forms
# Create form
curl -u "user:app-password" \
-X POST \
-H "Content-Type: application/json" \
-d '{"title": "New Survey", "path": "/"}' \
https://nc.example.com/apps/formvox/api/forms
# Submit public form
curl -X POST \
-H "Content-Type: application/json" \
-d '{"answers": {"q1": "Test"}}' \
https://nc.example.com/apps/formvox/api/public/abc123/submit
Next Steps¶
- External API & Webhooks - API keys and webhooks for integrations
- File Format - Understanding the data structure
- Architecture Overview - System design