Intro
Endpoint: https://api.omnisend.com/api/forms
The Forms Reports API lets you retrieve performance statistics for your forms, list contacts collected through a form, and access A/B test reports for form experiments.
All endpoints are keyed by formID, a 24-character hexadecimal identifier, and require the forms.read scope.
Form summary report
Use GET /api/forms/{formID}/report to retrieve total statistics and a breakdown by device for a form within a date range.
Query parameters
Both date range parameters are required.
| Parameter | Type | Description |
|---|---|---|
| createdAtFrom | string | Required. Start of the date range, inclusive (RFC3339, e.g. 2024-01-01T00:00:00Z) |
| createdAtTo | string | Required. End of the date range, inclusive (RFC3339, e.g. 2024-01-31T23:59:59Z) |
Metrics
| Metric | Description |
|---|---|
| views | Number of times the form was displayed to a visitor |
| interactions | Number of views where the visitor engaged with the form without necessarily completing it |
| submits | Number of successful form submissions |
| signups | Number of contacts gained through the form |
Views, interactions and submits form a funnel, so views ≥ interactions ≥ submits. Signups can differ from submits — a submission by an already known contact does not produce a new contact — so treat the two as related but not interchangeable.
The statisticsByDevice object contains the same metrics grouped by device type (desktop, mobile, tablet). Device buckets without activity in the range are omitted.
Date ranges and time buckets are interpreted in the brand's timezone.
Example: Get form summary report
curl --request GET \
--url 'https://api.omnisend.com/api/forms/000000000000000000000001/report?createdAtFrom=2024-01-01T00:00:00Z&createdAtTo=2024-01-31T23:59:59Z' \
--header 'Authorization: Omnisend-API-Key YOUR_API_KEY' \
--header 'Omnisend-Version: 2026-preview' \
--header 'accept: application/json'Response:
{
"formID": "000000000000000000000001",
"statistics": {
"views": 12500,
"interactions": 3200,
"submits": 840,
"signups": 790
},
"statisticsByDevice": {
"desktop": {
"views": 8000,
"interactions": 2100,
"submits": 560,
"signups": 530
},
"mobile": {
"views": 4000,
"interactions": 1000,
"submits": 250,
"signups": 235
},
"tablet": {
"views": 500,
"interactions": 100,
"submits": 30,
"signups": 25
}
}
}Form periodic report
Use GET /api/forms/{formID}/report/periodic to retrieve time-bucketed statistics for a form within a date range.
Rows carry the same metrics as the summary report, but this endpoint does not return a device breakdown — use the summary report for that.
Query parameters
| Parameter | Type | Description |
|---|---|---|
| createdAtFrom | string | Required. Start of the date range, inclusive (RFC3339, e.g. 2024-01-01T00:00:00Z) |
| createdAtTo | string | Required. End of the date range, inclusive (RFC3339, e.g. 2024-01-31T23:59:59Z) |
| granularity | string | Time bucket granularity. One of hour, day, week, month, year |
Granularity
When granularity is omitted it is derived from the length of the requested range:
| Date range | Granularity used |
|---|---|
| One day | hour |
| Up to a month | day |
| Up to two years | month |
| Longer than two years | year |
When it is provided, it must be available for the range or the request is rejected with 400:
| Granularity | Allowed date range |
|---|---|
hour | One day |
day | Longer than a day, up to a month |
week | Longer than a day, up to three months |
month | Longer than a month, up to two years |
year | Longer than two years |
The period value of each row is formatted according to the granularity in effect: RFC3339 for hour, a date for day and week, YYYY-MM for month, and YYYY for year.
Example: Get form periodic report
curl --request GET \
--url 'https://api.omnisend.com/api/forms/000000000000000000000001/report/periodic?createdAtFrom=2024-01-01T00:00:00Z&createdAtTo=2024-01-07T23:59:59Z&granularity=day' \
--header 'Authorization: Omnisend-API-Key YOUR_API_KEY' \
--header 'Omnisend-Version: 2026-preview' \
--header 'accept: application/json'Response — one row per time bucket:
{
"formID": "000000000000000000000001",
"granularity": "day",
"rows": [
{
"period": "2024-01-01",
"statistics": {
"views": 1800,
"interactions": 450,
"submits": 120,
"signups": 110
}
},
{
"period": "2024-01-02",
"statistics": {
"views": 2100,
"interactions": 520,
"submits": 140,
"signups": 132
}
}
]
}Form contacts
Use GET /api/forms/{formID}/contacts to retrieve contacts who submitted a specific form.
Query parameters
| Parameter | Type | Description |
|---|---|---|
| limit | integer | Maximum number of contacts per page (default 250, max 250) |
| sort | string | Sort field. Currently only createdAt is supported |
| direction | string | Sort direction. asc or desc (default desc) |
| after | string | Opaque cursor for fetching the next page |
| before | string | Opaque cursor for fetching the previous page |
Contacts are ordered by contact creation time embedded in the contact ID. The response submittedAt field reflects when the contact signed up through this form and may differ from the sort key for existing subscribers.
Pagination is cursor-based: read the cursors from paging in the response and pass them to after to fetch the next page or to before to step back. Cursors are opaque — do not construct them.
Contact fields
| Field | Description |
|---|---|
| id | Contact identifier |
| Contact email address | |
| phoneNumber | Contact phone number |
| firstName | First name |
| lastName | Last name |
| country | Country |
| gender | Gender |
| discount | Discount code received |
| submittedAt | Signup timestamp on this form |
| customProperties | Array of custom properties collected by the form |
Each custom property has a name as configured on the form, a type (string, number, bool, date, or list), and a value whose shape follows that type. The set of properties varies per form, and can vary per contact when a field was optional or added after earlier signups.
Example: Get form contacts
curl --request GET \
--url 'https://api.omnisend.com/api/forms/000000000000000000000001/contacts?limit=50' \
--header 'Authorization: Omnisend-API-Key YOUR_API_KEY' \
--header 'Omnisend-Version: 2026-preview' \
--header 'accept: application/json'To paginate through results, use the after cursor from the previous response:
curl --request GET \
--url 'https://api.omnisend.com/api/forms/000000000000000000000001/contacts?limit=50&after=eyJpZCI6ImNhbXAtNDU2In0' \
--header 'Authorization: Omnisend-API-Key YOUR_API_KEY' \
--header 'Omnisend-Version: 2026-preview' \
--header 'accept: application/json'A/B setup reports
Use GET /api/forms/{formID}/ab-setup/reports to retrieve the A/B setup reports of a form.
Both running (enabled) and finished (completed) setups are included, so a test that is still collecting data is returned with its statistics so far. If the form has no A/B setups, the endpoint responds with 200 OK and an empty reports array.
Report fields
| Field | Description |
|---|---|
| abSetupID | Identifier of the A/B setup |
| status | Status of the A/B setup |
| startedAt | When the A/B setup started |
| completedAt | When the A/B setup completed; omitted while the test is running |
| winner | Name of the version selected when the test completed; omitted while the test is running and when no winner was determined |
| versionStatistics | Array of per-version statistics (see below) |
Each entry in versionStatistics contains:
| Field | Description |
|---|---|
| versionName | Name of the version |
| splitValue | Percentage of eligible traffic routed to the version; split values of a setup add up to 100 |
| statistics | Per-version form metrics (see Metrics) |
Compare versions using rates derived from views rather than raw counts, because an uneven split gives versions different traffic volumes.
Example: List A/B setup reports
curl --request GET \
--url 'https://api.omnisend.com/api/forms/000000000000000000000001/ab-setup/reports' \
--header 'Authorization: Omnisend-API-Key YOUR_API_KEY' \
--header 'Omnisend-Version: 2026-preview' \
--header 'accept: application/json'Response:
{
"reports": [
{
"abSetupID": "000000000000000000000010",
"status": "completed",
"startedAt": "2024-01-01T00:00:00Z",
"completedAt": "2024-01-15T00:00:00Z",
"winner": "Version A",
"versionStatistics": [
{
"versionName": "Version A",
"splitValue": 50,
"statistics": {
"views": 6000,
"interactions": 1500,
"submits": 420,
"signups": 400
}
},
{
"versionName": "Version B",
"splitValue": 50,
"statistics": {
"views": 6000,
"interactions": 1300,
"submits": 360,
"signups": 340
}
}
]
},
{
"abSetupID": "000000000000000000000011",
"status": "enabled",
"startedAt": "2024-02-01T00:00:00Z",
"versionStatistics": [
{
"versionName": "Version A",
"splitValue": 60,
"statistics": {
"views": 1200,
"interactions": 300,
"submits": 90,
"signups": 85
}
},
{
"versionName": "Version B",
"splitValue": 40,
"statistics": {
"views": 800,
"interactions": 190,
"submits": 55,
"signups": 52
}
}
]
}
]
}