API Documentation

Getting Started

The dr.eamer.dev API provides unified access to 13 LLM providers, 17 data sources, corpus linguistics, etymology, clinical reference data, 123+ data visualizations, multi-agent orchestration, and utility functions through a single REST API.

Base URL

https://api.dr.eamer.dev/v1
Rate Limit: 10,000 requests/day Resets at midnight UTC. Monitor via X-RateLimit headers.

Authentication

All API endpoints require authentication using one of three methods:

Method 1: X-API-Key Header (Recommended)

X-API-Key: your_api_key_here

Method 2: Authorization Bearer Token

Authorization: Bearer your_api_key_here

Method 3: Query Parameter

?api_key=your_api_key_here

Response headers include rate limit information:

X-RateLimit-Limit: 10000
X-RateLimit-Remaining: 9847
X-RateLimit-Reset: 1640995200

API Map

Visual overview of all available API endpoint trees. Click on any section in the sidebar to jump to full documentation.

graph LR
    API["api.dr.eamer.dev/v1"] --> AAC["/aac"]
    API --> Clinical["/clinical"]
    API --> Corpus["/corpus"]
    API --> Data["/data"]
    API --> DataVis["/datavis"]
    API --> Etymology["/etymology"]
    API --> SmartTemplates["/generate"]
    API --> Silly["/generators"]
    API --> Linguistics["/linguistics"]
    API --> LLM["/llm"]
    API --> Orchestrate["/orchestrate"]
    API --> Swarm["/swarm"]
    API --> Trove["/trove"]
    API --> Utils["/utils"]
    API --> Screenshot["/screenshot"]
    API --> Capabilities["/capabilities"]

    AAC --> AAC1["/symbols/search"]
    AAC --> AAC2["/symbols/arasaac"]
    AAC --> AAC3["/sentence"]

    Clinical --> CL1["/conditions"]
    Clinical --> CL2["/conditions/:id"]
    Clinical --> CL3["/search"]

    Corpus --> CO1["/search"]
    Corpus --> CO2["/collocations"]
    Corpus --> CO3["/frequency"]

    Data --> D1["/sources"]
    Data --> D2["/:source/search"]
    Data --> D3["/:source/get/:id"]

    DataVis --> DV1["/list"]
    DataVis --> DV2["/categories"]
    DataVis --> DV3["/proxy/:source"]

    Etymology --> ET1["/explore/:word"]
    Etymology --> ET2["/health"]

    SmartTemplates --> G1["/alt-text"]
    SmartTemplates --> G2["/story"]
    SmartTemplates --> G3["/lesson-plan"]
    SmartTemplates --> G4["/business-plan"]
    SmartTemplates --> G5["/resume"]
    SmartTemplates --> G6["/itinerary"]

    Silly --> GN1["/:type/random"]
    Silly --> GN2["/:type/multiple/:count"]

    Linguistics --> LI1["/languages"]
    Linguistics --> LI2["/languages/:code"]
    Linguistics --> LI3["/phonemes"]
    Linguistics --> LI4["/features"]
    Linguistics --> LI5["/search"]

    LLM --> LL1["/chat"]
    LLM --> LL2["/vision"]
    LLM --> LL3["/embed"]
    LLM --> LL4["/speech"]
    LLM --> LL5["/models"]

    Orchestrate --> OR1["/dream-cascade"]
    Orchestrate --> OR2["/dream-swarm"]

    Swarm --> SW1["/hive"]
    Swarm --> SW2["/chat"]
    Swarm --> SW3["/health"]

    Trove --> TR1["/:category"]
    Trove --> TR2["/:category/:dataset"]

    Utils --> UT1["/images/resize"]
    Utils --> UT2["/images/convert"]
    Utils --> UT3["/pdf/extract"]
    Utils --> UT4["/tts"]
    Utils --> UT5["/convert"]
    Utils --> UT6["/news/*"]
    Utils --> UT7["/search"]
    Utils --> UT8["/books/*"]

    Screenshot --> SC1["/capture"]

    style API fill:#1f6feb,stroke:#58a6ff,color:#fff
    style AAC fill:#238636,stroke:#3fb950,color:#fff
    style Clinical fill:#238636,stroke:#3fb950,color:#fff
    style Corpus fill:#238636,stroke:#3fb950,color:#fff
    style Data fill:#238636,stroke:#3fb950,color:#fff
    style DataVis fill:#238636,stroke:#3fb950,color:#fff
    style Etymology fill:#238636,stroke:#3fb950,color:#fff
    style SmartTemplates fill:#238636,stroke:#3fb950,color:#fff
    style Silly fill:#238636,stroke:#3fb950,color:#fff
    style Linguistics fill:#238636,stroke:#3fb950,color:#fff
    style LLM fill:#238636,stroke:#3fb950,color:#fff
    style Orchestrate fill:#238636,stroke:#3fb950,color:#fff
    style Swarm fill:#238636,stroke:#3fb950,color:#fff
    style Trove fill:#238636,stroke:#3fb950,color:#fff
    style Utils fill:#238636,stroke:#3fb950,color:#fff
    style Screenshot fill:#238636,stroke:#3fb950,color:#fff
    style Capabilities fill:#238636,stroke:#3fb950,color:#fff
                    

AAC (Accessibility)

Search and retrieve Augmentative and Alternative Communication (AAC) symbols from multiple libraries including Blissymbolics, SymbolStix, and ARASAAC. Essential for building accessible communication tools.

13,671+ Symbols Available Blissymbolics, SymbolStix, and ARASAAC libraries with proper attribution.
GET /v1/aac/symbols/search

Search AAC symbols across multiple sources with fuzzy matching. Returns ranked results from Blissymbolics, SymbolStix, and optionally ARASAAC.

Query Parameters
q string (required)
Search term (e.g., "happy", "food", "help")
limit integer
Maximum results to return (default: 10, max: 20)
sources string
Comma-separated sources: local (Blissymbolics/SymbolStix), arasaac. Default: local
language string
Language code for ARASAAC (default: en)
curl "https://api.dr.eamer.dev/v1/aac/symbols/search?q=happy&limit=5" \
  -H "X-API-Key: your_api_key"
import requests

response = requests.get(
    "https://api.dr.eamer.dev/v1/aac/symbols/search",
    headers={"X-API-Key": "your_api_key"},
    params={
        "q": "happy",
        "limit": 10,
        "sources": "local,arasaac"
    }
)

symbols = response.json()
for symbol in symbols["results"]:
    print(f"{symbol['keyword']}: {symbol['icon_url']}")
const params = new URLSearchParams({
  q: 'happy',
  limit: 10,
  sources: 'local,arasaac'
});

const response = await fetch(
  `https://api.dr.eamer.dev/v1/aac/symbols/search?${params}`,
  { headers: { 'X-API-Key': 'your_api_key' } }
);

const { results } = await response.json();
results.forEach(s => console.log(`${s.keyword}: ${s.icon_url}`));
Response
{
  "query": "happy",
  "results": [
    {
      "keyword": "happy",
      "icon_url": "/symbols/happy.svg",
      "source": "Bliss/SymbolStix",
      "license": "See repository documentation",
      "score": 1.0
    },
    {
      "keyword": "happiness",
      "icon_url": "/symbols/happiness.svg",
      "source": "Bliss/SymbolStix",
      "license": "See repository documentation",
      "score": 0.9
    }
  ],
  "total": 2,
  "sources": ["local"],
  "metadata": { "limit": 10, "language": "en" }
}
GET /v1/aac/symbols/arasaac

Search ARASAAC pictograms specifically. ARASAAC provides free pictographic communication resources under CC BY-NC-SA license from the Government of Aragón (Spain).

Query Parameters
q string (required)
Search term
limit integer
Maximum results (default: 10, max: 20)
language string
Language code (default: en). Supports: en, es, fr, de, it, pt, and more.
curl "https://api.dr.eamer.dev/v1/aac/symbols/arasaac?q=food&language=en" \
  -H "X-API-Key: your_api_key"
import requests

response = requests.get(
    "https://api.dr.eamer.dev/v1/aac/symbols/arasaac",
    headers={"X-API-Key": "your_api_key"},
    params={"q": "food", "language": "es"}  # Spanish
)

for symbol in response.json()["results"]:
    print(f"ARASAAC #{symbol['icon_url'].split('/')[-1]}: {symbol['keyword']}")
