Next.js route handler
Thesyncsnap package exports createRouteHandler from syncsnap/next. It returns GET and POST handlers that implement the endpoints the React SDK expects (create job, get job, wait for completion, get download URL), so you can wire SyncSnap with one file.
Setup
Create this file in your Next.js App Router app:app/api/syncsnap/[...syncsnap]/route.ts
SYNCSNAP_TOKEN is set in your environment.
Routes implemented
The catch-all segment[...syncsnap] is resolved to path segments. The handler maps them as follows:
| Request | Path segments | Action |
|---|---|---|
POST /api/syncsnap/job | ["job"] | Create job → client.createJob(), return JSON. |
GET /api/syncsnap/job/:id | ["job", id] | Get job → client.getJob(id), return JSON. |
GET /api/syncsnap/job/:id/wait | ["job", id, "wait"] | Wait for completion → client.waitForJobCompletion(id) (with optional timeoutMs, intervalMs query params), then return { job, result? }. The result is what your onCompleted callback returned, or the presigned URL when no callback. |
GET /api/syncsnap/job/:id/download | ["job", id, "download"] | Get download URL → client.getDownloadUrl(id, { expirationMinutes }), return JSON (and optionally completedPayload when onCompleted is set). |
404 with { error: "Not found" }.
onCompleted callback
When you passonCompleted to createRouteHandler, it is called when a job completes (in the wait handler) or when the download endpoint is used. Its return value is sent to the client: in the wait flow it becomes the result in onCompleted(job, result); in the download response it is included as completedPayload. Use it to return a custom payload (e.g. { downloadUrl, fileName }) instead of exposing the raw presigned URL.
Wait endpoint query params
The wait route accepts:timeoutMs— Max time to wait (ms). Default from client is 120000.intervalMs— Poll interval (ms). Default from client is 2000.
Download URL expiration
The download endpoint reads theexpiration query parameter (in minutes) and passes it to getDownloadUrl:
Using a different base path
If you want the API under a different prefix (e.g./api/transfer), move the route folder:
app/api/transfer/[...syncsnap]/route.ts— same code; routes becomePOST /api/transfer/job,GET /api/transfer/job/:id,GET /api/transfer/job/:id/wait,GET /api/transfer/job/:id/download.