Snapchat
Publish Stories, Saved Stories and Spotlight videos to a Snapchat Public Profile with the Zernio API, once your account is approved for the closed beta.
Publish Stories, Saved Stories and Spotlight videos to Snapchat with POST /v1/posts and platform: "snapchat". Snapchat is in closed beta, so new connections need approval before anything on this page works.
Quick reference
| Property | Value |
|---|---|
| Title limit | 45 characters (Saved Stories) |
| Description limit | 160 characters (Spotlight, including hashtags) |
| Media per post | 1 (a single image or video) |
| Image formats | JPEG, PNG |
| Image max size | 20 MB |
| Video format | MP4 only |
| Video max size | 500 MB |
| Video duration | 5 to 60 seconds |
| Post types | Story, Saved Story, Spotlight |
| Scheduling | Yes |
| Inbox | No |
| Analytics | Yes (views, unique viewers, shares) |
Before you start
Snapchat requires a Public Profile (Person, Business or Official); a regular Snapchat account cannot publish through the API. Every post carries exactly 1 image or video: there are no text-only posts, no carousels and no albums, and 9:16 vertical media is expected. Zernio encrypts each file with AES-256-CBC before uploading it to Snapchat, so nothing changes on your side.
Snapchat is in closed beta. GET /v1/connect/snapchat returns 403 with code PLATFORM_BETA_RESTRICTED for any account that is not on the beta allowlist, and there is no public release date yet. Everything on this page applies once your account is approved.
Connect
Call GET /v1/connect/snapchat with profileId on Get OAuth connect URL. After the user authorizes, they pick which Public Profile to connect, so Snapchat is one of the platforms requiring secondary selection: in standard mode Zernio hosts that screen, in headless mode you build it. The connecting accounts guide covers the OAuth flow and scopes in general.
import Zernio from '@zernio/node';
const zernio = new Zernio();
const { data: connect } = await zernio.connect.getConnectUrl({
path: { platform: 'snapchat' },
query: { profileId: '66a1f0c2a4b9d3e8f1a2b3c4', redirect_url: 'https://myapp.com/callback' }
});
// Send the user's browser to connect.authUrlResponse (200):
{
"authUrl": "https://accounts.snapchat.com/accounts/oauth2/auth?client_id=...",
"state": "..."
}In standard mode the user picks a Public Profile on Zernio's screen and lands on your redirect_url with the connection details appended.
OAuth scopes
The consent screen asks for 1 scope:
| Scope | What it enables |
|---|---|
snapchat-profile-api | Manage the connected Public Profile: publish to Spotlight and Stories, read profile data and analytics |
Headless mode
Add headless=true to the connect call to show your own Public Profile picker. After OAuth the user lands on your redirect_url with these query parameters:
tempToken: temporary Snapchat access tokenuserProfile: URL-encoded JSON with the user's infopublicProfiles: URL-encoded JSON array of the available Public Profilesconnect_token: short-lived token that authenticates the 2 calls belowplatform=snapchatandstep=select_public_profile
List the Public Profiles with List Snapchat profiles, passing connect_token in the X-Connect-Token header:
const { data: profiles } = await zernio.connect.snapchat.listSnapchatProfiles({
headers: { 'X-Connect-Token': connectToken },
query: { profileId: '66a1f0c2a4b9d3e8f1a2b3c4', tempToken }
});
console.log(profiles.publicProfiles);Response (200):
{
"publicProfiles": [
{
"id": "abc123-def456",
"display_name": "My Brand",
"username": "mybrand",
"profile_image_url": "https://cf-st.sc-cdn.net/...",
"subscriber_count": 15000
},
{
"id": "xyz789-uvw012",
"display_name": "Side Project",
"username": "sideproject",
"profile_image_url": "https://cf-st.sc-cdn.net/...",
"subscriber_count": 5000
}
]
}Connect the chosen profile with Select Snapchat profile:
const { data: selected } = await zernio.connect.snapchat.selectSnapchatProfile({
headers: { 'X-Connect-Token': connectToken },
body: {
profileId: '66a1f0c2a4b9d3e8f1a2b3c4',
selectedPublicProfile: {
id: 'abc123-def456',
display_name: 'My Brand',
username: 'mybrand'
},
tempToken,
userProfile
}
});
console.log(selected.account.accountId);Response (200):
{
"message": "Snapchat connected successfully with public profile",
"account": {
"accountId": "66b2e19d8c3f5a7e9d0b1c2d",
"platform": "snapchat",
"username": "mybrand",
"displayName": "My Brand",
"profilePicture": "https://cf-st.sc-cdn.net/...",
"isActive": true,
"publicProfileName": "My Brand"
}
}account.accountId is the accountId for every call below.
Publish
A plain post becomes a Story: contentType defaults to "story". Set it to "saved_story" or "spotlight" for the other 2 types.
contentType | What it publishes | Lifetime | Text |
|---|---|---|---|
story | A snap in the profile's Story | 24 hours | No caption |
saved_story | A permanent story on the Public Profile | Permanent | content is the title, max 45 characters |
spotlight | A video in Snapchat's Spotlight feed | Permanent | content is the description, max 160 characters, hashtags allowed |
Story
A Story is visible for 24 hours and carries no caption, so content is not used:
const { data: published } = await zernio.posts.createPost({
body: {
mediaItems: [
{ type: 'video', url: 'https://cdn.example.com/backstage.mp4' }
],
platforms: [
{
platform: 'snapchat',
accountId: '66b2e19d8c3f5a7e9d0b1c2d',
platformSpecificData: { contentType: 'story' }
}
],
publishNow: true
}
});
console.log(published.post.status);Response (201):
{
"post": {
"_id": "65f1c0a9e2b5af0012ab34cd",
"status": "published",
"platforms": [
{
"platform": "snapchat",
"status": "published"
}
]
}
}Every sample below changes only the content or the platforms entry of this request. An image works the same way with { "type": "image", "url": "https://cdn.example.com/backstage.jpg" }.
Saved Story
A Saved Story stays on the Public Profile. content becomes its title, at most 45 characters:
{
"content": "Behind the scenes",
"platforms": [
{
"platform": "snapchat",
"accountId": "66b2e19d8c3f5a7e9d0b1c2d",
"platformSpecificData": { "contentType": "saved_story" }
}
]
}Spotlight
Spotlight is Snapchat's public video feed and takes video only. content becomes the description, at most 160 characters including hashtags:
{
"content": "Sunset over the pier #sunset #nature",
"platforms": [
{
"platform": "snapchat",
"accountId": "66b2e19d8c3f5a7e9d0b1c2d",
"platformSpecificData": { "contentType": "spotlight" }
}
]
}Platform fields
All fields go in platformSpecificData on the Snapchat entry.
| Field | Type | Default | Description |
|---|---|---|---|
contentType | "story", "saved_story", "spotlight" | "story" | Where the media publishes. See Publish. |
Media requirements
Every post needs exactly 1 media item; a video outside these limits is rejected rather than compressed.
Images
| Property | Requirement |
|---|---|
| Formats | JPEG, PNG |
| Max file size | 20 MB |
| Recommended dimensions | 1080 x 1920 px |
| Aspect ratio | 9:16 (portrait) |
Videos
| Property | Requirement |
|---|---|
| Format | MP4 |
| Max file size | 500 MB |
| Duration | 5 to 60 seconds |
| Min resolution | 540 x 960 px |
| Recommended dimensions | 1080 x 1920 px |
| Aspect ratio | 9:16 (portrait) |
Zernio encrypts the file with AES-256-CBC before uploading it to Snapchat. Upload files through the media endpoint to get a URL that qualifies.
Analytics
Call GET /v1/analytics?platform=snapchat (Analytics API). Metrics are fetched per content type (story, saved_story, spotlight), and 3 of them come back: views, reach, which is Snapchat's unique viewer count, and shares. likes, comments and saves read 0, because Snapchat has none of them, and its screenshot count and completion rate stop at Snapchat rather than reaching this response.
const { data: analytics } = await zernio.analytics.getAnalytics({
query: { platform: 'snapchat', fromDate: '2026-08-01', toDate: '2026-08-31' }
});
console.log(analytics.posts);Response (200), one entry per post:
{
"posts": [
{
"_id": "65f1c0a9e2b5af0012ab34cd",
"platform": "snapchat",
"status": "published",
"publishedAt": "2026-08-14T10:00:05Z",
"analytics": {
"views": 15420,
"reach": 12350,
"shares": 45
}
}
]
}Inbox
Snapchat has no inbox: its messaging API is closed to third-party apps, so there are no DMs, and snap comments are not accessible through the API.
What you cannot do
Snapchat's API does not expose:
- AR lenses or filters
- Ads
- Snap Map
- Snapchat sounds
- Collaborative stories
- Friends' stories
- DMs or comments
- Text-only posts (media is required)
- More than 1 media item per post
Common errors
| Error | Cause | Fix |
|---|---|---|
403 with code PLATFORM_BETA_RESTRICTED | The account is not on the closed-beta allowlist | Ask for beta access; there is no public release date. |
| "Public Profile required" | The Snapchat account has no Public Profile | Create a Public Profile (Person, Business or Official) and select it during connection. |
| "Media is required" | The post has no media | Add an image or video. Snapchat has no text-only posts. |
| "Only one media item supported" | The post has more than 1 media item | Send a single image or video. |
| Video rejected | The video breaks a Snapchat requirement | Check duration (5 to 60 seconds), format (MP4 only), minimum resolution (540 x 960 px) and size (under 500 MB). |
| "Title too long" (Saved Stories) | content is over 45 characters | Shorten content to 45 characters or fewer. |
| "Description too long" (Spotlight) | content is over 160 characters | Shorten content to 160 characters or fewer, hashtags included. |
While the account is not approved, the connect call fails before any OAuth screen appears:
{
"error": "Snapchat is in closed beta. New connections require approval.",
"type": "permission_error",
"code": "PLATFORM_BETA_RESTRICTED"
}Branch on code, never on error. Request access for your account and retry the same call once it is approved; nothing else on the request needs to change. Error handling covers the envelope.
Related
- Connecting accounts: the OAuth flow and the Public Profile selection step.
- Create post: every field of the request.
- Media uploads: upload images and videos instead of hosting them.
- Analytics: post performance metrics.
- Pricing: what a connected account and analytics cost.
Fields, Media & Limits
Every platformSpecificData field for a Google Business Profile post, the image requirements, what Google's API does not expose, and common errors with their fixes.
Send template messages, broadcasts, flows and replies from a WhatsApp Business Account with the Zernio API, plus groups, calling and Click-to-WhatsApp attribution.