Response
{
  "query": "food",
  "results": [
    {
      "keyword": "food",
      "icon_url": "https://api.arasaac.org/v1/pictograms/2456",
      "source": "ARASAAC",
      "author": "Sergio Palao",
      "license": "CC BY-NC-SA",
      "attribution": "Pictograms author: Sergio Palao. Origin: ARASAAC...",
      "score": 1.0
    }
  ],
  "total": 10,
  "source": "arasaac",
  "metadata": {
    "attribution": "Pictograms by Sergio Palao under CC BY-NC-SA from ARASAAC",
    "language": "en",
    "limit": 10
  }
}
POST /v1/aac/sentence

Convert a sentence into AAC symbols. Each word is matched to available symbols, creating a "symbol strip" for AAC communication boards.

Request Body
sentence string (required)
The sentence to convert to symbols
sources string
Symbol sources: local (default), arasaac, or local,arasaac
language string
Language code (default: en)
curl -X POST "https://api.dr.eamer.dev/v1/aac/sentence" \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"sentence": "I want water please"}'
import requests

response = requests.post(
    "https://api.dr.eamer.dev/v1/aac/sentence",
    headers={"X-API-Key": "your_api_key"},
    json={
        "sentence": "I want water please",
        "sources": "local"
    }
)

result = response.json()
print(f"Coverage: {result['statistics']['coverage']}%")

for word_data in result["words"]:
    word = word_data["word"]
    if word_data["matched"]:
        symbol = word_data["symbols"][0]
        print(f"  {word} → {symbol['icon_url']}")
    else:
        print(f"  {word} → (no symbol)")
const response = await fetch('https://api.dr.eamer.dev/v1/aac/sentence', {
  method: 'POST',
  headers: {
    'X-API-Key': 'your_api_key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    sentence: 'I want water please'
  })
});

const { words, statistics } = await response.json();
console.log(`Coverage: ${statistics.coverage}%`);
words.forEach(w => {
  const symbol = w.matched ? w.symbols[0].icon_url : 'none';
  console.log(`${w.word}: ${symbol}`);
});
Response
{
  "sentence": "I want water please",
  "words": [
    {
      "word": "i",
      "matched": true,
      "symbols": [
        {"keyword": "i", "icon_url": "/symbols/i.svg", "score": 1.0, "source": "Bliss/SymbolStix"}
      ]
    },
    {
      "word": "want",
      "matched": true,
      "symbols": [
        {"keyword": "want", "icon_url": "/symbols/want.svg", "score": 1.0, "source": "Bliss/SymbolStix"}
      ]
    },
    {
      "word": "water",
      "matched": true,
      "symbols": [
        {"keyword": "water", "icon_url": "/symbols/water.svg", "score": 1.0, "source": "Bliss/SymbolStix"}
      ]
    },
    {
      "word": "please",
      "matched": true,
      "symbols": [
        {"keyword": "please", "icon_url": "/symbols/please.svg", "score": 1.0, "source": "Bliss/SymbolStix"}
      ]
    }
  ],
  "statistics": {
    "total_words": 4,
    "matched": 4,
    "unmatched": 0,
    "coverage": 100.0
  },
  "sources": ["local"],
  "language": "en"
}

Clinical Reference

Medical condition information designed for complex communication needs. Covers 51 conditions with accessible language for AAC users, caregivers, and educators. For educational and communication support purposes only - not medical advice.

⚠️
Disclaimer This data is for educational and communication support only. Not a substitute for professional medical advice.
GET /v1/clinical/conditions

List all 51 available clinical conditions with summary information.

curl "https://api.dr.eamer.dev/v1/clinical/conditions" \
  -H "X-API-Key: your_api_key"
GET /v1/clinical/conditions/{id}

Get detailed information about a specific condition including symptoms, treatments, and communication strategies.

Path Parameters

ParameterTypeDescription
idstringCondition identifier (slug or numeric ID)
curl "https://api.dr.eamer.dev/v1/clinical/conditions/cerebral-palsy" \
  -H "X-API-Key: your_api_key"
GET /v1/clinical/search

Search clinical conditions by keyword.

Query Parameters

ParameterTypeDescription
qstringSearch query (required)
curl "https://api.dr.eamer.dev/v1/clinical/search?q=autism" \
  -H "X-API-Key: your_api_key"

Corpus

Search and analyze the Corpus of Contemporary American English (COCA) - a 35M+ token linguistic database spanning 1990-2019, plus historical English corpora.

Available Corpora

COCA (Contemporary) COHA (Historical) Old English Middle English Early Modern English
GET /v1/corpus/search

Search the corpus with KWIC (Key Word In Context) results. Supports wildcards and part-of-speech filtering.

Query Parameters

ParameterTypeDescription
qstringSearch term (supports * wildcards) — required
corpusstringCorpus to search: coca, old_english, middle_english, early_modern (default: coca)
contextintegerContext words on each side (default: 5)
limitintegerMaximum results (default: 100, max: 500)
curl "https://api.dr.eamer.dev/v1/corpus/search?q=awesome&limit=20" \
  -H "X-API-Key: your_api_key"
GET /v1/corpus/collocations

Find words that frequently appear together with the target word (collocations and word associations).

Query Parameters

ParameterTypeDescription
wordstringTarget word to find collocations for
limitintegerMaximum collocations to return (default: 10)
curl "https://api.dr.eamer.dev/v1/corpus/collocations?word=make&limit=10" \
  -H "X-API-Key: your_api_key"
GET /v1/corpus/frequency

Get word frequency data across corpora with optional genre and time period filtering.

Query Parameters

ParameterTypeDescription
wordstringWord to check frequency for
corpusstringCorpus to search (default: all)
curl "https://api.dr.eamer.dev/v1/corpus/frequency?word=awesome" \
  -H "X-API-Key: your_api_key"

Data Sources

Search and retrieve data from 17 structured sources including academic databases, government data, media APIs, and archives.

Academic Sources

arxiv pubmed semantic_scholar openlibrary

Government Data

census fec judiciary

Science & Research

nasa weather wolfram

Media & Content

news youtube wikipedia

Technical & Archives

github finance archive wayback
GET /v1/data/sources

Get list of all available data sources organized by category.

curl https://api.dr.eamer.dev/v1/data/sources \
  -H "X-API-Key: your_api_key"
GET /v1/data/{source}/search

Search a specific data source.

Query Parameters
query string
Search query
max_results integer
Maximum number of results (default: 10)
# Search arXiv
curl "https://api.dr.eamer.dev/v1/data/arxiv/search?query=quantum+computing&max_results=5" \
  -H "X-API-Key: your_api_key"

# Search Wikipedia
curl "https://api.dr.eamer.dev/v1/data/wikipedia/search?query=artificial+intelligence" \
  -H "X-API-Key: your_api_key"
response = requests.get(
    "https://api.dr.eamer.dev/v1/data/arxiv/search",
    headers={"X-API-Key": "your_api_key"},
    params={
        "query": "quantum computing",
        "max_results": 5
    }
)

results = response.json()["results"]
GET /v1/data/{source}/get/{id}

Retrieve a specific item by its identifier (arXiv ID, DOI, etc.).

# Get arXiv paper by ID
curl https://api.dr.eamer.dev/v1/data/arxiv/get/2301.07041 \
  -H "X-API-Key: your_api_key"

DataVis Gallery

Access a catalog of 123+ D3.js data visualizations with real data from authoritative sources including Census Bureau, USGS, CoinGecko, and more. Includes live data proxy endpoints.

Data Sources

US Census Bureau USGS Earthquakes CoinGecko Crypto IOC Olympics NOAA Temperature WHO COVID-19
GET /v1/datavis/list

List all available D3.js visualizations organized by category.

Query Parameters

ParameterTypeDescription
categorystringFilter by category name (optional)
# List all visualizations
curl "https://api.dr.eamer.dev/v1/datavis/list" \
  -H "X-API-Key: your_api_key"

# Filter by category
curl "https://api.dr.eamer.dev/v1/datavis/list?category=economics" \
  -H "X-API-Key: your_api_key"
GET /v1/datavis/categories

List visualization categories with counts.

curl "https://api.dr.eamer.dev/v1/datavis/categories" \
  -H "X-API-Key: your_api_key"
GET /v1/datavis/proxy/{source}

