Skip to content

Users

Users are your site’s users, addressed by your own id: the sub of the client token, called external_id in the API. mondochat stores a display name, avatar, language and role, never an email.

  • An app with an active server secret. Every call below sends two headers:

    Authorization: Bearer <mcs_ server secret>
    Mondochat-App-Id: <app id>
  • Roles that exist in the app’s settings, if you pass role. See Settings overview.

  • For export and delete, a webhook endpoint that listens for user.exported and user.deleted. See Webhooks overview.

  1. Create or update a user without a browser, for example so others can open a conversation with them before they ever sign in. name is required. avatar (https), role, lang, perms and tier are optional.

    Terminal window
    curl -X PUT https://app.mondochat.io/v1/server/users/bob \
    -H "Authorization: Bearer $MONDOCHAT_SERVER_SECRET" -H "Mondochat-App-Id: $MONDOCHAT_APP_ID" \
    -H 'content-type: application/json' \
    -d '{"name": "Bob", "role": "member", "lang": "en"}'

    The answer is {id, external_id, kind, role, name, avatar}. kind is member or guest. A user also exists after their first session. An upsert alone sends no user.created webhook: it goes out with the user’s first session, whether from an exchange, POST /v1/server/sessions or an installed-app sign-in. An avatar the user uploaded wins over avatar, and an upsert never clears it. See Upsert a user.

  2. Read a user back with GET /v1/server/users/{external_id}:

    Terminal window
    curl https://app.mondochat.io/v1/server/users/bob \
    -H "Authorization: Bearer $MONDOCHAT_SERVER_SECRET" -H "Mondochat-App-Id: $MONDOCHAT_APP_ID"
  3. Export a user’s data. The call answers 202 with {export_id}. When the export is ready, a user.exported webhook carries a download URL that works for 24 hours. The export is a zip in S3 with a JSON file (profile, conversations, messages, purchases and reports by the user) and the user’s photos.

    Terminal window
    curl -X POST https://app.mondochat.io/v1/server/users/bob/export \
    -H "Authorization: Bearer $MONDOCHAT_SERVER_SECRET" -H "Mondochat-App-Id: $MONDOCHAT_APP_ID" \
    -H 'Idempotency-Key: export-bob-1'

    See Export a user.

  4. Delete a user. The call answers 202. The user and their data are deleted within 24 hours, then a user.deleted webhook is sent.

    Terminal window
    curl -X DELETE https://app.mondochat.io/v1/server/users/bob \
    -H "Authorization: Bearer $MONDOCHAT_SERVER_SECRET" -H "Mondochat-App-Id: $MONDOCHAT_APP_ID"

    Deletion removes the user’s messages, photos, IPs and profile fields. The row stays as a tombstone so conversations keep their shape: the peer sees “deleted user” and only their own messages. The open frame gets session.revoked with reason deleted, and the user’s devices are deleted. See Delete a user.

  5. Revoke a user’s installed-app devices when they lose chat access. The call answers 204, or 404 for an unknown user:

    Terminal window
    curl -X DELETE https://app.mondochat.io/v1/server/users/bob/devices \
    -H "Authorization: Bearer $MONDOCHAT_SERVER_SECRET" -H "Mondochat-App-Id: $MONDOCHAT_APP_ID"

    Their sessions stop refreshing within 15 minutes. See Installed app and Revoke devices.

  6. Let users manage their own profile from the chat or a headless client. With a session token, GET /v1/me returns the user and PATCH /v1/me changes these fields. A field left out is unchanged, and any other value answers 422.

    Field Values Effect
    lang en, it, es, fr The user’s interface language.
    last_seen everyone or nobody nobody hides the user’s last seen from everyone and everyone’s from them. online stays visible.
    read_receipts true or false false stops read ticks both ways.
    inbound everyone or members members refuses guests. It needs workspace.inbound and a member that is not guest-like, else 403 policy_denied with reason inbound.

    New users have last_seen: everyone, read_receipts: true and inbound: everyone. Webhooks carry the real last_seen_at and read pointer whatever these choices say, because they go to your server and not to peers. With chat.avatar_upload on, a user uploads a picture that photo moderation checks before it shows.

  • The upsert answers 200 with the user, and GET returns the same external_id.
  • After step 3, your endpoint receives user.exported with a url and expires_at. After step 4, it receives user.deleted with the external_id.
  • After step 4, the peer’s inbox shows “deleted user”.
Answer Cause
401 unauthorized The secret or the app id is missing, wrong or revoked.
404 not_found The user does not exist in this app. Ids from another app answer 404 too.
409 idempotency_conflict The same Idempotency-Key was sent with a different body.
422 validation A field is missing or malformed, for example a role that is not in the app’s settings. errors lists each one.
403 forbidden with reason test_user_limit A tenant in test status accepts 50 users per app.
  • Export and delete take an Idempotency-Key. A repeat with the same key within 24 hours returns the first answer with Idempotent-Replayed: true.
  • A deletion finishes within 24 hours, not at once.
  • An export URL works for 24 hours.
  • After a hard delete, a client that holds an old sync cursor for an affected conversation gets 410 gone with reason stale_cursor and reloads. See Sync and recovery.
  • retention.messages_days, retention.photos_days and retention.ip_log_days (default 90) delete old data on their own. See Settings reference.