Business

API REST

Lleva los envíos automáticamente a tu CRM, sistema de tickets o scripts propios, con una API JSON sencilla.

Autenticación

Cada solicitud necesita una clave API en la cabecera Authorization. Como titular de una cuenta Business, creas las claves en tu cuenta, en «API».

curl https://www.formpost.eu/api/v1/submissions?since=2026-10-01T00:00:00Z \
  -H "Authorization: Bearer fp_..."

Una clave pertenece a la cuenta, no a una persona, y ve todos los formularios de la cuenta. Si el plan Business vence, la API responde con 403 hasta que se vuelva a contratar.

Endpoints

GET /forms

Todos los formularios de la cuenta.

GET /forms/{id}

Un formulario. El ID es el identificador de la dirección del formulario (/f/abc123).

GET /submissions

Envíos de todos los formularios, los más recientes primero.

GET /forms/{id}/submissions

Envíos de un formulario.

GET /submissions/{id}

Un envío concreto.

PATCH /submissions/{id}

Marcar como spam o liberar.

DELETE /submissions/{id}

Eliminar un envío definitivamente.

Todas las rutas son relativas a https://www.formpost.eu/api/v1. Las respuestas son JSON.

Parámetros de listas

filter
valid (por defecto), spam o all: los mismos filtros que en la bandeja de entrada.
since
Solo envíos a partir de este momento (ISO 8601). Así consultas periódicamente solo lo nuevo.
page
Página, empezando en 1.
per_page
Entradas por página, de 1 a 100 (por defecto 50).

Respuestas

Las listas van en data, los datos de paginación en meta.

{
  "data": [
    {
      "id": 4711,
      "form_id": "abc123",
      "state": "valid",
      "spam": false,
      "verified": true,
      "encrypted": false,
      "data": { "email": "anna@example.com", "message": "Hallo!" },
      "encrypted_data": null,
      "recipient_email": "info@example.com",
      "referer": "https://example.com/kontakt",
      "created_at": "2026-10-12T09:30:00Z"
    }
  ],
  "meta": { "page": 1, "per_page": 50, "total": 1, "total_pages": 1, "filter": "valid" }
}

En formularios cifrados, data está vacío y encrypted_data contiene el sobre sellado. Tampoco a través de la API conocemos el contenido: solo se abre con tu clave privada. Más en Zero-knowledge encryption.

Marcar spam

Con spam: true un envío pasa a spam; con spam: false se libera de nuevo.

curl -X PATCH https://www.formpost.eu/api/v1/submissions/4711 \
  -H "Authorization: Bearer fp_..." \
  -H "Content-Type: application/json" \
  -d '{"spam": true}'

Errores

Los errores llegan con el estado HTTP correspondiente y un código legible por máquina.

{ "error": { "code": "unauthorized", "message": "Missing or invalid API key" } }
  • 401 – Clave ausente, incorrecta o revocada.
  • 403 – La cuenta no tiene un plan Business activo.
  • 404 – El formulario o el envío no existe en esta cuenta.
  • 400 – Parámetro no válido, p. ej. un formato de fecha incorrecto.
  • 429 – Demasiadas solicitudes: como máximo 120 por minuto y clave.

Webhooks

En lugar de consultar periódicamente, puedes recibir cada nuevo envío. Enviamos un POST con JSON a tu dirección en cuanto el envío supera la protección antispam, al mismo tiempo que el correo.

POST https://example.com/formpost-webhook
Content-Type: application/json
FormPost-Event: submission.created
FormPost-Delivery: 5f0c2c1e-8a8e-4c4a-9b7e-2d6b1d0f7a11
FormPost-Signature: t=1760261400,v1=3b1f…

{
  "id": "5f0c2c1e-8a8e-4c4a-9b7e-2d6b1d0f7a11",
  "type": "submission.created",
  "created_at": "2026-10-12T09:30:00Z",
  "data": {
    "submission": { "id": 4711, "form_id": "abc123", "state": "valid", "data": { "email": "anna@example.com" }, … },
    "form": { "id": "abc123", "name": "Kontakt", … }
  }
}
  • Eventos: submission.created para envíos nuevos y válidos, y ping para el mensaje de prueba desde tu cuenta.
  • Si tu servidor no responde con un estado 2xx en 10 segundos, lo reintentamos hasta seis veces durante unas nueve horas. Tras diez entregas fallidas seguidas desactivamos el webhook.
  • En formularios cifrados, el webhook solo contiene el sobre sellado, igual que la API.
  • Cada entrega tiene un ID único (FormPost-Delivery). Si el mismo ID llega dos veces, procésalo solo una vez.

Comprobar la firma

Cada mensaje está firmado con el secreto del webhook (HMAC-SHA256 sobre la marca de tiempo, un punto y el contenido). Comprueba la firma antes de procesar nada: así tu servidor sabe que el mensaje viene realmente de nosotros.

<?php
$secret = 'whsec_...';
$body = file_get_contents('php://input');
$header = $_SERVER['HTTP_FORMPOST_SIGNATURE'] ?? '';
parse_str(str_replace(',', '&', $header), $sig); // ['t' => ..., 'v1' => ...]

$expected = hash_hmac('sha256', $sig['t'] . '.' . $body, $secret);
if (!hash_equals($expected, $sig['v1'] ?? '') || abs(time() - (int) $sig['t']) > 300) {
    http_response_code(400);
    exit;
}

$event = json_decode($body, true);
// $event['data']['submission'] verarbeiten …
http_response_code(200);

Empezar

La API REST está incluida en el plan Business, junto con accesos de equipo y hasta 1.000 formularios.

Crear una clave API