Proxy live data APIs for visualizations. Avoids CORS issues and provides cached/fallback data.

Path Parameters

ParameterTypeDescription
sourcestringData source: earthquake (USGS), crypto (CoinGecko), airquality (WAQI)
# Get recent earthquake data
curl "https://api.dr.eamer.dev/v1/datavis/proxy/earthquake" \
  -H "X-API-Key: your_api_key"

# Get cryptocurrency prices
curl "https://api.dr.eamer.dev/v1/datavis/proxy/crypto" \
  -H "X-API-Key: your_api_key"

Data Trove

50+ curated datasets across 15 categories (~1.2GB total). Everything from billionaire wealth to UFO sightings, phoneme inventories to shipwrecks. No API key required for browsing.

Available Categories (15)

accessibility attention cultural environmental geographic healthcare linguistic quirky urban wild economic_billionaires economic_boards economic_housing retail cms

Dataset Inventory

CategoryDatasetsHighlights
accessibility (3) WLASL sign language, VizWiz image a11y, Census disability Sign language vocab index, image accessibility annotations, state-level disability stats
attention (10+) Wikipedia pageviews, trending articles, GDELT events, Google Trends Time-series attention data, weekly event timelines, unified attention metrics
cultural (3) Emoji by category, emoji usage timeline, emoji metadata 3,600+ emoji with categories, historical usage patterns
environmental Air quality trends, AQI by state EPA data on air quality over time
geographic (2) Country centroids, country metadata Lat/lng centers for every country, GeoJSON-ready
healthcare (4) CMS hospitals, healthcare deserts, food access atlas 6,000+ US hospitals, 2.3M census tracts, desert classifications
linguistic (10+) Glottolog, ISO 639-3, WALS, PHOIBLE, world languages 17,000+ languages, phoneme inventories, typological features, coordinates
quirky (30+) Asteroids, aurora, caves, cheese atlas, cryptids, deep sea, fossils, ghost ships, lighthouses, megaliths, volcanoes, witch trials, wine... The fun stuff - natural wonders, historical oddities, food geography
wild (5+) Ghost sightings, NASA meteorites, disasters, animal attacks, bridges 45K+ meteorites, ghost reports, landslide data
urban (4) NYC parking violations, worst streets, violations by hour/vehicle 10K sample records, temporal and spatial breakdowns
economic_* (3 cats) Billionaires, corporate boards, housing crisis 334 billionaires with wealth data, 3,200 county housing metrics
retail LA County retail locations Retail location data for urban analysis
cms CMS hospitals (2026 snapshot) Full hospital dataset direct from CMS
GET /v1/trove

List all Data Trove categories with dataset counts. No API key required.

# List all categories
curl https://api.dr.eamer.dev/v1/trove
GET /v1/trove/{category}

List all datasets in a category with file size information. No API key required.

Path Parameters

ParameterTypeDescription
categorystringCategory name (e.g., quirky, wild, economic_billionaires)
# List datasets in the quirky category
curl https://api.dr.eamer.dev/v1/trove/quirky
GET /v1/trove/{category}/{dataset}

Fetch a specific dataset. Supports pagination for large files. CSV files are automatically converted to JSON.

Path Parameters

ParameterTypeDescription
categorystringCategory name
datasetstringDataset name (without extension)

Query Parameters

ParameterTypeDescription
limitintegerMaximum records to return (default: 100)
offsetintegerNumber of records to skip
# Get USGS earthquake data with pagination
curl "https://api.dr.eamer.dev/v1/trove/wild/usgs_earthquakes?limit=10" \
  -H "X-API-Key: your_api_key"

Etymology

Look up word origins, definitions, pronunciation, cognates across languages, related word networks, language lineage tracing, and network graph visualization data.

GET /v1/etymology/explore/{word}

Full etymology analysis including definitions, pronunciation, cognates, related words, language lineage, and visualization data for network graphs.

Path Parameters

ParameterTypeDescription
wordstringWord to analyze

Query Parameters

ParameterTypeDescription
viz_typestringVisualization type: network, mermaid, matrix (default: network)
adj_typestringAdjacency type: temporal, linguistic, semantic (default: temporal)
# Explore etymology of "water"
curl "https://api.dr.eamer.dev/v1/etymology/explore/water" \
  -H "X-API-Key: your_api_key"

# With visualization options
curl "https://api.dr.eamer.dev/v1/etymology/explore/language?viz_type=mermaid&adj_type=semantic" \
  -H "X-API-Key: your_api_key"
GET /v1/etymology/health

Check etymology service health status. No authentication required.

curl "https://api.dr.eamer.dev/v1/etymology/health"

Smart Templates

Pre-configured prompt templates with optimized model selection. Prompt engineering is handled server-side for consistent results - just send your data and get structured output back.

POST /v1/generate/alt-text

Generate WCAG-compliant alt text for images. Uses xAI Grok Vision with carefully tuned prompts for accessibility compliance.

Request Body
image string (required)
Base64 encoded image data OR an image URL
context string
Optional context about the image (e.g., "product photo", "news article header")
style string
Alt text style: concise (default, ~125 chars), detailed (comprehensive), or functional (focus on purpose/action)
curl -X POST https://api.dr.eamer.dev/v1/generate/alt-text \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "image": "https://example.com/photo.jpg",
    "style": "concise",
    "context": "product photography"
  }'
import requests
import base64

# Using URL
response = requests.post(
    "https://api.dr.eamer.dev/v1/generate/alt-text",
    headers={"X-API-Key": "your_api_key"},
    json={
        "image": "https://example.com/photo.jpg",
        "style": "detailed"
    }
)

# Or using base64 encoded image
with open("image.jpg", "rb") as f:
    img_data = base64.b64encode(f.read()).decode()

response = requests.post(
    "https://api.dr.eamer.dev/v1/generate/alt-text",
    headers={"X-API-Key": "your_api_key"},
    json={
        "image": img_data,
        "style": "functional",
        "context": "e-commerce listing"
    }
)

print(response.json()["alt_text"])
const response = await fetch('https://api.dr.eamer.dev/v1/generate/alt-text', {
  method: 'POST',
  headers: {
    'X-API-Key': 'your_api_key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    image: 'https://example.com/photo.jpg',
    style: 'concise'
  })
});

const { alt_text, style } = await response.json();
document.querySelector('img').alt = alt_text;
Response
{
  "alt_text": "A ceramic coffee mug with steam rising, placed on a wooden table with morning sunlight streaming through a nearby window",
  "style": "concise",
  "provider": "xai",
  "model": "grok-2-vision-1212"
}
POST /v1/generate/story

Generate interactive story flows with branching choices. Returns structured JSON with nodes and connections for building choose-your-own-adventure style narratives.

Request Body
description string (required)
Natural language description of the story (e.g., "A detective investigating a haunted mansion")
complexity string
Story complexity: simple (5-8 nodes), medium (10-15 nodes), or complex (20+ nodes with multiple endings)
provider string
LLM provider to use (default: xai)
curl -X POST https://api.dr.eamer.dev/v1/generate/story \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "description": "A detective investigating a haunted mansion",
    "complexity": "simple"
  }'
import requests

response = requests.post(
    "https://api.dr.eamer.dev/v1/generate/story",
    headers={"X-API-Key": "your_api_key"},
    json={
        "description": "A space explorer discovering an ancient alien artifact",
        "complexity": "medium"
    }
)

story = response.json()
print(f"Title: {story['title']}")
print(f"Nodes: {len(story['nodes'])}")
print(f"Connections: {len(story['connections'])}")

# Find the starting node
start_node = next(n for n in story['nodes'] if n['id'] == 'start')
print(f"Beginning: {start_node['text']}")
const response = await fetch('https://api.dr.eamer.dev/v1/generate/story', {
  method: 'POST',
  headers: {
    'X-API-Key': 'your_api_key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    description: 'A time traveler stuck in medieval times',
    complexity: 'simple'
  })
});

const story = await response.json();

// Build a simple story engine
let currentNode = story.nodes.find(n => n.id === 'start');
console.log(currentNode.text);

// Get available choices
const choices = story.connections
  .filter(c => c.from === currentNode.id)
  .map(c => ({
    text: c.label,
    nextNode: story.nodes.find(n => n.id === c.to)
  }));
