BETA

POST /properties/verify

Você envia o objeto de um imóvel e respondemos três coisas:

  1. Se o objeto é válido de acordo com o contrato da Mapaprop, e o que falta se não for.
  2. O que entendemos do que você enviou — quantos campos reconstruímos do seu array attributes.
  3. Se cada portal poderia publicá-lo, e quando não, exatamente o que falta e de quem é o problema.

Este endpoint não cria, não modifica e não publica nada. Não deixa rastro. Serve para você ajustar o seu objeto antes de se integrar, quantas vezes quiser.

Está em beta. A forma da resposta pode mudar enquanto durar esta etapa. As mudanças são anunciadas nesta página com antecedência.

Para que serve

Integrar-se a vários portais tem um problema que aparece tarde: você envia um objeto que lhe parece completo, ele é publicado, e só então você vê que o anúncio saiu sem preço, sem piscina ou com o tipo errado — porque cada portal pede coisas diferentes e se cala sobre o que não entende.

Este endpoint deixa você ver isso antes de publicar, sem criar nada e sem precisar ter as contas dos portais conectadas.

Resource information
AuthenticationObrigatória (JWT) — scope property-api-verify
HTTP MethodPOST
ResponseJSON
Version1

Resource URL

https://property-api.mapaprop.com/property-v1/properties/verify

Autenticação

É exigido um token OAuth2 e o scope property-api-verify.

POST /property-v1/properties/verify
Host: property-api.mapaprop.com
Content-Type: application/json
Authorization: Bearer {access_token}

O token é obtido como qualquer outro: POST /api/action/oauth2-v1/authorize.

Os scopes viajam assinados dentro do token. Se adicionarmos um scope depois de você ter gerado o seu, ele precisa ser gerado de novo para ter efeito — e gerar um novo invalida o anterior. Peça desde o início todos os scopes de que você vai precisar.

O corpo da requisição

O verify funciona SEM você ter declarado seu cliente. É um testador: valida o token e descreve o objeto, não cadastra nada. Se você ainda não o declarou, ele preenche os dados do cliente com um placeholder, e avisa em customerSource — assim você pode testar o objeto no primeiro dia, sem nenhum passo anterior e sem confundir o preenchimento com os seus dados.

⚠️ Onde ela É necessária é no cadastro: POST /property-v1/properties responde 400 com rule: account_required se a conta não tiver cliente declarado. Declara-se UMA vez com POST /property-v1/customers. Os imóveis que você carregar depois a herdam; os já carregados mantêm o contato com que foram criados.

⚠️ Um detalhe do placeholder: o country não é preenchido. Um valor de preenchimento ali seria indistinguível de uma resposta real, e é o dado que não conviria adivinhar.

{
  "canonical": { …el objeto de la propiedad… },
  "portals": ["argenprop", "zonaprop", "cabaprop"]
}
ChaveObrigatórioO que é
canonicalsimO objeto do imóvel. property é aceito como nome alternativo
portalsnãoQuais portais avaliar. Se você omitir, todos são avaliados

O objeto que vai em canonical é o de sempre: O objeto JSON do imóvel.

Se você enviar um portal que não existe, a requisição falha com um 400 em vez de ignorá-lo em silêncio.

Quais portais são reportados

Se em publication.api você declarar…A resposta traz…
Um ou vários portaisapenas esses
Nada (você não envia publication)todos

A ideia é que não cheguem até você problemas de um portal que você não configurou. Se já declarou o Argenprop e mais nada, o Zonaprop não aparece na resposta nem conta no summary.

E se você ainda não configurou nenhum, vê todos: é o caso de quem está avaliando a integração e quer ver como o seu objeto se converte em cada portal antes de decidir.

Se você quiser restringir a resposta sem declarar a configuração, use portals no corpo da requisição. São duas coisas diferentes: portals diz o que você quer olhar, publication diz o que você tem configurado.

publication — a configuração de publicação, dentro do objeto

Dentro de canonical você pode enviar uma chave publication com o que cada portal precisa da sua conta e das suas escolhas de publicação. Não é um campo do imóvel: é como você o publica.

{
  "publication": {
    "api": {
      "argenprop": { "advertiserId": 99999, "visible": true },
      "zonaprop": {
        "plan": { "plan": "SUPERDESTACADO" },
        "branch": { "custId": 1, "email": "contacto@ejemplo.com", "name": "Inmobiliaria", "phone1": "1144445555" }
      },
      "cabaprop": { "branchOfficeId": 42 }
    }
  }
}

O branch do Zonaprop e o sellerContact do MercadoLibre são preenchidos automaticamente a partir do cliente que você declarou: não é preciso enviá-los. Estão no exemplo porque, se você os enviar, eles ganham — o preenchimento automático tem a menor precedência de todas.

