NoteBugsDocs

API reference

Backup

Make, keep, inspect and restore the `.zip`.

Eight routes, all admin-only and all off the air in demo mode.

There is no GET /api/backup/export

Exporting is a job: POST /api/backup/job schedules it, GET /api/backup/job follows it and GET /api/backup/file downloads it once ready.

GET/api/backup/job
Role: Admin

The export's state: status, destination, size and when it became ready.

The export is a JOB, not a synchronous download: a .zip with the whole volume does not fit in the time of one request.

Request

curl -s http://localhost:3000/api/backup/job \
  -H "Authorization: Bearer $TOKEN"

Response200

{
  "status": "SENT",
  "origin": "MANUAL",
  "destination": "S3",
  "location": "backups/notebugs-backup-2026-09-08T22-39-26.zip",
  "requestedAt": "2026-09-09T01:38:55.706Z",
  "startsAt": "2026-09-09T01:39:25.706Z",
  "readyAt": "2026-09-09T01:39:27.980Z",
  "expiresAt": null,
  "downloadedAt": null,
  "filename": "notebugs-backup-2026-09-08T22-39-26.zip",
  "size": 28092801,
  "missingFiles": 0,
  "error": null
}

Error responses

CodeWhen it happens
401No credential, or one that no longer holds. Send the session cookie or the Authorization: Bearer header.
403The account is not an admin. This prefix requires ADMIN in every method, reading included.
403The installation is in demo mode, where backup, storage and accounts are off the air.

SENT means the file went to the bucket, which is why /api/backup/file refuses in that state.

POST/api/backup/job
Role: Admin

Schedules the generation of a backup.

Request body

FieldTypeDescription
destinationenumLOCAL writes in the container; S3 sends it to the bucket. Absent uses whatever is configured.LOCAL · S3When absent: o destino configurado

Request

curl -s -X POST http://localhost:3000/api/backup/job \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "destination": "S3" }'

Response200

{
  "status": "PENDING",
  "origin": "MANUAL",
  "destination": "S3",
  "location": "backups/notebugs-backup-2026-09-08T22-39-26.zip",
  "requestedAt": "2026-09-09T01:38:55.706Z",
  "startsAt": "2026-09-09T01:39:25.706Z",
  "readyAt": null,
  "expiresAt": null,
  "downloadedAt": null,
  "filename": "notebugs-backup-2026-09-08T22-39-26.zip",
  "size": null,
  "missingFiles": 0,
  "error": null
}

Error responses

CodeWhen it happens
401No credential, or one that no longer holds. Send the session cookie or the Authorization: Bearer header.
403The account is not an admin. This prefix requires ADMIN in every method, reading included.
403The installation is in demo mode, where backup, storage and accounts are off the air.
409An export is already under way.
422Destination S3 was asked for, but no bucket is configured for backups.

The .zip that stays in the container has a fixed name, one copy and an expiry; the one that goes to the bucket has a timestamped name, accumulates and never expires.

DELETE/api/backup/job
Role: Admin

Cancels the export under way, or discards the file already made.

Request

curl -s -X DELETE http://localhost:3000/api/backup/job \
  -H "Authorization: Bearer $TOKEN"

Response200

{
  "status": "IDLE",
  "origin": null,
  "destination": null,
  "location": null,
  "requestedAt": null,
  "startsAt": null,
  "readyAt": null,
  "expiresAt": null,
  "downloadedAt": null,
  "filename": null,
  "size": null,
  "missingFiles": 0,
  "error": null
}

Error responses

CodeWhen it happens
401No credential, or one that no longer holds. Send the session cookie or the Authorization: Bearer header.
403The account is not an admin. This prefix requires ADMIN in every method, reading included.
403The installation is in demo mode, where backup, storage and accounts are off the air.
GET/api/backup/schedule
Role: Admin

The automatic backup: mode, effective expression, next and last run, and the container's timezone.

Read only. The schedule is WRITTEN by PATCH /api/settings; the next run is not configuration: it comes from the process's timer.

Request

curl -s http://localhost:3000/api/backup/schedule \
  -H "Authorization: Bearer $TOKEN"

Response200

{
  "mode": "DAILY",
  "time": "08:30",
  "weekdays": [],
  "cron": "30 8 * * *",
  "timezone": "America/Sao_Paulo",
  "nextRunAt": "2026-09-09T11:30:00.000Z",
  "lastRunAt": null,
  "lastResult": null
}

Error responses

CodeWhen it happens
401No credential, or one that no longer holds. Send the session cookie or the Authorization: Bearer header.
403The account is not an admin. This prefix requires ADMIN in every method, reading included.
403The installation is in demo mode, where backup, storage and accounts are off the air.

Error messages and payloads never carry a formatted date: the container runs in UTC and would get the day wrong. Formatting is the client's job.

GET/api/backup/file
Role: Admin

Downloads the ready .zip that is in the container.

Request

curl -s -o notebugs-backup.zip \
  http://localhost:3000/api/backup/file \
  -H "Authorization: Bearer $TOKEN"

Response200

content-type: application/zip
content-disposition: attachment; filename="notebugs-backup-2026-09-08T22-39-26.zip"

Error responses

