Skip to main content
The Thumbnails API provides endpoints for retrieving thumbnail images for various Roblox entities including users, games, groups, and assets.

Importing endpoints

Import the endpoints you need from the thumbnails module:
import { getUsersAvatar, getGamesIcons, getGroupsIcons } from 'rozod/endpoints/thumbnailsv1';
import { fetchApi } from 'rozod';

Get user avatars

Fetch full-body avatar thumbnails for users.
const avatars = await fetchApi(getUsersAvatar, {
  userIds: [1234567890, 987654321],
  size: '150x150',
  format: 'Png',
  isCircular: false,
});

if (!isAnyErrorResponse(avatars)) {
  avatars.data.forEach((avatar) => {
    console.log(`User ${avatar.targetId}:`);
    console.log(`Image: ${avatar.imageUrl}`);
    console.log(`State: ${avatar.state}`);
  });
}

Available avatar sizes

  • 30x30, 48x48, 60x60, 75x75, 100x100
  • 110x110, 140x140, 150x150, 150x200, 180x180
  • 250x250, 352x352, 420x420, 720x720

Get avatar headshots

Fetch headshot thumbnails for users.
import { getUsersAvatarHeadshot } from 'rozod/endpoints/thumbnailsv1';

const headshots = await fetchApi(getUsersAvatarHeadshot, {
  userIds: [1234567890, 987654321],
  size: '150x150',
  format: 'Png',
  isCircular: true, // Circular crop
});

if (!isAnyErrorResponse(headshots)) {
  headshots.data.forEach((headshot) => {
    console.log(`${headshot.targetId}: ${headshot.imageUrl}`);
  });
}

Available headshot sizes

  • 48x48, 50x50, 60x60, 75x75, 100x100
  • 110x110, 150x150, 180x180, 352x352
  • 420x420, 720x720
Set isCircular: true to get circular thumbnails, which is great for profile pictures.

Get avatar bust

Fetch bust (upper body) thumbnails for users.
import { getUsersAvatarBust } from 'rozod/endpoints/thumbnailsv1';

const busts = await fetchApi(getUsersAvatarBust, {
  userIds: [1234567890],
  size: '150x150',
  format: 'Png',
});

if (!isAnyErrorResponse(busts)) {
  busts.data.forEach((bust) => {
    console.log(bust.imageUrl);
  });
}

Get game icons

Fetch game/universe icons.
const icons = await fetchApi(getGamesIcons, {
  universeIds: [1234567890, 987654321],
  size: '256x256',
  format: 'Png',
  returnPolicy: 'PlaceHolder',
});

if (!isAnyErrorResponse(icons)) {
  icons.data.forEach((icon) => {
    console.log(`Game ${icon.targetId}: ${icon.imageUrl}`);
  });
}

Available game icon sizes

  • 50x50, 128x128, 150x150, 256x256
  • 420x420, 512x512

Return policies

  • PlaceHolder - Return placeholder if thumbnail not ready
  • AutoGenerated - Return auto-generated thumbnail
  • ForceAutoGenerated - Force auto-generation
  • ForcePlaceHolder - Always return placeholder

Get game thumbnails

Fetch game thumbnail screenshots.
import { getGamesMultigetThumbnails } from 'rozod/endpoints/thumbnailsv1';

const thumbnails = await fetchApi(getGamesMultigetThumbnails, {
  universeIds: [1234567890],
  countPerUniverse: 5,
  defaults: true,
  size: '768x432',
  format: 'Png',
});

if (!isAnyErrorResponse(thumbnails)) {
  thumbnails.data.forEach((universe) => {
    console.log(`Universe ${universe.universeId}:`);
    universe.thumbnails.forEach((thumb) => {
      console.log(`  - ${thumb.imageUrl}`);
    });
  });
}

Available game thumbnail sizes

  • 768x432, 576x324, 480x270, 384x216, 256x144
Game thumbnails are typically in landscape orientation (16:9 aspect ratio).

Get group icons

Fetch group icons/emblems.
const groupIcons = await fetchApi(getGroupsIcons, {
  groupIds: [1234567, 7654321],
  size: '150x150',
  format: 'Png',
});

if (!isAnyErrorResponse(groupIcons)) {
  groupIcons.data.forEach((icon) => {
    console.log(`Group ${icon.targetId}: ${icon.imageUrl}`);
  });
}

Available group icon sizes

  • 150x150, 420x420

Get asset thumbnails

Fetch thumbnails for catalog assets.
import { getAssets } from 'rozod/endpoints/thumbnailsv1';

const assets = await fetchApi(getAssets, {
  assetIds: [1028595, 1365767],
  size: '150x150',
  format: 'Png',
});

if (!isAnyErrorResponse(assets)) {
  assets.data.forEach((asset) => {
    console.log(`Asset ${asset.targetId}: ${asset.imageUrl}`);
  });
}

Get bundle thumbnails

Fetch thumbnails for bundles.
import { getBundlesThumbnails } from 'rozod/endpoints/thumbnailsv1';

const bundles = await fetchApi(getBundlesThumbnails, {
  bundleIds: [123, 456],
  size: '150x150',
  format: 'Png',
});

