Los planes de tu cliente en el portal
GET /property-v1/customers/{portal}/account
Cuando publicás, mandás un plan. Para elegirlo necesitás saber qué planes tiene tu cliente y
cuántas publicaciones le quedan libres — y ese dato vive en el portal, no en nuestro sistema.
Lo tenés en dos lugares, y conviene usar los dos:
| Dónde | Qué te da | Cuesta |
|---|---|---|
GET /property-v1/customers | Lo último que leímos, con su fecha | nada |
GET /property-v1/customers/{portal}/account | Lo que el portal dice ahora, y actualiza lo anterior | 1 llamada del cupo de tu cliente |
El camino barato es pedir el cliente —que es gratis— y mirar el campo plansStale. Si dice true,
hubo una publicación o una baja después de esa lectura; ahí decidís si gastás la llamada.
Cómo se pide
curl https://property-api.mapaprop.com/property-v1/customers/zonapropapi/account \
-H "Authorization: Bearer $TOKEN" \
-H "x-client-ref: cliente-42"
Respuesta 200:
{
"portal": "zonapropapi",
"portalAccountId": "17064147",
"plans": [
{ "plan": "DESARROLLOS_HOME", "planTotal": 5, "planAvailable": 1 },
{ "plan": "HOME", "planTotal": 80, "planAvailable": 31 },
{ "plan": "SIMPLE", "planTotal": 80, "planAvailable": 20 }
],
"plansReadAt": "2026-10-07T19:32:22.975Z",
"plansStale": false,
"planExpirations": [
{ "plan": "HOME", "date": "2026-12-31T03:00:00.000Z", "quantity": 85 }
],
"cached": true
}
| Campo | Qué es |
|---|---|
plans[].plan | El nombre del plan, tal como lo llama el portal. Es el valor que mandás como plan al publicar |
plans[].planTotal | Cuántos tiene contratados. Puede venir null si el portal no lo informa |
plans[].planAvailable | Cuántas publicaciones le quedan libres |
plansReadAt | Cuándo leímos esto del portal |
plansStale | false acá siempre: lo acabamos de leer |
planExpirations | Cuándo vencen y cuántos. Se omite si el portal no informa ninguno |
cached | Si guardamos la copia. En false, la lectura gratis te va a seguir dando la anterior |
El portal sólo lista los planes que tienen cupo. Un plan que tu cliente contrató pero ya agotó
no aparece en la lista. Por eso "no está en plans" no significa "no lo tiene contratado": puede
significar las dos cosas, y el portal no las distingue.
Es lo que hace confuso el error de publicación por plan: dice "La empresa tiene utilizados todos sus disponibles" y se lee como si la cuenta estuviera sin nada.
Dónde encaja en el flujo
1. POST /property-v1/customers declarás el cliente
2. conectás su cuenta del portal ← acá entran los planes, sin costo extra
3. GET /property-v1/customers los ves, gratis, con su fecha
4. GET /property-v1/customers/{portal}/account los actualizás contra el portal (1 llamada)
5. PUT …/publication/{portal} publicás
El paso 2 ya guarda los planes: la llamada que verifica que tu cliente autorizó es la misma que los trae, así que al conectar ya los tenés sin pagar nada.
Después de cada publicación o baja, el paso 3 te los devuelve con plansStale: true.
Por qué no los actualizamos solos
Porque cada lectura sale del cupo mensual de tu cliente en el portal —el que cada uno define a su manera; en Zonaprop son 1.500 llamadas—, y es el mismo que usás para publicar y para traer consultas. Refrescar en cada publicación duplicaría el gasto de tu integración, y la decisión de cuándo vale la pena es tuya.
Y hay una razón más: el portal no nos dice qué plan consumió una publicación. Su respuesta trae el código del aviso, su id y sus errores — ningún plan. Si restáramos el que pediste podríamos restar el equivocado, así que preferimos avisarte que la copia quedó vieja antes que darte un número inventado.
Si no lo llamás nunca
No pasa nada grave: mandás tu plan al publicar y, si tu cliente no lo tiene, la respuesta del publish
te dice cuáles sí tiene en el bloque planIssue. Este endpoint existe para que puedas consultarlo
cuando quieras, no para que tengas que hacerlo.
Códigos de respuesta
| Código | error | Qué pasó |
|---|---|---|
200 | — | Los planes, recién leídos del portal |
400 | portal is required | Falta el portal en la ruta |
400 | clientRef is required (header x-client-ref) | Falta identificar al cliente |
401 | Unauthorized | Token ausente o inválido |
403 | Missing scope: property-api-read | Tu token no puede leer |
403 | Missing required scope: zonapropapi:connect | Tu token no está habilitado para ese portal |
409 | portal_not_connected | Tu cliente no tiene una conexión activa con ese portal |
409 | connection_incomplete | La conexión existe pero está incompleta. Volvé a conectarla |
501 | portal_sin_consulta_de_cuenta | Todavía no consultamos la cuenta en ese portal |
502 | portal_no_contesto | El portal no respondió. Reintentá; no pisamos la copia anterior |
El 502 no borra lo que ya teníamos. Guardar una lista vacía porque el portal no contestó diría
que tu cliente no tiene planes, y eso sería falso. La copia anterior sigue disponible en el
GET del cliente con su fecha.
Portales
| Portal | {portal} | Estado |
|---|---|---|
| Zonaprop | zonapropapi | disponible |
| Argenprop · Cabaprop · MercadoLibre | — | 501 |
Un 501 no significa que te equivocaste: significa que ese portal todavía no tiene esta consulta de
nuestro lado.
Relacionado
GETdel cliente — la lectura gratis, conplansStale- Publicar — dónde se manda el
plany qué diceplanIssue - Cupo mensual y límites — las 1.500 llamadas