Crear una página de suscripción

POST /api/v1/signup-pages Crea una página de suscripción. Responde 201 con la página creada: su id es lo que reciben todas las demás llamadas de páginas de suscripción. Sin status, la página es un borrador: responde con una página de no encontrado en su dirección y no recoge nada hasta que la publiques. Aprovisionar nunca pone una dirección en línea por accidente.

Autorización

Rol en la organizaciónEste endpoint
OWNERPermitido
ADMINPermitido
MEMBERRechazado — 403
Una clave lleva el rol que su creador tiene en esta organización, nunca un rol en AgentsMail en sí. Consulta Claves de API.

Cuerpo de la solicitud

CampoTipoObligatorioDescripción
namestringsíNombre interno, de 1 a 100 caracteres. Solo lo ve tu equipo
slugstringsíÚltima parte de la dirección pública. De 2 a 100 caracteres, solo letras minúsculas, dígitos y guiones. Único en la organización
listIdstringsíLa lista que recibe a los suscriptores. Debe pertenecer a tu organización
contentstringsíEl HTML de la página. Debe llevar {{form}}
heroTitlestringsíEl título que leen los visitantes, hasta 200 caracteres
submitLabelstringsíTexto del botón de suscripción, hasta 60 caracteres
successMessagestringsíSe muestra tras una suscripción cuando no hay redirección, hasta 300 caracteres
sourceTemplateNamestringnoEl tema del que se copió el HTML, hasta 100 caracteres
heroSubtitlestringnoSubtítulo bajo el título, hasta 300 caracteres
redirectUrlstringnoDirección http:// o https:// a la que enviar al visitante en lugar de mostrar successMessage
collectFirstNamebooleannotrue por defecto
collectLastNamebooleannofalse por defecto
statusstringnodraft (por defecto) o published
json
{
  "name": "Newsletter footer",
  "slug": "newsletter",
  "listId": "9f8e7d6c-1111-4bbb-8ccc-ddddeeeeffff",
  "content": "<html><body><h1>{{heroTitle}}</h1>{{form}}{{poweredBy}}</body></html>",
  "heroTitle": "Join the list",
  "submitLabel": "Sign me up",
  "successMessage": "Check your inbox.",
  "status": "published"
}

Ejemplo

bash
curl -X POST -H "x-api-key: $AGENTMAIL_API_KEY" -H "content-type: application/json" \
  -d '{"name":"Newsletter footer","slug":"newsletter","listId":"'$LIST_ID'","content":"<html><body>{{form}}</body></html>","heroTitle":"Join the list","submitLabel":"Sign me up","successMessage":"Check your inbox."}' \
  "https://www.agentsmail.io/api/v1/signup-pages"

Respuesta

  • 201 Created: la página creada, content incluido.
  • 400 Bad Request: falta un campo obligatorio o está mal formado, o el HTML no lleva {{form}}. Cuando el fallo está en la forma, details lleva los problemas campo por campo.
  • 401 Unauthorized: clave ausente o no válida, o su propietario dejó la organización.
  • 403 Forbidden: el propietario de la clave es member de la organización, no admin.
  • 404 Not Found: listId no nombra ninguna lista de tu organización. Desconocida y ajena responden lo mismo.
  • 409 Conflict: otra página ya ocupa ese slug; el mensaje la nombra. No se creó nada.
  • 429 Too Many Requests: la clave superó su límite de peticiones.

Campos de la respuesta

CampoTipoDescripción
successbooleanIndica si la operación tuvo éxito
data.idstringIdentificador único de la página
data.namestringNombre interno
data.slugstringÚltima parte de la dirección pública
data.statusstringdraft o published
data.listIdstringLa lista que recibe a los suscriptores
data.contentstringEl HTML de la página
data.sourceTemplateNamestring | nullEl tema del que se copió, null para HTML pegado
data.heroTitlestringEl título que leen los visitantes
data.heroSubtitlestring | nullEl subtítulo, null si no está definido
data.submitLabelstringTexto del botón de suscripción
data.successMessagestringSe muestra tras una suscripción cuando no hay redirección
data.redirectUrlstring | nullAdónde va el visitante tras suscribirse, null si no hay ninguna
data.collectFirstNamebooleanSi el formulario pide el nombre
data.collectLastNamebooleanSi el formulario pide el apellido
data.createdAtstringFecha de creación ISO
data.updatedAtstringFecha ISO del último cambio

Ejemplo de respuesta

json
{
  "success": true,
  "data": {
    "id": "3d3d3d3d-4444-4eee-9fff-000011112222",
    "name": "Newsletter footer",
    "slug": "newsletter",
    "status": "published",
    "listId": "9f8e7d6c-1111-4bbb-8ccc-ddddeeeeffff",
    "content": "<html><body>{{form}}</body></html>",
    "sourceTemplateName": null,
    "heroTitle": "Join the list",
    "heroSubtitle": null,
    "submitLabel": "Sign me up",
    "successMessage": "Check your inbox.",
    "redirectUrl": null,
    "collectFirstName": true,
    "collectLastName": false,
    "createdAt": "2026-08-23T10:22:05.000Z",
    "updatedAt": "2026-08-23T10:22:05.000Z"
  }
}

Receta para agentes

Copia un tema y publica una vez confirmada la dirección: tres llamadas, en este orden:
js
const themes = (await get('/api/v1/signup-page-templates')).data
const theme = themes[0]

const page = (
  await post('/api/v1/signup-pages', {
    name: 'Newsletter footer',
    slug: 'newsletter',
    listId,
    content: theme.content,
    sourceTemplateName: theme.name,
    heroTitle: 'Join the list',
    submitLabel: 'Sign me up',
    successMessage: 'Check your inbox.',
  })
).data

// Aquí la página sigue siendo un borrador: nada responde todavía en su dirección
await patch(`/api/v1/signup-pages/${page.id}`, {status: 'published'})
Un 409 en la segunda llamada significa que el slug está ocupado. Elige otro: reintentar no servirá.

Notas

  • El HTML es una copia, nunca un enlace. Si el tema cambia después en el catálogo, tu página queda exactamente como está.
  • redirectUrl y successMessage no son alternativas que se definen a la vez: una página con redirección nunca muestra el mensaje.

Relacionado