StoryLenses API Documentation
StoryLenses provides AI-powered cover letter generation through 5 composable MCP tools and REST endpoints. Build career agents, job application bots, or integrate story-driven cover letters into your platform.
Base URL for all REST endpoints:
https://www.storylenses.app/apiAuthentication
All authenticated requests use Bearer token authentication with a StoryLenses API key. Some endpoints (like job analysis) work without a key but with stricter rate limits.
Key Format
API keys use the sl_live_ prefix followed by 32 alphanumeric characters:
sl_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxUsage
Include your key in the Authorization header:
Authorization: Bearer sl_live_YOUR_API_KEYAPI keys are hashed before storage and can only be viewed once at creation. If you lose your key, create a new one from the Developer Portal.
Get your API key from the Developer Portal
Quickstart
Get started in under 2 minutes. Pick your client and paste the config.
Claude Desktop
Add to your Claude Desktop MCP configuration:
{
"mcpServers": {
"storylenses": {
"url": "https://mcp.storylenses.app/sse",
"headers": {
"Authorization": "Bearer sl_live_YOUR_API_KEY"
}
}
}
}Cursor / VS Code
Add to your Cursor or VS Code MCP settings:
{
"mcp": {
"servers": {
"storylenses": {
"url": "https://mcp.storylenses.app/sse",
"headers": {
"Authorization": "Bearer sl_live_YOUR_API_KEY"
}
}
}
}
}cURL
Test the API directly with cURL:
curl -X POST https://www.storylenses.app/api/analyze-job-description \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sl_live_YOUR_API_KEY" \
-d '{
"jobDescription": "Senior Frontend Engineer at Stripe...",
"locale": "en"
}'MCP Integration
StoryLenses supports both Stdio and HTTP transports for MCP clients. Use whichever fits your architecture.
Stdio Transport (npm)
Install and run via npx — ideal for local agents and CLI tools:
npx -y @storylenses/mcp-serverSet these environment variables:
STORYLENSES_API_KEY=sl_live_YOUR_API_KEY
STORYLENSES_API_URL=https://www.storylenses.appHTTP Transport (Streamable HTTP)
Send JSON-RPC 2.0 requests directly — ideal for cloud-hosted agents and server-side integrations:
POST https://www.storylenses.app/api/mcp/endpoint
Content-Type: application/json
Authorization: Bearer sl_live_YOUR_API_KEYSupported Methods
The MCP endpoint supports the following JSON-RPC methods:
| Method | Description |
|---|---|
initialize | Initialize the MCP session and exchange capabilities |
tools/list | List all available tools and their schemas |
tools/call | Execute a tool with the given arguments |
Tools Reference
All 5 tools available through the MCP protocol. Parameter schemas are pulled directly from the tool definitions.
StoryLenses API is in active development. 2 of 5 tools are fully live. The remaining 3 return realistic sample data so you can build your integration now — they will work end-to-end when the full API launches.
storylenses_analyze_jobLiveExtract 15+ structured fields from a job posting — role requirements, company challenges, culture signals, recruiter priorities
| Parameter | Type | Required | Description |
|---|---|---|---|
job_url | string | — | URL of the job posting to analyze |
job_text | string | — | Raw text of the job posting (use if no URL) |
locale | string | — | Response language (en, de, es, or pt) (en, de, es, pt) [default: en] |
storylenses_match_profilePreviewMatch a candidate profile/CV against job data — identifies fit score, matching skills, career gaps, and strongest narrative angle
| Parameter | Type | Required | Description |
|---|---|---|---|
job_analysis | object | ✓ | Job analysis output from storylenses_analyze_job |
candidate_cv | string | ✓ | Candidate's CV or resume as plain text |
locale | string | — | Response language (en, de, es, or pt) (en, de, es, pt) [default: en] |
storylenses_generate_letterPreviewGenerate a story-driven cover letter using matched data and a narrative archetype. Supports en/de/es/pt.
| Parameter | Type | Required | Description |
|---|---|---|---|
job_analysis | object | ✓ | Job analysis from storylenses_analyze_job |
match_data | object | ✓ | Match data from storylenses_match_profile |
candidate_name | string | ✓ | Candidate's full name for the letter greeting |
archetype | string | — | Narrative archetype ID (use storylenses_list_archetypes to see options) [default: golden-fleece] |
tone | string | — | Writing tone — professional, conversational, confident, etc. (professional, conversational, formal, confident, analytical, storytelling, humble, technical, creative) [default: professional] |
length | string | — | Letter length — short (150-200 words), medium (250-350), or full (400-500) (short, medium, full) [default: medium] |
locale | string | — | Output language (en, de, es, or pt) (en, de, es, pt) [default: en] |
storylenses_quality_checkPreviewScore and evaluate a cover letter for relevance, narrative strength, and completeness. Returns score 0-100 with actionable feedback.
| Parameter | Type | Required | Description |
|---|---|---|---|
letter_text | string | ✓ | The cover letter text to evaluate (minimum 200 characters) |
job_analysis | object | ✓ | Job analysis from storylenses_analyze_job for context |
locale | string | — | Feedback language (en, de, es, or pt) (en, de, es, pt) [default: en] |
storylenses_list_archetypesLiveReturn available narrative archetypes with descriptions so the agent or user can select a style
| Parameter | Type | Required | Description |
|---|---|---|---|
locale | string | — | Description language (en, de, es, or pt) (en, de, es, pt) [default: en] |
REST API
Direct HTTP endpoints for when you don't need the full MCP protocol. Same underlying logic as the MCP tools.
/api/analyze-job-descriptionExtract structured fields from a job posting. Accepts either raw text or a URL.
| Parameter | Type | Description |
|---|---|---|
jobDescription | string | Raw text of the job posting |
jobUrl | string | URL of the job posting (alternative to jobDescription) |
locale | string | Response language: en, de, es, or pt (default: en) |
/api/evaluate-letterScore and evaluate a cover letter for relevance, narrative strength, and completeness.
| Parameter | Type | Description |
|---|---|---|
letterText | string | The cover letter text to evaluate (min 200 characters) |
jobAnalysis | object | Job analysis from /api/analyze-job-description |
locale | string | Feedback language: en, de, es, or pt (default: en) |
/api/healthHealth check endpoint. Returns status object — no authentication required.
{ "status": "ok" }Errors & Rate Limits
All errors follow a consistent format. Rate limits are applied per IP for unauthenticated requests and per API key for authenticated requests.
HTTP Status Codes
| Code | Meaning | Description |
|---|---|---|
200 | OK | Request succeeded |
400 | Bad Request | Invalid or missing parameters |
401 | Unauthorized | Missing or invalid API key |
403 | Forbidden | Valid key but insufficient permissions or plan limit exceeded |
429 | Too Many Requests | Rate limit exceeded — retry after the indicated time |
500 | Server Error | Internal error — contact support if persistent |
Error Response Format
{
"error": "Human-readable error message"
}Rate Limits
Rate limits vary by endpoint and authentication method. API key users get higher limits based on their plan.
| Endpoint | Limit |
|---|---|
/api/analyze-job-description | 10 req/min (IP) / plan-based (API key) |
/api/evaluate-letter | 10 req/min (IP) / plan-based (API key) |
/api/mcp/endpoint | 30 req/min (IP) |
Code Examples
Complete, copy-pasteable examples for common integration patterns.
TypeScript — Full MCP Workflow
End-to-end cover letter generation using the MCP SDK:
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
// Connect to StoryLenses MCP
const transport = new SSEClientTransport(
new URL("https://mcp.storylenses.app/sse"),
{ requestInit: { headers: { Authorization: "Bearer sl_live_YOUR_API_KEY" } } }
);
const client = new Client({ name: "my-agent", version: "1.0" });
await client.connect(transport);
// 1. Analyze the job posting
const jobResult = await client.callTool({
name: "storylenses_analyze_job",
arguments: { job_url: "https://linkedin.com/jobs/view/12345" }
});
const jobAnalysis = JSON.parse(jobResult.content[0].text);
// 2. Match candidate profile
const matchResult = await client.callTool({
name: "storylenses_match_profile",
arguments: {
job_analysis: jobAnalysis,
candidate_cv: "Jane Doe — 8 years frontend, React, TypeScript..."
}
});
const matchData = JSON.parse(matchResult.content[0].text);
// 3. Generate cover letter
const letterResult = await client.callTool({
name: "storylenses_generate_letter",
arguments: {
job_analysis: jobAnalysis,
match_data: matchData,
candidate_name: "Jane Doe",
archetype: matchData.suggested_archetype || "golden-fleece",
tone: "professional",
length: "medium"
}
});
const letter = JSON.parse(letterResult.content[0].text);
// 4. Quality check
const scoreResult = await client.callTool({
name: "storylenses_quality_check",
arguments: {
letter_text: letter.letter_text,
job_analysis: jobAnalysis
}
});
const score = JSON.parse(scoreResult.content[0].text);
console.log(letter.letter_text); // Story-driven cover letter
console.log(score.overall_score); // 87/100cURL — JSON-RPC Requests
Initialize, list tools, and call a tool via the HTTP endpoint:
# Initialize MCP session
curl -X POST https://www.storylenses.app/api/mcp/endpoint \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sl_live_YOUR_API_KEY" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": { "name": "my-agent", "version": "1.0" }
}
}'
# List available tools
curl -X POST https://www.storylenses.app/api/mcp/endpoint \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sl_live_YOUR_API_KEY" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list"
}'
# Call a tool
curl -X POST https://www.storylenses.app/api/mcp/endpoint \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sl_live_YOUR_API_KEY" \
-d '{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "storylenses_analyze_job",
"arguments": {
"job_url": "https://linkedin.com/jobs/view/12345",
"locale": "en"
}
}
}'Python — REST API
Using httpx to call the REST endpoints directly:
import httpx
API_KEY = "sl_live_YOUR_API_KEY"
BASE = "https://www.storylenses.app/api"
# Analyze a job posting
resp = httpx.post(
f"{BASE}/analyze-job-description",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"jobDescription": "Senior Engineer at Acme...", "locale": "en"}
)
job = resp.json()
# Evaluate a cover letter
resp = httpx.post(
f"{BASE}/evaluate-letter",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"letterText": "Dear Hiring Manager, ...",
"jobAnalysis": job,
"locale": "en"
}
)
score = resp.json()
print(f"Score: {score['overall_score']}/100")Plans & Billing
All plans include access to all 5 tools in all 4 languages. Only cover letter generation counts toward your usage limit.
| Plan | Price | Generations | Overage |
|---|---|---|---|
| Free | $0 | 10 / month | — |
| Developer | $29/month | 200 / month | $0.25 |
| Scale | $99/month | 1,000 / month | $0.25 |
| Enterprise | Custom | Unlimited | Custom |
What counts as a generation?
Only one tool is billable:
storylenses_generate_letter— each call counts as 1 generation- All other tools (analyze, match, quality check, list archetypes) are free and unlimited
Support
Need help integrating? Here are the best places to start.
Developer Portal
Create and manage API keys, view usage analytics
MCP Overview
Marketing overview, quickstart guides, pricing details
Partners
Partnership opportunities and B2B integrations
For technical support, email support@storylenses.app