v3.0.0  ·  GA

GODLE API reference

The GODLE API gives you programmatic access to 185 expert roles and 1,741 prompt templates, plus a stateful execution engine that handles LLM calls, eval-driven retries, sessions, streaming, and multi-step workflow orchestration.

The API has two layers with different base URLs:

Layer 1 https://godle.app/api/v3 — static JSON, CDN-cached, no auth
Layer 2 https://orchestration.godle.app — stateful edge execution, Cloudflare Workers

Both layers are live. Layer 1 is open and requires no API key. Layer 2 requires a Bearer token — see the authentication section.

Quick start

Fetch a role and run it against any LLM in under two minutes.

1
Fetch a role

No auth required. Layer 1 is open and CDN-cached.

bash
curl https://godle.app/api/v3/roles/copywriter.json

You get the role's systemPrompt, all its templates with pre-written prompts, eval rubrics, and nextSteps for chaining to other roles.

2
Discover the right role for any intent

Not sure which role to use? Match a natural-language intent against all 1,741 capabilities (requires Layer 2).

bash
curl -X POST https://orchestration.godle.app/api/v3/capabilities/match \
  -H "Authorization: Bearer sk-godle-your-key" \
  -H "Content-Type: application/json" \
  -d '{"intent": "write a compelling product launch email"}'
3
Submit a task and stream the output

Layer 2 calls the LLM, runs eval checks, and retries automatically. You get a live SSE stream.

javascript
// Submit a task
const { id: taskId } = await fetch('https://orchestration.godle.app/api/v3/tasks', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer sk-godle-your-key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    roleId:      'copywriter',
    templateKey: 'product-launch-email',
    input:       'Product: TaskFlow. Audience: remote teams.',
    autoApprove: true
  })
}).then(r => r.json());

// Stream output via SSE
const res = await fetch(`https://orchestration.godle.app/api/v3/tasks/${taskId}/stream`, {
  headers: { 'Authorization': 'Bearer sk-godle-your-key' }
});
// ... handle ReadableStream (see Streaming section)
💡

Prefer a no-setup path? Load the SDK from CDN and call GODLE.run('copywriter', 'your prompt') — it handles the fetch, eval, and output in one call. See the SDK reference.

Architecture

The API has two layers that work together. You can use Layer 1 alone, or combine both.

Layer 1 — Static CDN (always live)
185 expert role definitions
1,741 prompt templates
Capability index (searchable)
Workflow DAG definitions
Eval rubrics
UMD SDK bundle
MCP manifest / A2A Agent Card
Layer 2 — Cloudflare Workers
LLM execution (Anthropic / OpenAI)
Eval-driven retries (up to 3×)
Sessions + memory (Durable Objects)
Streaming via SSE
Workflow DAG orchestration
MCP JSON-RPC endpoint
A2A task protocol
Layer 1Layer 2
HostVercel CDNCloudflare Workers
AuthNone requiredBearer API key
StateStateless JSONDurable Objects (12h TTL)
DeployLive — Vercel CDNLive — orchestration.godle.app
Use forRoles, templates, capability indexTask execution, sessions, streaming

Authentication

All Layer 2 endpoints require a Bearer token in the Authorization header:

http
Authorization: Bearer sk-godle-your-key-here

For MCP endpoints, the key can alternatively be passed as params._apiKey inside the JSON-RPC body. The MCP and A2A endpoints also function in an unauthenticated mode (no rate limiting applied).

Layer 1 endpoints (CDN static files) require no authentication.

Provisioning API keys

API keys are stored as a Cloudflare Worker secret. Set them before deploying:

bash
# Comma-separated list of valid keys
wrangler secret put GODLE_API_KEYS
# When prompted, enter: sk-godle-key1,sk-godle-key2

Every response from Layer 2 includes an X-Request-Id header (req_xxxxxxxx) for distributed tracing.

Rate limits

Layer 2 enforces a sliding-window limit of 60 requests per minute per API key, backed by Cloudflare KV.

The limit is configurable via the RATE_LIMIT_RPM environment variable in wrangler.toml.

Rate-limited requests return HTTP 429:

json
{
  "error": {
    "code":    "RATE_LIMITED",
    "message": "Too many requests. Limit: 60/min"
  }
}

