Skip to content
API Reference

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.

2 tools live3 tools in preview

Base URL for all REST endpoints:

https://www.storylenses.app/api

Authentication

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_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Usage

Include your key in the Authorization header:

Authorization: Bearer sl_live_YOUR_API_KEY

API 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-server

Set these environment variables:

STORYLENSES_API_KEY=sl_live_YOUR_API_KEY
STORYLENSES_API_URL=https://www.storylenses.app

HTTP 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_KEY

Supported Methods

The MCP endpoint supports the following JSON-RPC methods:

MethodDescription
initializeInitialize the MCP session and exchange capabilities
tools/listList all available tools and their schemas
tools/callExecute 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_jobLive

Extract 15+ structured fields from a job posting — role requirements, company challenges, culture signals, recruiter priorities

Auth: Optional (IP-limited without key)Billing: Free
ParameterTypeRequiredDescription
job_urlstringURL of the job posting to analyze
job_textstringRaw text of the job posting (use if no URL)
localestringResponse language (en, de, es, or pt) (en, de, es, pt) [default: en]
storylenses_match_profilePreview

Match a candidate profile/CV against job data — identifies fit score, matching skills, career gaps, and strongest narrative angle

Auth: API key requiredBilling: Free
ParameterTypeRequiredDescription
job_analysisobjectJob analysis output from storylenses_analyze_job
candidate_cvstringCandidate's CV or resume as plain text
localestringResponse language (en, de, es, or pt) (en, de, es, pt) [default: en]
storylenses_generate_letterPreview

Generate a story-driven cover letter using matched data and a narrative archetype. Supports en/de/es/pt.

Auth: API key requiredBilling: Billable ($0.25 overage)
ParameterTypeRequiredDescription
job_analysisobjectJob analysis from storylenses_analyze_job
match_dataobjectMatch data from storylenses_match_profile
candidate_namestringCandidate's full name for the letter greeting
archetypestringNarrative archetype ID (use storylenses_list_archetypes to see options) [default: golden-fleece]
tonestringWriting tone — professional, conversational, confident, etc. (professional, conversational, formal, confident, analytical, storytelling, humble, technical, creative) [default: professional]
lengthstringLetter length — short (150-200 words), medium (250-350), or full (400-500) (short, medium, full) [default: medium]
localestringOutput language (en, de, es, or pt) (en, de, es, pt) [default: en]
storylenses_quality_checkPreview

Score and evaluate a cover letter for relevance, narrative strength, and completeness. Returns score 0-100 with actionable feedback.

Auth: API key requiredBilling: Free
ParameterTypeRequiredDescription
letter_textstringThe cover letter text to evaluate (minimum 200 characters)
job_analysisobjectJob analysis from storylenses_analyze_job for context
localestringFeedback language (en, de, es, or pt) (en, de, es, pt) [default: en]
storylenses_list_archetypesLive

Return available narrative archetypes with descriptions so the agent or user can select a style

Auth: NoneBilling: Free
ParameterTypeRequiredDescription
localestringDescription 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.

POST/api/analyze-job-description

Extract structured fields from a job posting. Accepts either raw text or a URL.

ParameterTypeDescription
jobDescriptionstringRaw text of the job posting
jobUrlstringURL of the job posting (alternative to jobDescription)
localestringResponse language: en, de, es, or pt (default: en)
POST/api/evaluate-letter

Score and evaluate a cover letter for relevance, narrative strength, and completeness.

ParameterTypeDescription
letterTextstringThe cover letter text to evaluate (min 200 characters)
jobAnalysisobjectJob analysis from /api/analyze-job-description
localestringFeedback language: en, de, es, or pt (default: en)
GET/api/health

Health 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

CodeMeaningDescription
200OKRequest succeeded
400Bad RequestInvalid or missing parameters
401UnauthorizedMissing or invalid API key
403ForbiddenValid key but insufficient permissions or plan limit exceeded
429Too Many RequestsRate limit exceeded — retry after the indicated time
500Server ErrorInternal 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.

EndpointLimit
/api/analyze-job-description10 req/min (IP) / plan-based (API key)
/api/evaluate-letter10 req/min (IP) / plan-based (API key)
/api/mcp/endpoint30 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/100

cURL — 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.

PlanPriceGenerationsOverage
Free$010 / month
Developer$29/month200 / month$0.25
Scale$99/month1,000 / month$0.25
EnterpriseCustomUnlimitedCustom

What counts as a generation?

Only one tool is billable:

  • storylenses_generate_lettereach 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.

For technical support, email support@storylenses.app