Documentación API
Conecta tu web con
el catálogo y los leads de NORA
API REST con autenticación por API key: consulta el catálogo de viviendas y promociones, recibe leads desde tus formularios y confirma publicaciones entre tu web y el CRM.
Base URL: https://noraapp.es/api/v1
Autenticación
API key por conexión, con scopes
Cada integración (una web, un portal, un CMS) tiene su propia credencial, con solo los permisos que necesita. Se solicita desde tu equipo de NORA y se gestiona en Configuración → Integraciones.
Cabecera de autenticación
Envía la API key como Bearer token (o como X-Api-Key si tu cliente no soporta cabeceras Authorization personalizadas).
Authorization: Bearer <api_key>
# alternativa
X-Api-Key: <api_key>Límite de peticiones
120 solicitudes por minuto por credencial. Al superarlo, la API responde 429 rate_limited. Las respuestas incluyen Cache-Control: no-store.
| Scope | Qué permite |
|---|---|
| catalog:read | Leer el catálogo de viviendas y promociones publicadas de la empresa. |
| leads:write | Crear leads desde formularios de la web o landing pages. |
| webhooks:receive | Confirmar publicaciones y verificar conexiones de integración. |
Endpoints
Catálogo, promociones, leads e integraciones
/api/v1/propertiescatalog:readLista el catálogo de viviendas publicadas, con paginación por cursor.
limitMáximo de resultados (1–100, por defecto 50).cursorCursor devuelto por la página anterior.updated_sinceSolo viviendas actualizadas desde esa fecha.development_idFiltra las viviendas de una única promoción.Petición
curl "https://noraapp.es/api/v1/properties?limit=20" \
-H "Authorization: Bearer <api_key>"Respuesta
{
"api_version": "v1",
"data": [
{
"id": "8f2b...",
"reference": "VIV-0231",
"title": "Ático con terraza en el centro",
"price": 285000,
"currency": "EUR",
"status": "available",
"bedrooms": 3,
"bathrooms": 2,
"development": { "id": "...", "name": "Residencial Aurora", "city": "Málaga" },
"media": [ { "url": "...", "is_main": true } ],
"updated_at": "2026-06-30T10:12:00Z"
}
],
"pagination": { "limit": 20, "next_cursor": "eyJ...", "has_more": true }
}/api/v1/properties/:idcatalog:readDetalle completo de una vivienda publicada, incluida su promoción y galería.
idIdentificador de la vivienda (en la ruta).Petición
curl "https://noraapp.es/api/v1/properties/8f2b..." \
-H "Authorization: Bearer <api_key>"Respuesta
{
"api_version": "v1",
"data": {
"id": "8f2b...",
"reference": "VIV-0231",
"title": "Ático con terraza en el centro",
"development": { "id": "...", "name": "Residencial Aurora", "city": "Málaga" },
"media": [ { "url": "...", "checksum": "..." } ]
}
}/api/v1/developmentscatalog:readLista las promociones con al menos una vivienda publicada, con paginación por cursor.
limitMáximo de resultados (1–100, por defecto 50).cursorCursor devuelto por la página anterior.updated_sinceSolo promociones actualizadas desde esa fecha.Petición
curl "https://noraapp.es/api/v1/developments?limit=20" \
-H "Authorization: Bearer <api_key>"Respuesta
{
"api_version": "v1",
"data": [
{
"id": "3a91...",
"name": "Residencial Aurora",
"city": "Málaga",
"address": "Calle del Puerto, 12",
"delivery_date": "2027-03-01",
"total_units": 48,
"published_units": 21,
"media": [ { "url": "...", "is_main": true } ],
"updated_at": "2026-06-30T10:12:00Z"
}
],
"pagination": { "limit": 20, "next_cursor": "eyJ...", "has_more": false }
}/api/v1/developments/:idcatalog:readFicha completa de una promoción publicada, con su galería propia.
idIdentificador de la promoción (en la ruta).Petición
curl "https://noraapp.es/api/v1/developments/3a91..." \
-H "Authorization: Bearer <api_key>"Respuesta
{
"api_version": "v1",
"data": {
"id": "3a91...",
"name": "Residencial Aurora",
"city": "Málaga",
"province": "Málaga",
"total_units": 48,
"published_units": 21,
"media": [ { "url": "...", "checksum": "..." } ]
}
}/api/v1/leadsleads:writeRegistra un lead desde un formulario web, con consentimiento RGPD y UTMs.
Idempotency-KeyObligatorio. Evita duplicar el lead si repites la petición.first_name / email / phoneDatos de contacto. Email o teléfono es obligatorio.consent{ accepted, text, timestamp } — texto de consentimiento mostrado al usuario.Petición
curl -X POST "https://noraapp.es/api/v1/leads" \
-H "Authorization: Bearer <api_key>" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 2f6a6f3e-9c31-4b7a-9b1a-9b6b3f0d2e11" \
-d '{
"first_name": "Laura",
"email": "laura@example.com",
"phone": "+34600111222",
"message": "Interesada en el ático con terraza",
"property_id": "8f2b...",
"page_url": "https://tuweb.com/aticos/8f2b",
"consent": {
"accepted": true,
"text": "Acepto la política de privacidad para ser contactada.",
"timestamp": "2026-07-06T09:00:00Z"
},
"utm": { "source": "google", "medium": "cpc", "campaign": "aticos-verano" }
}'Respuesta
{ "api_version": "v1", "data": { "id": "3c9d..." }, "created": true }/api/v1/integrations/publicationswebhooks:receiveConfirma desde tu portal/CMS que una vivienda quedó publicada, sin publicar o con error.
property_idVivienda dentro de tu empresa.external_id / external_urlIdentificador y URL en tu sistema.statuspublished | unpublished | error.Petición
curl -X POST "https://noraapp.es/api/v1/integrations/publications" \
-H "Authorization: Bearer <api_key>" \
-H "Content-Type: application/json" \
-d '{
"property_id": "8f2b...",
"external_id": "portal-8891",
"external_url": "https://tuportal.com/inmuebles/8891",
"status": "published"
}'Respuesta
{ "api_version": "v1", "ok": true }/api/v1/integrations/verifywebhooks:receiveVerifica la conexión con el token que NORA te entregó al crearla.
X-Nora-Verification-TokenToken de verificación asociado a la conexión.Petición
curl -X POST "https://noraapp.es/api/v1/integrations/verify" \
-H "Authorization: Bearer <api_key>" \
-H "X-Nora-Verification-Token: <verification_token>"Respuesta
{
"api_version": "v1",
"ok": true,
"connection": { "id": "...", "name": "Web principal", "status": "active" }
}Idempotencia en leads
POST /api/v1/leads exige la cabecera Idempotency-Key. Si repites la misma petición con la misma clave, NORA devuelve la respuesta original en lugar de crear un lead duplicado. Usa un UUID por envío de formulario.
Si reutilizas la clave con un payload distinto, la API responde 409 idempotency_conflict.
Formato de errores
{
"api_version": "v1",
"error": { "code": "validation_error", "message": "..." }
}| HTTP | Código | Cuándo ocurre |
|---|---|---|
| 401 | unauthorized | API key inválida, revocada o sin el scope requerido. |
| 400 / 422 | validation_error / invalid_cursor / idempotency_required | Payload o parámetros inválidos. |
| 404 | not_found | El recurso no existe o no pertenece a tu empresa. |
| 409 | idempotency_conflict | La misma Idempotency-Key se usó con un payload distinto. |
| 429 | rate_limited | Límite de solicitudes superado para esta credencial. |
| 500 | internal_error | Error inesperado del servidor. |
Cómo empezar
Tres pasos para tu primera integración
Crea la conexión desde Configuración → Integraciones e indica el dominio HTTPS de tu web.
Genera la API key con los scopes que necesites (catálogo, leads o ambos).
Verifica la conexión con /api/v1/integrations/verify y ya puedes consumir la API.
¿Necesitas una credencial de API?
Escríbenos y activamos tu conexión con los scopes que necesites, sin coste adicional sobre tu plan.
Incluido en todos los planes CRM