Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.scute.io/llms.txt

Use this file to discover all available pages before exploring further.

Programmatic CRUD over users in an app.

Authentication (same for all endpoints)

Authorization: Bearer <api_secret_key>
Content-Type: application/json
The key must own the app you’re calling against:
  • App key (scapp_…) — can only manage users in its own app
  • Workspace key (scwor_…) — can manage users in any app within the workspace (or any child workspace, if you’re an MSP parent)
Wrong scope → 403 "API key not authorized for this app".

Create a user

POST /v1/:app_id/users
:app_id is the Client App ID (app_…) — the app the user should belong to.

Body

Either email or phone is required. Everything else is optional.
FieldTypeDescription
emailstringPrimary email identifier
phonestringE.164 phone identifier
identifierstringBack-compat: pass either, type is auto-detected
first_name, middle_name, last_namestringStored together as name
external_idstringYour own ID for cross-system mapping (unique per app)
user_metaobjectArbitrary key/value metadata
statusactive | inactiveDefaults to active
send_inviteboolSend magic-link invitation email
add_as_workspace_memberboolAlso add the underlying user as a workspace team member
workspace_rolestringRole if add_as_workspace_member: true

Example

curl -X POST https://api.scute.io/v1/app_l3Rx.../users \
  -H "Authorization: Bearer scapp_..." \
  -H "Content-Type: application/json" \
  -d '{
    "email": "jane@acme.com",
    "first_name": "Jane",
    "last_name": "Doe",
    "external_id": "acme-user-42",
    "user_meta": { "plan": "pro", "org": "acme" }
  }'

Response — 200 OK

{
  "user": {
    "id": "57f9b630-eb98-4ef4-...",
    "app_id": "app_l3Rx...",
    "workspace_id": "8a1c...",
    "external_id": "acme-user-42",
    "status": "active",
    "name": "Jane Doe",
    "email": "jane@acme.com",
    "phone": null,
    "email_verified": false,
    "phone_verified": false,
    "meta": { "plan": "pro", "org": "acme" },
    "signup_date": "2026-05-25T10:00:00Z",
    "...": "..."
  },
  "invite_sent": false,
  "workspace_membership_error": null
}
app_id and workspace_id echo the parent — use them to map users back to the right client in your own database.

Get a user

GET /v1/:app_id/users/:id
:id is the user UUID returned at creation.

List / search users

GET /v1/:app_id/users?page=1&per_page=50&search=jane

Query parameters

  • page, per_page — pagination
  • search — fuzzy match on name / email / phone (requires pg_trgm)
  • status — filter by active or inactive

Response

{
  "users": [ /* ... */ ],
  "pagination": {
    "total": 1234,
    "page": 1,
    "per_page": 50,
    "total_pages": 25
  }
}

Update a user

PATCH /v1/:app_id/users/:id    # partial update (only fields you send)
PUT   /v1/:app_id/users/:id    # force-replace (use carefully)
Same body shape as create. PATCH leaves untouched fields alone; PUT overwrites the whole record.

Activate / deactivate

POST /v1/:app_id/users/:id/activate
POST /v1/:app_id/users/:id/deactivate
No body. Toggles status between active and inactive. Deactivated users can’t sign in but aren’t deleted.

Delete a user

DELETE /v1/:app_id/users/:id
Hard-deletes the user, their sessions, credentials, and challenges within that app. Other apps in the workspace are untouched.

Bulk: invite / import

POST /v1/:app_id/users/invite    # send magic-link invites to a list
POST /v1/:app_id/users/import    # bulk create
Both accept arrays. See the individual endpoint references for body shapes.

Errors

StatusWhen
400Invalid identifier (malformed email / phone)
401Missing or invalid API key
403API key not authorized for this app
404App or user not found
422Validation error (e.g. external_id already in use)