Skip to main content
Supported on
Snapchat

API reference

This page documents version 0.1.0 of the @snap/web-lens-api package, generated from its type declarations. Web Lens API explains how to add the API to a Lens, and the Leaderboards, Bitmoji, and Storage guides show each capability in use.

Snapchat Web Lens API (window.snapchat) — one include for iOS, Android, and desktop development.

Put the built file in your game's zip (the one you upload to My Lenses, with index.html at its root): the Lens CSP blocks runtime fetches by design.

await snapchat.init();
if (snapchat.isSupported('leaderboards')) {
await snapchat.leaderboards.submitScore({ leaderboardId: 'main', score: 42 });
await snapchat.leaderboards.show();
}

Variables​

errors​

const errors: WebLensAPIErrors;

Stable error codes. A rejected call's error.message is always one of these.


snapchat​

const snapchat: SnapchatWebLensAPI;

The singleton also installed as window.snapchat.

Example​

// With a bundler or native ES modules:
import snapchat from '@snap/web-lens-api';

// With a classic <script src="snap-api.js"> include, use window.snapchat directly.

Interfaces​

WebLensAPIErrors​

Stable error codes. A rejected call's error.message is always one of these; native error text never crosses the bridge.

Example​

try {
await snapchat.storage.set('replay', frames);
} catch (e) {
// The store is unchanged, so the previous save is still intact.
if (e.message !== snapchat.errors.QUOTA_EXCEEDED) throw e;
await snapchat.storage.remove('replay');
}

Properties​

PropertyModifierTypeDescription
MALFORMED_REQUESTreadonly"ERR_MALFORMED_REQUEST"The request envelope or app://<capability>/<action> URI failed validation (API bug — file it).
UNKNOWN_CAPABILITYreadonly"ERR_UNKNOWN_CAPABILITY"No handler is registered for the capability on this app version / surface. Check SnapchatWebLensAPI.isSupported first.
INVALID_PARAMSreadonly"ERR_INVALID_PARAMS"The capability rejected the params against its allowlist.
INTERNALreadonly"ERR_INTERNAL"The capability failed internally; details stay in native logs.
QUOTA_EXCEEDEDreadonly"ERR_QUOTA_EXCEEDED"A storage write would exceed the per-Lens byte or key-count quota; the store is unchanged.
STORAGE_UNAVAILABLEreadonly"ERR_STORAGE_UNAVAILABLE"storage has no durable backing on this device or session.
UNSUPPORTED_HOSTreadonly"ERR_UNSUPPORTED_HOST"API-only: the page runs inside Snapchat, but this app version or its WebView can't serve the API (the host injected no bridge). Every call rejects with it, so hide the feature.

SubmitScoreParams​

Properties​

PropertyTypeDescription
leaderboardIdstringBoard id as configured for the Lens.
scorenumberInteger in the safe-integer range; non-integers reject ERR_INVALID_PARAMS.
ordering?"ascending" | "descending"Lower-is-better games must send 'ascending' on every submission. Defaults to 'descending'.

SubmitScoreResult​

Properties​

PropertyTypeDescription
bestScore?numberThe player's best score on this board, as the server acknowledged it; absent when the backend omits it.

Get2DAvatarParams​

Properties​

PropertyTypeDescription
variant?stringVariant id from BitmojiAPI.getVariants; omit for the default portrait.
size?"small" | "medium" | "large"Defaults to 'medium'.

MediaURL​

Properties​

PropertyTypeDescription
urlstringSame-origin, opaque and ephemeral (~5 min): fetch or render promptly, never parse, re-call on error. The shape differs between the stub and a device.

StorageInfo​

Properties​

PropertyTypeDescription
usedBytesnumberBytes the store holds now.
maxBytesnumberPer-Lens store cap, in bytes (100 KiB).
keyCountnumberKeys the store holds now.
maxKeysnumberPer-Lens key cap (256).
maxValueBytesnumberPer-value cap, in bytes of JSON (32 KiB).
persistenceMode"memory" | "disk"memory for Lens Studio previews and the desktop stub.

LeaderboardsAPI​

Native leaderboards (leaderboards capability, v1). Only Lenses configured with the leaderboard module see it in SnapchatWebLensAPI.init.

Methods​

submitScore()​
submitScore(params): Promise<SubmitScoreResult>;

Submits a score to one board.

Parameters​
ParameterType
paramsSubmitScoreParams
Returns​

Promise<SubmitScoreResult>

