Projects

List and read projects with an API token, and create, update, archive, and manage project members from a browser session, through the SAQ REST API.

Written for
integration-developer
Roles
owner, admin, project-manager, member, elevated-client-user, agent
Requires
API token with read scope for GET /projects and GET /projects/{key}; Create, update, archive, and members: browser session only
Feature
projects

Projects are addressed by key in paths (a lowercase slug such as web), not by UUID. Workspace users see every project; a client user sees a project only when elevated on it or when their client is its billing or a collaborating client. Agent accounts are members of every project. Tokens may only read projects; every change is browser-session only.

GET /api/w/{slug}/projects

The projects the caller may see. Token: yes, read.

Query parameter Type Meaning
archived true Include archived projects

Request

curl https://saq.no/api/w/acme/projects \
  -H 'Authorization: Bearer saq_YOUR_TOKEN'

Response 200 { "projects": ProjectSummary[] }

{
  "projects": [
    {
      "id": "01924c3e-6b2a-7d11-9d0e-3a1f4b5c6d7e",
      "key": "web",
      "name": "Website",
      "description": "Public website and login saq.",
      "billingClient": {
        "id": "01924c3e-0005-7000-8000-000000000001",
        "name": "Acme AS"
      },
      "collaboratingClients": [],
      "billingMode": "period",
      "memberCount": 4,
      "openTickets": 12,
      "myRole": "member",
      "archived": false
    }
  ]
}
Field Type Meaning
id, key, name, description Identity and description
billingClient { id, name } or null Null means internal work
collaboratingClients[] { id, name } Clients whose users may be elevated and to whom tickets may be billed
billingMode period or on_close Default billing mode for tickets on the project
memberCount integer Project members
openTickets integer Tickets in an open state
myRole member, manager, or null The caller's project role
archived boolean Archived

GET /api/w/{slug}/projects/{key}

One project with its members and what the caller may do. Token: yes, read.

curl https://saq.no/api/w/acme/projects/web \
  -H 'Authorization: Bearer saq_YOUR_TOKEN'

Response 200 (ProjectDetail): every ProjectSummary field plus:

Field Type Meaning
members[] ProjectMember id, identityId, name, email, kind (workspace or client), clientId, clientName, role (member or manager), categoryId (consultant category override), hasFullLogin
permissions object edit, members, collaborators, billing (booleans)
Error Status When
not_found 404 Unknown key or not visible

POST /api/w/{slug}/projects

Create a project. Token: no (browser session only). Owner or Admin.

Body field (CreateProject) Type Required Validation
key string yes 1–32 lowercase letters, digits, or hyphens; unique; fixed after creation
name string yes 1–120 characters
description string no At most 2 000 characters
billingClientId uuid or null no Null is internal work
billingMode period or on_close no Default period
collaboratingClientIds uuid[] no At most 20

Response 201 (ProjectDetail).

Error Status details.reason
forbidden 403 admin_only
invalid 400 project_key_format, name_length, unknown_client
conflict 409 project_key_exists

PATCH /api/w/{slug}/projects/{key}

Change a project. Token: no (browser session only). Owner, Admin, or a workspace-user Project manager; billingClientId and billingMode are Owner or Admin only; collaboratingClientIds replaces the set and needs Owner, Admin, or a workspace-user Project manager.

Body (UpdateProject): any of name, description, billingClientId, billingMode, collaboratingClientIds, with the validation above. Response 200 (ProjectDetail).

Error Status details.reason
forbidden 403 Not allowed to edit; admin_only for billing fields; manager_only for collaborators
invalid 400 name_length, unknown_client
not_found 404 Unknown key

DELETE /api/w/{slug}/projects/{key}

Archive a project (projects are never deleted). Token: no (browser session only). Owner or Admin. Response 200 { "ok": true }. Errors: forbidden 403, not_found 404.

PUT /api/w/{slug}/projects/{key}/members

Add a member or change their role. For a client user this is the elevation. Token: no (browser session only). Needs a re-authentication within the last ten minutes. Owner, Admin, or a workspace-user Project manager may add workspace users; a client Project manager may elevate only users of their own client, and that client must be on the project.

Body (ProjectMemberInput): { "identityId": "…", "role": "member" } where role is member or manager. Response 200 (ProjectDetail).

Error Status details.reason
reauth_required 403 No recent re-authentication
forbidden 403 manager_only, elevate_own_client
invalid 400 client_not_on_project
not_found 404 unknown_person, or unknown project

DELETE /api/w/{slug}/projects/{key}/members/{identityId}

Remove a member (for a client user: remove the elevation). Token: no (browser session only). Recent re-authentication required; same roles as adding. Response 200 { "ok": true }. Errors: reauth_required 403, forbidden 403, not_found 404.