📚 Referencia

API de Presupuestapp

Todos los endpoints usados por el dashboard y el widget embebido son una API REST pública. Base URL:https://api.presupuestapp.com. Las rutas marcadas "Sesión" requieren la cookie de sesión del dashboard (credentials: 'include'); el resto son públicas y las llama el propio widget.js.

Autenticación

Login sin contraseña por enlace mágico. La sesión viaja en una cookie httpOnly — todas las rutas del dashboard la requieren.

POST/api/auth/request-magic-linkPública

Envía un enlace de acceso al email indicado.

Request
{ "email": "tu@negocio.com" }
Response
{ "success": true, "message": "Te hemos enviado un enlace de acceso a tu email." }
GET/api/auth/verify?token=…Pública

Canjea el token del enlace mágico por una sesión (cookie).

Response
{ "success": true, "email": "tu@negocio.com" }
GET/api/auth/meSesión

Devuelve el usuario autenticado.

Response
{ "success": true, "user": { "email": "tu@negocio.com" } }
POST/api/auth/logoutSesión

Cierra la sesión actual.

Response
{ "success": true, "message": "Sesión cerrada." }

Widgets

Configuración de tus calculadoras: preguntas, precios, apariencia. El límite de widgets depende de tu plan (Free: 1 · Starter: 3 · Pro/Agency: ilimitados).

POST/api/widgetsSesión

Crea un widget.

Request
{ "name": "Pintura", "mode": "bubble", "appearance": { "primaryColor": "#0c7a6a" }, "questions": [...], "pricing": { "basePrice": 0, "modifiers": [...] } }
Response
{ "success": true, "widget": { "id": "widget_…", "name": "Pintura", … } }
GET/api/widgetsSesión

Lista tus widgets.

Response
{ "success": true, "widgets": [ { "id": "widget_…", … } ] }
GET/api/widgets/:idPública

Configuración de un widget (usada por widget.js).

Response
{ "success": true, "widget": { … } }
PATCH/api/widgets/:idSesión

Actualiza un widget. Acepta cualquier subconjunto de los campos de creación, incluido "workspaceId".

Response
{ "success": true, "widget": { … } }
DELETE/api/widgets/:idSesión

Elimina un widget.

Response
{ "success": true, "message": "Widget eliminado." }

Leads

Captura de leads (llamada por el widget embebido) y panel de leads del negocio.

POST/api/leadsPública

Registra un lead al enviar el formulario del widget.

Request
{ "widgetId": "widget_…", "serviceType": "pintura", "answers": { … }, "priceEstimate": { "min": 300, "max": 450 }, "contactInfo": { "name": "Ana", "phone": "600111222" } }
Response
{ "success": true, "leadId": "lead_…", "message": "Presupuesto solicitado correctamente. Te contactaremos en breve." }
GET/api/leads?status=new&search=ana&page=1&pageSize=20Sesión

Lista tus leads con filtros (status, service, search, from, to, sort) y paginación.

Response
{ "success": true, "leads": [ … ], "total": 42, "page": 1, "pageSize": 20, "services": ["pintura"] }
PATCH/api/leads/:id/statusSesión

Cambia el estado (new/contacted/won/lost).

Request
{ "status": "contacted" }
Response
{ "success": true, "lead": { … } }
DELETE/api/leads/:idSesión

Elimina un lead.

Response
{ "success": true, "message": "Lead eliminado." }

Plantillas

Plantillas prediseñadas por sector (pintura, reforma de baño, mudanza, limpieza) para arrancar un widget nuevo.

GET/api/templatesPública

Lista las plantillas disponibles.

Response
{ "success": true, "templates": [ { "id": "pintura", "name": "Pintura", "icon": "🎨", "description": "…" } ] }
GET/api/templates/:idPública

Configuración completa de una plantilla.

Response
{ "success": true, "template": { "id": "pintura", "questions": [...], "pricing": { … } } }

Analíticas / ROI

Embudo de conversión, ROI por widget, y tracking externo (pixel + conversiones de Google Ads/Facebook).

POST/api/analytics/trackPública

Registra un evento (visit / calculator_started / calculator_completed).

