Upgrading from v1.0 to v2.0
This guide covers the breaking changes between snap spec v1.0 and v2.0, and what you need to update in your snap server.
Version field
Change the version field in your snap response from "1.0" to "2.0":
{
"version": "2.0",
"theme": { "accent": "purple" },
"ui": { ... }
}
Authentication changes
The POST payload shape has changed. v2 adds audience, user, and surface, and
removes button_index.
Removed: button_index
The button_index field is no longer included in POST payloads. If your server reads
ctx.action.button_index, remove that code. Instead, use distinct submit target URLs
for each button to distinguish which button was pressed:
// Before (v1): read button_index
const idx = ctx.action.button_index;
// After (v2): use the request URL to distinguish buttons
const url = new URL(ctx.request.url);
const action = url.searchParams.get("action"); // e.g. ?action=vote or ?action=skip
Added: audience, user, and surface
Every v2 POST payload includes audience (server origin), user, and surface. The
top-level fid field is deprecated in favor of user.fid but is still temporarily
necessary with the same value during a migration phase.
If you use @farcaster/snap-hono, these fields are validated automatically by
parseRequest. No code changes needed on your end — just upgrade the package.
If you handle verification manually, you MUST:
- Verify
audiencematches your server's origin - Reject requests with timestamps outside your allowed skew (default 5 minutes)
Prefer reading ctx.action.user.fid in new code; ctx.action.fid remains for
compatibility.
See Authentication and Surfaces for the full spec.
Structural constraints (new)
v2 enforces structural limits on your snap's UI tree to prevent endlessly tall or complex snaps:
| Constraint | Limit |
|---|---|
| Total elements | Max 64 in ui.elements |
| Root children | Max 7 on the root element |
| Children per container | Max 6 per stack or item_group |
| Nesting depth | Max 4 levels from root to deepest leaf |
Snaps that exceed these limits will fail validation and not render. If your v1 snap has large or deeply nested UIs, you may need to restructure.
See Constraints for the full list.
Client upgrade required
Farcaster clients must be updated to send audience, user, and surface in every
POST payload. v2 snap servers will reject requests that omit these fields. See the
Client Upgrade Guide for the full payload format and fallback
behavior for older servers.
Package updates
Update your dependencies to the latest versions:
pnpm update @farcaster/snap @farcaster/snap-hono
The latest @farcaster/snap-hono handles all v2 changes automatically — parseRequest
validates the POST payload, and the response validator enforces structural constraints.
Testing
Use the Emulator to test your upgraded snap. The emulator supports both v1 and v2 snaps and will show validation errors if your snap violates any v2 constraints.
Checklist
- Set
versionto"2.0"in your snap response - Remove any code that reads
button_index - Use distinct submit target URLs to distinguish buttons
- Verify your UI tree fits within structural constraints
- Update
@farcaster/snapand@farcaster/snap-honopackages - Ensure your Farcaster client sends
audience,user, andsurfacein POST payloads (details) - Test in the emulator