Example​
// A time trial: lower is better, so say so on every submission.
const { bestScore } = await snapchat.leaderboards.submitScore({
leaderboardId: 'fastest-lap',
score: Math.round(lapSeconds * 1000), // integers only
ordering: 'ascending',
});
if (bestScore !== undefined) bestLabel.textContent = `Best: ${bestScore} ms`;
show()​
show(): Promise<void>;

Opens the Lens's own native leaderboard panel. Submit first so it has data; rejects ERR_INTERNAL when nothing can host it or no board data loads within the bounded wait.

Returns​

Promise<void>

Example​
await snapchat.leaderboards.submitScore({ leaderboardId: 'main', score });
await snapchat.leaderboards.show();

BitmojiAPI​

The current user's own Bitmoji (bitmoji capability, v1). No avatar id ever crosses the bridge. participant is a reserved parameter: every v1 action rejects it with ERR_INVALID_PARAMS.

Always keep a default Bitmoji as a fallback: hasAvatar may be false and any media call may reject ERR_INTERNAL, and a game should never show an empty character in either case. Put the fallback GLB in your game's zip: a Lens cannot fetch it from the network at runtime.

Methods​

getAvatarInfo()​
getAvatarInfo(): Promise<{
hasAvatar: boolean;
}>;

Whether the current user has a Bitmoji. Check it before the media calls, which reject ERR_INTERNAL for a user without one.

Returns​

Promise<{ hasAvatar: boolean; }>

Example​
const { hasAvatar } = await snapchat.bitmoji.getAvatarInfo();
if (!hasAvatar) useDefaultCharacter();
get2DAvatar()​
get2DAvatar(params?): Promise<MediaURL>;

A head-and-shoulders 2D render of the avatar: the default portrait, or one of the variants from BitmojiAPI.getVariants. Rejects ERR_INVALID_PARAMS for a variant outside the current set (variants can retire server-side — fall back to the portrait) and ERR_INTERNAL when the user has no Bitmoji.

Parameters​
ParameterType
params?Get2DAvatarParams
Returns​

Promise<MediaURL>

Example​
let image;
try {
image = await snapchat.bitmoji.get2DAvatar({
variant: savedVariant,
size: 'large',
});
} catch (e) {
if (e.message !== snapchat.errors.INVALID_PARAMS) throw e;
// The variant has retired: show the portrait instead.
image = await snapchat.bitmoji.get2DAvatar({ size: 'large' });
}
avatarImg.src = image.url; // render promptly: the URL expires after ~5 min
get3DAvatar()​
get3DAvatar(): Promise<MediaURL>;

The rigged avatar GLB (standard skeleton, no clips — bundle your own). Rejects ERR_INTERNAL when the user has no Bitmoji or the model fetch fails; the URL is never empty.

Returns​

Promise<MediaURL>

Example​
// Keep a default avatar in your game's zip for users without a Bitmoji and for failed fetches.
let url = './assets/avatar_default.glb';
try {
const { hasAvatar } = await snapchat.bitmoji.getAvatarInfo();
if (hasAvatar) url = (await snapchat.bitmoji.get3DAvatar()).url;
} catch {
// ERR_INTERNAL: keep the default.
}
const glb = await (await fetch(url)).arrayBuffer(); // hand this to your engine's GLB loader
getVariants()​
getVariants(): Promise<{
variants: string[];
}>;

The server-curated set of 2D variants: head-and-shoulders renders of the avatar, the same set the native selfie picker offers. Ids are unnamed: build a visual picker by rendering each via get2DAvatar({ variant, size: 'small' }) in small batches (~6), so the user's own avatar in each variant is its label. Or pick ids at authoring time and keep them as data, falling back to the portrait when one retires.

Returns​

Promise<{ variants: string[]; }>

Example​
const { variants } = await snapchat.bitmoji.getVariants();
for (let i = 0; i < variants.length; i += 6) {
const batch = variants.slice(i, i + 6);
const images = await Promise.all(
batch.map((variant) =>
snapchat.bitmoji.get2DAvatar({ variant, size: 'small' })
)
);
images.forEach(({ url }, j) => addVariantButton(batch[j], url));
}

StorageAPI​

Account-bound key/value persistence for this Lens (storage capability, v1). Values are JSON (≤ 32 KiB each); keys are non-empty strings (≤ 256 bytes). Writes past the store quota reject ERR_QUOTA_EXCEEDED and leave the store unchanged; ERR_STORAGE_UNAVAILABLE means no durable backing exists on this device or session. Lens Studio previews and the desktop stub persist in memory only.