Response
{
  "title": "The Haunted Mansion Investigation",
  "nodes": [
    {
      "id": "start",
      "text": "You stand before the decrepit Blackwood Manor...",
      "type": "start"
    },
    {
      "id": "node_1",
      "text": "The front door creaks open, revealing a dusty foyer...",
      "type": "story"
    },
    {
      "id": "ending_good",
      "text": "You've uncovered the truth and freed the spirits!",
      "type": "ending"
    }
  ],
  "connections": [
    {
      "from": "start",
      "to": "node_1",
      "label": "Enter through the front door"
    },
    {
      "from": "start",
      "to": "node_2",
      "label": "Search around the back"
    }
  ],
  "complexity": "simple",
  "provider": "xai"
}
POST /v1/generate/lesson-plan

Generate full EFL/ESL lesson plans with warm-up activities, presentations, practice exercises, production tasks, and assessment strategies. Returns CEFR-aligned plans with ready-to-use handout content.

Request Body
topic string (required)
Lesson topic or theme (e.g., "ordering food at restaurants", "job interview skills")
level string
CEFR level: "A1", "A2", "B1", "B2", "C1", "C2" (default: "B1")
duration string
Class duration: "30min", "45min", "60min", "90min" (default: "60min")
focus string
Primary skill focus: "grammar", "vocabulary", "speaking", "listening", "reading", "writing", "pronunciation", "communication" (default: "speaking")
provider string
LLM provider to use (default: "xai")
curl -X POST https://api.dr.eamer.dev/v1/generate/lesson-plan \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "topic": "ordering food at restaurants",
    "level": "B1",
    "duration": "60min",
    "focus": "speaking"
  }'
import requests

response = requests.post(
    "https://api.dr.eamer.dev/v1/generate/lesson-plan",
    headers={"X-API-Key": "your_api_key"},
    json={
        "topic": "job interview skills",
        "level": "B2",
        "duration": "90min",
        "focus": "communication"
    }
)

lesson = response.json()
print(f"Title: {lesson['title']}")
print(f"Objectives: {lesson['objectives']}")
print(f"Warm-up: {lesson['outline']['warm_up']}")
const response = await fetch('https://api.dr.eamer.dev/v1/generate/lesson-plan', {
  method: 'POST',
  headers: {
    'X-API-Key': 'your_api_key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    topic: 'making complaints politely',
    level: 'B1',
    duration: '45min',
    focus: 'speaking'
  })
});

const lesson = await response.json();
console.log('Title:', lesson.title);
console.log('Handout:', lesson.handout_content);
Response
{
  "title": "Ordering Food at Restaurants",
  "level": "B1",
  "duration": "60min",
  "objectives": [
    "Use restaurant vocabulary confidently",
    "Order food and drinks politely",
    "Handle common restaurant situations"
  ],
  "outline": {
    "warm_up": "Restaurant vocabulary matching game...",
    "presentation": "Key phrases and expressions...",
    "practice": "Controlled practice activities...",
    "production": "Role-play restaurant scenarios...",
    "wrap_up": "Review and homework assignment..."
  },
  "handout_content": "Ready-to-print student handout...",
  "video_suggestions": ["YouTube video links..."],
  "visual_aids": ["Suggested images and materials..."],
  "assessment_ideas": ["Formative assessment strategies..."],
  "differentiation": {
    "struggling": "Support strategies...",
    "advanced": "Extension activities..."
  },
  "provider": "xai"
}
POST /v1/generate/business-plan

Generate business plans with executive summaries, market analysis, competitive assessment, financial projections, and action plans. Supports different business stages and detail levels.

Request Body
idea string (required)
Business idea description (e.g., "smart plant care app for urban gardeners")
industry string
Industry or sector (e.g., "AgriTech", "SaaS", "Food & Beverage")
location string
Target location or market (e.g., "Portland, Oregon", "Southeast Asia")
stage string
Business stage: "idea", "startup", "growth", "expansion" (default: "startup")
detail_level string
Detail level: "brief", "standard", "comprehensive" (default: "standard")
provider string
LLM provider to use (default: "xai")
curl -X POST https://api.dr.eamer.dev/v1/generate/business-plan \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "idea": "Vegan meal prep delivery service",
    "industry": "Food & Beverage",
    "location": "Portland, Oregon",
    "stage": "startup",
    "detail_level": "comprehensive"
  }'
import requests

response = requests.post(
    "https://api.dr.eamer.dev/v1/generate/business-plan",
    headers={"X-API-Key": "your_api_key"},
    json={
        "idea": "Adaptive tutoring platform for K-12 students",
        "industry": "EdTech",
        "stage": "growth",
        "detail_level": "comprehensive"
    }
)

plan = response.json()
print(f"Executive Summary: {plan['executive_summary']}")
print(f"Market Size: {plan['market_analysis']['market_size']}")
const response = await fetch('https://api.dr.eamer.dev/v1/generate/business-plan', {
  method: 'POST',
  headers: {
    'X-API-Key': 'your_api_key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    idea: 'Sustainable packaging marketplace',
    industry: 'E-commerce',
    location: 'US West Coast',
    stage: 'idea'
  })
});

const plan = await response.json();
console.log('Financial Projections:', plan.financial_projections);
Response
{
  "business_name": "GreenMeal Co.",
  "executive_summary": "A plant-based meal prep service targeting...",
  "market_analysis": {
    "market_size": "$15.7 billion plant-based food market",
    "target_segments": ["Health-conscious professionals", "..."],
    "trends": ["Growing vegan population", "..."],
    "opportunities": ["Underserved suburban areas", "..."]
  },
  "competitive_analysis": {
    "direct_competitors": [{"name": "...", "strengths": "...", "weaknesses": "..."}],
    "competitive_advantage": "Local sourcing and customization..."
  },
  "business_model": {
    "revenue_streams": ["Subscription meals", "A la carte orders"],
    "pricing_strategy": "Premium positioning at $12-18/meal",
    "cost_structure": ["Ingredients 35%", "Labor 25%", "..."]
  },
  "operations_plan": {
    "key_activities": ["Menu development", "..."],
    "resources_needed": ["Commercial kitchen", "..."],
    "milestones": [{"month": 1, "goal": "..."}, "..."]
  },
  "financial_projections": {
    "startup_costs": "$75,000",
    "monthly_burn": "$8,500",
    "break_even": "Month 8",
    "year_1_revenue": "$180,000",
    "year_3_revenue": "$650,000"
  },
  "risk_assessment": [
    {"risk": "Supply chain disruption", "mitigation": "..."}
  ],
  "action_plan": {
    "immediate": ["Secure kitchen space", "..."],
    "short_term": ["Launch MVP", "..."],
    "long_term": ["Expand to Seattle", "..."]
  },
  "provider": "xai"
}
POST /v1/generate/resume

Generate optimized, ATS-friendly resumes with professional formatting. Tailors content based on industry, role, and style preferences. Returns structured data with keyword optimization.

Request Body
name string (required)
Full name for the resume
title string
Professional title or target role
summary string
Brief professional summary or background
experience array
Work experience entries with title, company, dates, and highlights
education array
Education entries with degree, institution, and year
skills array
List of skills and competencies
style string
Resume style: "professional", "creative", "technical", "executive" (default: "professional")
provider string
LLM provider to use (default: "xai")
curl -X POST https://api.dr.eamer.dev/v1/generate/resume \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Jane Smith",
    "title": "Senior Software Engineer",
    "summary": "10 years building scalable web applications",
    "experience": [
      {"title": "Tech Lead", "company": "StartupCo", "dates": "2020-Present"}
    ],
    "skills": ["Python", "React", "AWS", "Team Leadership"],
    "style": "technical"
  }'
import requests

response = requests.post(
    "https://api.dr.eamer.dev/v1/generate/resume",
    headers={"X-API-Key": "your_api_key"},
    json={
        "name": "Alex Johnson",
        "title": "Product Manager",
        "experience": [
            {
                "title": "Senior PM",
                "company": "TechCorp",
                "dates": "2021-Present",
                "highlights": ["Launched 3 products", "Grew team to 12"]
            }
        ],
        "education": [
            {"degree": "MBA", "institution": "Stanford", "year": 2019}
        ],
        "style": "executive"
    }
)

