Submit Form POST
Send a response. The submission becomes a message on the owner's account and is pushed to their phone — the same pipeline a webhook call goes through. No authentication.
Endpoint
POST https://api.pocketalert.app/v1/forms/{tid}/submitAuthentication
Not required
Anyone holding the link can submit. The owner controls who may: see allowed origins and the limits below.
Request
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
tid | string | ✅ | Form identifier |
Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
values | object | ✅ | Answers keyed by field id |
website | string | ❌ | Honeypot. Leave it out; anything non-empty is treated as a bot |
Value per field type:
| Type | Value |
|---|---|
text, textarea, email, phone, number, url | String. Format is validated for email, phone, number and URL |
date | String, YYYY-MM-DD |
dropdown, radio | String, one of the field's options |
checkboxes | Array of strings from options |
checkbox | Boolean |
rating | Number, 1–5 |
nps | Number, 0–10 |
hidden | String, normally taken from the page URL |
Layout fields (heading, paragraph, divider) take no value, and unknown keys are ignored. The body is capped at 64 KB.
Example Request
curl -X POST "https://api.pocketalert.app/v1/forms/vml19aihrga216gt8apc5e3m9/submit" \
-H "Content-Type: application/json" \
-d '{
"values": {
"name": "Jane Doe",
"email": "[email protected]",
"message": "Do you ship to Canada?",
"src": "newsletter"
}
}'const response = await fetch(
'https://api.pocketalert.app/v1/forms/vml19aihrga216gt8apc5e3m9/submit',
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
values: {
name: 'Jane Doe',
email: '[email protected]',
message: 'Do you ship to Canada?'
}
})
}
);
const result = await response.json();
if (response.status === 400) {
// result.fields = { email: "Enter a valid email address" }
console.log(result.fields);
}import requests
response = requests.post(
'https://api.pocketalert.app/v1/forms/vml19aihrga216gt8apc5e3m9/submit',
json={
'values': {
'name': 'Jane Doe',
'email': '[email protected]',
'message': 'Do you ship to Canada?',
}
}
)
print(response.status_code, response.json())Response
Success Response
200 OK
{ "status": "ok" }The owner receives a push built from the answers. Nothing about the owner — their plan, their devices, their quota — is exposed to the visitor.
Validation Errors
400 Bad Request
fields maps a field id to the reason it was rejected, which is what the form page renders under each input.
{
"error": "Please check the highlighted fields.",
"fields": {
"email": "Enter a valid email address",
"name": "This field is required"
}
}Closed Form
410 Gone
{
"error": "This form is no longer accepting responses.",
"closed": true
}error carries the owner's own closed_message.
Limits
| Limit | Value |
|---|---|
| Per IP | 10 submissions a minute |
| Per form | 60 a minute, 300 an hour |
| Owner's quota | Each submission uses one message from their daily allowance |
A submission that would exceed the owner's daily message limit gets a neutral 429 with a Retry-After header and no mention of the plan.
Error Responses
| Status | Description |
|---|---|
400 | Invalid body, or fields lists the answers to fix |
403 | The form does not accept submissions from this site — see allowed origins |
404 | Form not found |
410 | The form is closed |
429 | Too many submissions, or the owner is out of messages for today |
500 | The form is misconfigured, or the message could not be created |
