Documentação da API

Integre a pesquisa de moradas por código postal na sua aplicação. Comece com uma chave de API e um pedido HTTP.

Fazer o primeiro pedido Experimentar no site

Visão geral

A API GEOPT permite consultar as moradas associadas a um código postal português. Envie pedidos com um corpo JSON e receba a localidade, o concelho, o distrito e as moradas disponíveis.

POST https://geopt.growrs.pt/api/v1/search

Autenticação

Envie a sua chave no cabeçalho X-API-Key de cada pedido. A chave está disponível na sua conta após concluir o registo e tem de estar válida e associada a uma conta ativa.

X-API-Key: YOUR_API_KEY
Content-Type: application/json
Accept: application/json

Mantenha a chave privada. Faça os pedidos a partir do servidor da sua aplicação e não publique a chave no código do navegador ou em repositórios.

Codificação

Use JSON com codificação UTF-8. Envie as duas partes do código postal como texto, para preservar os zeros à esquerda: "2530" e "073".

Versão

Os endpoints desta versão usam o prefixo /api/v1.

Primeiro pedido

  1. Crie uma conta e conclua o registo. A chave inicial é válida durante 15 dias.
  2. Copie a chave de API disponível na sua conta.
  3. Substitua YOUR_API_KEY no exemplo e execute o comando no terminal.

Criar conta

cURL
curl --request POST 'https://geopt.growrs.pt/api/v1/search' \
  --header 'X-API-Key: YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json' \
  --data '{"pc4":"2530","pc3":"073"}'

Confirme que o campo code da resposta é 200 antes de utilizar os dados. Consulte as respostas e erros para tratar os restantes casos. Ver códigos de resposta.

Endpoints

Obtém as moradas associadas às duas partes de um código postal. Cada pesquisa autenticada com parâmetros válidos é registada na sua conta, incluindo pesquisas sem resultados.

POST /api/v1/search

Corpo do pedido

Parâmetros JSON obrigatórios
CampoTipoDescrição
pc4stringObrigatório. Primeira parte do código postal, com 4 caracteres. 2530
pc3stringObrigatório. Segunda parte do código postal, com 3 caracteres. 073
{
    "pc4": "2530",
    "pc3": "073"
}

Exemplo de resposta com sucesso

Exemplo ilustrativo com uma morada. O número de moradas e os respetivos valores variam com o código postal consultado.

{
    "code": 200,
    "status": "OK",
    "message": "Data retrieved successfully",
    "data": {
        "pc": "2530-073",
        "locality": "Lourinhã",
        "city": "Lisboa",
        "district": "Lisboa",
        "extra": "Lourinhã, Lisboa",
        "addresses": [
            {
                "street": "Beco da Palmeira",
                "gps": "39.202397,-9.329441"
            }
        ]
    }
}

Campos da resposta

Estrutura da resposta JSON
CampoTipoDescrição
codeintegerResultado da operação: 200 em caso de sucesso. Não corresponde necessariamente ao estado HTTP.
statusstringDesignação do resultado, por exemplo OK ou Not Found.
messagestringMensagem descritiva em inglês. Use code para decidir como tratar a resposta.
dataobject | arrayObjeto com os dados em caso de sucesso; array vazio em caso de erro.
data.pcstring | nullCódigo postal completo, por exemplo 2530-073.
data.localitystring | nullLocalidade associada ao código postal.
data.citystring | nullConcelho indicado pela fonte. Se a fonte não o distinguir, pode repetir a localidade.
data.districtstring | nullDistrito indicado pela fonte. Pode repetir o concelho ou a localidade quando a fonte não os distinguir.
data.extrastring | nullInformação complementar de localização disponibilizada pela fonte.
data.addressesarrayLista de moradas encontradas.
data.addresses[].streetstringNome da rua, quando disponibilizado pela fonte.
data.addresses[].gpsstringCoordenadas no formato latitude,longitude. O campo pode estar ausente quando a fonte não disponibiliza coordenadas; verifique a sua existência antes de o usar.

Os campos pc, locality, city, district e extra podem ser null quando a informação não está disponível. As coordenadas GPS são texto; não são um objeto com latitude e longitude separadas.

Exemplos de integração

Execute estes exemplos no servidor. Substitua YOUR_API_KEY por uma chave carregada da configuração privada da sua aplicação. Não inclua a chave no código enviado para o navegador.

Ambos os exemplos limitam o tempo de espera e verificam o estado HTTP e o campo code. Não repetem pedidos automaticamente: cada pesquisa pode criar um registo na sua conta.

JavaScript — Node.js 18+