resume = response.json()
print(resume['professional_summary'])
print(resume['keywords'])
const response = await fetch('https://api.dr.eamer.dev/v1/generate/resume', {
  method: 'POST',
  headers: {
    'X-API-Key': 'your_api_key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: 'Sam Wilson',
    title: 'UX Designer',
    skills: ['Figma', 'User Research', 'Prototyping'],
    style: 'creative'
  })
});

const resume = await response.json();
console.log('ATS Keywords:', resume.keywords);
Response
{
  "header": {
    "name": "Jane Smith",
    "title": "Senior Software Engineer",
    "contact": "Formatted contact section..."
  },
  "professional_summary": "Results-driven software engineer with 10+ years...",
  "experience": [
    {
      "title": "Tech Lead",
      "company": "StartupCo",
      "dates": "2020-Present",
      "bullets": [
        "Led team of 8 engineers to deliver $2M platform",
        "Reduced deployment time by 60% through CI/CD improvements",
        "Mentored 5 junior developers to promotion-ready level"
      ]
    }
  ],
  "education": [
    {
      "degree": "B.S. Computer Science",
      "institution": "UC Berkeley",
      "year": 2013,
      "honors": "Cum Laude"
    }
  ],
  "skills": {
    "technical": ["Python", "React", "AWS", "PostgreSQL"],
    "soft": ["Team Leadership", "Agile/Scrum", "Cross-functional Collaboration"]
  },
  "keywords": ["software engineer", "tech lead", "Python", "React", "AWS", "scalable", "leadership"],
  "ats_score": 85,
  "provider": "xai"
}
POST /v1/generate/itinerary

Generate detailed travel itineraries with day-by-day activities, local recommendations, practical travel tips, and cost estimates. Customizable by interests, budget, and travel style.

Request Body
destination string (required)
Travel destination (e.g., "Tokyo, Japan", "Tuscany, Italy")
duration integer
Number of days (default: 3)
interests array
Travel interests (e.g., ["food", "history", "nature", "art", "nightlife"])
budget string
Budget level: "budget", "moderate", "luxury" (default: "moderate")
travelers string
Travel group: "solo", "couple", "family", "group" (default: "couple")
pace string
Trip pace: "relaxed", "moderate", "packed" (default: "moderate")
provider string
LLM provider to use (default: "xai")
curl -X POST https://api.dr.eamer.dev/v1/generate/itinerary \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "destination": "Tokyo, Japan",
    "duration": 5,
    "interests": ["food", "technology", "anime"],
    "budget": "moderate",
    "travelers": "couple",
    "pace": "moderate"
  }'
import requests

response = requests.post(
    "https://api.dr.eamer.dev/v1/generate/itinerary",
    headers={"X-API-Key": "your_api_key"},
    json={
        "destination": "Barcelona, Spain",
        "duration": 4,
        "interests": ["architecture", "food", "beaches"],
        "budget": "moderate",
        "pace": "relaxed"
    }
)

itinerary = response.json()
for day in itinerary['daily_itinerary']:
    print(f"Day {day['day']}: {day['theme']}")
    for activity in day['activities']:
        print(f"  - {activity['time']}: {activity['activity']}")
const response = await fetch('https://api.dr.eamer.dev/v1/generate/itinerary', {
  method: 'POST',
  headers: {
    'X-API-Key': 'your_api_key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    destination: 'Iceland',
    duration: 7,
    interests: ['nature', 'photography', 'adventure'],
    budget: 'moderate',
    travelers: 'solo',
    pace: 'packed'
  })
});

const trip = await response.json();
console.log('Overview:', trip.overview);
console.log('Must-Try:', trip.must_try);
Response
{
  "destination": "Tokyo, Japan",
  "duration": 5,
  "overview": "An immersive 5-day journey through Tokyo...",
  "daily_itinerary": [
    {
      "day": 1,
      "theme": "Traditional Tokyo",
      "activities": [
        {
          "time": "9:00 AM",
          "activity": "Senso-ji Temple & Asakusa",
          "duration": "2 hours",
          "cost_estimate": "$0",
          "tips": "Arrive early to avoid crowds..."
        },
        {
          "time": "12:00 PM",
          "activity": "Lunch at Nakamise Shopping Street",
          "duration": "1 hour",
          "cost_estimate": "$15-25",
          "tips": "Try the ningyo-yaki (sweet cakes)..."
        }
      ],
      "meals": {
        "breakfast": "Hotel or convenience store onigiri",
        "lunch": "Street food at Nakamise",
        "dinner": "Izakaya experience in Shinjuku"
      }
    }
  ],
  "practical_info": {
    "best_time_to_visit": "March-May or Sept-Nov",
    "transportation": "Get a 72-hour metro pass (~$15)",
    "accommodation_areas": ["Shinjuku", "Shibuya", "Asakusa"],
    "estimated_daily_budget": "$150-200",
    "essential_apps": ["Google Maps", "Hyperdia", "Tabelog"],
    "etiquette_tips": ["Remove shoes indoors", "..."]
  },
  "must_try": {
    "foods": ["Ramen at Ichiran", "Tsukiji market sushi"],
    "experiences": ["Robot Restaurant", "Shibuya Crossing"],
    "neighborhoods": ["Akihabara", "Harajuku", "Shimokitazawa"]
  },
  "provider": "xai"
}

Silly

Random jokes, insults, colors, and compliments. Perfect for adding personality to applications, testing, or entertainment. All use shuffle-bag algorithms to prevent immediate repetition.

Available Content Types

Dad Jokes Anti-Jokes Rare Insults Compliments Colors
GET /v1/generators/{generator}/random

Get a random item of the specified content type. Uses shuffle-bag algorithm to avoid repetition.

Path Parameters

ParameterTypeDescription
generatorstringContent type: dadjokes, antijokes, insults, compliments, colors
# Get a random dad joke
curl https://api.dr.eamer.dev/v1/generators/dadjokes/random

# Get a random color (29,956 named colors)
curl https://api.dr.eamer.dev/v1/generators/colors/random

# Get a random rare insult
curl https://api.dr.eamer.dev/v1/generators/insults/random
GET /v1/generators/{generator}/multiple/{count}

Get multiple items at once (1-50). Works for all content types including colors.

Path Parameters

ParameterTypeDescription
generatorstringContent type: dadjokes, antijokes, insults, compliments, colors
countintegerNumber of items (1-50)
# Get 5 anti-jokes
curl https://api.dr.eamer.dev/v1/generators/antijokes/multiple/5

# Get a color palette (2-10 colors)
curl https://api.dr.eamer.dev/v1/generators/colors/multiple/5

Linguistics

Linguistic data covering 7,925+ languages with ISO 639-3 codes, 105,484 phonemes from PHOIBLE, and 192 typological features from WALS. Full-text search across all data.

Data Sources

ISO 639-3 PHOIBLE 2.0 WALS Glottolog
GET /v1/linguistics/languages

List or search languages. Filter by family, region, or endangerment status.

Query Parameters

ParameterTypeDescription
familystringFilter by language family (e.g., Indo-European)
regionstringFilter by geographic region
statusstringFilter by endangerment status
limitintegerMax results (default: 100)
offsetintegerPagination offset (default: 0)
# List all languages (paginated)
curl "https://api.dr.eamer.dev/v1/linguistics/languages?limit=20" \
  -H "X-API-Key: your_api_key"

# Filter by family
curl "https://api.dr.eamer.dev/v1/linguistics/languages?family=Indo-European&limit=50" \
  -H "X-API-Key: your_api_key"
GET /v1/linguistics/languages/{code}

Get detailed information about a specific language by its ISO 639-3 code.

Path Parameters

ParameterTypeDescription
codestringISO 639-3 code (e.g., eng, spa, cmn, jpn)
curl "https://api.dr.eamer.dev/v1/linguistics/languages/eng" \
  -H "X-API-Key: your_api_key"
GET /v1/linguistics/phonemes

Search phonemes across languages from the PHOIBLE 2.0 database (105,484 phoneme records).

Query Parameters

ParameterTypeDescription
languagestringISO 639-3 code to filter by language
typestringPhoneme type: consonant, vowel, tone
mannerstringManner of articulation: plosive, fricative, nasal, etc.
placestringPlace of articulation: bilabial, alveolar, velar, etc.
limitintegerMax results (default: 100)
# Get phonemes for English
curl "https://api.dr.eamer.dev/v1/linguistics/phonemes?language=eng" \
  -H "X-API-Key: your_api_key"

