Conecta tus sistemas con Plensity
Da de alta clientes y ofertas desde tu CRM, sigue en qué estado va cada oferta y descarga el PDF firmado y su certificado, sin pasar por la pantalla.
Primeros pasos
- 1En Plensity, un administrador entra en Ajustes → API y crea una clave. Se enseña una sola vez: guárdala en un sitio seguro.
- 2Cada llamada lleva la clave en la cabecera
Authorization: Bearer pls_…. - 3Comprueba que funciona con
GET /me: responde con el nombre de tu empresa y el permiso de la clave.
https://app.plensity.io/api/v1Claves y permisos
- Solo lectura: consulta y descarga. Lectura y escritura: además crea y modifica.
- Una clave solo ve los datos de tu empresa, y actúa en nombre del administrador que la creó: lo que cambia queda en la auditoría como «API: nombre de la clave».
- Deja de funcionar al momento si se revoca, si quien la creó deja de ser administrador o si la empresa deja el plan Corporate.
- Plensity no guarda la clave, solo una huella. Si se pierde, se revoca y se crea otra.
Formato
- Peticiones y respuestas en JSON (
Content-Type: application/json). Los nombres de campo están en inglés. - Fechas en ISO 8601. Importes como número, en la moneda de
currency. - Las listas se paginan con
limit(hasta 200, por defecto 50) yoffset, y responden{"data": [...], "total", "limit", "offset"}. - Hasta 120 llamadas por minuto por clave. Al pasarse,
429 rate_limited: espera un momento y reintenta.
Referencia
Clientes
/clientsLista los clientes. Filtra con q (nombre o sector).
/clients/{id}Un cliente.
/clientsescrituraDa de alta un cliente. name es obligatorio; además sector, contact_name, contact_role, contact_email y contact_phone. Si ya hay uno con ese nombre (sin contar mayúsculas ni tildes), no se repite: devuelve el que hay con 200 y already_existed: true.
/clients/{id}escrituraModifica los campos que envíes.
Ofertas
/proposalsLista las ofertas. Filtra con status, client_id y updated_since (fecha ISO 8601).
/proposals/{id}Una oferta con sus servicios, si el cliente la ha abierto (tracking), si está firmada y por quién (signature) y los enlaces al PDF y al certificado. Cada servicio dice cómo se cobra en billing (fixed, per_day, monthly, per_unit) y recurring_monthly es la cuota al mes; amount es el valor total del contrato, sin IVA.
/proposalsescrituraCrea el borrador de una oferta, como «+ Nueva propuesta». client_id es obligatorio; además title, description (lo que pide el cliente), deadline (AAAA-MM-DD), owner_email (quien la lleva) y template_id.
/proposals/{id}escrituraCambia el estado con status (y lost_reason al perderla). Con las mismas reglas que en Plensity: un borrador no pasa a ganada, ni sale sin el margen aprobado.
/proposals/{id}/pdfEl PDF. Si ya se envió, el que recibió el cliente.
/proposals/{id}/signature-certificateEl certificado de la firma. 404 not_signed si no está firmada.
draftgeneratedsentclient_approvedwonlostcancelledEjemplo
curl "https://app.plensity.io/api/v1/proposals/42" \ -H "Authorization: Bearer pls_…"
{
"id": 42,
"reference": "REF-2026-042",
"title": "Servicio gestionado 2027",
"client_id": 7,
"client_name": "Transportes Aldama",
"status": "sent",
"amount": 24900.0,
"currency": "EUR",
"sent_at": "2026-09-21T10:14:03",
"tracking": {
"opened": true,
"views": 3,
"first_opened_at": "2026-09-21T11:02:40",
"last_opened_at": "2026-09-24T08:31:12"
},
"signature": { "signed": false, "signed_at": null, "signer_name": null, "signer_email": null, "signer_company": null },
"recurring_monthly": 2075.0,
"services": [{
"name": "Servicio gestionado", "type": "managed", "price": 24900.0,
"billing": { "type": "monthly", "unit_price": 2075.0, "quantity": 12, "unit": null }
}],
"links": {
"pdf": "https://app.plensity.io/api/v1/proposals/42/pdf",
"signature_certificate": null
}
}curl -X POST "https://app.plensity.io/api/v1/proposals" \
-H "Authorization: Bearer pls_…" \
-H "Content-Type: application/json" \
-d '{"title": "Renovación 2027", "client_id": 7,
"deadline": "2027-01-31",
"owner_email": "laura@tuempresa.com"}'Errores
Siempre con la misma forma. En validation_failed, fields dice qué falla en cada campo.
{
"error": {
"code": "validation_failed",
"message": "…",
"fields": { "client_id": "…" }
}
}| 400 | invalid_json | El cuerpo no es un objeto JSON. |
| 400 | invalid_parameter | Un parámetro de la URL no es válido. |
| 401 | unauthorized | Falta la clave. |
| 401 | invalid_key | La clave no existe o está revocada. |
| 401 | key_owner_inactive | Quien creó la clave ya no es administrador activo. |
| 403 | plan_required | Tu plan no incluye la API. |
| 403 | read_only_key | La clave es de solo lectura. |
| 404 | not_found | No existe, o no es de tu empresa. |
| 404 | not_signed | La oferta no está firmada. |
| 405 | method_not_allowed | Ese método no existe en esa ruta. |
| 409 | invalid_transition | Ese cambio de estado no se puede hacer. |
| 410 | gone | Ya no existe. Las oportunidades se quitaron: todo sale de las ofertas (<code>/proposals</code>). |
| 422 | validation_failed | Hay campos no válidos. |
| 429 | rate_limited | Demasiadas llamadas: espera un momento. |
| 500 | server_error | Algo ha fallado en Plensity: reintenta en un momento. |
¿Quieres que te avisemos?
Para enterarte al momento de que una oferta se envía, cambia de estado o se gana, sin preguntar cada rato, configura un webhook en Ajustes → Webhooks: Plensity llama a tu sistema cuando pasa.