Layer 1 (CDN) has no rate limits. Requests are served directly from the Vercel edge cache with a Cache-Control: public, max-age=3600, s-maxage=86400 header.

Error format

All Layer 2 errors use a consistent JSON envelope:

json
{
  "error": {
    "code":    "ERROR_CODE",
    "message": "Human-readable description"
  }
}
HTTPCodeWhen
400BAD_REQUESTMalformed JSON or missing required field
401UNAUTHORIZEDMissing or invalid API key
402BUDGET_EXHAUSTEDSession token budget exceeded
404NOT_FOUNDResource does not exist
405METHOD_NOT_ALLOWEDWrong HTTP method for this path
409CONFLICTResource already exists or invalid state transition
410GONESession has expired (12h TTL)
413PAYLOAD_TOO_LARGERequest body exceeds 100 KB
429RATE_LIMITEDExceeded 60 requests/minute
500INTERNAL_ERRORUnexpected worker error
502LAYER1_UNAVAILABLEWorker failed to fetch from CDN

Layer 1 — static endpoints

All Layer 1 endpoints are served from https://godle.app/api/v3. No authentication. Responses are CDN-cached for up to 24 hours at the edge (s-maxage=86400) and 1 hour in browsers (max-age=3600).

Roles

GET /api/v3/roles.json CDN cached

Returns all 185 expert roles — slugs, names, categories, descriptions, system prompts, templates, and nextSteps for multi-role chains.

json — response
{
  "version":     "3.0.0",
  "generatedAt": "2026-02-25T00:00:00Z",
  "totalRoles":  185,
  "roles": [
    {
      "slug":         "copywriter",
      "name":         "Copywriter",
      "category":     "content",
      "description":  "Expert at persuasive, brand-aligned copy",
      "systemPrompt": "You are an expert copywriter...",
      "templates": [
        {
          "key":    "product-launch-email",
          "label": "Product Launch Email",
          "prompt": "Write a product launch email for..."
        }
      ],
      "nextSteps": ["designer", "strategist"]
    }
  ]
}
GET /api/v3/roles/{slug}.json CDN cached

Returns a single role by slug with full template list and eval rubric data. The slug is the role's slug field (e.g., copywriter, software-engineer).

GET /api/v3/roles/{slug}/templates.json CDN cached

Returns only the template array for a role. Useful for lighter payloads when you already have the role metadata.

GET /api/v3/categories.json CDN cached

Returns all 24 role categories with labels and slugs. Use this to build category filters or navigation.

GET /api/v3/workflows.json CDN cached

Returns all workflow definitions including DAG step configs, input mappings, and handoff schemas. Use these as templates for POST /api/v3/tasks/compose.

Capability index

GET /api/v3/capabilities.json CDN cached

Returns the full capability index: 1,741 entries, each representing one role + template pair. Each entry includes intent phrases, tags, domains, expected output sections, and token estimates. This is the data source used by POST /capabilities/match on Layer 2.

json — capability entry
{
  "id":              "copywriter--product-launch-email",
  "roleId":          "copywriter",
  "templateKey":     "product-launch-email",
  "templateLabel":   "Product Launch Email",
  "intent":          ["write launch email", "announce product"],
  "tags":            ["email", "marketing", "launch"],
  "domains":         ["saas", "ecommerce", "startup"],
  "outputSections":  ["subject", "preview", "body", "cta"],
  "constraints":     { "estimatedOutputTokens": 800 }
}

Eval rubrics

GET /api/v3/evals/{roleSlug}--{templateKey}.json CDN cached

Returns the LLM-as-judge eval rubric for a specific role + template pair. The task executor fetches this automatically when evalRetry: true is set on a task. The rubric defines scoring criteria and pass/fail thresholds.

bash
curl https://godle.app/api/v3/evals/copywriter--product-launch-email.json

SDK bundle and protocol manifests

GET /api/v3/godle-sdk.js CDN cached

The UMD SDK bundle. Load in a <script> tag to get window.GODLE with all 7 modules. See the SDK reference for the full API surface.

GET /.well-known/mcp.json CDN cached

MCP tool manifest. Register this URL with any MCP host to expose GODLE's 4 tools (godle/list_roles, godle/match_capability, godle/execute_task, godle/compose_workflow).