# Get all bilabial consonants
curl "https://api.dr.eamer.dev/v1/linguistics/phonemes?type=consonant&place=bilabial" \
  -H "X-API-Key: your_api_key"
GET /v1/linguistics/features

Get typological features from the World Atlas of Language Structures (WALS). 192 parameters covering phonology, morphology, and syntax.

Query Parameters

ParameterTypeDescription
languagestringISO 639-3 code to get features for
featurestringWALS feature ID
categorystringFeature category (phonology, morphology, syntax)
curl "https://api.dr.eamer.dev/v1/linguistics/features?language=eng" \
  -H "X-API-Key: your_api_key"
GET /v1/linguistics/search

Full-text search across all linguistic data including language names, families, phonemes, and features.

Query Parameters

ParameterTypeDescription
qstringSearch query (required)
typestringSearch type: languages, phonemes, features, all (default: all)
limitintegerMax results per type (default: 20)
curl "https://api.dr.eamer.dev/v1/linguistics/search?q=romance&type=languages" \
  -H "X-API-Key: your_api_key"

LLM

Access 13 LLM providers through a unified interface: Anthropic (Claude), OpenAI (GPT-4), xAI (Grok), Mistral, Cohere, Gemini, Perplexity, Groq, HuggingFace, Gradient, ElevenLabs, Manus, and Ollama.

Anthropic
OpenAI
xAI
Mistral
Cohere
Gemini
Perplexity
Groq
HuggingFace
Gradient
ElevenLabs
Manus
Ollama
POST /v1/llm/chat

Generate chat completions using any supported LLM provider.

Request Body
provider string
Provider name (default: xai). Options: anthropic, openai, xai, mistral, cohere, gemini, perplexity, groq, huggingface, gradient, ollama, manus
messages array
Array of message objects with role and content: [{role: "user", content: "Hello"}]
model string
Model name (optional, uses provider default)
stream boolean
Enable SSE streaming (default: false)
temperature number
Sampling temperature (0.0-2.0, optional)
curl -X POST https://api.dr.eamer.dev/v1/llm/chat \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "xai",
    "messages": [
      {"role": "user", "content": "Explain quantum computing"}
    ],
    "temperature": 0.7
  }'
import requests

response = requests.post(
    "https://api.dr.eamer.dev/v1/llm/chat",
    headers={"X-API-Key": "your_api_key"},
    json={
        "provider": "anthropic",
        "messages": [
            {"role": "user", "content": "Explain quantum computing"}
        ],
        "temperature": 0.7
    }
)

data = response.json()
print(data["content"])
const response = await fetch('https://api.dr.eamer.dev/v1/llm/chat', {
  method: 'POST',
  headers: {
    'X-API-Key': 'your_api_key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    provider: 'openai',
    messages: [
      {role: 'user', content: 'Explain quantum computing'}
    ],
    temperature: 0.7
  })
});

const data = await response.json();
console.log(data.content);
Response
{
  "content": "Quantum computing uses quantum mechanics principles...",
  "model": "grok-3",
  "usage": {
    "prompt_tokens": 12,
    "completion_tokens": 150,
    "total_tokens": 162
  },
  "provider": "xai"
}
POST /v1/llm/chat?stream=true

Stream chat completions using Server-Sent Events (SSE).

curl -N -X POST https://api.dr.eamer.dev/v1/llm/chat \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "xai",
    "messages": [{"role": "user", "content": "Hello"}],
    "stream": true
  }'
import requests
import json

response = requests.post(
    "https://api.dr.eamer.dev/v1/llm/chat",
    headers={"X-API-Key": "your_api_key"},
    json={
        "provider": "xai",
        "messages": [{"role": "user", "content": "Hello"}],
        "stream": True
    },
    stream=True
)

for line in response.iter_lines():
    if line and line.startswith(b"data: "):
        data = json.loads(line[6:])
        if "content" in data:
            print(data["content"], end="", flush=True)
const eventSource = new EventSource(
  'https://api.dr.eamer.dev/v1/llm/chat?stream=true',
  {
    headers: {'X-API-Key': 'your_api_key'}
  }
);

eventSource.onmessage = (event) => {
  const data = JSON.parse(event.data);
  if (data.content) {
    console.log(data.content);
  }
  if (data.done) {
    eventSource.close();
  }
};
POST /v1/llm/vision

Analyze images using vision-capable models.

Request Body
image string
Base64 encoded image or image URL
prompt string
Analysis prompt (default: "Describe this image in detail.")
provider string
Provider name (default: xai). Supports: xai, openai, anthropic, gemini
import requests
import base64

with open("image.jpg", "rb") as f:
    image_data = base64.b64encode(f.read()).decode()

response = requests.post(
    "https://api.dr.eamer.dev/v1/llm/vision",
    headers={"X-API-Key": "your_api_key"},
    json={
        "provider": "xai",
        "image": image_data,
        "prompt": "What's in this image?"
    }
)

print(response.json()["content"])
// Using image URL
const response = await fetch('https://api.dr.eamer.dev/v1/llm/vision', {
  method: 'POST',
  headers: {
    'X-API-Key': 'your_api_key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    provider: 'anthropic',
    image: 'https://example.com/image.jpg',
    prompt: 'What objects are in this image?'
  })
});

const data = await response.json();
console.log(data.content);
POST /v1/llm/embed

Generate text embeddings for semantic search and similarity.

Request Body
text string | array
Text or array of texts to embed
provider string
openai or ollama (default: openai)
model string
Embedding model (optional, defaults: text-embedding-3-small for openai, nomic-embed-text for ollama)
response = requests.post(
    "https://api.dr.eamer.dev/v1/llm/embed",
    headers={"X-API-Key": "your_api_key"},
    json={
        "provider": "openai",
        "text": ["Document 1", "Document 2", "Document 3"]
    }
)

embeddings = response.json()["embedding"]  # List of vectors
POST /v1/llm/speech

Convert text to speech using ElevenLabs or OpenAI.

Request Body
text string
Text to convert to speech
provider string
elevenlabs or openai (default: elevenlabs)
voice string
Voice ID or name (optional)
GET /v1/llm/models

List available models for each provider.

# List all provider capabilities
curl https://api.dr.eamer.dev/v1/llm/models \
  -H "X-API-Key: your_api_key"

# Get models for specific provider
curl "https://api.dr.eamer.dev/v1/llm/models?provider=xai" \
  -H "X-API-Key: your_api_key"

Orchestration

Execute multi-agent LLM workflows for complex research and search tasks.

POST /v1/orchestrate/dream-cascade

Execute hierarchical research workflow with 3-tier synthesis (Belters → Drummer → Camina).

Request Body
task string
Research task description
num_agents integer
Number of Belter agents (default: 8)
provider_name string
LLM provider (default: xai)
response = requests.post(
    "https://api.dr.eamer.dev/v1/orchestrate/dream-cascade",
    headers={"X-API-Key": "your_api_key"},
    json={
        "task": "Analyze the impact of language models on education",
        "num_agents": 8,
        "provider_name": "xai"
    }
)

result = response.json()
print(result["result"])  # Final synthesized output
POST /v1/orchestrate/dream-swarm

Execute parallel multi-domain search workflow with specialized agents.

Request Body
query string
Search query
num_agents integer
Number of search agents (default: 5)
provider_name string
LLM provider (default: xai)
response = requests.post(
    "https://api.dr.eamer.dev/v1/orchestrate/dream-swarm",
    headers={"X-API-Key": "your_api_key"},
    json={
        "query": "Latest developments in quantum computing",
        "num_agents": 5
    }
)

result = response.json()
print(result["result"])

Swarm

Multi-agent research orchestration with parallel query analysis and synthesis. Generates adjacent research queries, executes them in parallel, and synthesizes findings into a unified response. Supports both deep research and simple chat modes.

🧠
Streaming Responses Both /hive and /chat return Server-Sent Events (SSE) streams. Use EventSource or a streaming HTTP client.
POST /v1/swarm/hive

Multi-step research with parallel query generation and execution. Breaks your query into adjacent sub-queries, researches them in parallel, then synthesizes a unified answer.

Request Body (JSON)

ParameterTypeDescription
querystringResearch query (required)
num_tasksintegerNumber of adjacent queries to generate (0 = auto, default: 0)

SSE Stream Events

