Skip to content

Autenticación y Rate Limiting

Todos los endpoints requieren autenticación mediante API key en el header:

Authorization: Bearer sk-normatia-xxxxx

La 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.

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_code

El 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:

CampoValor
namebeta-es
country_codees
monthly_limit500
rate_limit_pm10 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.

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.

Los endpoints se agrupan en dos categorías:

GrupoEndpointsRate limitConsume cuota
data/location, /codes, /projects, /project/info60 req/minNo
intelligence/api/v2/ask, /verifySegún api_plan.rate_limit_pmSí — 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.

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"
}
]
}
CampoTipoDescripción
errorstringCódigo de error legible por máquina (snake_case)
messagestringDescripción legible por humanos
candidatesarrayOpciones de desambiguación cuando error = ambiguous_location

Códigos de error comunes:

StatusCódigoCondición
400missing_scopeNi geo_id ni codes fueron proporcionados
400invalid_codeUn slug de normativa no existe
400invalid_versionLa versión especificada no existe
403country_mismatchEl geo_id pertenece a otro país
403plan_not_allowedEl plan no tiene acceso al endpoint
404not_foundEl identificador referenciado no existe
429quota_exceededSe han agotado los créditos del plan
429rate_limit_exceededSe ha superado el límite de peticiones por minuto del grupo
400no_active_projectLa petición no lleva project_id y el usuario no tiene proyecto activo
404project_not_foundEl proyecto no existe o el usuario no tiene acceso