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.
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/jsonMantenha 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
- Crie uma conta e conclua o registo. A chave inicial é válida durante 15 dias.
- Copie a chave de API disponível na sua conta.
- Substitua YOUR_API_KEY no exemplo e execute o comando no terminal.
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
Pesquisa por código postal
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.
/api/v1/search
Corpo do pedido
| Campo | Tipo | Descrição |
|---|---|---|
pc4 | string | Obrigatório. Primeira parte do código postal, com 4 caracteres. 2530 |
pc3 | string | Obrigató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
| Campo | Tipo | Descrição |
|---|---|---|
code | integer | Resultado da operação: 200 em caso de sucesso. Não corresponde necessariamente ao estado HTTP. |
status | string | Designação do resultado, por exemplo OK ou Not Found. |
message | string | Mensagem descritiva em inglês. Use code para decidir como tratar a resposta. |
data | object | array | Objeto com os dados em caso de sucesso; array vazio em caso de erro. |
data.pc | string | null | Código postal completo, por exemplo 2530-073. |
data.locality | string | null | Localidade associada ao código postal. |
data.city | string | null | Concelho indicado pela fonte. Se a fonte não o distinguir, pode repetir a localidade. |
data.district | string | null | Distrito indicado pela fonte. Pode repetir o concelho ou a localidade quando a fonte não os distinguir. |
data.extra | string | null | Informação complementar de localização disponibilizada pela fonte. |
data.addresses | array | Lista de moradas encontradas. |
data.addresses[].street | string | Nome da rua, quando disponibilizado pela fonte. |
data.addresses[].gps | string | Coordenadas 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+
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
$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.
| code | status | Significado e ação |
|---|---|---|
| 200 | OK | Pesquisa concluída. Consulte data.addresses. |
| 400 | Bad Request | Falta um campo obrigatório ou o comprimento é inválido. Confirme pc4 e pc3. |
| 401 | Unauthorized | Chave ausente, inválida ou expirada, ou conta inativa. Verifique a chave e a validade na sua conta. |
| 404 | Not Found | Nã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