FormaVex API

The FormaVex REST API lets you read your forms and submissions programmatically. API access requires a Pro or Enterprise plan.


Authentication

All API requests must include your API key as a Bearer token in the Authorization header. Find your API key in Settings → General.

curl https://forma-vex.com/api/v1/forms \
-H "Authorization: Bearer fvx_your_api_key_here"

Base URL

https://forma-vex.com/api/v1
GET

/v1/forms

List all form templates in your organization.

Response

{
"forms": [
{
"id": "uuid",
"name": "Site Inspection",
"fields": [...],
"is_public": false,
"created_at": "2025-01-15T10:00:00Z"
}
]
}
GET

/v1/submissions

List submissions with optional filtering and pagination.

Query Parameters

ParameterTypeDescription
form_idstringFilter by form template ID
sourceinternal | externalFilter by submission source
fromISO 8601 dateFilter submissions after this date
toISO 8601 dateFilter submissions before this date
limitnumber (max 200)Results per page (default 50)
offsetnumberPagination offset (default 0)

Example Request

curl "https://forma-vex.com/api/v1/submissions?limit=10&source=external" \
-H "Authorization: Bearer fvx_..."

Response

{
"submissions": [...],
"total": 142,
"limit": 10,
"offset": 0
}
GET

/v1/submissions/:id

Retrieve a single submission with all answers and photos.

{
"submission": {
"id": "uuid",
"form_template_id": "uuid",
"answers": { "field_id": "value", ... },
"submitted_at": "2025-01-15T10:30:00Z",
"source": "internal",
"gps_lat": 37.7749,
"gps_lng": -122.4194,
"pdf_url": "https://...",
"photos": [{ "id": "...", "storage_url": "..." }]
}
}

Webhooks

FormaVex can POST events to your server in real-time. Configure webhooks in your Webhooks settings.

Signature Verification

Each request includes an X-FormaVex-Signature header with an HMAC-SHA256 signature. Use your webhook secret to verify it.

// Node.js example
const crypto = require('crypto')

function verifySignature(body, signature, secret) {
const expected = `sha256=$${crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex')}`

return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signature)
)
}

Event: submission.created

{
"event": "submission.created",
"timestamp": "2025-01-15T10:30:00Z",
"data": {
"id": "uuid",
"form_template_id": "uuid",
"org_id": "uuid",
"answers": { ... },
"submitted_at": "2025-01-15T10:30:00Z",
"source": "external"
}
}

Errors

The API uses standard HTTP status codes.

StatusMeaning
200Success
400Bad request — missing or invalid parameters
401Unauthorized — invalid or missing API key
403Forbidden — API access requires Pro plan
404Resource not found
500Internal server error
{
"error": "Invalid API key"
}