Opt-in Forms API
Opt-in forms are embeddable subscription widgets that collect email addresses and subscriber data. Each form can be customized with themes, automation rules, security settings, and trigger behavior. Use this API to manage forms, retrieve embed codes, and access form analytics.
Base URL
https://app.sendbroadcast.com/api/v1
Authentication
All requests require a Bearer token with the appropriate opt-in form permissions. See Authentication for details.
The Opt-in Form Object
| Field | Type | Description |
|---|---|---|
id |
integer | Unique identifier |
identifier |
string | Public identifier used in embed URLs |
label |
string | Display name for the form |
form_type |
string | Form type classification |
widget_type |
string | Widget display type (e.g., inline, popup, slide-in) |
enabled |
boolean | Whether the form is active and accepting submissions |
allowed_embedding_domains |
string | Newline-separated list of domains where the form can be embedded |
theme_settings |
object | Visual customization (colors, typography, layout, effects) |
automation_settings |
object | Post-submission automation (tags, welcome email, sequences) |
security_settings |
object | Anti-spam and rate limiting configuration |
trigger_settings |
object | Display trigger rules (delay, scroll, exit intent) |
widget_settings |
object | Widget-specific display options |
analytics |
object | Aggregate form performance metrics |
is_variant |
boolean | Whether this form is an A/B test variant |
variant_name |
string | Name of the variant (if applicable) |
variant_weight |
integer | Traffic weight for A/B testing |
variants_count |
integer | Number of A/B test variants |
opt_in_form_blocks |
array | Form content blocks (main form view) |
opt_in_post_submission_blocks |
array | Content blocks shown after submission |
embed_url |
string | JavaScript embed URL for the form |
created_at |
datetime | When the form was created (ISO 8601) |
updated_at |
datetime | When the form was last modified (ISO 8601) |
Theme Settings
{
"colors": {
"primary": "#3B82F6",
"background": "#FFFFFF",
"text": "#1F2937",
"border": "#D1D5DB"
},
"typography": {
"font_family": "Inter, sans-serif",
"heading_size": "24px",
"body_size": "16px",
"label_size": "14px"
},
"layout": {
"padding": "24px",
"border_radius": "8px",
"input_height": "44px",
"button_height": "48px",
"gap": "16px"
},
"effects": {
"shadow": "md",
"border_width": "1px"
}
}
Automation Settings
{
"tag_list": "newsletter,website-signup",
"send_welcome_email": true,
"double_opt_in": false,
"sequence_ids": [12, 45]
}
Security Settings
{
"honeypot_enabled": true,
"time_validation_enabled": true,
"min_submission_time_seconds": 3,
"rate_limit_enabled": true,
"rate_limit_per_ip": 5,
"rate_limit_window_minutes": 60,
"turnstile_enabled": false,
"turnstile_site_key": null
}
Trigger Settings
{
"trigger_type": "time_delay",
"time_delay_seconds": 5,
"scroll_percentage": 50,
"exit_intent_enabled": false,
"frequency": "once_per_session",
"frequency_cookie_days": 30,
"show_on_mobile": true,
"show_on_desktop": true
}
Analytics Object
{
"views_count": 12500,
"unique_views_count": 8300,
"submissions_count": 415,
"conversion_rate": 5.0
}
Form Block Object
Each form is composed of ordered content blocks. Block types include headings, text, input fields, buttons, images, dividers, spacers, checkboxes, dropdowns, and radio buttons.
| Field | Type | Description |
|---|---|---|
id |
integer | Block identifier |
block_type |
string | Type of block (e.g., heading, text, input, button, image, divider, spacer, checkbox, dropdown, radio) |
form_view |
string | Which view the block belongs to |
position |
integer | Display order |
text_value |
string | Text content (for heading/text blocks) |
heading_level |
string | Heading level (h1-h6) |
input_field_label |
string | Label for input fields |
input_field_placeholder |
string | Placeholder text |
input_field_value_type |
string | Input type (email, text, etc.) |
button_label |
string | Button text |
custom_field_key |
string | Maps input to a custom subscriber data field |
field_required |
boolean | Whether the field is required |
field_validation |
string | Validation rule |
custom_css |
string | Custom CSS for the block |
List Opt-in Forms
Retrieve all main forms (excluding variants) for the current broadcast channel.
GET /api/v1/opt_in_forms
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
filter |
string | No | Search forms by label |
widget_type |
string | No | Filter by widget type |
enabled |
string | No | Set to true to return only enabled forms |
Request
curl -X GET "https://app.sendbroadcast.com/api/v1/opt_in_forms" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json"
Response
{
"opt_in_forms": [
{
"id": 18,
"identifier": "f_abc123",
"label": "Homepage Signup",
"form_type": "standard",
"enabled": true,
"allowed_embedding_domains": "example.com\nblog.example.com",
"opt_in_form_blocks": [
{
"id": 101,
"block_type": "heading",
"form_view": "main",
"position": 1,
"text_value": "Join our newsletter",
"heading_level": "h2"
},
{
"id": 102,
"block_type": "input",
"form_view": "main",
"position": 2,
"input_field_label": "Email",
"input_field_placeholder": "[email protected]",
"input_field_value_type": "email",
"field_required": true
},
{
"id": 103,
"block_type": "button",
"form_view": "main",
"position": 3,
"button_label": "Subscribe"
}
],
"opt_in_post_submission_blocks": [
{
"id": 201,
"block_type": "heading",
"form_view": "post_submission",
"position": 1,
"text_value": "Thanks for subscribing!"
}
],
"created_at": "2025-07-10T14:00:00Z",
"updated_at": "2025-09-20T09:30:00Z"
}
],
"pagination": {
"total": 1,
"count": 1,
"from": 1,
"to": 1,
"current": 1,
"total_pages": 1
}
}
Get an Opt-in Form
Retrieve a single form with full details including theme, automation, security, trigger settings, blocks, analytics, and the embed URL.
GET /api/v1/opt_in_forms/:id
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
integer | Yes | The opt-in form ID |
Request
curl -X GET "https://app.sendbroadcast.com/api/v1/opt_in_forms/18" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json"
Response
{
"id": 18,
"identifier": "f_abc123",
"label": "Homepage Signup",
"form_type": "standard",
"widget_type": "inline",
"enabled": true,
"allowed_embedding_domains": "example.com\nblog.example.com",
"theme_settings": {
"colors": { "primary": "#3B82F6", "background": "#FFFFFF", "text": "#1F2937", "border": "#D1D5DB" },
"typography": { "font_family": "Inter, sans-serif", "heading_size": "24px", "body_size": "16px", "label_size": "14px" },
"layout": { "padding": "24px", "border_radius": "8px", "input_height": "44px", "button_height": "48px", "gap": "16px" },
"effects": { "shadow": "md", "border_width": "1px" }
},
"automation_settings": {
"tag_list": "newsletter,website-signup",
"send_welcome_email": true,
"double_opt_in": false,
"sequence_ids": [12]
},
"security_settings": {
"honeypot_enabled": true,
"time_validation_enabled": true,
"min_submission_time_seconds": 3,
"rate_limit_enabled": true,
"rate_limit_per_ip": 5,
"rate_limit_window_minutes": 60,
"turnstile_enabled": false,
"turnstile_site_key": null
},
"trigger_settings": {
"trigger_type": "immediate",
"time_delay_seconds": 0,
"scroll_percentage": 0,
"exit_intent_enabled": false,
"frequency": "always",
"frequency_cookie_days": 0,
"show_on_mobile": true,
"show_on_desktop": true
},
"widget_settings": {},
"analytics": {
"views_count": 12500,
"unique_views_count": 8300,
"submissions_count": 415,
"conversion_rate": 5.0
},
"is_variant": false,
"variant_name": null,
"variant_weight": 100,
"variants_count": 0,
"opt_in_form_blocks": [
{
"id": 101,
"block_type": "heading",
"form_view": "main",
"position": 1,
"text_value": "Join our newsletter",
"heading_level": "h2",
"input_field_label": null,
"input_field_placeholder": null,
"input_field_value_type": null,
"button_label": null,
"custom_field_key": null,
"field_required": false,
"field_validation": null,
"custom_css": null
}
],
"opt_in_post_submission_blocks": [],
"embed_url": "https://app.sendbroadcast.com/opt_in/f_abc123.js",
"created_at": "2025-07-10T14:00:00Z",
"updated_at": "2025-09-20T09:30:00Z"
}
Create an Opt-in Form
Create a new opt-in form with blocks and settings.
POST /api/v1/opt_in_forms
Request
curl -X POST "https://app.sendbroadcast.com/api/v1/opt_in_forms" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"opt_in_form": {
"label": "Blog Sidebar Signup",
"form_type": "standard",
"widget_type": "inline",
"enabled": true,
"allowed_embedding_domains": ["blog.example.com"],
"automation_settings": {
"tag_list": "blog-reader",
"send_welcome_email": true,
"double_opt_in": true
},
"security_settings": {
"honeypot_enabled": true,
"rate_limit_enabled": true,
"rate_limit_per_ip": 3,
"rate_limit_window_minutes": 60
},
"opt_in_form_blocks_attributes": [
{
"block_type": "heading",
"form_view": "main",
"position": 1,
"text_value": "Stay updated",
"heading_level": "h3"
},
{
"block_type": "input",
"form_view": "main",
"position": 2,
"input_field_label": "Email address",
"input_field_placeholder": "[email protected]",
"input_field_value_type": "email",
"field_required": true
},
{
"block_type": "button",
"form_view": "main",
"position": 3,
"button_label": "Subscribe"
}
]
}
}'
Response 201 Created
Returns the full opt-in form object.
Update an Opt-in Form
Update form settings, blocks, or automation rules.
PATCH /api/v1/opt_in_forms/:id
Request
curl -X PATCH "https://app.sendbroadcast.com/api/v1/opt_in_forms/18" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"opt_in_form": {
"enabled": false,
"automation_settings": {
"tag_list": "newsletter,paused",
"send_welcome_email": false
}
}
}'
Response
Returns the updated opt-in form object.
Delete an Opt-in Form
Permanently remove an opt-in form and all its blocks.
DELETE /api/v1/opt_in_forms/:id
Request
curl -X DELETE "https://app.sendbroadcast.com/api/v1/opt_in_forms/18" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json"
Response
{
"message": "Opt-in form deleted successfully"
}
Form Analytics
Retrieve detailed analytics for a specific form over a date range.
GET /api/v1/opt_in_forms/:id/analytics
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
start_date |
date | No | Start of the period (default: 30 days ago) |
end_date |
date | No | End of the period (default: today) |
Request
curl -X GET "https://app.sendbroadcast.com/api/v1/opt_in_forms/18/analytics?start_date=2025-09-01&end_date=2025-09-30" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json"
Response
{
"form_id": 18,
"identifier": "f_abc123",
"period": {
"start_date": "2025-09-01",
"end_date": "2025-09-30"
},
"totals": {
"views": 12500,
"unique_views": 8300,
"submissions": 415,
"conversion_rate": 5.0
},
"daily": [
{ "date": "2025-09-01", "views": 420, "unique_views": 280, "submissions": 14 },
{ "date": "2025-09-02", "views": 395, "unique_views": 260, "submissions": 12 }
],
"variants": [
{
"id": 19,
"name": "Variant B",
"weight": 50,
"views": 4100,
"submissions": 230,
"conversion_rate": 5.6
}
]
}
Error Responses
404 Not Found
{
"error": "Opt-in form not found"
}
422 Unprocessable Content
{
"error": "Label can't be blank"
}
Required Permissions
| Action | Permission |
|---|---|
| List / Get / Analytics | opt_in_forms_read |
| Create / Update / Delete / Duplicate / Variants | opt_in_forms_write |
Next: Webhook Endpoints API – Manage webhook endpoint configurations via API.