Developer platform — live today

Drive Storylayer from any AI agent.

Public REST API, an MCP server for Claude and ChatGPT, OAuth 2.1 with Dynamic Client Registration, and signed webhooks. Built on standards. Shipped today.

Generate a tokenMCP setup →OAuth 2.1Webhooks
REST endpoints
40+
/api/v1/*
MCP tools
38
Claude / ChatGPT / agents
Webhook events
5
HMAC-signed, retried
Auth methods
PAT · OAuth 2.1
PKCE + DCR
Quickstart

From zero to first call in two minutes.

Generate a Personal Access Token in your dashboard, pick a scope preset, and call any endpoint with a standard Authorization: Bearer header.

1. Generate a token

Visit /dashboard/developers, pick a scope preset (AI agent, read-only, publish-only), copy the token. Tokens are shown once and stored as SHA-256 hashes.

2. Make your first call
curl https://app.storylayer.ai/api/v1/health \
  -H "Authorization: Bearer sl_pat_..."

# {
#   "ok": true,
#   "user_id": "...",
#   "scopes": ["projects:read","stories:read",...],
#   "server_time": "2026-04-29T..."
# }
REST API

Same surface the dashboard uses.

Bearer-auth, JSON in / JSON out, scopes per token, every call audited (90-day retention). Project-scoped tokens are isolated to one project; account-scoped tokens see everything.

GET /api/v1/projects
List projects you own
GET /api/v1/templates
Visual templates per project
GET /api/v1/social-connections
Connected accounts (no secrets)
GET /api/v1/moments
Detected moments awaiting review
GET /api/v1/stories
Drafts, scheduled, published
POST /api/v1/stories
Create a draft story
POST /api/v1/stories/:id/schedule
Pin a publish time
POST /api/v1/stories/:id/publish
Ship now
GET /api/v1/media
Project asset library
POST /api/v1/media/from-url
Pull a remote image
GET /api/v1/webhooks
List webhook endpoints
POST /api/v1/webhooks
Subscribe a URL
Available scopes
projects:readList + read project metadata
projects:writeUpdate project settings
templates:readList + read templates
connections:readList social/data connections (no secrets)
moments:readRead detected moments
stories:readRead draft/scheduled/published stories
stories:writeCreate + edit stories
stories:publishSchedule + publish stories
media:readList project media
media:writeUpload media
webhooks:readList webhook endpoints + deliveries
webhooks:writeCreate + manage webhook endpoints
Model Context Protocol

An MCP server for AI agents.

Streamable HTTP transport at https://app.storylayer.ai/api/mcp. 38 tools, 8 MCP prompts, same auth as the REST API. Compatible with Claude Desktop, Claude.ai, ChatGPT custom connectors, Cursor, and any spec-compliant MCP client.

Claude Desktop config
macOS
# ~/Library/Application Support/Claude/
#   claude_desktop_config.json
{
  "mcpServers": {
    "storylayer": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/inspector",
        "https://app.storylayer.ai/api/mcp"
      ],
      "env": {
        "MCP_HEADERS": "Authorization: Bearer sl_pat_..."
      }
    }
  }
}
Windows / Linux
# Windows: %APPDATA%\Claude\
#   claude_desktop_config.json
# Linux:   ~/.config/Claude/
#   claude_desktop_config.json
#
# Same JSON structure as macOS. Restart
# Claude Desktop after saving.
#
# After restart:
#   Settings → Developer → MCP Servers
# should show "storylayer" with all
# 38 tools · 8 prompts enabled.
Tools available (38)
whoamiIntrospect the connected token. Returns token_scope, scopes, plan, mcp_usage quota, discovery URL…
list_projectsList Storylayer projects (id, name, industry, timezone). Use to resolve project_id from a human-p…
list_templatesList Creatomate design templates for a project. Optional content_type filter. Use when the user w…
list_social_connectionsList connected social channels for a project (instagram, facebook, x, linkedin, pinterest, ghost)…
list_pinterest_boardsList Pinterest boards for a connected Pinterest account. Returns board ids for channel_overrides.…
list_momentsList detected data moments awaiting review (status, severity filters). Use when user asks what tr…
get_bio_linkFetch the Instagram bio-link landing page config for a project (title, items, tracking).
update_bio_linkUpdate bio-link page settings (title, destination URL, active flag).
list_bio_link_itemsList items on the Instagram bio-link page.
add_bio_link_itemAdd a link item to the Instagram bio-link page.
update_bio_link_itemUpdate an existing bio-link item (label, URL, order).
remove_bio_link_itemRemove an item from the Instagram bio-link page.
list_storiesList stories (draft, scheduled, published). Filter by status, channel, limit. Includes published_…
mint_story_linksGenerate tracked short links for a story (bio-link tracker, per-slide swipe URLs). Use before pub…
get_storyFetch full story payload: variants, channel overrides, published_urls, tracked_links, permalinks.
get_slide_insightsPer-slide click and impression metrics for a published carousel or multi-slide story.
create_storyCreate a draft or scheduled story — single image/video or 2–10 slide carousel. Supports per-chann…
preview_storyResolved per-channel preview — exactly what would post to Instagram, X, LinkedIn, etc. after over…
create_stories_bulkCreate up to 50 stories in one call. Per-item failures do not block the batch. Run instagram_pref…
schedule_storySet or update publish time (UTC instant or local time + timezone). Bridges into content_queue for…
publish_storyPublish a story immediately (or at a future time). Use retry_story for failed publishes — do NOT …
retry_storyRetry a failed publish on an existing story. Prefer this over publish_story or create_story dupli…
move_storyRepair tool: re-point a story to a different project. Use when content was created under the wron…
update_story_statusChange story status (draft, archived, cancelled). Cascades to content_queue — cancelled stops sch…
retract_storyPull back a published post from platforms where supported and mark retracted in Storylayer. Use a…
update_storyUpdate a scheduled story in place (caption, hashtags, location_id, collaborators, scheduled_at). …
instagram_location_searchResolve free-text place names to Facebook Place IDs for Instagram location_id on create_story.
instagram_user_lookupVerify an Instagram handle exists and can be tagged or invited as a collaborator before create_st…
instagram_preflight_bulkOne-call pre-flight for batches: validate handles for user_tags/collaborators and resolve locatio…
list_mediaList brand assets in the project media library (images, videos).
upload_media_from_urlRegister a remote image/video URL as a brand asset without re-hosting bytes through the agent con…
upload_mediaWhole-file upload via base64 in JSON. Use for small assets when the agent payload cap fits (e.g. …
upload_media_initOpen a chunked upload session when per-call payload is capped but total budget is larger (Claude.…
upload_media_chunkAppend a base64 chunk to an upload session (~48 KB binary per call recommended).
upload_media_finalizeFinalize chunked upload — returns file_url for use in create_story slides[].
request_upload_urlMint a presigned PUT URL so bytes stream to storage via curl/shell without entering agent context…
list_webhooksList webhook endpoints subscribed to Storylayer events.
create_webhookSubscribe a URL to events (story.published, story.failed, etc.). Returns signing_secret once — st…
OAuth 2.1 + Dynamic Client Registration

One-click consent for hosted AI tools.

Building a Claude.ai connector, a ChatGPT GPT, or any hosted MCP client? Storylayer ships full OAuth 2.1 with PKCE, refresh-token rotation, RFC 7591 Dynamic Client Registration, and discoverable metadata. Your users sign in once, approve scopes, done — no token pasting.

GET /.well-known/oauth-authorization-server
RFC 8414 metadata
GET /.well-known/oauth-protected-resource
RFC 9728 metadata
GET /.well-known/ai-catalog.json
ARD agent discovery catalog
GET /.well-known/mcp.json
MCP Server Card (SEP-1649)
GET /.well-known/openapi.json
OpenAPI 3.1 REST spec
GET /.well-known/server.json
MCP Registry entry
GET /.well-known/agent-quickstart.md
Agent onboarding guide
POST /oauth/register
RFC 7591 client registration
GET /oauth/authorize
Consent screen + PKCE
POST /oauth/token
Code exchange + refresh
POST /oauth/revoke
RFC 7009 revocation
# 1. Discover
curl https://app.storylayer.ai/.well-known/oauth-authorization-server

# 2. Register (no client_secret — we issue public clients)
curl -X POST https://app.storylayer.ai/oauth/register \
  -H 'content-type: application/json' \
  -d '{
    "client_name": "Acme AI Agent",
    "redirect_uris": ["https://acme.example/oauth/callback"],
    "grant_types": ["authorization_code","refresh_token"],
    "token_endpoint_auth_method": "none",
    "scope": "stories:read stories:write moments:read"
  }'

# 3. Send your user to /oauth/authorize with PKCE.
# 4. Exchange the code at /oauth/token.
# 5. Use the access token (sl_oat_...) on /api/v1/* and /api/mcp.
Webhooks

Push events to your stack.

Subscribe a URL to story and moment events. Every delivery is signed with HMAC-SHA256 in X-Storylayer-Signature and retried with exponential backoff (1m → 5m → 15m → 1h → 4h → 12h) before being marked permanent_failure. Manage from the dashboard or via the API.

story.scheduled
A story has a confirmed publish time
story.published
A story shipped successfully
story.failed
A scheduled story errored on send
moment.detected
A detector fired against your data
moment.auto_drafted
A high-severity moment turned into a draft
# Verify signature in your webhook receiver:
const sig = req.headers["x-storylayer-signature"];
const expected = crypto
  .createHmac("sha256", SIGNING_SECRET)
  .update(rawBody)
  .digest("hex");
const ok = crypto.timingSafeEqual(
  Buffer.from(sig, "hex"),
  Buffer.from(expected, "hex"),
);
Security

Built for least privilege.

Hashed tokens
Personal Access Tokens are stored as SHA-256 hashes — the raw token is shown once, never persisted.
Scope-locked
Tokens carry a fixed scope list. publish-only tokens can't read analytics, read-only tokens can't ship posts.
Project-scoped tokens
Restrict a token to one project so an AI agent can't touch the rest of your account.
Audited every call
Method, path, status, duration, IP, and user-agent are logged for 90 days.
Rotation + revocation
Refresh tokens rotate on every exchange. Revoke any token instantly from the dashboard.
Connection secrets stay local
Instagram, Facebook, X tokens are never returned through the API — only metadata.

Ready to plug in?

Get a token, point your AI tool at the MCP server, and start shipping posts from your data.

Generate a tokenCreate an account