Skip to main content

Your first request

Let’s fetch game icons using RoZod. This example works in any environment without authentication.
1

Import the endpoint

Import fetchApi and the endpoint you want to use:
import { fetchApi } from 'rozod';
import { getGamesIcons } from 'rozod/lib/endpoints/gamesv1';
All 750+ endpoints are organized by API version in the rozod/lib/endpoints and rozod/lib/opencloud directories.
2

Make the request

Call fetchApi with the endpoint and parameters:
const response = await fetchApi(getGamesIcons, { 
  universeIds: [1534453623, 65241] 
});

console.log(response.data);
The response is fully typed based on the endpoint’s schema!
3

Handle errors

Check for errors using the isAnyErrorResponse helper:
import { fetchApi, isAnyErrorResponse } from 'rozod';
import { getGamesIcons } from 'rozod/lib/endpoints/gamesv1';

const response = await fetchApi(getGamesIcons, { 
  universeIds: [1534453623] 
});

if (isAnyErrorResponse(response)) {
  console.error('Error:', response.message);
  return;
}

console.log('Success:', response.data);

Complete example

Here’s a complete working example that fetches user details:
example.ts
import { fetchApi, isAnyErrorResponse } from 'rozod';
import { getUsersUserdetails } from 'rozod/lib/endpoints/usersv1';

// Fetch user details with full type safety
const userInfo = await fetchApi(getUsersUserdetails, { 
  userIds: [1, 123456] 
});

if (isAnyErrorResponse(userInfo)) {
  console.error('Failed to fetch users:', userInfo.message);
  process.exit(1);
}

// TypeScript knows the exact structure of userInfo.data
for (const user of userInfo.data) {
  console.log(`User: ${user.displayName} (@${user.name})`);
  console.log(`Has verified badge: ${user.hasVerifiedBadge}`);
}
Hover over variables in your IDE to see the inferred types. RoZod provides complete type information for all responses!

Working with pagination

Many Roblox APIs return paginated results. RoZod makes it easy to handle them:

Fetch all pages at once

import { fetchApiPages } from 'rozod';
import { getGroupsGroupidWallPosts } from 'rozod/lib/endpoints/groupsv2';

// Automatically fetches all pages and returns combined results
const allPosts = await fetchApiPages(
  getGroupsGroupidWallPosts, 
  { groupId: 11479637 }
);

console.log(`Found ${allPosts.length} wall posts`);

Process pages one at a time

import { fetchApiPagesGenerator } from 'rozod';
import { getGroupsGroupidWallPosts } from 'rozod/lib/endpoints/groupsv2';

// Process pages as they arrive
const pages = fetchApiPagesGenerator(
  getGroupsGroupidWallPosts, 
  { groupId: 11479637 }
);

for await (const page of pages) {
  console.log(`Processing page with ${page.data.length} posts`);
  // Process this page's data
  for (const post of page.data) {
    console.log(`- ${post.body}`);
  }
}
Use fetchApiPagesGenerator when working with large datasets to avoid loading everything into memory at once.

Batch processing

Some endpoints have limits on array parameters. RoZod can automatically split large requests:
import { fetchApiSplit } from 'rozod';
import { getGamesIcons } from 'rozod/lib/endpoints/gamesv1';

// This endpoint only accepts 100 universe IDs at a time
const manyUniverseIds = [1, 2, 3, 4, 5 /* ... 500 more IDs */];

// RoZod automatically splits into batches of 100
const allIcons = await fetchApiSplit(
  getGamesIcons,
  { universeIds: manyUniverseIds },
  { universeIds: 100 } // Max items per request
);

console.log(allIcons);
The third parameter specifies the maximum items per batch for each array parameter. RoZod handles the splitting and merging automatically.

Error handling strategies

RoZod supports multiple error handling patterns:

Safe unions (default)

import { fetchApi, isAnyErrorResponse } from 'rozod';
import { getGamesIcons } from 'rozod/lib/endpoints/gamesv1';

const res = await fetchApi(getGamesIcons, { universeIds: [1534453623] });

if (isAnyErrorResponse(res)) {
  console.error('Request failed:', res.message);
} else {
  console.log('Success:', res.data);
}

Throw on error

import { fetchApi } from 'rozod';
import { getGamesIcons } from 'rozod/lib/endpoints/gamesv1';

try {
  const res = await fetchApi(
    getGamesIcons, 
    { universeIds: [1534453623] }, 
    { throwOnError: true }
  );
  console.log(res.data);
} catch (err) {
  console.error('Request failed:', (err as Error).message);
}

Raw Response object

import { fetchApi } from 'rozod';
import { getGamesIcons } from 'rozod/lib/endpoints/gamesv1';

const resp = await fetchApi(
  getGamesIcons, 
  { universeIds: [1534453623] }, 
  { returnRaw: true }
);

const json = await resp.json();
console.log('Status:', resp.status);
console.log('Headers:', resp.headers);

Server-side authentication

For server environments (Node.js, Bun, Deno), configure authentication once at startup:
import { configureServer, fetchApi } from 'rozod';
import { getUsersUserdetails } from 'rozod/lib/endpoints/usersv1';

// Configure once at startup
configureServer({ 
  cookies: 'your_roblosecurity_cookie_here' 
});

// All subsequent requests automatically include the cookie
const userInfo = await fetchApi(
  getUsersUserdetails, 
  { userIds: [123456] }
);
Never commit .ROBLOSECURITY cookies to version control. Use environment variables instead:
configureServer({ cookies: process.env.ROBLOX_COOKIE });

OpenCloud APIs

RoZod fully supports Roblox’s OpenCloud APIs with the same interface:
import { fetchApi, configureServer } from 'rozod';
import { v2 } from 'rozod/lib/opencloud';

// Configure OpenCloud API key
configureServer({ 
  cloudKey: 'your_opencloud_api_key_here' 
});

// Get universe details through OpenCloud
const universeInfo = await fetchApi(
  v2.getCloudV2UniversesUniverseId,
  { universe_id: '123456789' }
);

console.log(universeInfo.displayName);
console.log(universeInfo.description);

DataStore example

import { fetchApi } from 'rozod';
import { getCloudV2UniversesUniverseIdDataStoresDataStoreIdEntries } from 'rozod/lib/opencloud/v2/cloud';

// Get DataStore entries with type safety
const entries = await fetchApi(
  getCloudV2UniversesUniverseIdDataStoresDataStoreIdEntries,
  {
    universe_id: '123456789',
    data_store_id: 'MyStore'
  }
);

for (const entry of entries.keys) {
  console.log(`Key: ${entry.key}`);
}
OpenCloud endpoints use snake_case parameters following Roblox’s API conventions, while classic endpoints use camelCase.

Next steps

Authentication

Learn about cookie pools, rotation, and HBA

API reference

Explore the core API functions

Custom endpoints

Define your own type-safe endpoints

Pagination

Handle paginated responses

Build docs developers (and LLMs) love