Autenticación y Rate Limiting
API Key
Section titled “API Key”Todos los endpoints requieren autenticación mediante API key en el header:
Authorization: Bearer sk-normatia-xxxxxLa API B2B es un producto separado de la aplicación web. La key se solicita durante el periodo beta a través de normatia.com/es/api. El acceso se activa manualmente.
La API key define el país y el plan
Section titled “La API key define el país y el plan”Toda API key está ligada a un api_plan que incluye exactamente un country_code (ISO 3166-1 alpha-2). No existen planes multi-país en la v1.
API key → api_plan → country_codeEl middleware extrae el country_code del plan y lo inyecta en el contexto de cada request. El developer no necesita pasar el país explícitamente.
Ejemplo de plan:
| Campo | Valor |
|---|---|
name | beta-es |
country_code | es |
monthly_limit | 500 |
rate_limit_pm | 10 req/min para los endpoints de IA (/ask, /verify) |
Si en el futuro un cliente necesita España y Portugal, usará dos keys en dos planes distintos.
Scoping automático por país
Section titled “Scoping automático por país”El country_code del plan filtra automáticamente todas las búsquedas:
/location/search— solo devuelve geografías del país de la key/codes/search— solo devuelve normativas del país de la key/verify— el RAG busca únicamente en los embeddings del país de la key
/api/v2/ask y los endpoints de proyecto no necesitan este filtro: su alcance sale del proyecto, que ya tiene su territorio y sus normativas fijados.
Si una request intenta acceder a datos de otro país (p. ej. pasando geo_id=PT-110300 con una key española), la API devuelve 403 country_mismatch.
Rate limiting y quota mensual
Section titled “Rate limiting y quota mensual”Los endpoints se agrupan en dos categorías:
| Grupo | Endpoints | Rate limit | Consume cuota |
|---|---|---|---|
data | /location, /codes, /projects, /project/info | 60 req/min | No |
intelligence | /api/v2/ask, /verify | Según api_plan.rate_limit_pm | Sí — 1 crédito por llamada |
La quota se reinicia en la fecha aniversario de activación de la key, no el día 1 del mes. Si la key se activó el 15 de marzo, el próximo ciclo empieza el 15 de abril.
Cuando la quota está agotada, los endpoints del grupo intelligence devuelven 429 quota_exceeded hasta el inicio del siguiente ciclo. Los del grupo data no consumen quota y siguen funcionando.
Una consulta a /api/v2/ask cuesta 1 crédito, encadene el agente una búsqueda o seis.
Manejo de errores
Section titled “Manejo de errores”Todos los errores siguen la misma estructura:
{ "error": "ambiguous_location", "message": "Se encontraron varios municipios para 'Villanueva'. Selecciona uno de los candidatos.", "candidates": [ { "geo_id": "ES-28185", "name": "Villanueva de la Cañada", "level": "municipality" } ]}| Campo | Tipo | Descripción |
|---|---|---|
error | string | Código de error legible por máquina (snake_case) |
message | string | Descripción legible por humanos |
candidates | array | Opciones de desambiguación cuando error = ambiguous_location |
Códigos de error comunes:
| Status | Código | Condición |
|---|---|---|
| 400 | missing_scope | Ni geo_id ni codes fueron proporcionados |
| 400 | invalid_code | Un slug de normativa no existe |
| 400 | invalid_version | La versión especificada no existe |
| 403 | country_mismatch | El geo_id pertenece a otro país |
| 403 | plan_not_allowed | El plan no tiene acceso al endpoint |
| 404 | not_found | El identificador referenciado no existe |
| 429 | quota_exceeded | Se han agotado los créditos del plan |
| 429 | rate_limit_exceeded | Se ha superado el límite de peticiones por minuto del grupo |
| 400 | no_active_project | La petición no lleva project_id y el usuario no tiene proyecto activo |
| 404 | project_not_found | El proyecto no existe o el usuario no tiene acceso |