Documentação da API ObraAberta
API REST de leitura com dados públicos de obras residenciais: empreendimentos, construtoras, linha do tempo, avaliações, serviços do entorno e bases abertas. Respostas em JSON, CORS liberado e paginação padronizada.
Início rápido
Base: https://obraaberta.com.br/api/v1. O caminho alternativo /api/public/v1 expõe exatamente os mesmos endpoints e é sempre público — use-o em integrações servidor-a-servidor.
# 1. checar disponibilidade
curl "https://obraaberta.com.br/api/v1/health"
# 2. listar 5 obras em construção em SP
curl "https://obraaberta.com.br/api/v1/projects?state=SP&status=em_construcao&limit=5"
# 3. mesma chamada com chave de API (limite ampliado)
curl "https://obraaberta.com.br/api/v1/projects?state=SP" -H "X-API-Key: $OBRAABERTA_KEY"JavaScript (fetch)
const r = await fetch(
"https://obraaberta.com.br/api/v1/projects/search?q=vila+mariana&limit=10",
{ headers: { "X-API-Key": process.env.OBRAABERTA_KEY } }
);
const { data, pagination } = await r.json();
console.log(pagination.total, data[0].name);Python (requests)
import os, requests
r = requests.get(
"https://obraaberta.com.br/api/v1/projects",
params={"state": "SP", "status": "em_construcao", "limit": 100},
headers={"X-API-Key": os.environ["OBRAABERTA_KEY"]},
timeout=30,
)
r.raise_for_status()
print(r.json()["pagination"]["total"])Autenticação e limites de uso
Os endpoints GET são abertos. A autenticação serve para elevar o limite de requisições, liberar uso automatizado e acessar o enriquecimento. Chaves são emitidas por administradores da ObraAberta e guardadas apenas como hash — copie no momento da criação.
| Perfil | Limite | Como enviar |
|---|---|---|
| Anônimo | 100 req/h por IP | Sem cabeçalho de autenticação. |
| Usuário logado | 1.000 req/h por usuário | Authorization: Bearer <JWT da sessão>. |
| Chave de API | 10.000 req/h por chave | X-API-Key: <chave emitida pelo admin>. |
Toda resposta traz X-RateLimit-Limit, X-RateLimit-Remaining e X-RateLimit-Reset (janela deslizante de 1 hora). Ao estourar, a API devolve 429 rate_limited. Respostas de leitura têm Cache-Control: public, max-age=60.
Convenções
Paginação
{
"data": [ /* itens */ ],
"pagination": { "page": 1, "limit": 50, "total": 18093, "pages": 362 }
}limit máximo de 500. Para varreduras completas, pagine com sort=created_at&order=asc para manter a ordem estável.
Erros
{ "error": { "code": "not_found", "message": "Obra não encontrada ou não publicada.", "status": 404 } }400bad_request — Parâmetro ausente, mal formatado ou filtro rejeitado pelo banco.401unauthorized — Endpoint exige JWT (Authorization: Bearer) ou chave (X-API-Key).403forbidden — Agente automatizado sem chave — o anti-bot bloqueia raspagem anônima.404not_found — Recurso inexistente, não publicado ou fora do seu escopo de acesso.405method_not_allowed — Só GET é aceito, exceto POST /projects/enrich.429rate_limited — Limite por hora excedido; consulte X-RateLimit-Reset.500internal_error — Falha inesperada no servidor — tente novamente.502enrichment_failed — Fonte externa indisponível durante o enriquecimento.
Status das obras
| Valor na API | Estado interno | Significado |
|---|---|---|
| lancamento | planejamento | Projeto anunciado, obra ainda não iniciada. |
| em_construcao | em_andamento | Canteiro ativo. |
| paralisada | paralisada | Obra interrompida. |
| pronto / entregue | concluida | Obra concluída ou entregue aos moradores. |
Objeto Obra
Estrutura devolvida em todas as listagens e no detalhe. Campos sem informação vêm como null (nunca são omitidos). data_quality_score vai de 0 a 1 e indica a completude dos dados; data_sources lista as fontes que alimentaram o registro.
{
"id": "0f0a1c7e-4a2b-4e0f-9c3a-2f5d8b1c9e11",
"slug": "evolve-vila-mariana",
"name": "Evolve Vila Mariana",
"description": "Empreendimento residencial com 2 torres...",
"address": "Rua Domingos de Morais, 1200 - Vila Mariana - São Paulo",
"neighborhood": "Vila Mariana",
"city": "São Paulo",
"state": "SP",
"cep": "04010-100",
"phone": "+55 11 4000-0000",
"geolocation": { "latitude": -23.5896, "longitude": -46.6383 },
"status": "em_construcao",
"completion_percentage": 42,
"total_units": 180,
"available_units": 37,
"price_from": 620000,
"price_to": 1180000,
"price_per_m2": 12400,
"total_area": 8600,
"bedrooms": 2,
"bathrooms": 2,
"parking_spaces": 1,
"amenities": ["piscina", "academia", "coworking"],
"cover_url": "https://.../capa.jpg",
"floor_plans": [],
"constructor": { "id": "…", "name": "Construtora Exemplo" },
"launch_date": "2024-03-01",
"completion_date": "2026-12-31",
"data_sources": ["mcmv", "osm", "brasilapi"],
"data_quality_score": 0.82,
"last_enriched_at": "2026-08-01T12:00:00Z",
"last_updated_at": "2026-08-05T09:31:00Z",
"created_at": "2025-11-02T18:22:00Z",
"url": "https://obraaberta.com.br/obras/sp/sao-paulo/vila-mariana/evolve-vila-mariana"
}Referência de endpoints
Obras (Projects)
Consulta às obras publicadas na ObraAberta: listagem, busca, geolocalização, linha do tempo, avaliações e serviços do entorno.
/projectsRetorna obras com o envelope padrão de paginação. Somente obras com publicada = true aparecem. Todos os filtros podem ser combinados.
| Parâmetro | Local | Tipo | Padrão | API REST de leitura com dados públicos de obras residenciais: empreendimentos, construtoras, linha do tempo, avaliações, serviços do entorno e bases abertas. Respostas em JSON, CORS liberado e paginação padronizada. |
|---|---|---|---|---|
| page | query | integer | 1 | Página desejada (começa em 1). |
| limit | query | integer | 50 | Itens por página. Máximo 500. |
| city | query | string | — | Nome exato da cidade (sem diferenciar maiúsculas). |
| state | query | string | — | Sigla da UF, ex.: SP. |
| status | query | enum | — | lancamento | em_construcao | paralisada | pronto | entregue. |
| min_price | query | number | — | Preço mínimo (R$) a partir do menor valor da obra. |
| max_price | query | number | — | Preço máximo (R$) sobre o menor valor da obra. |
| bedrooms | query | integer | — | Número exato de dormitórios. |
| amenities | query | string | — | Lista separada por vírgula; retorna obras que tenham todas. |
| sort | query | enum | created_at | created_at | name | price | completion_percentage | updated_at. |
| order | query | enum | desc | asc ou desc. |
Requisição
curl "https://obraaberta.com.br/api/v1/projects?state=SP&status=em_construcao&limit=20"Resposta
{
"data": [ /* array de Obra */ ],
"pagination": { "page": 1, "limit": 50, "total": 18093, "pages": 362 }
}/projects/searchMesma resposta de /projects, acrescentando busca por texto em nome, endereço, bairro e construtora. O termo é sanitizado (máx. 120 caracteres).
| Parâmetro | Local | Tipo | Padrão | API REST de leitura com dados públicos de obras residenciais: empreendimentos, construtoras, linha do tempo, avaliações, serviços do entorno e bases abertas. Respostas em JSON, CORS liberado e paginação padronizada. |
|---|---|---|---|---|
| q | query | string | — | Termo de busca livre. |
| page | query | integer | 1 | Página desejada (começa em 1). |
| limit | query | integer | 50 | Itens por página. Máximo 500. |
| city | query | string | — | Nome exato da cidade (sem diferenciar maiúsculas). |
| state | query | string | — | Sigla da UF, ex.: SP. |
| status | query | enum | — | lancamento | em_construcao | paralisada | pronto | entregue. |
| min_price | query | number | — | Preço mínimo (R$) a partir do menor valor da obra. |
| max_price | query | number | — | Preço máximo (R$) sobre o menor valor da obra. |
| bedrooms | query | integer | — | Número exato de dormitórios. |
| amenities | query | string | — | Lista separada por vírgula; retorna obras que tenham todas. |
| sort | query | enum | created_at | created_at | name | price | completion_percentage | updated_at. |
| order | query | enum | desc | asc ou desc. |
Requisição
curl "https://obraaberta.com.br/api/v1/projects/search?q=vila%20mariana&limit=10"Resposta
{
"data": [ /* array de Obra */ ],
"pagination": { "page": 1, "limit": 50, "total": 18093, "pages": 362 }
}/projects/by-city/{city}Atalho para /projects com o filtro city preenchido pelo caminho.
| Parâmetro | Local | Tipo | Padrão | API REST de leitura com dados públicos de obras residenciais: empreendimentos, construtoras, linha do tempo, avaliações, serviços do entorno e bases abertas. Respostas em JSON, CORS liberado e paginação padronizada. |
|---|---|---|---|---|
| city* | path | string | — | Nome da cidade (URL-encoded). |
| page | query | integer | 1 | Página desejada (começa em 1). |
| limit | query | integer | 50 | Itens por página. Máximo 500. |
| city | query | string | — | Nome exato da cidade (sem diferenciar maiúsculas). |
| state | query | string | — | Sigla da UF, ex.: SP. |
| status | query | enum | — | lancamento | em_construcao | paralisada | pronto | entregue. |
| min_price | query | number | — | Preço mínimo (R$) a partir do menor valor da obra. |
| max_price | query | number | — | Preço máximo (R$) sobre o menor valor da obra. |
| bedrooms | query | integer | — | Número exato de dormitórios. |
| amenities | query | string | — | Lista separada por vírgula; retorna obras que tenham todas. |
| sort | query | enum | created_at | created_at | name | price | completion_percentage | updated_at. |
| order | query | enum | desc | asc ou desc. |
Requisição
curl "https://obraaberta.com.br/api/v1/projects/by-city/S%C3%A3o%20Paulo"Resposta
{
"data": [ /* array de Obra */ ],
"pagination": { "page": 1, "limit": 50, "total": 18093, "pages": 362 }
}/projects/by-state/{state}Atalho para /projects com o filtro state preenchido pelo caminho.
| Parâmetro | Local | Tipo | Padrão | API REST de leitura com dados públicos de obras residenciais: empreendimentos, construtoras, linha do tempo, avaliações, serviços do entorno e bases abertas. Respostas em JSON, CORS liberado e paginação padronizada. |
|---|---|---|---|---|
| state* | path | string | — | Sigla da UF. |
| page | query | integer | 1 | Página desejada (começa em 1). |
| limit | query | integer | 50 | Itens por página. Máximo 500. |
| city | query | string | — | Nome exato da cidade (sem diferenciar maiúsculas). |
| state | query | string | — | Sigla da UF, ex.: SP. |
| status | query | enum | — | lancamento | em_construcao | paralisada | pronto | entregue. |
| min_price | query | number | — | Preço mínimo (R$) a partir do menor valor da obra. |
| max_price | query | number | — | Preço máximo (R$) sobre o menor valor da obra. |
| bedrooms | query | integer | — | Número exato de dormitórios. |
| amenities | query | string | — | Lista separada por vírgula; retorna obras que tenham todas. |
| sort | query | enum | created_at | created_at | name | price | completion_percentage | updated_at. |
| order | query | enum | desc | asc ou desc. |
Requisição
curl "https://obraaberta.com.br/api/v1/projects/by-state/MG"Resposta
{
"data": [ /* array de Obra */ ],
"pagination": { "page": 1, "limit": 50, "total": 18093, "pages": 362 }
}/projects/by-regionBusca geográfica: filtra por caixa delimitadora, calcula a distância exata (Haversine) e ordena da mais próxima para a mais distante. Cada item ganha o campo distance_km e a resposta traz o objeto center.
| Parâmetro | Local | Tipo | Padrão | API REST de leitura com dados públicos de obras residenciais: empreendimentos, construtoras, linha do tempo, avaliações, serviços do entorno e bases abertas. Respostas em JSON, CORS liberado e paginação padronizada. |
|---|---|---|---|---|
| latitude* | query | number | — | Latitude do centro. |
| longitude* | query | number | — | Longitude do centro. |
| radius_km | query | number | 5 | Raio de busca em km. |
| page | query | integer | 1 | Página desejada (começa em 1). |
| limit | query | integer | 50 | Itens por página. Máximo 500. |
| city | query | string | — | Nome exato da cidade (sem diferenciar maiúsculas). |
| state | query | string | — | Sigla da UF, ex.: SP. |
| status | query | enum | — | lancamento | em_construcao | paralisada | pronto | entregue. |
| min_price | query | number | — | Preço mínimo (R$) a partir do menor valor da obra. |
| max_price | query | number | — | Preço máximo (R$) sobre o menor valor da obra. |
| bedrooms | query | integer | — | Número exato de dormitórios. |
| amenities | query | string | — | Lista separada por vírgula; retorna obras que tenham todas. |
| sort | query | enum | created_at | created_at | name | price | completion_percentage | updated_at. |
| order | query | enum | desc | asc ou desc. |
Requisição
curl "https://obraaberta.com.br/api/v1/projects/by-region?latitude=-23.5896&longitude=-46.6383&radius_km=3"Resposta
{
"data": [ { /* Obra */ "distance_km": 0.84 } ],
"pagination": { "page": 1, "limit": 50, "total": 12, "pages": 1 },
"center": { "latitude": -23.5896, "longitude": -46.6383, "radius_km": 3 }
}- 400 bad_request — latitude/longitude ausentes ou inválidas.
/projects/{id}Objeto Obra completo acrescido de timeline (etapas com fotos), ratings (resumo de avaliações), recent_reviews (5 mais recentes) e nearby_services_url.
| Parâmetro | Local | Tipo | Padrão | API REST de leitura com dados públicos de obras residenciais: empreendimentos, construtoras, linha do tempo, avaliações, serviços do entorno e bases abertas. Respostas em JSON, CORS liberado e paginação padronizada. |
|---|---|---|---|---|
| id* | path | string | — | UUID da obra ou o slug público (ex.: evolve-vila-mariana). |
Requisição
curl "https://obraaberta.com.br/api/v1/projects/evolve-vila-mariana"Resposta
{
"id": "0f0a1c7e-4a2b-4e0f-9c3a-2f5d8b1c9e11",
"slug": "evolve-vila-mariana",
"name": "Evolve Vila Mariana",
"description": "Empreendimento residencial com 2 torres...",
"address": "Rua Domingos de Morais, 1200 - Vila Mariana - São Paulo",
"neighborhood": "Vila Mariana",
"city": "São Paulo",
"state": "SP",
"cep": "04010-100",
"phone": "+55 11 4000-0000",
"geolocation": { "latitude": -23.5896, "longitude": -46.6383 },
"status": "em_construcao",
"completion_percentage": 42,
"total_units": 180,
"available_units": 37,
"price_from": 620000,
"price_to": 1180000,
"price_per_m2": 12400,
"total_area": 8600,
"bedrooms": 2,
"bathrooms": 2,
"parking_spaces": 1,
"amenities": ["piscina", "academia", "coworking"],
"cover_url": "https://.../capa.jpg",
"floor_plans": [],
"constructor": { "id": "…", "name": "Construtora Exemplo" },
"launch_date": "2024-03-01",
"completion_date": "2026-12-31",
"data_sources": ["mcmv", "osm", "brasilapi"],
"data_quality_score": 0.82,
"last_enriched_at": "2026-08-01T12:00:00Z",
"last_updated_at": "2026-08-05T09:31:00Z",
"created_at": "2025-11-02T18:22:00Z",
"url": "https://obraaberta.com.br/obras/sp/sao-paulo/vila-mariana/evolve-vila-mariana"
}- 404 not_found — obra inexistente ou não publicada.
/projects/{id}/timelineEtapas registradas com percentual, data de referência e fotos associadas.
| Parâmetro | Local | Tipo | Padrão | API REST de leitura com dados públicos de obras residenciais: empreendimentos, construtoras, linha do tempo, avaliações, serviços do entorno e bases abertas. Respostas em JSON, CORS liberado e paginação padronizada. |
|---|---|---|---|---|
| id* | path | string | — | UUID da obra ou o slug público (ex.: evolve-vila-mariana). |
| order | query | enum | desc | asc | desc por data de referência. |
Requisição
curl "https://obraaberta.com.br/api/v1/projects/evolve-vila-mariana/timeline?order=asc"Resposta
{
"project_id": "…",
"timeline": [
{
"id": "…",
"title": "Fundação concluída",
"description": "…",
"date": "2025-06-14",
"completion_percentage": 25,
"photos": [{ "url": "https://…", "caption": "Vista aérea" }]
}
]
}/projects/{id}/ratingsAvaliações públicas moderadas, com resumo (média e contagem) e lista paginada.
| Parâmetro | Local | Tipo | Padrão | API REST de leitura com dados públicos de obras residenciais: empreendimentos, construtoras, linha do tempo, avaliações, serviços do entorno e bases abertas. Respostas em JSON, CORS liberado e paginação padronizada. |
|---|---|---|---|---|
| id* | path | string | — | UUID da obra ou o slug público (ex.: evolve-vila-mariana). |
| page | query | integer | 1 | Página desejada (começa em 1). |
| limit | query | integer | 50 | Itens por página. Máximo 500. |
Requisição
curl "https://obraaberta.com.br/api/v1/projects/evolve-vila-mariana/ratings"Resposta
{
"summary": { "average": 4.3, "count": 27 },
"ratings": [ { "rating": 5, "comment": "…", "created_at": "…" } ],
"pagination": { "page": 1, "limit": 50, "total": 27, "pages": 1 }
}/projects/{id}/nearby-servicesEscolas, hospitais, transporte e comércio num raio configurável, via Overpass API com cache de 7 dias por obra+raio. Dados sob licença ODbL — mantenha a atribuição ao OpenStreetMap.
| Parâmetro | Local | Tipo | Padrão | API REST de leitura com dados públicos de obras residenciais: empreendimentos, construtoras, linha do tempo, avaliações, serviços do entorno e bases abertas. Respostas em JSON, CORS liberado e paginação padronizada. |
|---|---|---|---|---|
| id* | path | string | — | UUID da obra ou o slug público (ex.: evolve-vila-mariana). |
| radius_km | query | number | 2 | Raio em km. Máximo 10. |
| types | query | string | — | Lista separada por vírgula: schools, hospitals, transport, commerce. |
Requisição
curl "https://obraaberta.com.br/api/v1/projects/evolve-vila-mariana/nearby-services?radius_km=2&types=schools,transport"Resposta
{
"schools": [
{ "id": "osm-123", "name": "EMEF …", "distance_km": 0.42, "type": "school", "source": "openstreetmap" }
],
"transport": [],
"cached": false,
"attribution": "© OpenStreetMap contributors (ODbL)"
}/projects/enrichCria um job de enriquecimento e executa as fontes solicitadas de forma síncrona (resposta 202 com o resultado). Fontes não suportadas ou que exigem contrato voltam em skipped_sources. Exige JWT ou chave de API.
| Parâmetro | Local | Tipo | Padrão | API REST de leitura com dados públicos de obras residenciais: empreendimentos, construtoras, linha do tempo, avaliações, serviços do entorno e bases abertas. Respostas em JSON, CORS liberado e paginação padronizada. |
|---|---|---|---|---|
| project_id* | body | uuid | — | Identificador da obra. |
| sources | body | string[] | — | brasilapi | osm | mcmv. Vazio = todas. |
| force_refresh | body | boolean | — | Ignora o cache das fontes. |
Requisição
curl -X POST "https://obraaberta.com.br/api/v1/projects/enrich" \
-H "X-API-Key: $OBRAABERTA_KEY" \
-H "Content-Type: application/json" \
-d '{"project_id":"0f0a1c7e-…","sources":["brasilapi","osm"]}'Resposta
{
"job_id": "…",
"status": "done",
"updated_fields": ["cep", "bairro", "latitude"],
"skipped_sources": [{ "source": "orulo", "reason": "Requer contrato." }]
}- 401 unauthorized — sem JWT nem chave de API.
- 404 not_found — obra inexistente.
- 502 enrichment_failed — a fonte externa falhou.
/jobs/{id}Visível apenas para quem criou o job (usuário ou dono da chave) e para administradores; para os demais retorna 404 por privacidade.
| Parâmetro | Local | Tipo | Padrão | API REST de leitura com dados públicos de obras residenciais: empreendimentos, construtoras, linha do tempo, avaliações, serviços do entorno e bases abertas. Respostas em JSON, CORS liberado e paginação padronizada. |
|---|---|---|---|---|
| id* | path | uuid | — | job_id devolvido pelo enrich. |
Requisição
curl "https://obraaberta.com.br/api/v1/jobs/6b1f…" -H "X-API-Key: $OBRAABERTA_KEY"Resposta
{
"job_id": "…",
"project_id": "…",
"sources": ["brasilapi"],
"status": "done",
"result": { },
"error": null,
"created_at": "…",
"finished_at": "…"
}Construtoras (Builders)
Cadastro das construtoras, suas obras e o Índice de Sinais de Estresse (ISE), calculado por fórmula pública.
/buildersCadastro básico ordenado por nome, com o ISE quando já calculado.
| Parâmetro | Local | Tipo | Padrão | API REST de leitura com dados públicos de obras residenciais: empreendimentos, construtoras, linha do tempo, avaliações, serviços do entorno e bases abertas. Respostas em JSON, CORS liberado e paginação padronizada. |
|---|---|---|---|---|
| page | query | integer | 1 | Página desejada (começa em 1). |
| limit | query | integer | 50 | Itens por página. Máximo 500. |
Requisição
curl "https://obraaberta.com.br/api/v1/builders?limit=100"Resposta
{
"data": [
{ "id": "…", "name": "Construtora Exemplo", "slug": "construtora-exemplo",
"cnpj": "00.000.000/0001-00", "website": "https://…", "headquarters": "São Paulo/SP", "ise_score": 87 }
],
"pagination": { "page": 1, "limit": 100, "total": 340, "pages": 4 }
}/builders/{id}Cadastro, média de avaliações das obras, indicadores de reputação e ticker na B3 quando houver.
| Parâmetro | Local | Tipo | Padrão | API REST de leitura com dados públicos de obras residenciais: empreendimentos, construtoras, linha do tempo, avaliações, serviços do entorno e bases abertas. Respostas em JSON, CORS liberado e paginação padronizada. |
|---|---|---|---|---|
| id* | path | string | — | UUID da construtora ou o slug (ex.: mrv). |
Requisição
curl "https://obraaberta.com.br/api/v1/builders/mrv"Resposta
{
"id": "…", "slug": "mrv", "name": "MRV", "cnpj": null, "website": "https://…",
"rating": { "average": 4.1, "count": 88 },
"reputation": { "ise_score": 74, "completed_projects": 120, "active_projects": 44,
"stalled_projects": 2, "delayed_projects": 9, "total_projects": 166, "legal_issues": null },
"stock_info": { "ticker": "MRVE3" },
"projects_count": 166
}- 404 not_found — construtora sem cadastro e sem obras.
/builders/{id}/projectsLista paginada das obras publicadas vinculadas à construtora, com filtro opcional por status.
| Parâmetro | Local | Tipo | Padrão | API REST de leitura com dados públicos de obras residenciais: empreendimentos, construtoras, linha do tempo, avaliações, serviços do entorno e bases abertas. Respostas em JSON, CORS liberado e paginação padronizada. |
|---|---|---|---|---|
| id* | path | string | — | UUID da construtora ou o slug (ex.: mrv). |
| status | query | enum | — | Mesmos valores de /projects. |
| page | query | integer | 1 | Página desejada (começa em 1). |
| limit | query | integer | 50 | Itens por página. Máximo 500. |
Requisição
curl "https://obraaberta.com.br/api/v1/builders/mrv/projects?status=em_construcao"Resposta
{
"data": [ /* array de Obra */ ],
"pagination": { "page": 1, "limit": 50, "total": 18093, "pages": 362 }
}/builders/{id}/reputationRetorna os indicadores e a metodologia: o ISE parte de 100 e desconta proporcionalmente obras atrasadas (peso 60) e paralisadas (peso 40) sobre o total de obras publicadas.
| Parâmetro | Local | Tipo | Padrão | API REST de leitura com dados públicos de obras residenciais: empreendimentos, construtoras, linha do tempo, avaliações, serviços do entorno e bases abertas. Respostas em JSON, CORS liberado e paginação padronizada. |
|---|---|---|---|---|
| id* | path | string | — | UUID da construtora ou o slug (ex.: mrv). |
Requisição
curl "https://obraaberta.com.br/api/v1/builders/mrv/reputation"Resposta
{
"reputation": { "ise_score": 74, "delayed_projects": 9, "stalled_projects": 2, "total_projects": 166 },
"methodology": "O ISE parte de 100 e desconta…"
}Dados abertos
Bases públicas incorporadas à plataforma e a relação de fontes utilizadas.
/data/mcmvBase importada dos dados abertos do programa, com unidades, situação, regime e geolocalização quando disponível.
| Parâmetro | Local | Tipo | Padrão | API REST de leitura com dados públicos de obras residenciais: empreendimentos, construtoras, linha do tempo, avaliações, serviços do entorno e bases abertas. Respostas em JSON, CORS liberado e paginação padronizada. |
|---|---|---|---|---|
| page | query | integer | 1 | Página desejada (começa em 1). |
| limit | query | integer | 50 | Itens por página. Máximo 500. |
| city | query | string | — | Cidade do empreendimento. |
| state | query | string | — | Sigla da UF. |
Requisição
curl "https://obraaberta.com.br/api/v1/data/mcmv?state=BA&limit=100"Resposta
{
"mcmv_projects": [
{ "id": "…", "external_code": "…", "name": "Residencial …", "city": "Salvador", "state": "BA",
"total_units": 240, "units_delivered": 240, "status": "Concluído", "regime": "FAR",
"geolocation": { "latitude": -12.97, "longitude": -38.5 }, "source": "mcmv" }
],
"pagination": { "page": 1, "limit": 100, "total": 18093, "pages": 181 }
}/data/public-sourcesRelação das fontes públicas usadas, quais estão habilitadas para enriquecimento e quais dependem de contrato/autorização do detentor dos dados.
Requisição
curl "https://obraaberta.com.br/api/v1/data/public-sources"Resposta
{
"sources": { "mcmv": { "license": "Dados abertos", "notes": "…" } },
"enabled_for_enrichment": ["brasilapi", "osm", "mcmv"],
"notes": "Fontes marcadas como 'requer_contrato' só são ativadas mediante API oficial…"
}Sistema
Descoberta, disponibilidade e especificação legível por máquina.
/Nome, versão e links para documentação e especificação OpenAPI.
Requisição
curl "https://obraaberta.com.br/api/v1"Resposta
{ "name": "ObraAberta API", "version": "1.0.0",
"documentation": "https://obraaberta.com.br/api/v1/docs",
"openapi": "https://obraaberta.com.br/api/v1/openapi.json" }/healthResponde sem consultar o banco; use para monitoramento (uptime checks). Nunca é cacheado.
Requisição
curl "https://obraaberta.com.br/api/v1/health"Resposta
{ "status": "ok", "version": "1.0.0", "time": "2026-08-11T16:00:00.000Z" }/openapi.jsonContrato completo para gerar SDKs (openapi-generator), importar no Postman/Insomnia ou validar.
Requisição
curl "https://obraaberta.com.br/api/v1/openapi.json"Resposta
{ "openapi": "3.0.3", "info": { "title": "ObraAberta API", … } }/docsInterface para testar os endpoints direto no navegador.
Requisição
open https://obraaberta.com.br/api/v1/docsResposta
HTML (Swagger UI)GraphQL
Um único endpoint devolve imóvel, construtora, reputação, entorno e ofertas na mesma consulta. Usa a mesma autenticação do REST. O schema é público e o playground está disponível no mesmo caminho. A profundidade máxima é de 10 níveis; a introspecção via POST exige cliente identificado. /graphql/schema.graphql
Consulta completa
curl -X POST "https://obraaberta.com.br/api/v1/graphql" \
-H "Content-Type: application/json" \
-H "X-API-Key: $OBRAABERTA_KEY" \
-d '{"query":"{
building(slug: \"evolve-vila-mariana\") {
name city status completionPercentage delayMonths
priceFrom priceTo totalUnits availableUnits
geolocation { latitude longitude }
builder { name transparencyIndex reputation { score methodologyUrl } }
reputation { score reviewsCount }
timeline { title status date }
nearbyServices(radiusKm: 2, page: 1, limit: 50) {
nodes { category name distanceKm }
pageInfo { page limit total pages }
}
offers(page: 1, limit: 5) { nodes { title partner price sponsored } pageInfo { total } }
}
}"}'Busca paginada e meus direitos
{
# Convenção única (igual ao REST v1): filter + sort + order + page + limit
buildings(
filter: { state: "SP", status: "em_construcao" }
sort: created_at
order: desc
page: 1
limit: 50
) {
pageInfo { page limit total pages hasNextPage hasPreviousPage }
nodes { id slug name neighborhood delayMonths priceFrom }
}
buildingsNearby(latitude: -23.58, longitude: -46.63, radiusKm: 3, page: 1, limit: 50) {
nodes { name city }
pageInfo { total pages }
center
}
myEntitlements {
plan planName maxObjectsPerQuery maxExportPerMonth
labels { label level }
quotas { hour { used limit } day { used limit } month { used limit } }
}
}Mutations (moderadas)
mutation {
trackOfferClick(offerId: "…") { ok status }
submitReview(input: {
buildingId: "…", rating: 5, comment: "Obra evoluiu bem",
termsVersion: "2026-01", privacyVersion: "2026-01"
}) { ok status message }
submitContribution(input: { buildingId: "…", type: "informacao", field: "endereco", value: "…" }) { ok status }
requestPartnerLead(input: { name: "…", email: "…", message: "…", consent: true }) { ok status }
}Avaliações e contribuições exigem usuário autenticado e entram na fila de moderação; leads exigem consentimento LGPD explícito. Ofertas patrocinadas são sempre marcadas como sponsored e nunca alteram a ordenação orgânica.
Liberação de campos por plano (entitlements)
Cada campo sensível tem uma etiqueta. Sem direito, o campo volta null — nunca erro — e a resposta explica o porquê em extensions.obraaberta.campos_restritos. Preços podem vir em faixa quando o plano só permite o nível resumo.
| Etiqueta | Campos cobertos |
|---|---|
| basico | identificação, endereço, status, progresso, datas, atraso |
| geo | geolocation, buildingsNearby |
| precos | priceFrom, priceTo, pricePerM2 (faixa no nível resumo) |
| unidades | totalUnits, availableUnits, tipologias e plantas |
| contatos | telefone e canais de contato |
| reputacao_detalhada | componentes da reputação e do Índice de Transparência |
| fontes_brutas | dataSources, dataQualityScore, divergências |
| entorno | nearbyServices (POIs OpenStreetMap) |
| marketplace | offers, promoções e parceiros |
| historico | timeline, histórico de status e dados de condomínio |
| exportacao | volumes altos e exportação em lote |
"extensions": {
"obraaberta": {
"plano": "anonimo",
"campos_restritos": [
{ "campo": "totalUnits", "etiqueta": "unidades", "nivelAtual": "bloqueado",
"nivelExigido": "resumo",
"mensagem": "O campo \"totalUnits\" exige a etiqueta \"unidades\"." }
],
"limites_atingidos": [
{ "tipo": "objetos_consulta", "detalhe": "Pedido 200 objetos; o plano Anônimo permite 20.",
"pedido": 200, "aplicado": 20 }
],
"cotas": { "hora": { "uso": 4, "limite": 100 } },
"upgrade_sugerido": { "id": "pro", "nome": "Pro" },
"upgrade_url": "https://obraaberta.com.br/planos"
}
}A cota do plano foi excedida: a resposta vem com HTTP 429 e code: QUOTA_EXCEEDED.
upgrade_sugerido indica o plano ativo mais barato que libera todas as etiquetas que faltaram naquela requisição. Vem null quando nada foi bloqueado; nas respostas REST v1 os mesmos dados aparecem em entitlements.
Toda requisição que teve campo bloqueado ou limite atingido é registrada na trilha de auditoria de entitlements por 90 dias e fica visível apenas para a equipe ObraAberta. Nenhum conteúdo da consulta ou das variáveis é armazenado.
SDK de exemplo (TypeScript, sem dependências)
// obraaberta.ts
const ENDPOINT = "https://obraaberta.com.br/api/v1/graphql";
export type Resultado<T> = {
data?: T;
errors?: { message: string; extensions?: Record<string, unknown> }[];
extensions?: {
obraaberta?: {
plano: string;
campos_restritos: { campo: string; etiqueta: string; mensagem: string }[];
cotas: Record<string, { uso: number; limite: number }> | null;
upgrade_url: string;
};
};
};
export function criarCliente(apiKey?: string) {
return async function consultar<T>(
query: string,
variables: Record<string, unknown> = {},
): Promise<Resultado<T>> {
const r = await fetch(ENDPOINT, {
method: "POST",
headers: {
"Content-Type": "application/json",
...(apiKey ? { "X-API-Key": apiKey } : {}),
},
body: JSON.stringify({ query, variables }),
});
if (r.status === 429) throw new Error("Cota do plano excedida (429).");
const json = (await r.json()) as Resultado<T>;
const bloqueados = json.extensions?.obraaberta?.campos_restritos ?? [];
if (bloqueados.length) {
console.warn("Campos bloqueados pelo plano:", bloqueados.map((c) => c.campo).join(", "));
}
return json;
};
}
// uso
const consultar = criarCliente(process.env.OBRAABERTA_KEY);
const { data } = await consultar<{ building: { name: string; delayMonths: number | null } }>(
`query Obra($slug: String!) {
building(slug: $slug) { name delayMonths builder { name transparencyIndex } }
}`,
{ slug: "evolve-vila-mariana" },
);
console.log(data?.building);O mesmo padrão funciona em Python com requests.post ou em qualquer cliente GraphQL, como Apollo, urql ou graphql-request, apontando para o endpoint acima.
Persisted queries (APQ) e limites
O endpoint aceita Automatic Persisted Queries: envie apenas o hash SHA-256 da consulta. Se o servidor ainda não a conhecer, ele responde PERSISTED_QUERY_NOT_FOUND e basta reenviar o texto da consulta com o hash; a partir daí só o hash é necessário. Consultas têm profundidade máxima de 10 e custo máximo de 1500.
# hash = SHA-256 do texto exato da consulta
# node: crypto.createHash('sha256').update(query).digest('hex')
# 1) tentativa só com o hash
curl -s https://obraaberta.com.br/api/v1/graphql \
-H 'Content-Type: application/json' -H "X-API-Key: $OBRAABERTA_KEY" \
-d '{"extensions":{"persistedQuery":{"version":1,"sha256Hash":"<hash>"}}}'
# -> {"errors":[{"message":"PersistedQueryNotFound", ...}]}
# 2) registra a consulta (uma única vez)
curl -s https://obraaberta.com.br/api/v1/graphql \
-H 'Content-Type: application/json' -H "X-API-Key: $OBRAABERTA_KEY" \
-d '{"query":"query { buildings(limit: 5) { name } }","extensions":{"persistedQuery":{"version":1,"sha256Hash":"<hash>"}}}'Planos corporativos podem operar em modo estrito: nele só rodam consultas previamente aprovadas, consultas com texto solto são recusadas e a introspecção fica desativada. O schema continua público; para homologar novas consultas nesse modo, envie o texto para o suporte.
| Código | Significado |
|---|---|
| PERSISTED_QUERY_NOT_FOUND | Hash desconhecido — reenvie com o texto (modo livre) ou solicite aprovação (modo estrito). |
| PERSISTED_QUERY_HASH_MISMATCH | O hash enviado não corresponde ao texto da consulta. |
| PERSISTED_QUERY_REQUIRED | Modo estrito: é obrigatório usar extensions.persistedQuery. |
| PERSISTED_QUERY_BLOCKED | Consulta bloqueada pela administração. |
| INTROSPECTION_DISABLED | Introspecção indisponível para este cliente. |
Comparativo com a API da Órulo
| Recurso | Órulo | ObraAberta GraphQL |
|---|---|---|
| Empreendimento, tipologias, fotos | sim | sim |
| Consulta única aninhada (GraphQL) | não | sim |
| Atraso de entrega em meses | não | sim |
| Reputação de construtora, obra e condomínio | não | sim (fórmula pública) |
| Obras públicas / Minha Casa Minha Vida | não | sim |
| POIs do entorno (OpenStreetMap) | não | sim |
| Fontes de dados e score de qualidade | não | sim |
| Marketplace e ofertas rotuladas | não | sim |
| Liberação de campos por assinatura | não | sim (etiquetas + ACL) |
Uso responsável e licenças
- A API é somente leitura: nenhum endpoint cria ou altera obras. O envio de dados por construtoras passa por cadastro e moderação.
- Dados sensíveis, como fornecedores, canais privados, financeiro e propostas de leilão, nunca são expostos pela API.
- Serviços do entorno vêm do OpenStreetMap sob ODbL — mantenha a atribuição © OpenStreetMap contributors.
- Dados do Minha Casa Minha Vida vêm de bases abertas do governo federal; cite a origem ao republicar.
- Ao exibir obras, credite a ObraAberta e prefira apontar para a URL canônica do campo url.
- Use If-None-Match e cache local, respeite os cabeçalhos de rate limit e saiba que chaves com abuso são revogadas.