Web Lens API
A Web Lens can't reach the network, but it isn't cut off from Snapchat. The Web Lens API is a JavaScript package that lets your code call into the Snapchat app around it: to post scores to a leaderboard, to bring a Snapchatter's Bitmoji into the game, and to save progress between launches. The same code runs on iOS and Android. In any other browser, the API answers from a built-in stub, so you can build and debug the whole game before it reaches Snapchat.
The Web Lens API is in beta, like Web Lenses, and its interface can change before version 1.0. The API reference documents the current release.
Add the API to your Lens
Install the package:
npm install @snap/web-lens-api
With a bundler such as Vite, import it, and the bundler builds the API into your game:
import snapchat from '@snap/web-lens-api';
Without a bundler, copy dist/snap-api.js from the package into your build and include it before your own scripts. It installs the same object as window.snapchat:
<script src="./snap-api.js"></script>
Either way, the API has to ship inside the zip you upload, because the Lens's Content Security Policy blocks scripts loaded from a URL. Including it twice is safe: the second copy returns the first instance.
PlayCanvas
- Editor projects. Upload
snap-api.jsas a script asset and set its Loading Type to Before Engine, sowindow.snapchatis ready before your scripts initialize. The file is then part of every build you download, so you can zip the downloaded build without changes. Don't add the API under Settings > External Scripts: those load from a URL at runtime, which the policy blocks. - Engine-only projects. Import
@snap/web-lens-apialongsideplaycanvas, and your bundler builds it into the game.
Check what the host supports
Call init() once at startup to ask the host which capabilities it serves. Then check isSupported() before you use one:
await snapchat.init();
if (snapchat.isSupported('leaderboards')) {
await snapchat.leaderboards.submitScore({ leaderboardId: 'main', score: 42 });
}
Capabilities differ between app versions, platforms, and Lenses. Storage, for example, is available on iOS only for now. Check isSupported() rather than the platform, and keep the game playable when a capability is missing. isSupported() returns false until init() resolves.
A capability only grows. Its version goes up when it gains actions, and a breaking change ships under a new capability name, so code written for one version keeps working on newer hosts. To require a later version, pass it as the second argument, for example snapchat.isSupported('bitmoji', 2).
Handle errors
Every call returns a promise. A failed call rejects rather than throwing, with an Error whose message is one of the codes in snapchat.errors. Compare against those instead of parsing the text:
try {
await snapchat.storage.set('save', state);
} catch (e) {
if (e.message !== snapchat.errors.QUOTA_EXCEEDED) throw e;
// The store is unchanged, so the previous save is still intact.
}
| Code | Meaning |
|---|---|
ERR_UNKNOWN_CAPABILITY | This app version, platform, or Lens doesn't serve the capability. Check isSupported() first. |
ERR_INVALID_PARAMS | The capability rejected the parameters, such as a score that isn't an integer or a retired Bitmoji variant. |
ERR_INTERNAL | The capability failed inside Snapchat. There's nothing to parse or retry, so fall back. |
ERR_QUOTA_EXCEEDED | A storage write would exceed the store's limits. The store keeps its previous contents. |
ERR_STORAGE_UNAVAILABLE | Storage has no durable backing on this device or in this session. |
ERR_UNSUPPORTED_HOST | The page runs inside Snapchat, but this app version can't serve the API. Every call rejects with this code, so hide the features that need it. |
ERR_MALFORMED_REQUEST | The request failed validation. That's a bug in the API, so report it. |
Develop in a desktop browser
Outside Snapchat, the API answers every call from a built-in stub with canned data. That covers your desktop browser's developer tools, a local development server, the PlayCanvas Editor's Launch page, and the browser on your phone. snapchat.isStub is true, and the stub logs a console warning, so a stubbed run is never mistaken for a live one.
The stub rejects bad parameters with the same codes Snapchat returns, and echoes the scores you submit, so parameter mistakes show up on the desktop. It can't reproduce what depends on the player or the device:
- A player without a Bitmoji, or a media URL that has expired.
ERR_INTERNALfailures.- Storage that survives a restart. The stub keeps storage in memory.
- A real 3D avatar. The stub's model is an empty placeholder.
Those cases only occur inside Snapchat, where a Lens can't run until it passes review, so build a fallback for each one rather than waiting to see it.
The stub never runs inside Snapchat. On an app version that can't serve the API, init() resolves with no capabilities and every call rejects with ERR_UNSUPPORTED_HOST, so a game that checks isSupported() hides the feature.
Capabilities
- Leaderboards: submit scores and open the Lens's leaderboard.
- Bitmoji: bring the player's Bitmoji into the game as a 3D character or an image.
- Storage: save progress and settings between launches.
The API reference lists every method, type, and error code. If your game needs a Snapchat feature that isn't here, tell Snap through the feedback channels so it can inform the roadmap.