GET
/me
Usuario resource owner y su perfil de propietario.
Scope:
Bearer válido (cualquier scope de cuenta)
Output
{
"success": true,
"data": {
"id": 1,
"email": "ana@example.com",
"full_name": "Ana Pérez",
"confirmed": true,
"landlord_profile": {
"id": 9,
"slug": "ana-perez",
"full_name": "Ana Pérez",
"bio": null,
"contact_number": null,
"whatsapp_number": null,
"show_contact_number": false,
"show_whatsapp_number": false,
"allow_only_id_verified_contacts": false
}
}
}
PATCH
/me
Actualiza nombre del usuario.
Scope:
profile_write
Body: `full_name` o `first_name` / `last_name`
Output
{
"success": true,
"data": {
"id": 1,
"full_name": "Ana Pérez"
}
}
PATCH
/me/landlord_profile
Actualiza el perfil de propietario (no RNC).
Scope:
profile_write
Body: `landlord_profile`: full_name, bio, slug, contact_number, whatsapp_number, show_contact_number, show_whatsapp_number, allow_only_id_verified_contacts
Output
{
"success": true,
"data": {
"id": 1,
"landlord_profile": {
"slug": "ana-perez"
}
}
}
GET
/properties
Lista y busca propiedades del resource owner.
Scope:
listings_write
Query: `q`, `status`, `rental_unit_type_id`, `page`, `per_page`
Output
{
"success": true,
"data": {
"total": 1,
"page": 1,
"per_page": 10,
"total_pages": 1,
"properties": [
{
"id": 42,
"slug": "apartamento-en-piantini",
"title": "Apartamento en Piantini",
"status": "unlisted",
"property_type": "Apartamento",
"rent_price": 25000,
"selling_price": null,
"currency": "DOP",
"location": "Piantini, Santo Domingo",
"photos_count": 3,
"ready_to_publish": false,
"quality": {
"percent": 72,
"threshold": 90,
"suggestions": [
"Agrega más fotos"
]
},
"url": "https://alquila.do/propiedad/apartamento-en-piantini",
"view_url": "https://alquila.do/propietario/propiedades/apartamento-en-piantini",
"edit_url": "https://alquila.do/propietario/propiedades/apartamento-en-piantini/edit",
"message": "Propiedad creada como borrador."
}
]
}
}
POST
/properties
Crea un borrador (`unlisted`). Si hay precio sin moneda, se usa DOP.
Scope:
listings_write
Body: Campos de RentalUnitPublisher (title, rental_unit_type_id, province_id, municipality_id, description, rent_price, selling_price, currency_id, bedrooms, bathrooms, amenity_ids, …)
201. Gates: identity_verification_required, listing_limit_reached.
Output
{
"success": true,
"data": {
"id": 42,
"slug": "apartamento-en-piantini",
"title": "Apartamento en Piantini",
"status": "unlisted",
"property_type": "Apartamento",
"rent_price": 25000,
"selling_price": null,
"currency": "DOP",
"location": "Piantini, Santo Domingo",
"photos_count": 3,
"ready_to_publish": false,
"quality": {
"percent": 72,
"threshold": 90,
"suggestions": [
"Agrega más fotos"
]
},
"url": "https://alquila.do/propiedad/apartamento-en-piantini",
"view_url": "https://alquila.do/propietario/propiedades/apartamento-en-piantini",
"edit_url": "https://alquila.do/propietario/propiedades/apartamento-en-piantini/edit",
"message": "Propiedad creada como borrador."
}
}
GET
/properties/:id
Detalle de una propiedad propia (id o slug).
Scope:
listings_write
404 si no es del resource owner (no se filtra existencia de terceros).
Output
{
"success": true,
"data": {
"id": 42,
"slug": "apartamento-en-piantini",
"title": "Apartamento en Piantini",
"status": "unlisted",
"property_type": "Apartamento",
"rent_price": 25000,
"selling_price": null,
"currency": "DOP",
"location": "Piantini, Santo Domingo",
"photos_count": 3,
"ready_to_publish": false,
"quality": {
"percent": 72,
"threshold": 90,
"suggestions": [
"Agrega más fotos"
]
},
"url": "https://alquila.do/propiedad/apartamento-en-piantini",
"view_url": "https://alquila.do/propietario/propiedades/apartamento-en-piantini",
"edit_url": "https://alquila.do/propietario/propiedades/apartamento-en-piantini/edit",
"message": "Propiedad creada como borrador."
}
}
PATCH
/properties/:id
Actualiza una propiedad propia.
Scope:
listings_write
Body: Mismos campos que POST
Output
{
"success": true,
"data": {
"id": 42,
"slug": "apartamento-en-piantini",
"title": "Apartamento en Piantini",
"status": "unlisted",
"property_type": "Apartamento",
"rent_price": 25000,
"selling_price": null,
"currency": "DOP",
"location": "Piantini, Santo Domingo",
"photos_count": 3,
"ready_to_publish": false,
"quality": {
"percent": 72,
"threshold": 90,
"suggestions": [
"Agrega más fotos"
]
},
"url": "https://alquila.do/propiedad/apartamento-en-piantini",
"view_url": "https://alquila.do/propietario/propiedades/apartamento-en-piantini",
"edit_url": "https://alquila.do/propietario/propiedades/apartamento-en-piantini/edit",
"message": "Propiedad creada como borrador."
}
}
DELETE
/properties/:id
Elimina una propiedad no publicada.
Scope:
listings_write
Si está publicada: despublica antes.
Output
{
"success": true,
"data": {
"message": "Propiedad eliminada.",
"id": 42
}
}
POST
/properties/:id/publish
Publica si pasa `ready_to_publish?`.
Scope:
listings_write
Output
{
"success": true,
"data": {
"id": 42,
"slug": "apartamento-en-piantini",
"title": "Apartamento en Piantini",
"status": "available",
"property_type": "Apartamento",
"rent_price": 25000,
"selling_price": null,
"currency": "DOP",
"location": "Piantini, Santo Domingo",
"photos_count": 3,
"ready_to_publish": false,
"quality": {
"percent": 72,
"threshold": 90,
"suggestions": [
"Agrega más fotos"
]
},
"url": "https://alquila.do/propiedad/apartamento-en-piantini",
"view_url": "https://alquila.do/propietario/propiedades/apartamento-en-piantini",
"edit_url": "https://alquila.do/propietario/propiedades/apartamento-en-piantini/edit",
"message": "Propiedad publicada exitosamente.",
"published": true
}
}
POST
/properties/:id/unpublish
Despublica. Requiere motivo.
Scope:
listings_write
Body: `unpublish_reason`: sold_or_rented_on_alquila_do | sold_or_rented_elsewhere | not_yet_sold_or_rented | prefer_not_to_say
Output
{
"success": true,
"data": {
"id": 42,
"slug": "apartamento-en-piantini",
"title": "Apartamento en Piantini",
"status": "unlisted",
"property_type": "Apartamento",
"rent_price": 25000,
"selling_price": null,
"currency": "DOP",
"location": "Piantini, Santo Domingo",
"photos_count": 3,
"ready_to_publish": false,
"quality": {
"percent": 72,
"threshold": 90,
"suggestions": [
"Agrega más fotos"
]
},
"url": "https://alquila.do/propiedad/apartamento-en-piantini",
"view_url": "https://alquila.do/propietario/propiedades/apartamento-en-piantini",
"edit_url": "https://alquila.do/propietario/propiedades/apartamento-en-piantini/edit",
"message": "Propiedad despublicada."
}
}
GET
/properties/:id/quality
Índice de calidad del anuncio propio.
Scope:
listings_write
Output
{
"success": true,
"data": {
"id": 42,
"slug": "apartamento-en-piantini",
"title": "Apartamento en Piantini",
"status": "unlisted",
"property_type": "Apartamento",
"rent_price": 25000,
"selling_price": null,
"currency": "DOP",
"location": "Piantini, Santo Domingo",
"photos_count": 3,
"ready_to_publish": false,
"quality": {
"percent": 72,
"threshold": 90,
"suggestions": [
"Agrega más fotos"
]
},
"url": "https://alquila.do/propiedad/apartamento-en-piantini",
"view_url": "https://alquila.do/propietario/propiedades/apartamento-en-piantini",
"edit_url": "https://alquila.do/propietario/propiedades/apartamento-en-piantini/edit",
"message": "Índice de calidad del anuncio."
}
}
POST
/properties/:property_id/photos
Sube fotos (máx. 10, 5 MB, jpeg/png/webp/gif).
Scope:
listings_write
Body: multipart `photos[]` o JSON `{ "photos": [{ "url": "https://..." }] }`
201. Throttle: 5 POST /photos por min / usuario.
Output
{
"success": true,
"data": {
"photos_count": 3,
"message": "Fotos subidas correctamente.",
"quality": {
"percent": 80
}
}
}
DELETE
/properties/:property_id/photos/:id
Elimina una foto.
Scope:
listings_write
Output
{
"success": true,
"data": {
"photos_count": 2,
"message": "Foto eliminada."
}
}
GET
/agencies
Agencias donde el usuario es owner o miembro active.
Scope:
agencies_read
Output
{
"success": true,
"data": [
{
"id": 3,
"name": "Agencia Demo",
"slug": "agencia-demo",
"status": "active",
"role": "owner"
}
]
}
GET
/agencies/:id
Detalle de una agencia accesible.
Scope:
agencies_read
Agencia ajena: 404.
Output
{
"success": true,
"data": {
"id": 3,
"name": "Agencia Demo",
"slug": "agencia-demo",
"status": "active",
"role": "owner",
"email": "agencia@example.com",
"phone": "8090000000",
"website": null,
"description": null,
"address": null
}
}
PATCH
/agencies/:id
Actualiza datos de agencia (solo owner/partner).
Scope:
agencies_write
Body: `agency`: name, address, phone, email, website, description, redes, auto_detect_enabled
Output
{
"success": true,
"data": {
"id": 3,
"name": "Agencia Demo"
}
}
GET
/agencies/:id/properties
Inventario del equipo (unión de miembros active + owner). Solo lectura.
Scope:
agencies_read
Query: `q`, `status`, `rental_unit_type_id`, `page`, `per_page`
Output
{
"success": true,
"data": {
"properties": [
{
"id": 42,
"slug": "apartamento-en-piantini",
"title": "Apartamento en Piantini",
"status": "unlisted",
"property_type": "Apartamento",
"rent_price": 25000,
"selling_price": null,
"currency": "DOP",
"location": "Piantini, Santo Domingo",
"photos_count": 3,
"ready_to_publish": false,
"quality": {
"percent": 72,
"threshold": 90,
"suggestions": [
"Agrega más fotos"
]
},
"url": "https://alquila.do/propiedad/apartamento-en-piantini",
"view_url": "https://alquila.do/propietario/propiedades/apartamento-en-piantini",
"edit_url": "https://alquila.do/propietario/propiedades/apartamento-en-piantini/edit",
"message": "Propiedad creada como borrador."
}
],
"pagination": {
"page": 1,
"per_page": 10,
"total": 1,
"total_pages": 1
}
}
}
GET
/agencies/:id/properties/:property_id
Una propiedad del inventario de la agencia.
Scope:
agencies_read
Output
{
"success": true,
"data": {
"id": 42,
"slug": "apartamento-en-piantini",
"title": "Apartamento en Piantini",
"status": "unlisted",
"property_type": "Apartamento",
"rent_price": 25000,
"selling_price": null,
"currency": "DOP",
"location": "Piantini, Santo Domingo",
"photos_count": 3,
"ready_to_publish": false,
"quality": {
"percent": 72,
"threshold": 90,
"suggestions": [
"Agrega más fotos"
]
},
"url": "https://alquila.do/propiedad/apartamento-en-piantini",
"view_url": "https://alquila.do/propietario/propiedades/apartamento-en-piantini",
"edit_url": "https://alquila.do/propietario/propiedades/apartamento-en-piantini/edit",
"message": "Propiedad creada como borrador."
}
}
GET
/agencies/:id/invitations
Membresías/invitaciones de esa agencia (owner/partner).
Scope:
invitations_write
Output
{
"success": true,
"data": {
"invitations": [
{
"id": 8,
"email": "agente@example.com",
"role": "agent",
"status": "pending",
"source": "manual",
"user_id": 11,
"created_at": "2026-10-28T12:00:00Z"
}
],
"pagination": {
"page": 1,
"per_page": 10,
"total": 1,
"total_pages": 1
}
}
}
POST
/agencies/:id/invitations
Invita un email o user_id (un destinatario). Si no existe, Devise invite.
Scope:
invitations_write
Body: `{ "email": "a@b.com", "role": "agent" }` o `{ "user_id": 11, "role": "manager" }` — roles: agent, manager, secretary, partner
201. Cupo del plan de agencia aplica. No hay CSV/bulk.
Output
{
"success": true,
"data": {
"id": 8,
"email": "a@b.com",
"role": "agent",
"status": "pending"
}
}
POST
/agencies/:id/invitations/:invitation_id/resend
Reenvía una invitación pending.
Scope:
invitations_write
Output
{
"success": true,
"data": {
"id": 8,
"status": "pending",
"message": "Invitación reenviada."
}
}
DELETE
/agencies/:id/invitations/:invitation_id
Cancela una invitación pending.
Scope:
invitations_write
Output
{
"success": true,
"data": {
"message": "Invitación cancelada."
}
}
GET
/me/agency_invitations
Invitaciones pending enviadas al resource owner.
Scope:
invitations_write
Output
{
"success": true,
"data": [
{
"id": 8,
"agency_id": 3,
"agency_name": "Agencia Demo",
"role": "agent",
"status": "pending",
"created_at": "2026-10-28T12:00:00Z"
}
]
}
POST
/me/agency_invitations/:id/accept
Acepta una invitación recibida.
Scope:
invitations_write
Output
{
"success": true,
"data": {
"id": 8,
"status": "active",
"message": "Te uniste a Agencia Demo."
}
}
POST
/me/agency_invitations/:id/decline
Rechaza (elimina) una invitación recibida.
Scope:
invitations_write
Output
{
"success": true,
"data": {
"message": "Rechazaste la invitación de Agencia Demo."
}
}
GET
/leads
Leads de listings propios. Con `agency_id` + `agencies_read`, leads agregados de esa agencia.
Scope:
leads_read
Query: `agency_id`, `page`, `per_page`
Output
{
"success": true,
"data": {
"leads": [
{
"id": 5,
"name": "Luis",
"email": "luis@example.com",
"phone": "8091112222",
"status": "new",
"message": "Me interesa",
"rental_unit_id": 42,
"created_at": "2026-10-28T12:00:00Z"
}
],
"pagination": {
"page": 1,
"per_page": 10,
"total": 1,
"total_pages": 1
}
}
}
GET
/leads/:id
Detalle y comentarios.
Scope:
leads_read
Output
{
"success": true,
"data": {
"lead": {
"id": 5,
"name": "Luis",
"status": "new",
"source": "web",
"updated_at": "2026-10-28T12:00:00Z"
},
"comments": [
{
"id": 1,
"message": "Llamar mañana",
"user": {
"id": 1,
"full_name": "Ana Pérez"
},
"created_at": "2026-10-28T12:00:00Z"
}
]
}
}
PATCH
/leads/:id
Cambia status. `comment` opcional crea un comentario.
Scope:
leads_write
Body: `status` (requerido), `comment` (opcional)
No hay DELETE. No cubre LeadRequest del marketplace.
Output
{
"success": true,
"data": {
"id": 5,
"status": "contacted"
}
}
POST
/leads/:lead_id/comments
Agrega un comentario.
Scope:
leads_write
Body: `message` o `comment`
Output
{
"success": true,
"data": {
"id": 2,
"message": "Llamar mañana",
"created_at": "2026-10-28T12:00:00Z"
}
}
GET
/rental_unit_types
Tipos de propiedad.
Scope:
Bearer válido (cualquier scope de cuenta)
Output
{
"success": true,
"data": [
{
"id": 1,
"name": "Apartamento",
"description": null
}
]
}
GET
/countries
Países.
Scope:
Bearer válido (cualquier scope de cuenta)
Output
{
"success": true,
"data": [
{
"id": 1,
"name": "República Dominicana",
"code": "DO"
}
]
}
GET
/currencies
Monedas.
Scope:
Bearer válido (cualquier scope de cuenta)
Output
{
"success": true,
"data": [
{
"id": 1,
"code": "DOP",
"name": "Peso dominicano"
}
]
}
GET
/amenities
Amenidades activas.
Scope:
Bearer válido (cualquier scope de cuenta)
Output
{
"success": true,
"data": [
{
"id": 4,
"name": "Piscina",
"code": "pool"
}
]
}
GET
/locations
Sectores (neighborhoods) para crear propiedades.
Scope:
Bearer válido (cualquier scope de cuenta)
Query: `q`, `page`, `per_page`
Output
{
"success": true,
"data": {
"locations": [
{
"id": 10,
"name": "Piantini",
"municipality": "Santo Domingo",
"province": "Distrito Nacional"
}
],
"pagination": {
"page": 1,
"per_page": 10,
"total": 1,
"total_pages": 1
}
}
}