API de Dazr Files: documentación para desarrolladores

Inicio rápido

  1. Registra tu app y activa la API de Dazr Files. Registra tu app, o usa una que ya tengas, en la consola de Dazr Identity: el mismo sitio que para Iniciar sesión con Dazr Identity y la API de Dazr Sign, con el mismo ID de cliente y el mismo secreto. En la página de tu app, elige Activar Dazr Files API. Para copias de seguridad desatendidas, debe ser una app de servidor web (con secreto de cliente).
  2. Consigue la aprobación. Da tu ID de cliente a la organización. Una persona titular o administradora abre Dazr Identity → Organizaciones → la organización → Apps conectadas a Files, introduce el ID de cliente y elige qué puede leer tu app: todos los archivos compartidos, o carpetas elegidas con todo su contenido. También puede limitar tu app a redes indicadas (rangos IP).
  3. Obtén un token. Tu servidor pide un token con grant_type=client_credentials, el id de la organización como org, y tu ID de cliente y secreto (HTTP Basic o el cuerpo del formulario). Solo las apps con secreto de cliente pueden hacerlo.
  4. Llama a la API. Envía el token de acceso como Authorization: Bearer. Dura 10 minutos y no hay token de actualización: pide uno nuevo cuando caduque.
curl -u "$DAZR_CLIENT_ID:$DAZR_CLIENT_SECRET" https://identity.dazr.eu/oauth/token \
  -d grant_type=client_credentials -d scope=files.read -d org=org_3k9x2m0q8w1v5t7a

{ "access_token": "eyJhbGciOiJFUzI1NiIs...", "token_type": "Bearer", "expires_in": 600, "scope": "files.read" }

curl -H "Authorization: Bearer $TOKEN" https://suite.dazr.eu/api/files/v1/spaces

Acceso de una organización para copias de seguridad

Hay dos formas de entrar. Una persona titular o administradora de una organización aprueba tu app para los archivos compartidos de la organización, y tu servidor obtiene tokens sin una persona (lo mejor para copias de seguridad desatendidas). O una persona permite tu app con el scope files.read, y tu app lee los archivos propios de esa persona.

Una organización que no aprobó tu app, una que la revocó y una que no existe responden todas invalid_grant. Los administradores ven cuándo se usó tu app por última vez y cada archivo que descargó, y pueden cambiar sus carpetas o revocarla en cualquier momento. Una aprobación revocada se detiene en la siguiente solicitud: los tokens ya emitidos dejan de funcionar al momento, igual que los enlaces de descarga ya entregados. Los archivos propios de los miembros nunca forman parte de la aprobación de una organización.

ParámetroSignificado
grant_typeclient_credentials
orgEl id de la organización, que sus administradores ven en Apps conectadas a Files.
scopefiles.read (el predeterminado y el único scope).
Client authenticationTu ID de cliente y tu secreto de cliente actual, con HTTP Basic (client_secret_basic) o en el cuerpo del formulario (client_secret_post). No se acepta un secreto anterior que siga vigente tras un traspaso.

Los archivos propios de una persona

Pide openid files.read (y offline_access para un token de actualización) en el flujo habitual de authorization code con PKCE. La persona ve en la pantalla de consentimiento que tu app puede ver y descargar sus archivos. El token llega a sus archivos propios, y a los archivos compartidos de una organización solo si esa organización también aprobó tu app y la persona es miembro y puede abrirlos, con las mismas carpetas. Cuando la persona quita tu app en Apps conectadas, sus tokens dejan de funcionar.

Referencia

URL base https://suite.dazr.eu/api/files/v1. Cada endpoint es GET (y HEAD); cualquier otro método responde 405. Los errores son JSON: { "error": { "code", "message" } }. Las listas aceptan limit (de 1 a 1000, 200 por defecto) y devuelven next_cursor mientras haya más.

SolicitudQué devuelve
GET /spacesLos espacios a los que llega tu token: me para los archivos propios de una persona, y las organizaciones por su id.
GET /spaces/{space}Un espacio.
GET /spaces/{space}/folders/root/childrenLas carpetas y luego los archivos del nivel superior de lo que alcanza tu token. Para una carpeta, usa su id en lugar de root.
GET /spaces/{space}/folders/{id}Una carpeta.
GET /spaces/{space}/files/{id}Un archivo: name, path, parent_id, size, mime, version, etag, created_at, modified_at y trashed_at.
GET /spaces/{space}/files/{id}/versionsLas versiones guardadas de un archivo, de la más reciente a la más antigua.
GET /spaces/{space}/files/{id}/contentUna redirección (302) a un enlace de descarga en files.dazr.eu que funciona 5 minutos y admite rangos de bytes. Añade version= para una versión anterior, o redirect=false para recibir el enlace como JSON.
GET /spaces/{space}/trashArchivos de la papelera, como metadatos. No se pueden descargar hasta que alguien los restaure.
GET /spaces/{space}/changesLo que cambió desde un cursor, para copias de seguridad incrementales (abajo).