PortalCampos
argenpropadvertiserId (number) · visible (boolean)
zonapropplan (object) · branch (object)
cabapropbranchOfficeId (number)
mercadolibrelistingTypeId (string) · condition (string) · sellerContact (object)

Cada portal aceita também um token (string), que é validado na forma e nunca na validade: este endpoint não verifica contas. O seu valor não aparece em nenhuma parte da resposta.

publication não viaja aos portais como mais um campo: é consumido aqui e descartado.

A referência completa —os dois níveis, o que acontece se você enviar algo que não corresponde, e o detalhe do token— está na sua própria página: A chave publication.

A resposta

A resposta traz o clientRef, o mesmo que você enviou no envelope. Nós o devolvemos nos seis caminhos (verify, cadastro, consulta, listagem, edição e exclusão) para que você possa cruzá-lo com a sua base sem ter que lembrar com qual clientRef perguntou.

{
  "mode": "client",
  "object": {
    "valid": true,
    "contract": [],
    "mapapropZone": "1-2-189-973",
    "conflicts": [],
    "conflicts": []
  },
  "portals": {
    "argenprop": {
      "status": "fields_complete",
      "connection": "not_verified",
      "zone": {
        "sent": {
          "code": "1-2-189-973",
          "level": 3
        },
        "publishingTo": "Mar del Plata",
        "status": "mapped"
      },
      "blockers": [],
      "pendingAtPublishTime": []
    },
    "zonaprop": {
      "status": "fields_complete",
      "connection": "not_verified",
      "zone": {
        "sent": {
          "code": "1-2-189-973",
          "level": 3
        },
        "publishingTo": "General Pueyrredón",
        "status": "mapped"
      },
      "blockers": [],
      "pendingAtPublishTime": []
    },
    "cabaprop": {
      "status": "fields_complete",
      "connection": "not_verified",
      "zone": {
        "sent": {
          "code": "1-2-189-973",
          "level": 3
        },
        "status": "not_mapped",
        "message": "Todavía no tenemos mapeada esta zona para cabaprop. Escribinos con el código de zona y la publicamos: el mapeo queda hecho para siempre."
      },
      "blockers": [],
      "pendingAtPublishTime": []
    },
    "mercadolibre": {
      "status": "coming_soon",
      "message": "MercadoLibre: disponible pronto. La integración todavía no está habilitada en este endpoint."
    }
  },
  "summary": {
    "complete": 3,
    "of": 4
  }
}

object — o que aconteceu com o seu objeto

CampoO que diz
validSe o objeto cumpre o contrato da Mapaprop
contractO que não cumpre: field, rule e o detalhe. Vazio se valid for true
mapapropZoneA zona que resolvemos, como zone0-zone1-zone2-zone3
conflictsCampos onde o seu attributes contradiz o campo avulso. attributes ganha

conflicts merece atenção: se você envia "type": 23 e o seu attributes diz "Departamento", é publicado como Departamento. Não é um erro, é a regra — mas se não era o que você queria, você vê aqui em vez de no anúncio.

portals — o que cada portal diz

CampoO que diz
statusO veredito. Valores abaixo
connectionconnected · not_connected · not_verified
zoneQual zona você enviou e em qual vamos publicar. Abaixo
blockersO que falta no objeto para poder publicar
pendingAtPublishTimeO que falta para publicar, mas não é do objeto (plano, filial, zona mapeada)

Valores de status:

ValorSignifica
fields_completeO objeto tem tudo o que esse portal precisa
missing_dataFalta um dado. Veja blockers — há algo que você pode resolver
not_supportedO portal não suporta algo deste imóvel. Você não resolve enviando mais dados
coming_soonA integração ainda não está habilitada neste endpoint

Alguns portais não conseguem montar o anúncio até terem a sua configuração: o Zonaprop precisa do plano e dos dados da filial para montar o anúncio. Nesses casos o portal aparece com o seu estado e os seus pendingAtPublishTime, mas sem o mapeamento — não porque o seu objeto esteja errado, mas porque ainda falta o dado de conta com o qual ele é construído.

Os blockers que vêm de publication trazem também um exemplo concreto de como resolvê-los, junto à mensagem: se espera number · ejemplo: "publication": { "api": { "argenprop": { "advertiserId": 99999 } } }. Veja A chave publication.

Cada blocker traz:

{ "field": "price",
  "kind": "missing",
  "message": "`price` es obligatorio en el objeto de Mapaprop y no vino…",
  "youCanFixIt": true }

youCanFixIt responde à única pergunta que importa sobre um blocker: eu resolvo isto enviando mais dados, ou é uma limitação do portal? Se for true, envie o dado. Se for false, esse portal não admite o que você está pedindo e não há JSON que resolva.

blockers e pendingAtPublishTime são coisas diferentes de propósito. Um objeto perfeito ao qual só falta escolher o plano não é um objeto incompleto: é uma publicação sem configurar. Por isso pendingAtPublishTime não afeta o status.

zone — em qual zona vamos publicar

