Skip to content

Create Form POST ​

Create a hosted form. It is published immediately at https://frms.click/{tid}, and every submission becomes a message on your account — see Forms.

Endpoint ​

POST https://api.pocketalert.app/v1/forms

Authentication ​

Required

Include one of these headers in your request:

  • Token: <your-api-key> — Get it from API Keys
  • Authorization: Bearer <jwt-token> — From Login

Request ​

Headers ​

HeaderRequiredDescription
Token✅Your API key
Authorization✅Bearer <jwt-token>

Body Parameters ​

ParameterTypeRequiredDescription
namestring✅Internal name, up to 191 characters. Also the default push title
fieldsarray✅The form's fields, max 30. At least one must be something a visitor fills in
settingsobject❌Title, texts and design. Every key has a default
application_tidstring❌Application the submissions belong to
device_tidstring❌Target device TID, or all. Omit for every device
default_levelint❌Priority level (-2..2) for submissions. See Message priority levels
push_titlestring❌Push title template with {Field label} tokens, up to 191 characters
allowed_originsarray❌Hosts allowed to embed and submit the form, max 10. Empty means anywhere
max_responsesint❌Close the form after this many responses. 0 (default) is unlimited
closes_atstring❌Closing time, RFC 3339. Stored in UTC
is_activeboolean❌false closes the form straight away. Defaults to true

Fields ​

Each entry in fields:

ParameterTypeRequiredDescription
idstring✅Unique within the form: letters, digits, _ and -, up to 40 characters
typestring✅One of the types below
labelstring✅Shown above the input, up to 200 characters (2000 for paragraph)
placeholderstring❌Text, textarea, email, phone, number, url and dropdown only
requiredboolean❌Ignored by layout fields
optionsarray✅ for choice fieldsUp to 50 entries for dropdown, radio and checkboxes
paramstring✅ for hiddenURL parameter the value is read from, e.g. utm_source
GroupTypesSubmitted value
Texttext, textarea, email, phone, number, url, dateString. text is capped at 1000 characters, textarea at 5000
Choicedropdown, radioOne of options
ChoicecheckboxesArray of options
ChoicecheckboxBoolean, rendered as Yes / No
Ratingrating (1–5), nps (0–10)Number
Layoutheading, paragraph, dividerNever submitted
TrackinghiddenTaken from the page URL, not from the visitor

Email, phone, number, URL and date values are validated on the server; the browser check is a convenience, not the guard.

Settings ​

All keys are optional — anything you leave out keeps its default.

ParameterTypeDefaultDescription
titlestring""Heading above the form, up to 200 characters
top_textstring""Intro text, up to 2000 characters. Plain text; links become clickable
bottom_textstring""Text under the button, up to 2000 characters
success_messagestringThanks! Your response has been sent.Shown after a submission, up to 500 characters
closed_messagestringThis form is no longer accepting responses.Shown when the form is closed
background_colorstring#f5f5f4Page background, #rrggbb
card_colorstring#ffffffForm background
text_colorstring#1c1917Text
primary_colorstring#3f5cadAccent and, unless overridden, the button
font_familystringInterA Google Font by name
font_sizeint1612–24
font_weightint400300, 400, 500, 600 or 700
border_radiusint100–48
hide_brandingbooleanfalseHides the "Powered by Pocket Alert" link. Paid plans only — on the free plan the API resets it to false
submitobject—{ "text": "Submit", "color": "", "size": "md" }. size is sm, md or lg; an empty color follows primary_color

Push Title Template ​

push_title builds the notification title from the answers:

New lead: {Name} ({Email})

Tokens reference fields by label, case-insensitive, plus {form} for the form name. Tokens with no answer drop out; if nothing is left, the title falls back to Form: {name}. The template is never exposed on the public page.

Allowed Origins ​

A form id travels in its public link, so by default anyone holding it can embed the form. allowed_origins closes that: only the listed hosts may frame the form, and a submission whose Origin (or Referer) is not on the list is rejected with 403.

Write hosts, not URLs: example.com, app.example.com, *.example.com for every subdomain, localhost:3000 while developing. www. is ignored.

Example Request ​