StatusDescription
planningGenerating adjacent research queries
planQuery plan with steps
executingRunning parallel research
completeFinal synthesized results
errorError with message
curl -N "https://api.dr.eamer.dev/v1/swarm/hive" \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"query": "What are the latest advances in transformer architecture?", "num_tasks": 3}'
const response = await fetch('https://api.dr.eamer.dev/v1/swarm/hive', {
  method: 'POST',
  headers: {
    'X-API-Key': 'your_api_key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    query: 'What are the latest advances in transformer architecture?',
    num_tasks: 3
  })
});

const reader = response.body.getReader();
const decoder = new TextDecoder();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  const text = decoder.decode(value);
  // Parse SSE events
  for (const line of text.split('\n')) {
    if (line.startsWith('data: ')) {
      const event = JSON.parse(line.slice(6));
      console.log(event.status, event.message);
    }
  }
}
POST /v1/swarm/chat

Simple streaming chat. Supports both single query and multi-turn conversation formats.

Request Body (JSON)

ParameterTypeDescription
querystringChat message (use this or messages)
messagesarrayChat messages array: [{role: "user", content: "..."}]
# Simple query
curl -N "https://api.dr.eamer.dev/v1/swarm/chat" \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"query": "Explain quantum entanglement simply"}'

# Multi-turn conversation
curl -N "https://api.dr.eamer.dev/v1/swarm/chat" \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"messages": [{"role": "user", "content": "What is CRISPR?"}, {"role": "assistant", "content": "CRISPR is..."}, {"role": "user", "content": "How is it used in medicine?"}]}'
GET /v1/swarm/health

Check Swarm service health. No authentication required.

curl "https://api.dr.eamer.dev/v1/swarm/health"

Utilities

Image processing, PDF extraction, text-to-speech, format conversion, news, web search, and reference lookups. Also available standalone at /utilities/api/ (port 5021).

POST /v1/utils/images/resize

Resize images while optionally maintaining aspect ratio.

Request Body
image string
Base64 encoded image
width integer
Target width (optional if height provided)
height integer
Target height (optional if width provided)
maintain_aspect boolean
Maintain aspect ratio (default: true)
format string
Output format: png, jpeg, webp (default: png)
POST /v1/utils/images/convert

Convert image between different formats.

Request Body
image string
Base64 encoded image
format string
Target format: png, jpeg, webp, gif, bmp
quality integer
Quality for lossy formats (1-100, default: 95)
POST /v1/utils/pdf/extract

Extract text content from PDF files.

Request Body
pdf string
Base64 encoded PDF
pages array
Specific page numbers to extract (1-indexed, optional)
include_metadata boolean
Include document metadata (default: false)
import base64

with open("document.pdf", "rb") as f:
    pdf_data = base64.b64encode(f.read()).decode()

response = requests.post(
    "https://api.dr.eamer.dev/v1/utils/pdf/extract",
    headers={"X-API-Key": "your_api_key"},
    json={
        "pdf": pdf_data,
        "pages": [1, 2, 3],  # Extract first 3 pages
        "include_metadata": True
    }
)

result = response.json()
print(result["text"])  # Combined text from all pages
POST /v1/utils/tts

Multi-provider text-to-speech. Returns MP3 audio. Providers: gTTS (free, 100+ languages), OpenAI (6 neural voices), ElevenLabs (voice cloning).

Request Body
text string (required)
Text to convert to speech (max 5000 chars)
provider string
TTS provider: gtts (default), openai, elevenlabs
voice string
Voice name for OpenAI (alloy, echo, fable, onyx, nova, shimmer) or ElevenLabs voice ID
lang string
Language code for gTTS (default: en)
# Free Google TTS
curl -X POST https://api.dr.eamer.dev/v1/utils/tts \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"text": "Hello world", "provider": "gtts", "lang": "en"}' -o speech.mp3

# OpenAI neural voice
curl -X POST https://api.dr.eamer.dev/v1/utils/tts \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"text": "Hello world", "provider": "openai", "voice": "nova"}' -o speech.mp3
GET /v1/utils/tts/providers

List available TTS providers with capabilities, max character limits, and voice options.

GET /v1/utils/voices

List available voices per TTS provider. OpenAI: alloy, echo, fable, onyx, nova, shimmer. ElevenLabs: dynamic from API. gTTS: language-based.

Query Parameters
provider string
Filter by provider: openai, elevenlabs, gtts, or all (default: all)
GET /v1/utils/languages

List supported gTTS languages with their codes. 100+ languages available.

POST /v1/utils/convert

Convert data between formats: JSON, YAML, TOML, XML, CSV. Any format to any format.

Request Body
data string | object (required)
Data to convert (string or object)
source_format string
Source format: json, yaml, toml, xml, csv (default: json)
target_format string
Target format: json, yaml, toml, xml, csv (default: yaml)
pretty boolean
Pretty-print output (default: true)
curl -X POST https://api.dr.eamer.dev/v1/utils/convert \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"data": {"name": "test", "value": 42}, "source_format": "json", "target_format": "yaml"}'
GET /v1/utils/news/headlines

Top news headlines from NewsAPI.org (80,000+ sources).

Query Parameters
country string
Country code: us, gb, etc. (default: us)
category string
Category: business, technology, science, health, sports, entertainment
q string
Search query within headlines
page_size integer
Number of results (default: 20, max: 100)
curl "https://api.dr.eamer.dev/v1/utils/news/headlines?country=us&category=technology" \
  -H "X-API-Key: your_api_key"
GET /v1/utils/news/search

Search news articles by keyword with date range and sort options.

Query Parameters
q string (required)
Search query
from string
Start date (YYYY-MM-DD)
to string
End date (YYYY-MM-DD)
sort_by string
Sort: relevancy, popularity, publishedAt (default: publishedAt)
GET /v1/utils/search

Web search via SerpAPI (Google results). Returns organic results with titles, URLs, and snippets.

Query Parameters
q string (required)
Search query
num integer
Number of results (default: 10, max: 100)
gl string
Country code for localized results (us, uk, etc.)
curl "https://api.dr.eamer.dev/v1/utils/search?q=climate+change&num=10" \
  -H "X-API-Key: your_api_key"
GET /v1/utils/books/search

Search books via OpenLibrary. Returns titles, authors, ISBNs, cover images, and publication dates.

Query Parameters
q string (required)
Search query (title, author, or subject)
limit integer
Number of results (default: 10, max: 100)
curl "https://api.dr.eamer.dev/v1/utils/books/search?q=dune" \
  -H "X-API-Key: your_api_key"
GET /v1/utils/books/isbn/{isbn}

Look up a book by ISBN. Returns full metadata including title, authors, publishers, page count, subjects, and cover URL.

Path Parameters

ParameterTypeDescription
isbnstringISBN-10 or ISBN-13

Advanced LLM

Specialized LLM capabilities: Gemini grounded search, code execution, embeddings, semantic similarity, tiered model selection, and Anthropic Batch API for async large-scale inference.

POST /v1/llm/grounded-chat

Chat with real-time Google Search grounding via Gemini. Best for current events, prices, sports scores, and time-sensitive queries.

Request Body
promptstring
User message (or use messages array)
modelstring
Gemini model (default: gemini-2.0-flash)
dynamic_thresholdnumber
Grounding aggressiveness 0.0–1.0 (default: 0.3)
curl -X POST https://api.dr.eamer.dev/v1/llm/grounded-chat \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "What is the current price of AAPL stock?"}'
POST /v1/llm/code-execute

Gemini writes and runs Python code to solve computation and data tasks. Returns both the code and the result.

Request Body
promptstring
Task description — Gemini writes and runs the code
modelstring
Gemini model (default: gemini-2.0-flash)
curl -X POST https://api.dr.eamer.dev/v1/llm/code-execute \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "Calculate the 50th Fibonacci number"}'
POST /v1/llm/embed-batch

Generate embeddings for a batch of texts. Returns vectors suitable for similarity search, clustering, or RAG pipelines.

Request Body
textsarray
List of strings to embed
providerstring
Embedding provider (default: openai)
curl -X POST https://api.dr.eamer.dev/v1/llm/embed-batch \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"texts": ["climate change effects", "ocean temperature rise"]}'
POST /v1/llm/similarity

Calculate semantic similarity between two texts. Returns a score from 0.0 (unrelated) to 1.0 (identical meaning).