Methods​

get()​
get(key): Promise<StorageGetResult>;

Reads one key. found tells a missing key apart from a stored null.

Parameters​
ParameterType
keystring
Returns​

Promise<StorageGetResult>

Example​
const result = await snapchat.storage.get('save');
const save = result.found ? result.value : { level: 1, coins: 0 };
set()​
set(key, value): Promise<void>;

Writes one key, replacing any previous value.

Parameters​
ParameterTypeDescription
keystring-
valueunknownAny JSON-serializable value.
Returns​

Promise<void>

Example​
await snapchat.storage.set('save', { level: 3, coins: 120 });
remove()​
remove(key): Promise<void>;

Idempotent: removing a missing key resolves.

Parameters​
ParameterType
keystring
Returns​

Promise<void>

Example​
await snapchat.storage.remove('save');
clear()​
clear(): Promise<void>;

Deletes this Lens's whole store for the current account.

Returns​

Promise<void>

Example​
resetButton.onclick = () => snapchat.storage.clear();
keys()​
keys(): Promise<{
keys: string[];
}>;

Stored keys in byte-lexicographic order.

Returns​

Promise<{ keys: string[]; }>

Example​
const { keys } = await snapchat.storage.keys();
const slots = keys.filter((key) => key.startsWith('slot:'));
getInfo()​
getInfo(): Promise<StorageInfo>;

Usage against the store's limits, and whether it persists across sessions.

Returns​

Promise<StorageInfo>

Example​
const { usedBytes, maxBytes, persistenceMode } =
await snapchat.storage.getInfo();
if (persistenceMode === 'memory')
console.warn('Progress will not survive a restart here');

SnapchatWebLensAPI​

The window.snapchat singleton: one include for iOS, Android, and desktop development.

Every call returns a Promise. Failures reject with an Error whose message is one of the stable codes in SnapchatWebLensAPI.errors; there is no native error text to parse. Calls never throw synchronously: a failure the API cannot classify, such as params that cannot be serialized, rejects with ERR_INTERNAL.

Methods​

init()​
init(): Promise<CapabilityMap>;

Fetches and caches the capabilities this host serves. Call once at startup, before SnapchatWebLensAPI.isSupported.

Resolves {} (nothing supported) instead of rejecting when discovery itself is unavailable: no bridge at all, or a host too old to answer sdk/getCapabilities. Genuine failures (ERR_INTERNAL, ERR_INVALID_PARAMS) still reject.

Returns​

Promise<CapabilityMap>

Example​
await snapchat.init();
leaderboardButton.hidden = !snapchat.isSupported('leaderboards');
isSupported()​
isSupported(capability, minVersion?): boolean;

Whether the host serves capability at contract version minVersion (default 1) or newer. Always false before SnapchatWebLensAPI.init resolves.

A capability's contract only grows: its version goes up when it gains actions, and a breaking change ships under a new capability name, so a minVersion check keeps working on newer hosts.

Parameters​
ParameterType
capabilityCapability
minVersion?number
Returns​

boolean

Example​
snapchat.isSupported('bitmoji'); // false: init() has not resolved yet
await snapchat.init();
snapchat.isSupported('bitmoji'); // true where the host serves bitmoji v1 or newer

Properties​

PropertyModifierTypeDescription
versionreadonlystringAPI version (semver).
errorsreadonlyWebLensAPIErrors-
isStubreadonlybooleanTrue when running against the desktop stub instead of a Snapchat host. Example // The stub's 3D avatar is an empty placeholder GLB, so show the bundled default instead. const showUserAvatar = snapchat.isSupported('bitmoji') && !snapchat.isStub;
leaderboardspublicLeaderboardsAPI-
bitmojipublicBitmojiAPI-
storagepublicStorageAPI-

Type Aliases​

WebLensAPIErrorCode​

type WebLensAPIErrorCode = WebLensAPIErrors[keyof WebLensAPIErrors];

Union of every ERR_* string in WebLensAPIErrors.


Capability​

type Capability = 'leaderboards' | 'bitmoji' | 'storage' | (string & object);

Capability names, as SnapchatWebLensAPI.init reports them and SnapchatWebLensAPI.isSupported takes them.


CapabilityMap​

type CapabilityMap = Record<string, number>;

Capability name → contract version, as resolved by SnapchatWebLensAPI.init.


StorageGetResult​

type StorageGetResult =
| {
found: true;
value: unknown;
}
| {
found: false;
};
Was this page helpful?
Yes
No