Topolo Docs Topolo Platform
Open workspace

Remove my profile photo

Remove the signed-in user’s platform-wide profile photo and its uploaded bytes.

Outcome

Remove the signed-in user’s platform-wide profile photo and its uploaded bytes.

Captures exercise real Auth/workspace handlers and canonical isolated SQL. Identity, Brand responses and the object store are simulated.

Before you start

  • Use the intended authenticated human. API keys, service/delegated and app/surface-scoped identities cannot edit a global human photo. Third-party credential-bound OAuth requires explicit Auth users:write consent; organization context does not select another user.

  • Retain the prior preset/Brand reference or original image before a mutation, review the exact plan and its compensation, and read canonical state after an unknown result before retrying.

  • Uploaded raster URLs are public to anyone holding the URL and permit a five-minute browser cache. Use an image suitable for public access; replacing/removing stored bytes cannot recall downloaded or cached copies.

Discover the target

topolo whoami --json
topolo actions get app_topolo_auth.me.avatar.remove --detail --json

Read me.get for the same authenticated human, or workspaces.list for the exact target app/organization, to resolve its current photo and uploaded UUID.

Input fields

Accepts exactly {}. The authenticated human is the target; do not add a userId or organization selector.

Effects

  • Sets the verified human’s global photo URL to null, then deletes its owned stored raster.

  • Does not remove another user’s photo or recall cached/downloaded copies; failure can follow the canonical write.

Interpret the response

The target is the verified human user, with no userId/organization selector in input. Its photo is platform-wide across applications and organizations. API keys, service/delegated identities and app/surface-scoped sessions cannot edit it. A normal organization context does not change another person’s profile.

Third-party credential-bound OAuth requires explicit Auth users:write consent; profile consent alone is refused. Canonical context-RBAC sessions follow their separate runtime authority. Permission denial is not evidence of expired OAuth and does not authorize a credential-context change.

userId acknowledges the actual authenticated target. avatarUrl is the current public opaque URL, or null after removal. Read me.get for the same identity and verify profilePicture, then verify the returned image separately. An existing user is required; the action does not provision one.

Identity SQL and old-object cleanup are not one transaction. A failure after the canonical write can leave the new profile photo in place. Read the same identity before retrying. Restore a previous photo with its saved original bytes or separately reviewed removal when the old state was empty; restoration creates a new public URL.

Removing an already absent photo also succeeds with avatarUrl null. The acknowledgment does not revoke a downloaded image, clear a remote browser cache or remove another user’s photo.

Worked examples

All ids, public URLs and raster bytes below are synthetic local fixtures. Resolve authorized live targets and review the exact unchanged plan before execution. These raw target responses do not prove the live gateway, provider persistence, public rendering or cache invalidation.

Authenticated human removes its photo and uploaded object

Input · payload.json:

{}

CLI:

topolo actions validate app_topolo_auth.me.avatar.remove --data @payload.json --json
topolo actions plan app_topolo_auth.me.avatar.remove --data @payload.json --confirm --json
topolo actions call app_topolo_auth.me.avatar.remove --data @payload.json --confirm --detail --json

MCP call after topolo_validate_action and topolo_plan_action on this same input:

{
  "tool": "topolo_call_action",
  "arguments": {
    "actionId": "app_topolo_auth.me.avatar.remove",
    "input": {},
    "confirm": true,
    "detail": true
  }
}

Captured local handler response · HTTP 200:

{
  "success": true,
  "message": "Profile photo updated",
  "data": {
    "userId": "usr_avatar_owner",
    "avatarUrl": null
  },
  "timestamp": "2026-10-03T00:00:00.000Z"
}

Removing an already absent personal photo also acknowledges null

Input · payload.json:

{}

CLI:

topolo actions validate app_topolo_auth.me.avatar.remove --data @payload.json --json
topolo actions plan app_topolo_auth.me.avatar.remove --data @payload.json --confirm --json
topolo actions call app_topolo_auth.me.avatar.remove --data @payload.json --confirm --detail --json

MCP call after topolo_validate_action and topolo_plan_action on this same input:

{
  "tool": "topolo_call_action",
  "arguments": {
    "actionId": "app_topolo_auth.me.avatar.remove",
    "input": {},
    "confirm": true,
    "detail": true
  }
}

Captured local handler response · HTTP 200:

{
  "success": true,
  "message": "Profile photo updated",
  "data": {
    "userId": "usr_avatar_owner",
    "avatarUrl": null
  },
  "timestamp": "2026-10-03T00:00:00.000Z"
}

Verify the result

  • Read me.get for the same pinned human identity and require profilePicture null.

  • A previously uploaded Auth image should be absent at the server; cache/download revocation is not implied.

Errors and recovery

Anonymous photo removal is refused

Input:

{}

Captured local refusal · HTTP 401 · application/json:

{
  "success": false,
  "error": {
    "message": "Access token required",
    "code": "AUTH_ERROR",
    "details": null,
    "timestamp": "2026-10-03T00:00:00.000Z"
  }
}

API-key identity cannot remove a human global photo

Input:

{}

Captured local refusal · HTTP 403 · application/json:

{
  "success": false,
  "error": {
    "message": "A personal user session is required to change your photo",
    "code": "FORBIDDEN",
    "details": null,
    "timestamp": "2026-10-03T00:00:00.000Z"
  }
}

Published recovery guidance

  • state_conflict (HTTP 409): Read the current resource state, reconcile the intended change, and retry only if still valid.

  • AUTH_ERROR (HTTP 401): Verify the pinned human identity and actual credential expiry. An invalid identity does not authorize another target or context.

  • FORBIDDEN (HTTP 403): Use the intended human session and, for third-party credential-bound OAuth, explicit Auth users:write consent. API keys or delegated/app-scoped identities cannot edit a human global photo. Respect refusal.

  • NOT_FOUND (HTTP 404): Resolve the existing authenticated human. Photo actions do not provision users.

  • VALIDATION_ERROR (HTTP 400): Validate the upload filename, base64, decoded size and matching raster MIME/signature. Removal accepts exactly {}.

  • SERVER_ERROR (HTTP 500): Read me.get for the same pinned human before reviewing a retry. Identity SQL and old-object deletion can fail separately; the new state may already be stored. Preserve sanitized evidence for the authorized maintainer.

Recovery boundaries

Before removing retain the original bytes if later restoration is required. After read-back, separately review me.avatar.upload for the same human with those bytes. The new upload has a new opaque URL. If no photo previously existed there is nothing to restore.

Discovery and evidence

This record belongs to Auth. Candidate human/machine URLs become valid only after native publication. Real canonical core/access migrations, identity/workspace SQL, raster validation, Brand response parsing and JSON/binary response construction were exercised. In-memory image storage, identities, seating, Brand workspace discovery and HTTP responses, ids/clock and fault injection are simulated. No live user photo, workspace avatar, Brand publication, OAuth state or Cloudflare object was changed.