Cada portal tem o seu próprio mapa de zonas, e nós mantemos a tradução entre a sua zona da Mapaprop e a desse portal. zone mostra as duas pontas:

{ "sent": { "code": "1-2-189-973", "level": 3 },
  "publishingTo": "Mar del Plata",
  "status": "mapped" }
CampoO que diz
sent.codeA zona que você enviou, tal como a montamos a partir dos seus zone0…zone3
sent.levelAté que nível esse código chega: 2 é o município inteiro, 3 desce até a localidade
sent.nameO nome da sua zona, se você enviou a descrição do nível correspondente
publishingToO nome da zona do portal onde o seu anúncio vai aparecer
statusmapped · not_mapped · not_sent · not_verified

Os estados:

ValorSignifica
mappedResolvemos a zona. publishingTo diz onde o anúncio vai aparecer
not_mappedA sua zona é válida, mas ainda não a temos mapeada para esse portal. Vem com um message explicando o que fazer
not_sentVocê não enviou a zona no objeto
not_verifiedNão chegamos a consultar o mapeamento, então não afirmamos nada

Olhe o publishingTo mesmo quando o estado for mapped. É o nome público da zona do portal: se você enviou uma zona e ali aparece outra, o anúncio vai sair nesse outro lugar. Escreva para nós e corrigimos — você é o único que pode perceber, porque é quem conhece o imóvel.

Um 0 no final do código não significa que falta um nível: 1-2-201-0 é o município inteiro, e é um destino de publicação válido por si só. Por isso o level conta até o último número diferente de zero.

summary

{ "summary": { "complete": 3, "of": 4 } }

Quantos portais têm os obrigatórios completos, sobre o total avaliado.

Os campos obrigatórios da Mapaprop prevalecem sobre os do portal

Esta é a coisa mais importante de entender sobre o endpoint.

A Mapaprop tem o seu próprio contrato de campos obrigatórios, e ele não depende do que cada portal pede. Se faltar um desses campos, nenhum portal fica em fields_complete — mesmo que esse portal em particular não o exija.

Exemplo: o Argenprop não exige o preço para montar o seu anúncio. Ainda assim, se você não enviar price:

{
  "object": {
    "valid": false,
    "contract": [ { "field": "price", "rule": "required", "detail": "" } ]
  },
  "portals": {
    "argenprop": {
      "status": "missing_data",
      "blockers": [
        { "field": "price",
          "kind": "missing",
          "message": "`price` es obligatorio en el objeto de Mapaprop y no vino. Sin él no se publica en ningún portal, lo exija o no este portal en particular.",
          "youCanFixIt": true }
      ]
    }
  },
  "summary": { "complete": 0, "of": 4 }
}

A lista completa de campos obrigatórios está em O objeto JSON do imóvel.

Apenas a ausência de um obrigatório bloqueia. Um campo presente mas com um formato incorreto aparece em object.contract e informa sem bloquear — para que você possa ir corrigindo sem que o endpoint se torne inutilizável. Verifique sempre object.contract, não apenas o summary.

Não é preciso ter o portal conectado

O campo connection diz se a conta desse portal está conectada, mas não condiciona nada: o objeto é mapeado do mesmo jeito e os blockers são calculados do mesmo jeito.

ValorSignifica
connectedA conta está conectada
not_connectedNão há conta conectada para esse portal
not_verifiedNão foi possível verificar o estado da conexão

É um dado ao lado, e continua importando: um objeto impecável não é publicado se a conta não estiver conectada. Mas para aperfeiçoar o seu objeto você não precisa ter nenhuma.

Erros

CódigoQuando
400Falta o body, não é JSON válido, falta canonical/property, ou você pediu um portal que não existe. ⚠️ O verify NÃO devolve 400 por não ter cliente declarado — isso é do cadastro; aqui se simula com um placeholder
403O token não tem o scope property-api-verify
{ "error": "Portales desconocidos: idealista. Válidos: argenprop, zonaprop, cabaprop, mercadolibre, mapaprop" }

MercadoLibre

Sai sempre como coming_soon. A integração existe mas ainda não está habilitada neste endpoint, e preferimos não mostrar um mapeamento sem verificar: você o tomaria por bom.

Como usá-lo

  1. Envie o seu objeto exatamente como você o tem hoje.
  2. Olhe primeiro object.valid e object.contract. Se faltar um obrigatório, resolva isso — ele está bloqueando todos os portais ao mesmo tempo.
  3. Olhe object.conflicts. Se aparecer algo, o seu attributes e os seus campos avulsos estão se contradizendo, e attributes ganha.
  4. Portal por portal, resolva os blockers com youCanFixIt: true.
  5. Os youCanFixIt: false você não resolve: são limites do portal.
  6. Repita. Nada é criado, então teste quantas vezes precisar.

Precisa de ajuda? Entre em contato com o Suporte técnico da Mapaprop