Request Body
text1string
First text
text2string
Second text
providerstring
Embedding provider (default: openai)
curl -X POST https://api.dr.eamer.dev/v1/llm/similarity \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text1": "the cat sat on the mat", "text2": "a feline rested on a rug"}'
POST /v1/llm/tiered-select

Get the optimal model for a task without running inference. Useful for planning cost-efficient workflows before committing to a provider.

Request Body
taskstring
Task description (e.g. "summarize a 10-page research paper")
budget_tierstring
cheap | balanced | premium (default: balanced)
providerstring
Provider family (default: gradient_v2)
curl -X POST https://api.dr.eamer.dev/v1/llm/tiered-select \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"task": "classify short customer reviews", "budget_tier": "cheap"}'
POST /v1/llm/batch/create

Submit a batch of Anthropic prompts for async processing at reduced cost. Use GET /v1/llm/batch/<batch_id>/results to retrieve results when complete.

Request Body
requestsarray
Array of request objects with custom_id and messages
modelstring
Claude model (default: claude-3-haiku-20240307)
max_tokensinteger
Max tokens per response (default: 1024)
curl -X POST https://api.dr.eamer.dev/v1/llm/batch/create \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "requests": [
    {"custom_id": "r1", "messages": [{"role":"user","content":"What is 2+2?"}]},
    {"custom_id": "r2", "messages": [{"role":"user","content":"Capital of France?"}]}
  ]
}'

Text Processing

Citation formatting, keyword extraction, text summarization, and format conversion between Markdown, HTML, and plain text.

POST /v1/utils/citations/format

Format a citation in APA, MLA, Chicago, or BibTeX style. No API key required.

Request Body
citationobject
Object with title, authors (array), year, journal, doi, url
stylestring
apa | mla | chicago | bibtex (default: apa)
curl -X POST https://api.dr.eamer.dev/v1/utils/citations/format \
  -H "Content-Type: application/json" \
  -d '{"citation": {"title": "Attention Is All You Need", "authors": ["Vaswani"], "year": 2017}, "style": "apa"}'
POST /v1/utils/text/keywords

Extract the top keywords from any text using frequency analysis. No API key required.

Request Body
textstring
Input text to analyze
top_kinteger
Number of keywords to return (default: 10)
curl -X POST https://api.dr.eamer.dev/v1/utils/text/keywords \
  -H "Content-Type: application/json" \
  -d '{"text": "Machine learning models are trained on large datasets...", "top_k": 5}'
POST /v1/utils/text/summarize

Summarize text using an LLM. Supports paragraph or bullet-point style.

Request Body
textstring
Text to summarize
max_wordsinteger
Target length in words (default: 150)
stylestring
paragraph | bullet (default: paragraph)
providerstring
LLM provider (default: xai)
curl -X POST https://api.dr.eamer.dev/v1/utils/text/summarize \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "...", "max_words": 100, "style": "bullet"}'
POST /v1/utils/format/convert

Convert between Markdown, HTML, and plain text formats. No API key required.

Request Body
contentstring
Input content to convert
from_formatstring
markdown | html | plain
to_formatstring
markdown | html | plain
curl -X POST https://api.dr.eamer.dev/v1/utils/format/convert \
  -H "Content-Type: application/json" \
  -d '{"content": "# Hello World", "from_format": "markdown", "to_format": "html"}'

Async Workflows

Check status, stream progress, and cancel long-running orchestration workflows started with POST /v1/orchestrate/dream-cascade or POST /v1/orchestrate/dream-swarm.

GET /v1/orchestrate/{task_id}/status

Poll the current status of an async workflow. Returns status, workflow type, timestamps, and result when complete.

Path Parameters
task_idstring
Task ID returned when the workflow was created
curl https://api.dr.eamer.dev/v1/orchestrate/TASK_ID/status \
  -H "X-API-Key: YOUR_KEY"
GET /v1/orchestrate/{task_id}/stream

SSE stream of workflow progress. Polls every 2 seconds, emits status events, and closes when the workflow completes or errors. Max 10 minutes.

Path Parameters
task_idstring
Task ID returned when the workflow was created
curl -N https://api.dr.eamer.dev/v1/orchestrate/TASK_ID/stream \
  -H "X-API-Key: YOUR_KEY"
DELETE /v1/orchestrate/{task_id}

Mark a workflow as canceled. Note: the background thread may finish anyway — this marks the record, it does not kill the process.

curl -X DELETE https://api.dr.eamer.dev/v1/orchestrate/TASK_ID \
  -H "X-API-Key: YOUR_KEY"

Tool Registry

Browse and execute the 36 registered tools covering data sources, LLM providers, and utility functions. Tools are self-describing — each has a name, description, and parameter schema.

GET /v1/tools

List all 36 registered tools with their descriptions and parameter schemas. No API key required for browsing.

curl https://api.dr.eamer.dev/v1/tools
POST /v1/tools/{tool_name}

Execute a registered tool by name. Pass parameters as a JSON body. See GET /v1/tools for the full parameter schema for each tool.

Path Parameters
tool_namestring
Tool name from the registry (e.g. arxiv_search, github_search, nasa_apod)
curl -X POST https://api.dr.eamer.dev/v1/tools/arxiv_search \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "transformer architecture", "max_results": 5}'

Social Search

Search social media platforms including Bluesky, Mastodon, and others via the Antisocial service.

POST /v1/social/search

Search social media posts across platforms. Returns recent posts matching the query.

Request Body
querystring
Search term
platformstring
bluesky | mastodon | twitter (default: bluesky)
limitinteger
Max results (default: 20)
curl -X POST https://api.dr.eamer.dev/v1/social/search \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "open source LLMs", "platform": "bluesky", "limit": 10}'

Screenshot

Capture full-page screenshots of any public URL via Playwright. Returns base64-encoded PNGs sized to common social media, mobile, and high-resolution presets. Useful for generating Open Graph images, device mockups, or archiving page state.

POST /v1/screenshot/capture

Capture one or more screenshots of a URL at preset dimensions. Each result includes the preset name, pixel dimensions, MIME type, and the image as a base64-encoded PNG string.

Request Body
url string (required)
Public URL to capture.
presets array of strings
Which size presets to capture. Defaults to all social presets when omitted. Available values: og-facebook, twitter, linkedin, instagram-square, instagram-portrait, instagram-story, pinterest, mobile-iphone, mobile-android, tablet-portrait, 2k, 4k, 8k, 16k.
waitStrategy string
When to consider the page ready before capturing. Options: networkidle (default), load, domcontentloaded, commit.
customSelector string
CSS selector to wait for before capturing (optional). Useful for pages with lazy-loaded content.
extraWaitMs integer
Additional milliseconds to wait after the page is ready (optional, max 30000).
Response
{
  "url": "https://example.com",
  "screenshots": [
    {
      "preset": "og-facebook",
      "label": "Facebook OG (1200x630)",
      "width": 1200,
      "height": 630,
      "mimeType": "image/png",
      "imageData": "iVBORw0KGgoAAAANSUhEUgA..."
    }
  ]
}
curl -X POST https://api.dr.eamer.dev/v1/screenshot/capture \
  -H "X-API-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://lukesteuber.com",
    "presets": ["og-facebook", "twitter"],
    "waitStrategy": "networkidle"
  }'
import requests, base64

resp = requests.post(
    "https://api.dr.eamer.dev/v1/screenshot/capture",
    headers={"X-API-Key": "YOUR_KEY"},
    json={
        "url": "https://lukesteuber.com",
        "presets": ["og-facebook", "twitter"],
        "waitStrategy": "networkidle"
    }
)
data = resp.json()

for shot in data["screenshots"]:
    filename = f"{shot['preset']}.png"
    with open(filename, "wb") as f:
        f.write(base64.b64decode(shot["imageData"]))
    print(f"Saved {filename} ({shot['width']}x{shot['height']})")
const res = await fetch("https://api.dr.eamer.dev/v1/screenshot/capture", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    url: "https://lukesteuber.com",
    presets: ["og-facebook", "twitter"],
    waitStrategy: "networkidle"
  })
});

const { screenshots } = await res.json();

for (const shot of screenshots) {
  const img = document.createElement("img");
  img.src = `data:image/png;base64,${shot.imageData}`;
  img.alt = shot.label;
  document.body.appendChild(img);
}