if (!isAnyErrorResponse(bundles)) {
  bundles.data.forEach((bundle) => {
    console.log(`Bundle ${bundle.targetId}: ${bundle.imageUrl}`);
  });
}

Get badge icons

Fetch badge icons.
import { getBadgesIcons } from 'rozod/endpoints/thumbnailsv1';

const badges = await fetchApi(getBadgesIcons, {
  badgeIds: [123456789, 987654321],
  size: '150x150',
  format: 'Png',
});

if (!isAnyErrorResponse(badges)) {
  badges.data.forEach((badge) => {
    console.log(`Badge ${badge.targetId}: ${badge.imageUrl}`);
  });
}

Get game pass icons

Fetch game pass icons.
import { getGamePasses } from 'rozod/endpoints/thumbnailsv1';

const gamePasses = await fetchApi(getGamePasses, {
  gamePassIds: [123456, 789012],
  size: '150x150',
  format: 'Png',
});

if (!isAnyErrorResponse(gamePasses)) {
  gamePasses.data.forEach((pass) => {
    console.log(`Game Pass ${pass.targetId}: ${pass.imageUrl}`);
  });
}

Batch thumbnail requests

Use the batch endpoint to fetch multiple thumbnail types at once.
import { postBatch } from 'rozod/endpoints/thumbnailsv1';

const batch = await fetchApi(postBatch, {
  body: [
    {
      requestId: '1',
      targetId: 1234567890,
      token: '',
      alias: '',
      type: 'AvatarHeadShot',
      size: '150x150',
      format: 'Png',
      isCircular: true,
      accessContext: '',
      headShape: '',
    },
    {
      requestId: '2',
      targetId: 9876543210,
      token: '',
      alias: '',
      type: 'GameIcon',
      size: '256x256',
      format: 'Png',
      isCircular: false,
      accessContext: '',
      headShape: '',
    },
  ],
});

if (!isAnyErrorResponse(batch)) {
  batch.data.forEach((item) => {
    console.log(`${item.requestId}: ${item.imageUrl}`);
  });
}

Thumbnail states

Thumbnails can have different states:
  • Completed - Thumbnail is ready
  • Pending - Thumbnail is being generated
  • InReview - Thumbnail is under moderation review
  • Blocked - Thumbnail was blocked by moderation
  • Error - Error generating thumbnail
  • TemporarilyUnavailable - Temporarily unavailable
Handle different states appropriately:
const avatars = await fetchApi(getUsersAvatar, {
  userIds: [1234567890],
  size: '150x150',
  format: 'Png',
});

if (!isAnyErrorResponse(avatars) && avatars.data.length > 0) {
  const avatar = avatars.data[0];
  
  if (avatar.state === 'Completed') {
    console.log('Thumbnail ready:', avatar.imageUrl);
  } else if (avatar.state === 'Pending') {
    console.log('Thumbnail is being generated, try again later');
  } else {
    console.log('Thumbnail unavailable:', avatar.state);
  }
}

Format options

Most endpoints support multiple image formats:
  • Png - PNG format (default)
  • Jpeg - JPEG format (smaller file size)
  • Webp - WebP format (modern format, best compression)
const avatars = await fetchApi(getUsersAvatar, {
  userIds: [1234567890],
  size: '150x150',
  format: 'Webp', // Use WebP for better compression
});
Use WebP format when possible for better performance. It offers superior compression while maintaining quality.

Common patterns

Fetch multiple thumbnail types for a user

const userId = 1234567890;

const [avatar, headshot, bust] = await Promise.all([
  fetchApi(getUsersAvatar, { userIds: [userId], size: '150x150', format: 'Png' }),
  fetchApi(getUsersAvatarHeadshot, { userIds: [userId], size: '150x150', format: 'Png' }),
  fetchApi(getUsersAvatarBust, { userIds: [userId], size: '150x150', format: 'Png' }),
]);

Create thumbnail URL helper

async function getUserThumbnail(
  userId: number,
  type: 'avatar' | 'headshot' | 'bust' = 'headshot',
  size: string = '150x150'
): Promise<string | null> {
  const endpoint = {
    avatar: getUsersAvatar,
    headshot: getUsersAvatarHeadshot,
    bust: getUsersAvatarBust,
  }[type];

  const result = await fetchApi(endpoint, {
    userIds: [userId],
    size,
    format: 'Png',
  });

  if (!isAnyErrorResponse(result) && result.data.length > 0) {
    return result.data[0].imageUrl;
  }

  return null;
}

Available endpoints

All endpoints are exported from rozod/endpoints/thumbnailsv1:
  • getUsersAvatar - Get avatar full body
  • getUsersAvatarHeadshot - Get avatar headshot
  • getUsersAvatarBust - Get avatar bust
  • getGamesIcons - Get game icons
  • getGamesMultigetThumbnails - Get game thumbnails
  • getGroupsIcons - Get group icons
  • getAssets - Get asset thumbnails
  • getBundlesThumbnails - Get bundle thumbnails
  • getBadgesIcons - Get badge icons
  • getGamePasses - Get game pass icons
  • postBatch - Batch thumbnail requests
  • And more…
For the complete list, refer to the TypeScript types in your IDE.

Build docs developers (and LLMs) love