Skip to content

Users & invitations

These endpoints manage the people on an instance. Users is the instance-wide admin roster — create, edit, and remove accounts. Invitations is the email-based onboarding path: an admin invites by email, and the recipient accepts to create their own account.

Onboarding has two mutually exclusive paths, gated by whether the instance can send email:

  • Email delivery off → admins create users directly (POST /users), which returns a one-time generated password to convey out of band.
  • Email delivery on → admins send invitations (POST /invitations); the invitee sets their own password on accept.

See Instance settings for the email toggle.

Field Type Description
id string Unique identifier.
name string Display name.
email string Account email.
isAdmin boolean Instance admin (full system management).
canManageTemplates boolean Template-author capability (manage instance-wide report templates without being a full admin).
disabled boolean Disabled accounts cannot sign in, but remain visible to admins.
createdAt string ISO 8601 creation instant.
providers string[] Linked social login providers (google, github); empty for password-only users.

GET /api/v1/users scope: admin

Instance admin only. Returns every user on the instance, each with its linked social providers.

curl "https://<your-instance>/api/v1/users" \
  -H "Authorization: Bearer spantail_pat_yourtoken"

POST /api/v1/users scope: admin

Instance admin only. Creates an account directly. This is the email-off path: when email delivery is enabled, the endpoint returns 403 and you must invite the user instead. A duplicate email returns 409.

The account is created with a generated temporary password, returned exactly once as generatedPassword for the admin to convey out of band. Admin-created accounts are marked verified so the user can later link a Google account.

Request body

Field Type Required Description
email string yes Account email (must be unique).
name string yes Display name (1–100 chars).
grantAdmin boolean no Make the user an instance admin (default false).
grantTemplateAuthor boolean no Grant the template-author capability (default false).
curl -X POST "https://<your-instance>/api/v1/users" \
  -H "Authorization: Bearer spantail_pat_yourtoken" \
  -H "Content-Type: application/json" \
  -d '{ "email": "bo@example.com", "name": "Bo" }'

Returns 201 Created.

PATCH /api/v1/users/:id scope: admin

Instance admin only. All fields are optional; send just what changes.

Request body

Field Type Required Description
name string no New display name (1–100 chars).
isAdmin boolean no Grant or revoke instance admin.
canManageTemplates boolean no Grant or revoke the template-author capability.
disabled boolean no Disable (blocks sign-in) or re-enable the account.
curl -X PATCH "https://<your-instance>/api/v1/users/usr_bo" \
  -H "Authorization: Bearer spantail_pat_yourtoken" \
  -H "Content-Type: application/json" \
  -d '{ "canManageTemplates": true }'

DELETE /api/v1/users/:id scope: admin

Instance admin only. Returns 204 No Content.

Field Type Description
id string Unique identifier.
email string Invited email address.
grantAdmin boolean Whether accepting grants instance admin.
grantTemplateAuthor boolean Whether accepting grants the template-author capability.
expiresAt string ISO 8601 expiry (7 days after creation).
acceptedAt string | null ISO 8601 accept instant, or null if still pending.
createdAt string ISO 8601 creation instant.

GET /api/v1/invitations scope: admin

Instance admin only. Returns the pending (unaccepted, unexpired) invitations.

curl "https://<your-instance>/api/v1/invitations" \
  -H "Authorization: Bearer spantail_pat_yourtoken"

POST /api/v1/invitations scope: admin

Instance admin only. Sends an invitation email with an accept link. This is the email-on path: when email delivery is disabled, the endpoint returns 403 and you must create the user directly instead. An existing account or an existing pending invitation for the same email returns 409. If the email fails to send, the pending invitation is rolled back.

Request body

Field Type Required Description
email string yes Address to invite (lowercased on storage).
grantAdmin boolean no Make the user an instance admin on accept (default false).
grantTemplateAuthor boolean no Grant the template-author capability on accept (default false).
curl -X POST "https://<your-instance>/api/v1/invitations" \
  -H "Authorization: Bearer spantail_pat_yourtoken" \
  -H "Content-Type: application/json" \
  -d '{ "email": "cleo@example.com" }'

Returns 201 Created with the created invitation.

DELETE /api/v1/invitations/:id scope: admin

Instance admin only. Cancels a pending invitation. A missing invitation returns 404; success returns 204 No Content.

GET /api/v1/invitations/accept/:token public

Public — the invitee has no account yet. Resolves a raw invite token and returns the email it was issued for, so the accept page can show who it is for. An invalid, accepted, or expired token returns 404.

curl "https://<your-instance>/api/v1/invitations/accept/tok_secret"

POST /api/v1/invitations/accept/:token public

Public. Creates the account from the invitation: the invitee sets their own name and password. The account is marked verified (so it can later link a Google account), any grantAdmin / grantTemplateAuthor from the invitation is applied, and the invitation is marked accepted. An invalid/expired token, or an email that already has an account, returns 404 / 409 respectively.

Request body

Field Type Required Description
name string yes Display name (1–100 chars).
password string yes Account password (8–128 chars).
curl -X POST "https://<your-instance>/api/v1/invitations/accept/tok_secret" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Cleo", "password": "correct horse battery" }'

Returns 201 Created.