Request
{ "widgetId": "widget_…", "type": "visit" }
Response
{ "success": true }
GET/api/analytics/pixel?widgetId=…&type=visitPública

Igual que /track pero como GIF 1x1 — para plataformas que solo permiten insertar una imagen.

Response
Content-Type: image/gif (43 bytes)
POST/api/analytics/track-conversionPública

Atribuye una conversión externa (Google Ads, Facebook…) a un widget.

Request
{ "widgetId": "widget_…", "source": "google_ads", "value": 450, "conversionId": "gclid_abc" }
Response
{ "success": true }
GET/api/analytics/overview?from=2026-08-01&to=2026-08-31Sesión

Visitas, calculadoras completadas, leads y facturación del rango.

Response
{ "success": true, "overview": { "visits": 320, "leads": 41, "totalRevenue": 8200 } }
GET/api/analytics/funnelSesión

Embudo paso a paso con % de abandono.

Response
{ "success": true, "funnel": [ { "key": "visits", "count": 320, "dropOffRate": 0 }, … ] }
GET/api/analytics/per-widgetSesión

Desglose de métricas por widget.

Response
{ "success": true, "widgets": [ { "widgetId": "widget_…", "leads": 12, "totalRevenue": 3100 } ] }
PATCH/api/analytics/leads/:id/convertSesión

Marca un lead como ganado con su valor (€).

Request
{ "value": 450 }
Response
{ "success": true, "lead": { "status": "won", "wonValue": 450 } }

Webhooks

Notifica a Zapier/CRM propio cuando entra o se cierra un lead.

GET/api/webhooksSesión

Lista tus webhooks.

Response
{ "success": true, "webhooks": [ { "id": "webhook_…", "url": "…", "events": ["lead.new"] } ] }
POST/api/webhooksSesión

Registra un webhook.

Request
{ "url": "https://hooks.zapier.com/…", "events": ["lead.new", "lead.won"] }
Response
{ "success": true, "webhook": { … } }
DELETE/api/webhooks/:idSesión

Elimina un webhook.

Response
{ "success": true, "message": "Webhook eliminado." }
POST/api/webhooks/:id/testSesión

Envía un payload de prueba.

Response
{ "success": true, "delivered": true, "statusCode": 200 }

WhatsApp

Envío del presupuesto al cliente y aviso al negocio por WhatsApp (Starter+). Sin credenciales reales configuradas todavía, las respuestas son simuladas (mock).

GET/api/whatsapp/settingsSesión

Estado de la conexión y si el plan la permite.

Response
{ "success": true, "settings": { "enabled": false, "connected": false }, "planAllowsWhatsApp": true }
PATCH/api/whatsapp/settingsSesión

Activa/desactiva y define el número del negocio.

Request
{ "enabled": true, "phoneNumber": "+34600111222" }
Response
{ "success": true, "settings": { … } }
POST/api/whatsapp/sendSesión

Envía un mensaje (mock).

Request
{ "to": "+34600111222", "message": "Hola…" }
Response
{ "success": true, "mock": true, "id": "wamock_…" }

PDF de presupuesto

Genera un presupuesto imprimible en HTML (base para el PDF real) a partir de un lead.

POST/api/pdf/generateSesión

Genera el presupuesto de un lead.

Request
{ "leadId": "lead_…" }
Response
{ "success": true, "quoteId": "quote_…", "previewUrl": "…/api/pdf/quote_…/preview" }
GET/api/pdf/:id/previewPública

Renderiza el presupuesto generado (compartible).

Response
HTML del presupuesto

Abandonos

Visitantes que empezaron la calculadora pero no la enviaron.

POST/api/abandons/recordPública

El widget registra el progreso en cada paso (upsert por sessionId).

Request
{ "sessionId": "sess_…", "widgetId": "widget_…", "stepsCompleted": 2 }
Response
{ "success": true }
GET/api/abandonsSesión

Lista los abandonos de tus widgets.

Response
{ "success": true, "abandons": [ { "sessionId": "sess_…", "stepsCompleted": 2 } ] }
GET/api/abandons/statsSesión

Recuento de hoy / esta semana / este mes.

Response
{ "success": true, "stats": { "today": 3, "week": 9, "month": 22 } }
DELETE/api/abandons/:sessionIdSesión

