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 Personal Access Token in your dashboard, pick a scope preset, and call any endpoint with a standard Authorization: Bearer header.
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.
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..."
# }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.
projects:readList + read project metadataprojects:writeUpdate project settingstemplates:readList + read templatesconnections:readList social/data connections (no secrets)moments:readRead detected momentsstories:readRead draft/scheduled/published storiesstories:writeCreate + edit storiesstories:publishSchedule + publish storiesmedia:readList project mediamedia:writeUpload mediawebhooks:readList webhook endpoints + deliverieswebhooks:writeCreate + manage webhook endpointsStreamable HTTP transport at https://app.storylayer.ai/api/mcp. 14 tools today, same auth as the REST API. Compatible with Claude Desktop, Claude.ai, ChatGPT custom connectors, and any spec-compliant MCP client.
# ~/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: %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
# 14 tools enabled.list_projectsEvery project the token can seelist_templatesVisual templates available to a projectlist_social_connectionsConnected channels per projectlist_momentsDetected moments awaiting reviewlist_storiesDrafts, scheduled, publishedget_storyFull story payload + variantscreate_storyDraft from template + dataschedule_storyPin a story to a specific timepublish_storyShip a story right nowlist_mediaProject asset libraryupload_media_from_urlPull a remote image into the librarylist_webhooksAll endpoints subscribed to eventscreate_webhookSubscribe a URL to eventswhoamiInspect the current token's principal + scopesBuilding 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.
# 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.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.scheduledstory.publishedstory.failedmoment.detectedmoment.auto_drafted# 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"),
);Get a token, point your AI tool at the MCP server, and start shipping posts from your data.