📘 API Документация FreeFormApi
FreeFormApi предоставляет REST API для управления формами, ответами и профилем пользователя.
API работает с JSON-запросами и ответами. Все даты передаются в формате ISO 8601.
🌐 Базовый URL:
https://freeformapi.ru/api
📦 Формат данных: JSON
🔤 Кодировка: UTF-8
⚠️ Важно: Все примеры используют переменную $TOKEN.
Замените её на реальный токен, полученный при входе.
🔐 Аутентификация
Для доступа к защищённым маршрутам необходимо передавать токен в заголовке запроса.
Заголовок запроса:
Authorization: Bearer {ваш_токен}
Токен можно получить при входе через POST /login.
Токен действует до момента его отзыва через DELETE /tokens/{id} или POST /logout.
📋 Коды ответов
API возвращает стандартные HTTP статусы:
Успешный запрос
Успешно создано
Не авторизован
Доступ запрещён / Лимит
Ресурс не найден
Форма удалена (истек срок)
Ошибка валидации
Слишком много запросов
200 — Успешный запрос
201 — Ресурс успешно создан
401 — Отсутствует или недействительный токен
403 — Нет прав или достигнут лимит тарифа
404 — Запрашиваемый ресурс не найден
410 — Гостевая форма удалена (срок 30 дней)
422 — Ошибки валидации данных
429 — Превышен лимит запросов
🌐 Публичные маршруты
Эти маршруты не требуют токена авторизации.
/login
Вход пользователя. Возвращает токен для дальнейших запросов.
📤 Тело запроса:
{
"email": "user@example.com",
"password": "password123"
}
📥 Успешный ответ (200):
{
"success": true,
"message": "Вход выполнен успешно",
"data": {
"user": {
"id": "019e4e57-2c21-73c2-bd89-8310e3755239",
"name": "Иван Иванов",
"email": "ivan@example.com",
"is_admin": false,
"is_blocked": false,
"email_verified_at": "2026-08-14T10:00:00.000000Z",
"plan": {
"name": "pro",
"display_name": "Pro",
"forms_used": 12,
"forms_limit": 20
}
},
"token": "1|abc123def456...",
"token_type": "Bearer"
}
}
❌ Ошибка: неверные данные (401):
{
"message": "Неверный email или пароль",
"errors": {
"email": ["Неверный email или пароль"]
}
}
⚠️ Аккаунт заблокирован (403):
{
"success": false,
"error": "account_blocked",
"message": "Ваш аккаунт заблокирован"
}
💡 Пример cURL:
curl -X POST https://freeformapi.ru/api/login \
-H "Content-Type: application/json" \
-d '{"email":"ivan@example.com","password":"password123"}'
/forms/{slug}/schema
Получить схему формы для заполнения. Возвращает все вопросы, типы, варианты ответов и настройки.
📤 Параметры пути:
| slug | — короткая ссылка формы (например, abc123) |
📥 Успешный ответ (200):
{
"id": "019e4e57-2c21-73c2-bd89-8310e3755239",
"title": "Опрос клиентов",
"description": "Расскажите о своём опыте использования нашего сервиса",
"is_anonymous": false,
"settings": {
"theme": "light",
"show_progress": true
},
"questions": [
{
"id": "019e4e57-2c21-73c2-bd89-8310e3755240",
"title": "Как вы оцениваете наш сервис?",
"type": "radio",
"required": true,
"options": ["Отлично", "Хорошо", "Средне", "Плохо"],
"placeholder": null,
"sort_order": 0
},
{
"id": "019e4e57-2c21-73c2-bd89-8310e3755241",
"title": "Ваши пожелания",
"type": "textarea",
"required": false,
"options": null,
"placeholder": "Напишите здесь...",
"sort_order": 1
}
]
}
❌ Ошибки:
Форма удалена (410):
{
"error": "form_expired",
"message": "Форма удалена (истек срок хранения 30 дней)"
}
Форма заполнена (403):
{
"error": "form_full",
"message": "Форма достигла лимита ответов (100)"
}
Форма не найдена (404):
{
"message": "No query results for model [App\\Models\\Form]"
}
💡 Пример cURL:
curl -X GET https://freeformapi.ru/api/forms/abc123/schema
/forms/{id}/submit
Отправить ответ на форму. Ограничение: 10 запросов в минуту с одного IP.
📤 Тело запроса:
{
"answers": {
"019e4e57-2c21-73c2-bd89-8310e3755240": "Отлично",
"019e4e57-2c21-73c2-bd89-8310e3755241": "Всё отлично!",
"019e4e57-2c21-73c2-bd89-8310e3755242": ["Вариант 1", "Вариант 3"]
},
"session_id": "optional-session-id"
}
Примечание: session_id — опционально, используется для отслеживания сессии.
📥 Успешный ответ (201):
{
"success": true,
"message": "Ответ успешно сохранён",
"response_id": "019e4e57-2c21-73c2-bd89-8310e3755242",
"warning": "Осталось всего 5 мест для ответов",
"redirect": "https://example.com/thank-you"
}
Примечание: Поля warning и redirect появляются только при наличии соответствующих условий.
❌ Ошибки:
Форма заполнена (403):
{
"error": "form_full",
"message": "Эта форма достигла лимита ответов (100)"
}
Форма удалена (410):
{
"error": "form_expired",
"message": "Эта форма удалена, так как истёк срок хранения (30 дней)"
}
Ошибка валидации (422):
{
"error": "validation_failed",
"message": "Не все ответы прошли валидацию",
"errors": [
"Вопрос 'Ваш email' должен содержать корректный email",
"Вопрос 'Как вы оцениваете?' обязателен для заполнения"
]
}
Превышен лимит запросов (429):
{
"error": "daily_limit_reached",
"message": "Вы достигли дневного лимита ответов (10) для этой формы",
"limit": 10,
"reset_at": "2026-08-15T10:00:00Z"
}
Также может вернуть rate_limit_exceeded с retry_after.
💡 Пример cURL:
curl -X POST https://freeformapi.ru/api/forms/019e4e57-2c21-73c2-bd89-8310e3755239/submit \
-H "Content-Type: application/json" \
-d '{
"answers": {
"019e4e57-2c21-73c2-bd89-8310e3755240": "Отлично",
"019e4e57-2c21-73c2-bd89-8310e3755241": "Всё отлично!"
}
}'
🔒 Защищённые маршруты
⚠️ Требуется авторизация:
Передавайте токен в заголовке Authorization: Bearer {token}
/logout
Выход пользователя. Удаляет текущий токен.
📥 Успешный ответ (200):
{
"success": true,
"message": "Выход выполнен успешно"
}
💡 Пример cURL:
curl -X POST https://freeformapi.ru/api/logout \
-H "Authorization: Bearer $TOKEN"
/me
Получить информацию о текущем пользователе.
📥 Успешный ответ (200):
{
"success": true,
"data": {
"id": "019e4e57-2c21-73c2-bd89-8310e3755239",
"name": "Иван Иванов",
"email": "ivan@example.com",
"is_admin": false,
"is_blocked": false,
"email_verified_at": "2026-08-14T10:00:00.000000Z",
"plan": {
"name": "pro",
"display_name": "Pro",
"forms_used": 12,
"forms_limit": 20
},
"created_at": "2026-08-14T10:00:00.000000Z"
}
}
💡 Пример cURL:
curl -X GET https://freeformapi.ru/api/me \
-H "Authorization: Bearer $TOKEN"
/profile
Обновить профиль пользователя. Все поля опциональны.
📤 Тело запроса:
{
"name": "Новое имя",
"email": "new@example.com",
"password": "newpassword123",
"password_confirmation": "newpassword123"
}
Примечание: При смене email email_verified_at будет сброшен.
📥 Успешный ответ (200):
{
"success": true,
"message": "Профиль обновлён",
"data": {
"id": "019e4e57-2c21-73c2-bd89-8310e3755239",
"name": "Новое имя",
"email": "new@example.com"
}
}
💡 Пример cURL:
curl -X PUT https://freeformapi.ru/api/profile \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Новое имя","email":"new@example.com"}'
/tokens
Получить список всех API-токенов пользователя.
📥 Успешный ответ (200):
{
"success": true,
"data": [
{
"id": "1",
"name": "api-token",
"last_used_at": "2026-08-14T10:00:00.000000Z",
"created_at": "2026-08-14T09:00:00.000000Z"
},
{
"id": "2",
"name": "mobile-app",
"last_used_at": "2026-08-13T15:30:00.000000Z",
"created_at": "2026-08-13T12:00:00.000000Z"
}
]
}
💡 Пример cURL:
curl -X GET https://freeformapi.ru/api/tokens \
-H "Authorization: Bearer $TOKEN"
/tokens/{tokenId}
Удалить (отозвать) конкретный токен. Токен перестанет работать.
📤 Параметры пути:
| tokenId | — ID токена (число, полученное из GET /tokens) |
📥 Успешный ответ (200):
{
"success": true,
"message": "Токен удалён"
}
❌ Ошибка: токен не найден (404):
{
"success": false,
"message": "Токен не найден"
}
💡 Пример cURL:
curl -X DELETE https://freeformapi.ru/api/tokens/1 \
-H "Authorization: Bearer $TOKEN"
/forms
Получить список всех форм пользователя. Поддерживает пагинацию.
📤 Параметры запроса (опционально):
| per_page | — количество форм на странице (по умолчанию 20) |
| page | — номер страницы (по умолчанию 1) |
📥 Успешный ответ (200):
{
"success": true,
"data": [
{
"id": "019e4e57-2c21-73c2-bd89-8310e3755239",
"title": "Опрос клиентов",
"description": "Расскажите о своём опыте",
"slug": "abc123",
"is_anonymous": false,
"max_responses": 100,
"current_responses": 45,
"created_at": "2026-08-14T10:00:00.000000Z",
"updated_at": "2026-08-14T10:00:00.000000Z",
"group": {
"id": "019e4e57-2c21-73c2-bd89-8310e3755240",
"name": "Маркетинг",
"team": {
"id": "019e4e57-2c21-73c2-bd89-8310e3755241",
"name": "Acme Inc"
}
}
},
{
"id": "019e4e57-2c21-73c2-bd89-8310e3755242",
"title": "Форма обратной связи",
"description": null,
"slug": "def456",
"is_anonymous": false,
"max_responses": 50,
"current_responses": 12,
"created_at": "2026-08-13T15:00:00.000000Z",
"updated_at": "2026-08-13T15:00:00.000000Z",
"group": null
}
],
"meta": {
"current_page": 1,
"last_page": 3,
"per_page": 20,
"total": 45
}
}
💡 Пример cURL:
curl -X GET https://freeformapi.ru/api/forms?per_page=10&page=2 \
-H "Authorization: Bearer $TOKEN"
/forms
Создать новую форму. Количество форм ограничено тарифом.
📤 Тело запроса:
{
"title": "Опрос клиентов",
"description": "Расскажите о своём опыте использования нашего сервиса",
"group_id": "019e4e57-2c21-73c2-bd89-8310e3755240",
"settings": {
"theme": "light",
"show_progress": true
},
"questions": [
{
"title": "Как вы оцениваете наш сервис?",
"type": "radio",
"required": true,
"options": ["Отлично", "Хорошо", "Средне", "Плохо"],
"placeholder": null
},
{
"title": "Ваши пожелания",
"type": "textarea",
"required": false,
"options": null,
"placeholder": "Напишите здесь..."
},
{
"title": "Выберите категории",
"type": "checkbox",
"required": false,
"options": ["Категория А", "Категория Б", "Категория В"]
}
]
}
Примечание: Поля group_id, settings и placeholder — опциональны.
📥 Успешный ответ (201):
{
"success": true,
"message": "Форма успешно создана",
"data": {
"form": {
"id": "019e4e57-2c21-73c2-bd89-8310e3755242",
"title": "Опрос клиентов",
"slug": "xyz789",
"created_at": "2026-08-14T10:00:00.000000Z"
},
"fill_url": "https://freeformapi.ru/f/xyz789",
"short_url": "https://q4m.ru/f/xyz789"
}
}
❌ Ошибка: достигнут лимит форм (403):
{
"success": false,
"error": "limit_reached",
"message": "Вы достигли лимита форм (20) для вашего тарифа",
"max_forms": 20,
"current_forms": 20
}
💡 Пример cURL:
curl -X POST https://freeformapi.ru/api/forms \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Опрос клиентов",
"questions": [
{"title": "Ваш email", "type": "email", "required": true}
]
}'
/forms/{id}
Получить полную информацию о форме для редактирования.
📤 Параметры пути:
| id | — UUID формы |
📥 Успешный ответ (200):
{
"success": true,
"data": {
"id": "019e4e57-2c21-73c2-bd89-8310e3755239",
"title": "Опрос клиентов",
"description": "Расскажите о своём опыте",
"slug": "abc123",
"settings": {
"theme": "light"
},
"is_anonymous": false,
"expires_at": null,
"max_responses": 100,
"current_responses": 45,
"created_at": "2026-08-14T10:00:00.000000Z",
"updated_at": "2026-08-14T10:00:00.000000Z",
"group": {
"id": "019e4e57-2c21-73c2-bd89-8310e3755240",
"name": "Маркетинг"
},
"user": {
"id": "019e4e57-2c21-73c2-bd89-8310e3755239",
"name": "Иван Иванов",
"email": "ivan@example.com"
},
"questions": [
{
"id": "019e4e57-2c21-73c2-bd89-8310e3755243",
"title": "Как вы оцениваете сервис?",
"type": "radio",
"sort_order": 0,
"required": true,
"options": ["Отлично", "Хорошо", "Средне", "Плохо"],
"placeholder": null
}
]
}
}
💡 Пример cURL:
curl -X GET https://freeformapi.ru/api/forms/019e4e57-2c21-73c2-bd89-8310e3755239 \
-H "Authorization: Bearer $TOKEN"
/forms/{id}
Обновить форму. Все поля опциональны. Можно обновлять вопросы.
📤 Тело запроса:
{
"title": "Новое название",
"description": "Новое описание",
"max_responses": 200,
"group_id": "019e4e57-2c21-73c2-bd89-8310e3755244",
"questions": [
{
"id": "019e4e57-2c21-73c2-bd89-8310e3755243",
"title": "Обновлённый вопрос",
"type": "text",
"required": true
},
{
"title": "Новый вопрос",
"type": "textarea",
"required": false
}
]
}
Примечание: Если передан массив questions, старые вопросы будут удалены, а новые созданы или обновлены.
📥 Успешный ответ (200):
{
"success": true,
"message": "Форма успешно обновлена",
"data": {
"id": "019e4e57-2c21-73c2-bd89-8310e3755239",
"title": "Новое название",
"updated_at": "2026-08-14T10:00:00.000000Z"
}
}
💡 Пример cURL:
curl -X PUT https://freeformapi.ru/api/forms/019e4e57-2c21-73c2-bd89-8310e3755239 \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Новое название"}'
/forms/{id}
Удалить форму вместе со всеми ответами и вопросами. Необратимо!
📥 Успешный ответ (200):
{
"success": true,
"message": "Форма 'Опрос клиентов' успешно удалена"
}
💡 Пример cURL:
curl -X DELETE https://freeformapi.ru/api/forms/019e4e57-2c21-73c2-bd89-8310e3755239 \
-H "Authorization: Bearer $TOKEN"
/forms/{id}/duplicate
Клонировать форму со всеми вопросами. Новая форма получает суффикс " (копия)".
📥 Успешный ответ (201):
{
"success": true,
"message": "Форма успешно скопирована",
"data": {
"form": {
"id": "019e4e57-2c21-73c2-bd89-8310e3755245",
"title": "Опрос клиентов (копия)",
"slug": "new123",
"created_at": "2026-08-14T10:00:00.000000Z"
},
"fill_url": "https://freeformapi.ru/f/new123",
"short_url": "https://q4m.ru/f/new123"
}
}
❌ Ошибка: достигнут лимит форм (403):
{
"success": false,
"error": "limit_reached",
"message": "Вы достигли лимита форм (20) для вашего тарифа",
"max_forms": 20,
"current_forms": 20
}
💡 Пример cURL:
curl -X POST https://freeformapi.ru/api/forms/019e4e57-2c21-73c2-bd89-8310e3755239/duplicate \
-H "Authorization: Bearer $TOKEN"
/forms/{id}/responses
Получить список ответов на форму с фильтрацией и пагинацией.
📤 Параметры запроса (опционально):
| date_from | — дата "от" (YYYY-MM-DD) |
| date_to | — дата "до" (YYYY-MM-DD) |
| sort_by | — поле для сортировки (created_at, id, ip) |
| sort_dir | — направление сортировки (asc или desc) |
| per_page | — количество на странице (по умолчанию 20) |
📥 Успешный ответ (200):
{
"success": true,
"data": [
{
"id": "019e4e57-2c21-73c2-bd89-8310e3755246",
"form_id": "019e4e57-2c21-73c2-bd89-8310e3755239",
"answers": {
"019e4e57-2c21-73c2-bd89-8310e3755240": "Отлично",
"019e4e57-2c21-73c2-bd89-8310e3755241": "Всё отлично!"
},
"is_encrypted": false,
"ip": "185.38.84.237",
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"is_read": false,
"created_at": "2026-08-14T10:00:00.000000Z",
"updated_at": "2026-08-14T10:00:00.000000Z"
}
],
"meta": {
"current_page": 1,
"last_page": 3,
"per_page": 20,
"total": 45
}
}
💡 Пример cURL:
curl -X GET "https://freeformapi.ru/api/forms/019e4e57-2c21-73c2-bd89-8310e3755239/responses?date_from=2026-08-01&date_to=2026-08-14&per_page=50" \
-H "Authorization: Bearer $TOKEN"
/responses/{id}
Получить один ответ по ID.
📥 Успешный ответ (200):
{
"success": true,
"data": {
"id": "019e4e57-2c21-73c2-bd89-8310e3755246",
"form_id": "019e4e57-2c21-73c2-bd89-8310e3755239",
"answers": {
"019e4e57-2c21-73c2-bd89-8310e3755240": "Отлично"
},
"is_encrypted": false,
"ip": "185.38.84.237",
"user_agent": "Mozilla/5.0...",
"is_read": false,
"created_at": "2026-08-14T10:00:00.000000Z",
"form": {
"id": "019e4e57-2c21-73c2-bd89-8310e3755239",
"title": "Опрос клиентов",
"slug": "abc123"
}
}
}
💡 Пример cURL:
curl -X GET https://freeformapi.ru/api/responses/019e4e57-2c21-73c2-bd89-8310e3755246 \
-H "Authorization: Bearer $TOKEN"
/responses/{id}
Удалить ответ. Счётчик ответов формы уменьшится.
📥 Успешный ответ (200):
{
"success": true,
"message": "Ответ успешно удалён"
}
💡 Пример cURL:
curl -X DELETE https://freeformapi.ru/api/responses/019e4e57-2c21-73c2-bd89-8310e3755246 \
-H "Authorization: Bearer $TOKEN"
/forms/{id}/export/csv
Экспортировать ответы в CSV файл. Поддерживает фильтрацию по датам.
📤 Параметры запроса (опционально):
| date_from | — дата "от" (YYYY-MM-DD) |
| date_to | — дата "до" (YYYY-MM-DD) |
📥 Ответ:
Файл responses_{slug}_{date}.csv скачивается автоматически.
Структура CSV: ID, Дата, IP, User Agent, [вопросы формы...]
💡 Пример cURL:
curl -X GET "https://freeformapi.ru/api/forms/019e4e57-2c21-73c2-bd89-8310e3755239/export/csv?date_from=2026-08-01&date_to=2026-08-14" \
-H "Authorization: Bearer $TOKEN" \
--output responses.csv
🚀 Быстрый старт (пошагово)
Получите токен:
curl -X POST https://freeformapi.ru/api/login \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","password":"password123"}'
Сохраните токен из ответа: TOKEN="1|abc123..."
Создайте форму:
curl -X POST https://freeformapi.ru/api/forms \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Моя первая форма",
"questions": [
{"title": "Ваше имя", "type": "text", "required": true}
]
}'
Запомните slug из ответа.
Заполните форму (публичный маршрут):
curl -X POST https://freeformapi.ru/api/forms/{form_id}/submit \
-H "Content-Type: application/json" \
-d '{
"answers": {
"question_id": "Иван Иванов"
}
}'
Получите ответы:
curl -X GET https://freeformapi.ru/api/forms/{form_id}/responses \
-H "Authorization: Bearer $TOKEN"