Skip to content

SDK de TypeScript y Python

Dos clientes oficiales, de código abierto con licencia MIT, en github.com/normatia/normatia. Cada método llama a una ruta de la API y devuelve su JSON, con el tipo de cada respuesta para el editor. Sirven con la clave de siempre y con una clave de prueba.

LenguajePaqueteNecesita
TypeScript y JavaScriptnormatia en npmNode 18 o posterior
Pythonnormatia en PyPIPython 3.9 o posterior

Los dos se publican desde ese repositorio con GitHub Actions, sin tokens y con certificado de procedencia: npm y PyPI muestran de qué commit sale cada versión.

Terminal window
npm install normatia

También con pnpm add normatia, yarn add normatia o bun add normatia.

Créala en normatia.com, Mi cuenta > Claves API, y guárdala en la variable de entorno NORMATIA_API_KEY. El cliente de Python la lee de ahí; al de TypeScript se le pasa al crearlo. Cómo funcionan las claves, sus permisos y sus límites está en Autenticación.

Una parcela con sus afecciones, los datos técnicos de su municipio y las normas municipales que le aplican. Con una clave de prueba funciona tal cual: la parcela está en el entorno de pruebas.

import { NormatiaClient } from "normatia";
const client = new NormatiaClient({ apiKey: process.env.NORMATIA_API_KEY! });
const parcel = await client.getParcel("6963301TG3466N", { include: ["constraints", "zoning"] });
for (const layer of parcel.constraints?.layers ?? []) {
// null es «sin datos», nunca «no afectada»
if (layer.affected) console.log(layer.layer, layer.summary);
}
const place = await client.getPlace("ES-41091");
console.log(place.technical_data?.climate_zone); // { value: "B4", source: { citation: "CTE DB-HE, Anejo B", ... } }
const { data } = await client.listRegulations({ place: "ES-41091", scope: "municipal" });
for (const regulation of data) console.log(regulation.slug, regulation.current_version?.curated);

Cada error de la API llega como una excepción con el código de la lista de errores, que es lo que debe mirar tu programa, y el identificador de la petición, que es lo que nos tienes que mandar si nos escribes.

DatoTypeScriptPython
Estado HTTPstatusCode (0 si falla la red)status_code
Códigocodecode
Mensaje para una personamessagemessage
Identificador de la peticiónrequestIdrequest_id
Segundos que esperarretryAfter, en RateLimitErrorretry_after

Las clases son las mismas en los dos: AuthenticationError (401), ForbiddenError (403), NotFoundError (404), ValidationError (422) y RateLimitError (429), todas hijas de NormatiaError. El de Python tiene además ServiceUnavailableError (503) y APIError para el resto.

import { NotFoundError } from "normatia";
try {
await client.getParcel("4141412VG4444S");
} catch (error) {
if (error instanceof NotFoundError) console.log(error.code, error.requestId); // parcel_not_found (not_in_sandbox con una clave de prueba), req_...
else throw error;
}
RutaTypeScriptPython
GET /v1/megetMe()get_me()
GET /v1/usagegetUsage()get_usage()
GET /v1/keys, DELETE /v1/keys/{id}listKeys(), revokeKey(id)list_keys(), revoke_key(id)
GET /v1/parcels/{ref}getParcel(ref, { include })get_parcel(ref, include=[...])
GET /v1/parcels?lat=&lon=findParcelsAtPoint(lat, lon)find_parcels_at_point(lat, lon)
GET /v1/sandboxgetSandbox()get_sandbox()
GET /v1/layers, GET /v1/coveragelistLayers(), getCoverage(place)list_layers(), get_coverage(place)
GET /v1/places, GET /v1/places/{place}findPlaces({ q }), getPlace(place)find_places(q), get_place(place)
GET /v1/regulationslistRegulations()list_regulations(), iter_regulations()
GET /v1/regulations/{slug}getRegulation(slug)get_regulation(slug)
GET /v1/regulations/{slug}/contentsgetRegulationContents(slug)get_regulation_contents(slug)
GET /v1/regulations/{slug}/sections/{section}getRegulationSection(slug, section)get_regulation_section(slug, section)
POST /api/v2/askaskV2({ query, project_id })ask(query, project_id=)
POST /api/v1/verifyverify({ ... })verify(...)

El de TypeScript tiene también los métodos de las rutas anteriores: searchLocations y getLocation (Location), searchCodes y getCode (Codes), listProjects y getProjectInfo (Projects).

La referencia completa de cada cliente, con todos los parámetros, está en su README: TypeScript y Python.