Cada solicitud necesita el scope files.read. Parámetros de consulta:

ParámetroSignificado
limitElementos por página para children, trash y changes: de 1 a 1000 (200 por defecto, 500 para changes).
cursorEl next_cursor de la página anterior, o para changes el cursor que devolvió.
versionPara content: un número de versión de versions. Sin él, la versión actual.
redirectPara content: false devuelve { "url", "expires_in" } en lugar de un 302.
GET /spaces
{ "spaces": [ { "id": "org_3k9x2m0q8w1v5t7a", "type": "organisation", "name": "Bakkerij Jansen", "folders": "chosen" } ] }

GET /spaces/org_3k9x2m0q8w1v5t7a/folders/root/children?limit=2
{ "items": [
    { "id": "Hk2mQ9xP4aL1", "type": "folder", "name": "Finance", "parent_id": null, "path": "/Finance",
      "created_at": "2026-09-01T08:12:40.000Z" },
    { "id": "p3RtY7uW0zQe", "type": "file", "name": "Budget 2027.xlsx", "parent_id": "Hk2mQ9xP4aL1",
      "path": "/Finance/Budget 2027.xlsx", "size": 48213,
      "mime": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "version": 3, "version_count": 3,
      "etag": "\"p3RtY7uW0zQe.3.48213\"", "sha256": null, "created_at": "2026-09-02T10:00:00.000Z",
      "modified_at": "2026-10-14T16:31:09.000Z", "trashed_at": null } ],
  "next_cursor": "o.2" }

GET /spaces/org_3k9x2m0q8w1v5t7a/files/p3RtY7uW0zQe/versions
{ "versions": [ { "version": 3, "size": 48213, "mime": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
                  "created_at": "2026-10-14T16:31:09.000Z", "current": true, "restored_from": null } ] }

GET /spaces/org_3k9x2m0q8w1v5t7a/files/p3RtY7uW0zQe/content
302 Found
Location: https://files.dazr.eu/v1/file?t=g1.…

curl -L -o "Budget 2027.xlsx" -H "Authorization: Bearer $TOKEN" \
  https://suite.dazr.eu/api/files/v1/spaces/org_3k9x2m0q8w1v5t7a/files/p3RtY7uW0zQe/content

Sigue la redirección (curl -L): el enlace en files.dazr.eu no necesita cabecera Authorization. Un archivo que aún no está en la pasarela de Files se transmite directamente en lugar de redirigirse.

Sumas de comprobación: Dazr Files no guarda un hash del contenido de cada archivo, así que sha256 siempre es null. El etag cambia cada vez que cambia el contenido (una nueva versión). Calcula tu propio hash mientras descargas si lo necesitas. Los archivos se guardan cifrados (AES-256-GCM, con una clave por espacio que custodia Dazr) y Dazr los descifra cuando los descargas por TLS. No es cifrado de extremo a extremo.

Copias de seguridad incrementales

Llama a changes una vez sin cursor: cada carpeta y cada archivo vuelven como created, con un cursor. Guarda el cursor y envíalo la próxima vez como cursor=. Recibes lo que cambió desde entonces: created, updated (contenido nuevo), moved (renombrado o movido a otra carpeta), trashed, restored y deleted (eliminado para siempre, o ya no está en las carpetas que tu app puede leer). Cada cambio tiene el id, el item_type y el item actual (null si se eliminó). Las carpetas van antes que los archivos y los padres antes que sus hijos. Mientras has_more sea true, vuelve a llamar con el nuevo cursor. Si no cambió nada, recibes el mismo cursor. Un cursor funciona 90 días, solo para tu app y ese espacio; uno caducado responde 410, y empiezas de nuevo sin cursor. Solo siguen siendo válidos los 5 cursores más recientes de tu app para un espacio.

GET /spaces/org_3k9x2m0q8w1v5t7a/changes?cursor=dc1.ds_…
{ "changes": [
    { "type": "updated", "id": "p3RtY7uW0zQe", "item_type": "file",
      "item": { "id": "p3RtY7uW0zQe", "type": "file", "name": "Budget 2027.xlsx", "version": 4, … } },
    { "type": "deleted", "id": "Zx81LmQa2bNc", "item_type": "file", "item": null } ],
  "cursor": "dc1.ds_…",
  "has_more": false }

Errores y límites