Descarta un abandono.

Response
{ "success": true, "message": "Abandono descartado." }

Facturación

Suscripciones vía Stripe. Sin claves configuradas todavía, devuelve datos simulados (mock: true).

POST/api/billing/create-checkout-sessionSesión

Inicia el checkout de un plan.

Request
{ "plan": "starter", "billing": "monthly" }
Response
{ "success": true, "mock": true, "checkoutUrl": "…" }
GET/api/billing/portalSesión

URL del portal de facturación.

Response
{ "success": true, "mock": true, "portalUrl": "…" }
GET/api/billing/invoicesSesión

Historial de facturas.

Response
{ "success": true, "mock": true, "invoices": [] }

Planes

Límites y uso del plan actual.

GET/api/plansPública

Definición de todos los planes.

Response
{ "success": true, "plans": { "free": { "widgets": 1, "estimates": 20 }, "agency": { "widgets": null, "workspaces": true } } }
GET/api/plans/my-planSesión

Plan y uso actual del usuario.

Response
{ "success": true, "plan": "starter", "usage": { "widgetsUsed": 2, "widgetsAllowance": 3 } }

Workspaces (Agency)

Agrupa widgets y leads por cliente final, con marca blanca propia. Solo disponible en el plan Agency.

GET/api/workspacesSesión · Agency

Lista tus workspaces.

Response
{ "success": true, "workspaces": [ { "id": "workspace_…", "name": "…", "clientName": "…" } ] }
POST/api/workspacesSesión · Agency

Crea un workspace.

Request
{ "name": "Reformas García", "clientName": "Reformas García S.L." }
Response
{ "success": true, "workspace": { … } }
GET/api/workspaces/:idSesión

Detalle con widgets, leads y estadísticas.

Response
{ "success": true, "workspace": { … }, "widgets": [...], "leads": [...], "stats": { "leads": 12, "totalRevenue": 3100 } }
PATCH/api/workspaces/:idSesión

Actualiza nombre, cliente o marca blanca.

Request
{ "brand": { "name": "García Presupuestos", "logoUrl": "https://…" } }
Response
{ "success": true, "workspace": { … } }
DELETE/api/workspaces/:idSesión

Elimina el workspace (los widgets no se borran, solo se desvinculan).

Response
{ "success": true, "message": "Workspace eliminado." }

Dominio personalizado (Agency)

Sirve el widget desde un subdominio propio en lugar de api.presupuestapp.com. La verificación DNS está simulada por ahora.

GET/api/domainsSesión · Agency

Lista tus dominios.

Response
{ "success": true, "domains": [ { "id": "domain_…", "subdomain": "presupuesto.tuagencia.com", "status": "pending" } ] }
POST/api/domainsSesión · Agency

Registra un subdominio (queda en estado "pending").

Request
{ "subdomain": "presupuesto.tuagencia.com" }
Response
{ "success": true, "domain": { "status": "pending" } }
POST/api/domains/:id/verifySesión · Agency

Comprueba el DNS (mock) y pasa a "verified".

Response
{ "success": true, "domain": { "status": "verified" } }
DELETE/api/domains/:idSesión

Elimina un dominio.

Response
{ "success": true, "message": "Dominio eliminado." }

Referidos

Cada cuenta tiene un código de referido (ref-XXXXXX). Cuando el referido paga, ambos reciben 1 mes gratis.

GET/api/referralsSesión

Tu enlace de referido y estadísticas.

Response
{ "success": true, "code": "ref-7K2F9Q", "link": "…/dashboard/login?ref=ref-7K2F9Q", "stats": { "totalReferred": 3, "rewarded": 1 } }
POST/api/referrals/applyPública

Aplica un código al darse de alta.

Request
{ "code": "ref-7K2F9Q", "email": "nuevo@negocio.com" }
Response
{ "success": true, "message": "Código de referido aplicado. Cuando tu cuenta pase a un plan de pago, ambos recibiréis 1 mes gratis." }

¿Necesitas ayuda con la integración?

Escríbenos y te ayudamos a conectar Presupuestapp con tu CRM, Zapier o web.

Ir al dashboard