GET /.well-known/agent.json CDN cached

A2A Agent Card. Register this URL with an A2A orchestrator to make GODLE available as an agent. The card describes supported skills and input/output schemas.

Layer 2 — Capabilities

These endpoints run on https://orchestration.godle.app and require a valid API key.

POST /api/v3/capabilities/match Auth required

Find the best role + template for a natural-language intent. Scores all 1,741 capabilities by keyword overlap across intent[], tags[], domains[], and the capability ID. Returns ranked matches.

json — request
{ "intent": "write a compelling product launch email" }
json — response
{
  "intent":          "write a compelling product launch email",
  "totalCandidates": 1741,
  "matches": [
    {
      "capabilityId":  "copywriter--product-launch-email",
      "roleId":        "copywriter",
      "templateKey":   "product-launch-email",
      "score":         4,
      "outputSections": ["subject", "preview", "body", "cta"],
      "constraints":   { "estimatedOutputTokens": 800 }
    }
  ]
}
POST /api/v3/capabilities/negotiate Auth required

Negotiate model hint, token budget, and estimated cost/latency for a capability before running it. Useful for cost-gating or latency-sensitive UIs.

json — request
{
  "capabilityId": "copywriter--product-launch-email",
  "budget":       0.10,
  "latencyMs":    4000,
  "qualityLevel": "high"
}
FieldTypeRequiredDescription
capabilityIdstringRequiredCapability ID from /match or capabilities.json
budgetnumberOptionalMax cost in USD
latencyMsnumberOptionalMax acceptable latency
qualityLevelstringOptional"fast" | "balanced" (default) | "high"

Sessions

Sessions are server-side stateful contexts stored in Cloudflare Durable Objects. They persist for 12 hours by default and can hold memory, token budgets, and task references across multiple calls.

POST /api/v3/sessions Auth required

Create a new session. Returns HTTP 201 on success.

json — request
{
  "config": {
    "defaultTone":        "balanced",
    "maxConcurrentTasks": 5,
    "costBudgetTokens":   100000
  },
  "callerAgent": { "name": "my-agent", "version": "1.0" }
}
json — response (201)
{
  "id":        "ses_abc12345",
  "version":   "3.0.0",
  "keyId":     "key_abc12345",
  "createdAt": "2026-02-25T10:00:00Z",
  "expiresAt": "2026-02-25T22:00:00Z",
  "status":    "active",
  "config":    {
    "defaultTone":        "balanced",
    "costBudgetTokens":   100000,
    "costConsumedTokens": 0
  },
  "tasks": []
}
GET /api/v3/sessions/{sessionId} Auth required

Retrieve current session state including token consumption and task list. Returns 410 GONE if the session has expired, 404 NOT_FOUND if it was explicitly deleted.

DELETE /api/v3/sessions/{sessionId} Auth required

Terminate a session immediately. All associated memory is deleted. Tasks that were attached to this session are not cancelled — they continue running but can no longer debit the session's token budget.

json — response
{ "id": "ses_abc12345", "status": "ended" }

Sessions expire automatically after 12 hours. If your app is long-running, create a fresh session before the old one expires and pass the new sessionId on subsequent tasks.

Tasks

Tasks are the core execution unit. Each task runs inside a Cloudflare Durable Object, supporting streaming, human-in-the-loop approval gates, and eval-driven automatic retries.

Task lifecycle

submitted running completed awaiting_approval running completed failed any state → cancelled
POST /api/v3/tasks Auth required

Submit a task for execution. Returns HTTP 202 immediately. Execution starts within ~50 ms via a Durable Object alarm. Poll GET /tasks/{id} or connect to the SSE stream to receive the result.

FieldTypeDefaultDescription
roleIdstringGodle role slug (e.g., copywriter)
templateKeystringTemplate within the role
inputstring""Task description or user prompt
sessionIdstringAttach to a session for memory and token budget
tonestring"balanced""fast" | "balanced" | "detailed"
evalRetrybooleantrueAutomatically retry if eval fails (up to 3×)
autoApprovebooleanfalseSkip human approval gates
json — response (202)
{
  "id":          "task_xyz98765",
  "status":      "submitted",
  "roleId":      "copywriter",
  "templateKey": "product-launch-email",
  "createdAt":   "2026-02-25T10:00:00Z"
}
GET /api/v3/tasks/{taskId} Auth required