JavaScript no servidor
async function searchPostalCode() {
    const apiKey = 'YOUR_API_KEY'; // Load from server-side secret configuration.
    const controller = new AbortController();
    const timeout = setTimeout(() => controller.abort(), 10000);

    try {
        const response = await fetch("https://geopt.growrs.pt/api/v1/search", {
            method: 'POST',
            headers: {
                'X-API-Key': apiKey,
                'Content-Type': 'application/json',
                'Accept': 'application/json'
            },
            body: JSON.stringify({ pc4: '2530', pc3: '073' }),
            signal: controller.signal
        });
        if (!response.ok) {
            throw new Error('HTTP error: ' + response.status);
        }
        const result = await response.json();
        if (result.code !== 200) {
            throw new Error(result.message || 'API request failed');
        }
        return result.data;
    } finally {
        clearTimeout(timeout);
    }
}

searchPostalCode()
    .then(data => console.log(data.addresses))
    .catch(error => console.error(error.message));

PHP 7.0+

Requer a extensão cURL do PHP.

PHP / cURL
<?php
$apiKey = 'YOUR_API_KEY'; // Load from server-side secret configuration.
$curl = curl_init('https://geopt.growrs.pt/api/v1/search');
curl_setopt_array($curl, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CONNECTTIMEOUT => 5,
    CURLOPT_TIMEOUT => 10,
    CURLOPT_HTTPHEADER => [
        'X-API-Key: ' . $apiKey,
        'Content-Type: application/json',
        'Accept: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode(['pc4' => '2530', 'pc3' => '073']),
]);

try {
    $body = curl_exec($curl);
    if ($body === false) {
        throw new RuntimeException('Network error: ' . curl_error($curl));
    }
    $httpStatus = curl_getinfo($curl, CURLINFO_HTTP_CODE);
    if ($httpStatus < 200 || $httpStatus >= 300) {
        throw new RuntimeException('HTTP error: ' . $httpStatus);
    }
    $result = json_decode($body, true);
    if (json_last_error() !== JSON_ERROR_NONE || !is_array($result)) {
        throw new RuntimeException('Invalid JSON response');
    }
    if (($result['code'] ?? null) !== 200) {
        throw new RuntimeException($result['message'] ?? 'API request failed');
    }
    echo json_encode($result['data'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
} catch (RuntimeException $error) {
    error_log($error->getMessage());
} finally {
    curl_close($curl);
}

Respostas e erros

As respostas da API incluem code, status, message e data. Em caso de erro, data é um array vazio.

Verifique o corpo da resposta. Atualmente, os sucessos e os erros devolvidos pela aplicação usam HTTP 200. O resultado da operação é indicado pelo campo code do JSON. Erros de routing, método HTTP ou infraestrutura podem usar outros estados HTTP.
Códigos devolvidos no corpo JSON
codestatusSignificado e ação
200OKPesquisa concluída. Consulte data.addresses.
400Bad RequestFalta um campo obrigatório ou o comprimento é inválido. Confirme pc4 e pc3.
401UnauthorizedChave ausente, inválida ou expirada, ou conta inativa. Verifique a chave e a validade na sua conta.
404Not FoundNão foram encontradas moradas para o código postal indicado.

Exemplo de erro: campo em falta

{
    "code": 400,
    "status": "Bad Request",
    "message": "Missing required field 'pc3'",
    "data": []
}

Outras mensagens possíveis: Invalid length, You must be authorized to make this request., Your API key has expired! e No results found.

Resolução de problemas

Comece por consultar o estado HTTP e o campo code do JSON. Um HTTP 200, por si só, não garante que a pesquisa teve sucesso.

Recebo code 401: chave inválida ou expirada

Confirme que envia X-API-Key no cabeçalho, sem espaços adicionais. Consulte a validade da chave e o estado da licença na sua conta. Se a chave foi renovada, atualize a configuração do seu servidor. A mensagem Your API key has expired! identifica uma chave expirada.

Recebo code 400: parâmetros inválidos

Envie um corpo JSON com pc4 e pc3, ambos como texto. pc4 deve ter 4 caracteres e pc3 deve ter 3. Por exemplo, use "073" em vez de 73. Missing required field identifica um campo em falta; Invalid length indica um comprimento incorreto.

Recebo code 404: não foram encontradas moradas

Confirme as duas partes do código postal. No results found indica que a pesquisa não encontrou moradas na fonte consultada. Mostre um estado sem resultados na sua aplicação; não repita automaticamente o mesmo pedido.

Recebo HTTP 404, HTTP 405 ou uma resposta HTML

Confirme o endereço da API no exemplo cURL e use POST em /api/v1/search. Abrir o endereço diretamente no navegador envia GET. Uma página HTML pode vir do servidor ou de um proxy; verifique o estado HTTP antes de tentar interpretar a resposta como JSON.

O pedido demora demasiado ou falha na rede

Defina um tempo limite no cliente e trate a falha sem bloquear a aplicação. Uma interrupção da ligação não garante que o pedido não foi processado. Antes de repetir, considere que uma nova pesquisa pode criar outro registo na conta.

Changelog

Documentação

  • Novo layout adaptável com índice de navegação e destaque da secção ativa.
  • Botões para copiar exemplos e novos exemplos de integração em PHP e JavaScript.
  • Referência dos campos da resposta, esclarecimento dos códigos de erro e guia de resolução de problemas.

v1

  • Lançamento da v1