CodeWhen it happens
401No credential, or one that no longer holds. Send the session cookie or the Authorization: Bearer header.
403The account is not an admin. This prefix requires ADMIN in every method, reading included.
403The installation is in demo mode, where backup, storage and accounts are off the air.
409There is no .zip ready to download. SENT also refuses: the file is in the bucket, not in the container.

409 outside READY, and SENT is not READY, because there the file is in the bucket. For those, use /api/backup/remote and restore by remote.

GET/api/backup/remote
Role: Admin

The .zip files already in the bucket, newest first.

Request

curl -s http://localhost:3000/api/backup/remote \
  -H "Authorization: Bearer $TOKEN"

Response200

[
  {
    "name": "notebugs-backup-2026-09-08T22-39-26.zip",
    "size": 28092801,
    "uploadedAt": "2026-09-08T22:39:31.000Z"
  }
]

Error responses

CodeWhen it happens
401No credential, or one that no longer holds. Send the session cookie or the Authorization: Bearer header.
403The account is not an admin. This prefix requires ADMIN in every method, reading included.
403The installation is in demo mode, where backup, storage and accounts are off the air.
409The configured bucket does not keep backups: the scope in effect sends the .zip to disk.

name comes without the prefix: it is exactly what you send back in the remote field of inspection and restore.

POST/api/backup/inspect
Role: Adminmultipart/form-data

Reads a backup and answers what the restore WOULD do. It writes no byte.

It returns the format version, one block per workspace with the count of each scope, the attachments that would not be recreated and how the file's accounts compare to today's.

Request body

FieldTypeDescription
filearquivo (.zip)The .zip sent in the multipart.
remotestringThe name of a backup in the bucket, downloaded on the SERVER.

Request

# from disk…
curl -s -X POST http://localhost:3000/api/backup/inspect \
  -H "Authorization: Bearer $TOKEN" \
  -F "[email protected]"

# …or from one already in the bucket. Never both: that is 400.
curl -s -X POST http://localhost:3000/api/backup/inspect \
  -H "Authorization: Bearer $TOKEN" \
  -F "remote=notebugs-backup-2026-09-08T22-39-26.zip"

Response200

{
  "version": 18,
  "exportedAt": "2026-09-08T22:39:26.000Z",
  "tenants": [
    {
      "id": "cmsp4djx60002p801o7ybpkv7",
      "name": "Pessoal",
      "counts": { "projects": 2, "epics": 5, "cards": 42, "tags": 8, "templates": 1, "relations": 11, "comments": 27, "history": 96, "attachments": 14 }
    }
  ],
  "skippedFiles": [],
  "users": { "file": 3, "current": 3 },
  "settings": { "columnScope": "TENANT", "epicsEnabled": true }
}

Error responses

CodeWhen it happens
400Both file and remote came in the same request. It is one or the other, never both.
401No credential, or one that no longer holds. Send the session cookie or the Authorization: Bearer header.
403The account is not an admin. This prefix requires ADMIN in every method, reading included.
403The installation is in demo mode, where backup, storage and accounts are off the air.
422The .zip is not a NoteBugs backup, is corrupted, or comes from a version this installation cannot read.

file and remote never come together: both is 400. A remote source loosens no validation: from there down there are only bytes.

POST/api/backup/import
Role: Adminmultipart/form-data

Restores a backup, whole or sliced per workspace.

Request body

FieldTypeDescription
filearquivo (.zip)
remotestring
selectionJSONJSON with the scopes PER workspace of the file, plus settings and users. This is what the interface sends.
scopesJSON (forma antiga)The old shape: a flat list of scopes applied to every workspace in the file. Still accepted.

Request

# restores everything: no selection, no scopes
curl -s -X POST http://localhost:3000/api/backup/import \
  -H "Authorization: Bearer $TOKEN" \
  -F "[email protected]"

# per-workspace selection: this is what the interface sends
curl -s -X POST http://localhost:3000/api/backup/import \
  -H "Authorization: Bearer $TOKEN" \
  -F "remote=notebugs-backup-2026-09-08T22-39-26.zip" \
  -F 'selection={
    "tenants": {
      "cmsp4djx60002p801o7ybpkv7": ["projects", "cards", "comments"]
    },
    "settings": false,
    "users": false
  }'

Response200

{
  "projects": 2,
  "epics": 0,
  "tags": 0,
  "templates": 0,
  "cards": 42,
  "relations": 0,
  "comments": 27,
  "history": 0,
  "attachments": 0,
  "tenants": 1,
  "scopes": ["projects", "cards", "comments"],
  "settings": false,
  "users": 0,
  "skippedFiles": []
}

Error responses

CodeWhen it happens
400Both file and remote came in the same request. It is one or the other, never both.
401No credential, or one that no longer holds. Send the session cookie or the Authorization: Bearer header.
403The account is not an admin. This prefix requires ADMIN in every method, reading included.
403The installation is in demo mode, where backup, storage and accounts are off the air.
422The .zip is not a NoteBugs backup, is corrupted, or comes from a version this installation cannot read.
422The selection asks for a scope without the one it depends on: epics without projects, comments without cards.

With neither selection nor scopes, it restores everything, except accounts, which take an explicit ask (users: true): restoring accounts changes who reaches the installation.