Get the current task state. When status is "completed", the response includes the artifacts array with the generated content, eval result, and provenance metadata.

json — completed task
{
  "id":          "task_xyz98765",
  "status":      "completed",
  "completedAt": "2026-02-25T10:00:42Z",
  "artifacts": [
    {
      "id":         "art_abc12345",
      "type":       "text",
      "mimeType":   "text/plain",
      "content":    "Subject: Something big is coming...",
      "evalResult": { "passed": true, "score": 92, "checks": [] },
      "provenance": {
        "modelUsed":    "claude-sonnet-4-6",
        "generatedAt": "2026-02-25T10:00:42Z",
        "attempt":     1
      }
    }
  ],
  "runLog": {
    "totalAttempts": 1,
    "model":         "claude-sonnet-4-6",
    "usage":         { "input_tokens": 512, "output_tokens": 280, "total_tokens": 792 },
    "evalScore":     92,
    "evalPassed":    true
  }
}
POST /api/v3/tasks/{taskId}/cancel Auth required

Cancel a task in any non-terminal state. Returns 409 CONFLICT if the task has already completed, failed, or been cancelled.

POST /api/v3/tasks/{taskId}/approve Auth required

Approve or reject a task that is in awaiting_approval state. When approved: false, the task transitions to failed.

json — request
{ "approved": true, "reason": "Looks good, proceed" }

Streaming (SSE)

GET /api/v3/tasks/{taskId}/stream Auth required

Connect to a Server-Sent Events stream for a running task. The stream closes automatically when the task reaches a terminal state (completed, failed, or cancelled).

The browser EventSource API does not support custom headers. Use fetch() with a ReadableStream reader to pass the Authorization header.

Event typeData shapeDescription
heartbeat{}Sent on connect to confirm the stream is live
status{ taskId, status }Emitted on every state transition
progress{ taskId, attempt, message }Progress notes per execution attempt
partial_artifact{ taskId, attempt, preview }First 500 chars of the output, streamed early
eval_result{ taskId, attempt, eval }Score and pass/fail after each eval check
completeFull task objectFinal state — stream closes after this event
error{ taskId, error }Task failed — stream closes after this event
cancelledFull task objectTask was cancelled — stream closes
javascript — SSE via fetch
const res = await fetch(`/api/v3/tasks/${taskId}/stream`, {
  headers: { 'Authorization': 'Bearer sk-godle-your-key' }
});

const reader  = res.body.getReader();
const decoder = new TextDecoder();
let buf = '';
let currentEvent = '';

while (true) {
  const { done, value } = await reader.read();
  if (done) break;

  buf += decoder.decode(value, { stream: true });
  const lines = buf.split('\n');
  buf = lines.pop(); // keep the incomplete trailing line

  for (const line of lines) {
    if (line.startsWith('event: ')) {
      currentEvent = line.slice(7).trim();
      continue;
    }
    if (!line.startsWith('data: ')) continue;

    const data = JSON.parse(line.slice(6));

    if (currentEvent === 'partial_artifact') {
      renderPreview(data.preview); // stream preview to UI
    }
    if (currentEvent === 'complete') {
      console.log(data.artifacts[0].content);
      reader.cancel();
    }
    if (currentEvent === 'error') {
      console.error(data.error);
      reader.cancel();
    }
  }
}

Workflow compose

POST /api/v3/tasks/compose Auth required

Submit a multi-step workflow as a directed acyclic graph (DAG). Steps with no dependsOn run in parallel. Steps with dependsOn wait for their predecessors and can reference prior outputs via interpolation.

Output interpolation

ExpressionResolves to
{{steps.{stepId}.output}}Text output of a completed step
{{steps.{stepId}.artifact.content}}Artifact content of a completed step
{{workflow.inputs.{key}}}Top-level input value from the inputs field
json — request
{
  "workflow": {
    "id": "launch-campaign",
    "steps": [
      {
        "id":     "research",
        "roleId": "researcher",
        "input":  "Top SaaS growth strategies 2025"
      },
      {
        "id":        "copy",
        "roleId":    "copywriter",
        "prompt":    "Write a launch email using these insights: {{steps.research.output}}",
        "dependsOn": ["research"],
        "modelHint": "balanced"
      }
    ]
  },
  "inputs":      { "audience": "remote teams" },
  "autoApprove": true
}

