Documents

List and download client timesheets (billing documents) through the SAQ REST API, with formats, headers, who may download, and the browser-only document grants.

Written for
integration-developer
Roles
owner, admin, project-manager, billing-contact, agent
Requires
API token with read scope; Owner or Admin: all documents; Billing contact with a full login: own client; workspace user: granted clients and managed projects; Document grants: browser session, Owner or Admin
Feature
documents

A document is a client timesheet produced by a billing run: one per run and format (html, pdf, csv), either combined (one per client, a section per project) or per project, according to the client's timesheet layout. Documents are immutable; a redaction supersedes them with a new version and a voided run voids them.

Who may download follows one rule for every door: Owner and Admin see all; a client user sees their own client's documents only when they are a Billing contact with a full login; a workspace user sees clients they hold a document grant for and projects where they are Project manager. A token restricted to named projects sees only project-scoped documents of those projects.

GET /api/w/{slug}/documents

The documents the caller may download. Token: yes, read.

Query parameter Type Meaning
clientId uuid Only this client
runId uuid Only this billing run

Request

curl "https://saq.no/api/w/acme/documents?clientId=01924c3e-0005-7000-8000-000000000001" \
  -H 'Authorization: Bearer saq_YOUR_TOKEN'

Response 200 (DocumentList)

{
  "documents": [
    {
      "id": "01924c3e-2b30-7c41-9d52-ae6f7a8b9c0d",
      "runId": "01924c3e-2a29-7b40-8c51-9d5e6f7a8b9c",
      "number": "ACME-2026-08-001",
      "scope": "combined",
      "projectId": null,
      "projectName": null,
      "clientId": "01924c3e-0005-7000-8000-000000000001",
      "clientName": "Acme AS",
      "periodStart": "2026-08-01",
      "format": "pdf",
      "version": 1,
      "locale": "nb",
      "checksum": "sha256:9f2c…",
      "bytes": 84213,
      "voided": false,
      "redacted": false,
      "createdAt": "2026-09-02T08:00:00.000Z",
      "deliveries": [
        {
          "email": "invoice@acme.example",
          "state": "sent",
          "detail": null,
          "attemptedAt": "2026-09-02T08:01:00.000Z"
        }
      ]
    }
  ],
  "scope": "all"
}
Field Type Meaning
id, runId uuid Document and its billing run
number string Document number
scope combined or project Layout
projectId, projectName uuid, string, or null Set for project scope
clientId, clientName The billing client
periodStart date The billed period
format html, pdf, csv Format of this document
version integer Increases when a redaction supersedes the document
locale string Language of the document (the client's locale)
checksum string Content checksum
bytes integer Size
voided, redacted boolean Voided with its run; superseded by a redaction
createdAt datetime
deliveries[] object email, state (pending, sent, failed, skipped, unknown), detail, attemptedAt per billing recipient
scope (top level) all, client, projects, none The widest download rule in force for the caller

The list is empty with scope: "none" when the caller may download nothing; that is not an error.

GET /api/w/{slug}/documents/{id}/download

The document's bytes. Token: yes, read.

Request

curl -o ACME-2026-08-001.pdf \
  https://saq.no/api/w/acme/documents/01924c3e-2b30-7c41-9d52-ae6f7a8b9c0d/download \
  -H 'Authorization: Bearer saq_YOUR_TOKEN'

Response 200 with the body and:

Header Value
Content-Type text/html; charset=utf-8, application/pdf, or text/csv; charset=utf-8
Content-Disposition inline for HTML, otherwise attachment; filename="<number>.<format>"
Cache-Control private, no-store
X-Content-Type-Options nosniff
Content-Security-Policy default-src 'none'; style-src 'unsafe-inline'; sandbox
Error Status details.reason
forbidden 403 The caller may download nothing, not this document, or a project-restricted token asked for a combined document
conflict 409 document_voided, document_redacted (download the current version instead)
not_found 404 Unknown id, or the file is not available

PDF rendering depends on the rendering service being available on the installation; when it is not, HTML and CSV are produced and no pdf document is listed.

Document grants

A grant lets a workspace user download every document of one client, regardless of projects. Token: no (browser session only). Owner or Admin.

Operation Body Response
GET /api/w/{slug}/clients/{id}/document-grants 200 { "grants": [{ id, identityId, name, email }], "candidates": [{ identityId, name, email }] }
PUT /api/w/{slug}/clients/{id}/document-grants { "identityId": "…", "granted": true } 200 { "ok": true }

Errors: forbidden 403 (admin_only), not_found 404.

Time bank balances

There is no token-enabled HTTP endpoint for time bank balances; the bank endpoints under /billing/banks and /clients/{id}/banks are Owner or Admin, browser session only. An integration or assistant with a token reads balances through the MCP tool get_bank_balances; see MCP.