Base URL
Authentication
All API requests (except public OAuth callbacks and webhooks) require anAuthorization header:
sp_live_...) for server-to-server use and Supabase JWTs issued to browser sessions. See Authentication for details.
Response format
Every response uses a consistent JSON shape. Success — the data directly (or a domain-specific envelope):success: false plus a human-readable message:
Pagination
Paginated list endpoints use a Stripe-style contract:limit: number of records to return, default15, max100starting_after: fetch the next page after the given object IDending_before: fetch the previous page before the given object ID
/assets, /products, /team/members, and /invites.
Status codes
| Code | Meaning |
|---|---|
| 200 | Success |
| 202 | Accepted — async job queued, poll /jobs/:id for result |
| 400 | Bad request — the message field explains what |
| 401 | Missing or invalid credentials |
| 403 | Authenticated but not authorized for this resource |
| 404 | Not found |
| 429 | Rate limit exceeded — see Retry-After header |
| 500 | Internal server error |
| 502 | Upstream provider error (FAL, Higgsfield, TikTok, etc.) |
Rate limits
Limits are per-team, bucketed by endpoint tier:| Tier | Limit | Endpoints |
|---|---|---|
| Expensive | 30 / minute | /generate/slides, /generate/image, /render, /stores/:id/sync |
| Mutating | 120 / minute | All POST / PATCH / DELETE writes |
| Read | 600 / minute | All GET requests (including /jobs/:id polling) |
429 with a Retry-After header.
Async jobs
Expensive generation endpoints (/generate/image and /render) are always async. They return 202 Accepted with a jobId immediately — clients then poll GET /jobs/:id for the result. This avoids long-running HTTP requests and stays within Cloudflare Worker CPU limits.
pending → processing → completed | failed.
The work runs on Cloudflare Queues with automatic retries and a dead-letter queue for failed messages.
Endpoints
Generation
| Method | Path | Description |
|---|---|---|
| POST | /generate/slides | AI-generate a multi-slide carousel |
| POST | /generate/image | Generate a single image (always async, returns jobId) |
| GET | /models | List available image generation models |
Rendering
| Method | Path | Description |
|---|---|---|
| POST | /render | Render slides to PNG via Satori + Resvg (always async, returns jobId) |
Jobs (async polling)
| Method | Path | Description |
|---|---|---|
| GET | /jobs | List recent jobs for the team |
| GET | /jobs/:id | Get a single job’s status and result |
Projects
| Method | Path | Description |
|---|---|---|
| GET | /projects | List projects |
| GET | /projects/:id | Get a project |
| POST | /projects | Create or update a project |
| DELETE | /projects/:id | Delete a project |
Scheduling
| Method | Path | Description |
|---|---|---|
| GET | /schedule/posts | List scheduled posts |
| POST | /schedule/posts | Create a scheduled post |
| PATCH | /schedule/posts/:id | Update / reschedule a post |
| DELETE | /schedule/posts/:id | Delete a scheduled post |
Publishing
| Method | Path | Description |
|---|---|---|
| POST | /publish/tiktok | Publish to TikTok drafts |
Influencers
| Method | Path | Description |
|---|---|---|
| GET | /influencers | List influencers |
| POST | /influencers | Create an influencer |
| PATCH | /influencers/:id | Update an influencer |
| DELETE | /influencers/:id | Delete an influencer |
Products
| Method | Path | Description |
|---|---|---|
| GET | /products | List products |
| GET | /products/:id | Get a product |
| POST | /products | Create a product |
| PATCH | /products/:id | Update a product |
| DELETE | /products/:id | Delete a product |
Stores (Shopify / Etsy)
| Method | Path | Description |
|---|---|---|
| GET | /stores | List connected stores |
| POST | /stores | Connect a new store (auto-syncs products) |
| DELETE | /stores/:id | Disconnect a store and delete its products |
| POST | /stores/:id/sync | Re-sync products from the store |
Assets / library
| Method | Path | Description |
|---|---|---|
| GET | /assets | List uploaded + generated assets |
| POST | /upload | Upload a file to the library |
| POST | /upload/presign | Get a presigned R2 upload URL |
| POST | /assets/bulk/delete | Delete assets in batches |
| DELETE | /assets/:id | Delete an asset |
| POST | /assets/delete | Delete an asset by URL |
Team
| Method | Path | Description |
|---|---|---|
| GET | /team/members | List team members |
| GET | /invites | List pending invites |
Social accounts
| Method | Path | Description |
|---|---|---|
| GET | /social/accounts | List connected social accounts |
| GET | /auth/tiktok | Start TikTok OAuth flow |
| POST | /auth/tiktok/disconnect | Disconnect a TikTok account |
| GET | /auth/instagram | Start Instagram OAuth flow |
| GET | /auth/shopify | Start Shopify OAuth flow |
API keys
| Method | Path | Description |
|---|---|---|
| GET | /keys | List API keys for the team |
| POST | /keys | Create a new API key |
| DELETE | /keys/:id | Delete an API key |