MCP — Model Context Protocol

GODLE implements the Model Context Protocol (MCP) as a JSON-RPC 2.0 endpoint. Register GODLE with any MCP host and your AI agent can discover and invoke any of GODLE's 4 tools automatically.

POST /api/v3/mcp Auth optional

Auth is via Authorization: Bearer header or params._apiKey in the request body. Unauthenticated requests are accepted but not rate-limited by key.

Supported methods

MethodDescription
initializeMCP handshake — returns protocol version, server capabilities, and tool list
tools/listList all 4 available GODLE tools
tools/callInvoke a tool by name with arguments
resources/listList available MCP resources
resources/readRead godle://capabilities as JSON

Available tools

Tool nameRequired paramsDescription
godle/list_rolesList roles (optional: category, limit)
godle/match_capabilityintentFind the best role + template for an intent string
godle/execute_taskroleId, inputExecute a task synchronously, wait for result (max 50 s)
godle/compose_workflowworkflowExecute a multi-step workflow and wait for all results
json — tools/call request
{
  "jsonrpc": "2.0",
  "id":      1,
  "method":  "tools/call",
  "params":  {
    "name":      "godle/execute_task",
    "arguments": {
      "roleId": "copywriter",
      "input":  "Write a tagline for a coffee brand"
    }
  }
}
json — response
{
  "jsonrpc": "2.0",
  "id":      1,
  "result":  {
    "content":    [{ "type": "text", "text": "Wake up, world." }],
    "taskId":     "task_xyz",
    "evalResult": { "passed": true, "score": 95 }
  }
}

A2A — Agent-to-Agent Protocol

GODLE implements the Google Agent-to-Agent Protocol, allowing any A2A orchestrator to discover and delegate tasks to GODLE as an agent. Authentication is optional but recommended for rate-limiting by key.

POST /api/v3/a2a Auth optional

Supported methods

MethodDescription
tasks/sendSubmit a task and poll until completion (synchronous)
tasks/getGet task status by ID
tasks/cancelCancel a running task
tasks/sendSubscribeSubmit a task and receive a live SSE stream

State mapping

GODLE stateA2A state
submittedsubmitted
running / streamingworking
awaiting_approvalinput-required
completedcompleted
failedfailed
cancelledcanceled
json — tasks/send request
{
  "method":  "tasks/send",
  "id":      "my-task-123",
  "message": {
    "role":  "user",
    "parts": [{ "type": "text", "text": "Write a product tagline for a coffee brand" }]
  },
  "skill": { "roleId": "copywriter" }
}
json — response
{
  "id":        "my-task-123",
  "status":    { "state": "completed" },
  "artifacts": [{
    "index": 0,
    "name":  "output",
    "parts": [{ "text": "Wake up, world." }]
  }],
  "metadata": { "godleTaskId": "task_xyz98765" }
}

SDK reference

The GODLE SDK is a UMD bundle exposing 7 modules under window.GODLE. Load it from the CDN — no build step, no npm package.

html
<script src="https://godle.app/api/v3/godle-sdk.js"></script>
GODLE.run()
One-liner task execution. Fetches the role, calls the LLM, returns the output and eval score.
GODLE.suggest()
Intent router. Returns ranked role + template matches for a natural-language intent string.
GODLE.buildWorkflow()
Fluent workflow builder. Chain steps with .step(), set dependsOn, then .build() and GODLE.run().
GODLE.createSession()
Session management. Creates a server-side session with memory and token budget, returns a session handle.
GODLE.connectStream()
SSE stream client. Connects to a task stream and calls your callbacks for onProgress and onComplete.
GODLE.mcp.client()
MCP protocol client. Wraps the JSON-RPC endpoint with typed methods: listRoles, matchCapability, executeTask.
GODLE.a2a.client()
A2A protocol client. send(), get(), cancel() methods. Pair with GODLE.a2a.makeMessage() and toA2ATask().

Core — GODLE.run()

javascript
const result = await GODLE.run('copywriter', 'Write a tagline for a coffee brand', {
  tone:  'friendly',
  model: 'claude-sonnet-4-6'
});