Los errores tienen un estado HTTP y un cuerpo como { "error": { "code": "not_found", "message": "..." } }. Todo lo que tu token no alcanza responde 404, igual que lo que no existe.

EstadoCódigos
400invalid_limit, invalid_cursor (un cursor de otra app o espacio)
401unauthenticated, invalid_token (caducado o revocado, se retiró la aprobación o el consentimiento de la persona, o se desactivó la API de Dazr Files para tu app)
403insufficient_scope, files_api_disabled, network_not_allowed (la organización indicó redes y esta solicitud viene de otro sitio)
404space_not_found, folder_not_found, not_found, version_not_found, unknown_endpoint
405method_not_allowed: cualquier método distinto de GET, HEAD y OPTIONS
410cursor_expired: empieza de nuevo sin cursor
429rate_limited, con una cabecera Retry-After
503not_available, storage_unavailable: inténtalo más tarde

El endpoint de token responde con errores OAuth: invalid_client (ID de cliente o secreto incorrectos, o una app sin secreto de cliente), unauthorized_client (la API de Dazr Files no está activada para tu app), invalid_scope e invalid_grant (sin aprobación de esa organización, o no desde sus redes indicadas).

QuéLímite
Solicitudes a la API600 por minuto por aprobación (o por persona y app), 6.000 por minuto por app, 1.200 por minuto por dirección IP
Descargas300 por minuto por aprobación por la API, 600 por minuto por WebDAV
changes120 por hora por espacio sin cursor de página; las páginas siguientes no se limitan aparte
Solicitudes WebDAV1.200 por minuto por aprobación
/oauth/token600 solicitudes por minuto por dirección IP, y 300 por minuto por app

Cada descarga se registra para los administradores de la organización con el nombre de tu app, el archivo, la hora y parte de la dirección IP: las últimas 5.000, hasta 180 días. El mismo archivo descargado de nuevo en 10 minutos cuenta una vez. La actividad de Files de la organización muestra una línea al día para tu app. Las descargas de los archivos propios de una persona aparecen en sus Apps conectadas.

WebDAV

Para herramientas de copia de seguridad que usan WebDAV, un administrador de la organización crea un acceso WebDAV para tu app en Apps conectadas a Files. La contraseña se muestra una vez, solo se guarda como hash y nunca es la contraseña de Dazr de nadie. El acceso sigue a la aprobación: las mismas carpetas, redes y límites, y se detiene cuando se revoca la aprobación.

AjusteValor
Servidorhttps://files.dazr.eu/dav/
Inicio de sesiónHTTP Basic con el usuario (dzw_…) y la contraseña que te da el administrador.
MétodosOPTIONS, PROPFIND con Depth: 0 o 1, GET y HEAD con rangos de bytes. Depth: infinity se rechaza. Toda escritura responde 403 o 405.

Los nombres de carpetas y archivos se muestran tal como están en Dazr Files. Cuando dos elementos de una carpeta tienen el mismo nombre (sin distinguir mayúsculas), el más antiguo lo conserva y los demás reciben su id entre paréntesis antes de la extensión, para que cada elemento tenga su propia ruta. Una carpeta con más de 10.000 elementos no se puede listar por WebDAV; usa la API para ella. Tras 10 inicios de sesión fallidos desde una dirección IP en 15 minutos, esa dirección espera 15 minutos.

rclone

  1. Ejecuta rclone config, elige n para un remote nuevo, llámalo dazr y elige el tipo de almacenamiento webdav.
  2. URL: https://files.dazr.eu/dav/. Vendor: other. User: el usuario (dzw_…). Password: elige escribirla tú y pega la contraseña.
  3. Deja vacío el bearer token y guarda. Compruébalo con rclone lsd dazr: y luego haz la copia.
# ~/.config/rclone/rclone.conf (rclone obscure <password> gives the pass value)
[dazr]
type = webdav
url = https://files.dazr.eu/dav/
vendor = other
user = dzw_0123456789abcdef0123
pass = <obscured password>

rclone lsd dazr:
rclone sync dazr: /backup/dazr --transfers 4

rclone compara el tamaño y la hora de modificación. Usa copy en lugar de sync para conservar en tu copia los archivos eliminados en Dazr Files.

Synology Cloud Sync

  1. Abre Cloud Sync en el NAS, añade un proveedor de nube y elige WebDAV.
  2. Dirección del servidor: https://files.dazr.eu/dav/. Usuario y contraseña: el acceso WebDAV que te da el administrador.
  3. Elige una carpeta local, la carpeta remota / (o una carpeta) y la dirección de sincronización Download remote changes only.

Cloud Sync con WebDAV, dirección de sincronización “Download remote changes only”. Hyper Backup escribe copias en WebDAV, pero no puede leer de él.