Documentation Index
Fetch the complete documentation index at: https://docs.agg.market/llms.txt
Use this file to discover all available pages before exploring further.
Avatar endpoints require a signed-in user session. See Authentication
for the initial sign-in flow.
Avatar upload is a two-step process: request a presigned upload URL, then upload the file directly
to S3. After upload, confirm or poll for the processed avatar before updating the UI.
Step 1: Get Upload URL
// POST /users/me/avatar
const { uploadUrl, assetKey, cdnUrl } = await client.createAvatarUploadUrl("image/jpeg");
// uploadUrl = presigned S3 PUT URL (valid for 10 minutes)
// cdnUrl = where the processed image will be served from
Step 2: Upload the Image
Upload the raw file bytes directly to the presigned URL:
const file = inputElement.files[0]; // from an <input type="file">
await fetch(uploadUrl, {
method: "PUT",
headers: { "Content-Type": file.type },
body: file,
});
Step 3: Wait for Processing
The image is processed asynchronously after upload. If you want the client to explicitly finish the
flow, retry updateUser({ confirmAvatar: true }) until the processed asset is ready:
async function confirmAvatar(maxAttempts = 10) {
for (let i = 0; i < maxAttempts; i++) {
try {
const profile = await client.updateUser({ confirmAvatar: true });
if (profile.avatarUrl) {
return profile.avatarUrl;
}
} catch (err: any) {
if (err.status !== 400) throw err;
}
await new Promise((r) => setTimeout(r, 1000));
}
throw new Error("Avatar processing timed out");
}
If you prefer not to confirm explicitly, you can also poll GET /users/me until avatarUrl
appears after processing finishes:
async function waitForAvatar(maxAttempts = 10) {
for (let i = 0; i < maxAttempts; i++) {
const profile = await client.getCurrentUser();
if (profile.avatarUrl) {
return profile.avatarUrl;
}
await new Promise((r) => setTimeout(r, 1000)); // wait 1s between polls
}
throw new Error("Avatar processing timed out");
}
const avatarUrl = await waitForAvatar();
Constraints
| Constraint | Value |
|---|
| Max file size | 5 MB |
| Allowed types | JPEG, PNG, GIF, WebP |
| Processing time | Usually 1-3 seconds |
| CDN variants | 44px, 48px, 60px, original, raw |
Removing an Avatar
await client.updateUser({ removeAvatar: true });
Error Handling
try {
const { uploadUrl } = await client.createAvatarUploadUrl(file.type);
const uploadRes = await fetch(uploadUrl, {
method: "PUT",
headers: { "Content-Type": file.type },
body: file,
});
if (!uploadRes.ok) {
throw new Error(`Upload failed: ${uploadRes.status}`);
}
const avatarUrl = await confirmAvatar();
console.log("Avatar ready:", avatarUrl);
} catch (err: any) {
if (err.status === 415) {
console.error("Unsupported file type");
} else {
console.error("Avatar upload failed:", err);
}
}