Facturiadocs
Autenticación

Scopes y empresas

Qué concede cada scope, cómo se combina con la lista blanca de empresas y qué error recibes cuando falta uno.

La tabla de scopes

ScopeConcede
documents:readLeer documentos emitidos, PDF, XML y eventos
documents:writeEmitir documentos, reintentar, enviar por correo
received:readLeer los DTE recibidos de proveedores
received:writeAceptar / reclamar / acusar recibo
empresas:readLeer empresas, puesta en marcha, configuración, folios
empresas:writeCrear empresas, cargar certificados, cambiar configuración
folios:writeSolicitar CAF al SII, cargar CAF
tax:readRCV, propuestas y declaraciones de F29, sugerencias
tax:writeCaracterizar, declarar F29, confirmar sugerencias, ingresar gastos
webhooks:read / webhooks:writeEndpoints de webhook y replay de eventos
usage:readLibro de consumo
keys:writeMintear, rotar y revocar llaves de API. Solo llaves root; nunca combinado con los scopes de arriba

Si falta un scope recibes 403 insufficient_scope, con el scope requerido nombrado en error.message. No tienes que adivinar cuál era.

Trampa

Una llave root no puede leer documentos

keys:write no se combina con ningún otro scope. Una llave root (sk_live_root_… / sk_test_root_…) no puede emitir, no puede leer documentos y no puede tocar datos tributarios: su único poder es mintear y revocar otras llaves.

Es la confusión más común al empezar: minteas la llave root, la pruebas contra /v1/documents y recibes un 403. No está rota — está haciendo exactamente lo que debe. Mintea con ella una llave ordinaria y usa esa.

Lista blanca de empresas

Además de los scopes, cada llave lleva una lista de empresas:

  • ["*"] — toda empresa de la cuenta, incluidas las que se creen después.
  • Una lista explícita de RUT — ["77928532-4", "78281439-7"].

Una llave con exactamente un RUT es un token de empresa y el header Facturia-Empresa se vuelve opcional.

Los dos ejes se aplican juntos: una llave con documents:write sobre ["77928532-4"] puede emitir para esa empresa y para ninguna otra. Nombrar otra empresa devuelve 403 empresa_not_allowed — no un 404, porque ya conoces su RUT y fingir que no existe no protege a nadie.

Combinaciones que conviene tener en la cabeza

FormaScopesEmpresasPara qué
Backend de un producto propiodocuments:*, received:*, tax:*["*"]Una sola llave que opera todas las empresas de la cuenta
Llave por cliente (ERP, SaaS vertical)lo mínimo que ese cliente necesitaun solo RUTEl sistema del cliente no puede direccionar nada más
Solo lectura para BI o conciliacióndocuments:read, tax:read, usage:read["*"]Una llave que no puede emitir aunque se filtre
Rootkeys:writesegún lo que va a delegarMintear y revocar llaves. Nada más
Exploración y demoscualquiera, pero sk_test_cualquieraUna llave de test es un límite de capacidad, no una política

Modo de sesión: Facturia-Mode

La superficie /dashboard/* se autentica con un JWT de cuenta en vez de una llave sk_, porque un navegador nunca debe sostener una llave sk_. Una sesión no tiene prefijo que cargue su modo, así que el modo viaja en un header:

Facturia-Mode: test

Por defecto es live. El backend lo aplica exactamente igual que aplicaría el modo de una llave: en modo live una empresa de sandbox no existe, y viceversa. Un valor no reconocido es un 400, nunca una caída silenciosa a live.

Dos reglas aplican a una sesión que no aplican a una llave:

  • Una sesión puede mintear llaves Y leer datos. Una llave root no puede lo segundo. La diferencia es intencional: una llave root es una credencial delegada, y una sesión es el dueño de la cuenta en persona.
  • Una sesión mintea solo llaves ordinarias — nunca una llave root, y nunca una llave con keys:write.

En esta página