bash
curl -X POST "https://api.pocketalert.app/v1/forms" \
  -H "Token: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Contact form",
    "push_title": "New lead: {Name}",
    "fields": [
      { "id": "name", "type": "text", "label": "Name", "required": true },
      { "id": "email", "type": "email", "label": "Email", "required": true },
      { "id": "message", "type": "textarea", "label": "Message" },
      { "id": "src", "type": "hidden", "label": "Source", "param": "utm_source" }
    ],
    "settings": {
      "title": "Get in touch",
      "top_text": "We reply within one business day.",
      "primary_color": "#3f5cad"
    }
  }'
javascript
const response = await fetch('https://api.pocketalert.app/v1/forms', {
  method: 'POST',
  headers: {
    'Token': 'your-api-key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: 'Contact form',
    push_title: 'New lead: {Name}',
    fields: [
      { id: 'name', type: 'text', label: 'Name', required: true },
      { id: 'email', type: 'email', label: 'Email', required: true },
      { id: 'message', type: 'textarea', label: 'Message' }
    ],
    settings: { title: 'Get in touch' }
  })
});

const form = await response.json();
console.log('Form link:', `https://frms.click/${form.tid}`);
python
import requests

response = requests.post(
    'https://api.pocketalert.app/v1/forms',
    headers={'Token': 'your-api-key'},
    json={
        'name': 'Contact form',
        'push_title': 'New lead: {Name}',
        'fields': [
            {'id': 'name', 'type': 'text', 'label': 'Name', 'required': True},
            {'id': 'email', 'type': 'email', 'label': 'Email', 'required': True},
            {'id': 'message', 'type': 'textarea', 'label': 'Message'},
        ],
        'settings': {'title': 'Get in touch'},
    }
)

form = response.json()
print(f"Form link: https://frms.click/{form['tid']}")
php
$form = Http::withHeaders([
    'Token' => 'your-api-key',
])->post('https://api.pocketalert.app/v1/forms', [
    'name' => 'Contact form',
    'push_title' => 'New lead: {Name}',
    'fields' => [
        ['id' => 'name', 'type' => 'text', 'label' => 'Name', 'required' => true],
        ['id' => 'email', 'type' => 'email', 'label' => 'Email', 'required' => true],
        ['id' => 'message', 'type' => 'textarea', 'label' => 'Message'],
    ],
    'settings' => ['title' => 'Get in touch'],
])->json();

echo 'Form link: https://frms.click/'.$form['tid'];

Response ​

Success Response ​

201 Created

The form is live. Share https://frms.click/{tid}, or embed it — see Forms.

The body is the same shape as one entry from Get All Forms.

json
{
  "tid": "vml19aihrga216gt8apc5e3m9",
  "name": "Contact form",
  "fields": [
    { "id": "name", "type": "text", "label": "Name", "required": true },
    { "id": "email", "type": "email", "label": "Email", "required": true },
    { "id": "message", "type": "textarea", "label": "Message" },
    { "id": "src", "type": "hidden", "label": "Source", "param": "utm_source" }
  ],
  "settings": {
    "title": "Get in touch",
    "top_text": "We reply within one business day.",
    "success_message": "Thanks! Your response has been sent.",
    "closed_message": "This form is no longer accepting responses.",
    "background_color": "#f5f5f4",
    "card_color": "#ffffff",
    "text_color": "#1c1917",
    "primary_color": "#3f5cad",
    "font_family": "Inter",
    "font_size": 16,
    "font_weight": 400,
    "border_radius": 10,
    "hide_branding": false,
    "submit": { "text": "Submit", "color": "", "size": "md" }
  },
  "application_tid": "",
  "device_tid": "",
  "default_level": null,
  "push_title": "New lead: {Name}",
  "allowed_origins": [],
  "max_responses": 0,
  "closes_at": null,
  "closed": false,
  "is_active": true,
  "submissions_count": 0,
  "last_submission_at": "",
  "created_at": "23.09.2026 11:40:02"
}

Error Responses ​

StatusDescription
400Validation error — the error field says which field or setting is wrong
401Unauthorized — Invalid or missing token
403You have reached the number of forms your plan allows
500Failed to create form

Pocket Alert Documentation