console.log(result.output);           // "Wake up, world."
console.log(result.evalResult.score); // 0–100

Intent router — GODLE.suggest()

javascript
const suggestions = await GODLE.suggest('I need a compelling product launch email');
// Returns ranked role + template matches

Workflow builder — GODLE.buildWorkflow()

javascript
const wf = GODLE.buildWorkflow('launch-campaign')
  .step('research', 'researcher', 'Top SaaS strategies 2025')
  .step('copy', 'copywriter', '{{steps.research.output}}', { dependsOn: ['research'] })
  .build();

const result = await GODLE.run(wf);

Sessions — GODLE.createSession()

javascript
const session = await GODLE.createSession({
  baseUrl: 'https://orchestration.godle.app',
  apiKey:  'sk-godle-your-key',
  config:  { costBudgetTokens: 50000 }
});

// session.id is a server-side ID, e.g. "ses_abc12345"
const result = await GODLE.run('copywriter', 'Write a tagline', { session });

Streaming — GODLE.connectStream()

javascript
const stream = await GODLE.connectStream(taskId, {
  baseUrl:    'https://orchestration.godle.app',
  apiKey:     'sk-godle-your-key',
  onProgress: msg  => console.log('progress:', msg),
  onComplete: task => console.log(task.artifacts[0].content)
});

MCP client — GODLE.mcp.client()

javascript
const mcp = GODLE.mcp.client({ baseUrl: 'https://orchestration.godle.app', apiKey: 'sk-godle-...' });

const roles  = await mcp.listRoles({ limit: 10 });
const result = await mcp.executeTask({ roleId: 'copywriter', input: 'Write a tagline' });

A2A client — GODLE.a2a.client()

javascript
const a2a = GODLE.a2a.client({ baseUrl: 'https://orchestration.godle.app' });

const task    = await a2a.send({
  message: GODLE.a2a.makeMessage('Write a product tagline for a coffee brand'),
  skill:   { roleId: 'copywriter' }
});

const a2aTask = GODLE.a2a.toA2ATask(task);
console.log(a2aTask.artifacts[0].parts[0].text);

Provider adapters

Use GODLE.adapters to integrate with Anthropic or OpenAI directly (Layer 1 pattern — you bring your own API key).

javascript
const adapter = GODLE.adapters.anthropic({ apiKey: 'sk-ant-...' });
// or
const adapter = GODLE.adapters.openai({ apiKey: 'sk-...' });

const result = await GODLE.run('copywriter', 'Write a tagline', { adapter });

Playground

The interactive API playground lets you test every endpoint live — including Layer 1 fetches, task submission, streaming, MCP calls, and workflow composition. It auto-generates curl commands and saves your configuration in localStorage.

Try the API interactively

Set your worker URL and API key once. Then test any endpoint and see the raw request, response, and auto-generated curl command side by side.

Keyboard shortcut: Cmd+Enter (macOS) or Ctrl+Enter (Windows/Linux) sends a request in the playground.

v2 → v3 migration

The v3 API is a superset of v2. All Layer 1 static endpoints and SDK methods remain backward-compatible. Layer 2 is live at orchestration.godle.app and purely additive — use it alongside v2 without any breaking changes.

What you need to change

If you useChange required
Static role/template JSONUpdate /api/v2//api/v3/ in fetch URLs
SDK bundleUpdate the <script src> path from /v2/ to /v3/
GODLE.run() / GODLE.suggest()No change — API surface is identical
Layer 2 features (tasks, sessions)Deploy the Cloudflare Worker — then opt in per request

v1 and v2 URLs remain live and will not be removed without a deprecation period of at least 90 days with advance notice.

Deploying Layer 2 for the first time

bash
# 1. Create the KV namespace for rate limiting
wrangler kv:namespace create RATE_LIMITS
# → copy the returned id into wrangler.toml

# 2. Set secrets
wrangler secret put GODLE_API_KEYS     # sk-godle-key1,sk-godle-key2
wrangler secret put ANTHROPIC_API_KEY  # sk-ant-...
wrangler secret put OPENAI_API_KEY     # sk-...  (optional)

# 3. Deploy
wrangler deploy

For the full step-by-step deploy runbook including staging environment setup and CI/CD configuration, see the DEPLOY.md in the repository.