Skip to content

Avatar uploads

View as Markdown

Users manage their account avatar in the With portal. Integrations that embed the account portal or call the With account surface should treat uploads as a two-step intent flow: create an upload intent, upload the file to object storage with the returned form fields, then complete the intent so Sudomimus can validate and process the image.

  1. Read /me/avatar to show the current avatar and upload constraints.
  2. Create an upload intent with the candidate contentType and contentLength.
  3. Submit the file to the returned uploadUrl using the returned method and fields.
  4. Complete the upload intent.
  5. Refetch /me/avatar after completion to show the current preview and review state.

The With REST client exposes this as getAvatar, createAvatarUploadIntent, completeAvatarUploadIntent, and resetAvatar.

/me/avatar returns the current constraints:

FieldMeaning
maxBytesMaximum accepted upload byte size reported by the account-avatar API. Today it matches candidateMaxBytes.
candidateMaxBytesMaximum size of the object you submit to storage. Currently 8 MiB.
acceptedMimeTypesCurrently image/png, image/jpeg, image/webp, and image/gif.
outputSizeNormalized square output size. Currently 512.

The create-intent request is rejected when contentLength is empty or larger than candidateMaxBytes. Completion validates the uploaded object’s actual metadata again, so clients should not assume that a created intent guarantees acceptance.

GIF and WebP candidates are treated as potentially animated. During normalization, Sudomimus accepts at most 60 frames and at most 5 seconds of total animation. Static PNG, JPEG, WebP, and GIF uploads still produce an animated projection URL, but if there is no animation that URL points to the static projection.

Uploaded and generated avatar delivery always uses WebP. Do not rely on the original file extension, input MIME type, or frame count after processing.

The avatar response separates the current account avatar from the uploaded avatar review state:

FieldMeaning
avatar.urlCurrent static account-avatar URL.
avatar.animatedUrlCurrent animated account-avatar URL, or the static URL when no animation is present.
avatar.sourceGENERATED or UPLOAD.
avatar.hasAnimationWhether the current account avatar has an animated projection.
avatar.statusProcessing status for the current account avatar.
uploadedAvatar.reviewStatusModeration state for an uploaded avatar: PENDING, APPROVED, or REJECTED.

While a new upload is pending review, user-facing account surfaces can show the uploaded preview, but applications continue to receive the currently approved avatar or the generated fallback. If moderation rejects an upload, keep your UI prepared to show the generated fallback or the last ready avatar. The delivery URL is display data, not a permanent identifier.

  • Use the returned upload constraints instead of hard-coding limits in UI validation.
  • Upload with the exact form fields returned by the intent response.
  • Complete the intent only after the storage upload succeeds.
  • Refetch /me/avatar after completion so the UI uses the server’s current URLs.
  • Show animated avatars only when your surface can do so respectfully; otherwise use the static URL.
  • Do not store uploaded originals, parse Sudomimus avatar URLs, or use avatar URLs as account keys.