Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.simplefunctions.dev/llms.txt

Use this file to discover all available pages before exploring further.

@spfunctions/sdk is the TypeScript data and contract client for SimpleFunctions. Use it when you want your application or agent to know what is happening in prediction markets, macro policy, legislation, elections, and portfolio state without scraping prose or shelling out to the CLI. It is now published as an alpha package:
npm install @spfunctions/sdk@0.1.0-alpha.0
Alpha means the package is usable by early TypeScript consumers, but the public API is not yet GA. Pin the alpha version instead of relying on a floating semver range.

Start Here

Start with the SDK when you want a normal TypeScript client. Start with the Agent SDK when you want a governed runtime.
NeedUseWhy
Build a dashboard, notebook, backend job, or internal research service@spfunctions/sdkTyped data calls, contract inspection, SDK preflight, typed errors
Execute one canonical tool under policy, trace, and replay@spfunctions/agent v0Direct governed calls without an LLM loop
Let a model choose tools, react to watch events, and stream messages@spfunctions/agent/v1Agent loop, provider adapter, hooks, sessions, watch primitives
Let Claude Code, Codex, Cursor, or another external agent use SimpleFunctionsMCP or CLICompatibility layer for agent clients that already own the runtime
Claude Agent SDK, Codex SDK, and Cursor SDK give a coding agent file, shell, editor, or repo control. SimpleFunctions gives an agent market and world context: strict prediction-market tools, cost and side-effect metadata, traces, and semi-realtime deltas. They compose. Use the SDK directly in your app, use the Agent SDK when you want SimpleFunctions to own the governed tool loop, or expose SimpleFunctions through MCP when another agent runtime is already in charge.

Five-minute Market Monitor

This is the smallest useful SDK-only path: pull current world context, search related markets, and ask a research question. It is a good starting point for a fund monitor, macro policy workflow, election desk, or personal market dashboard.
import { SimpleFunctions } from "@spfunctions/sdk"

const sf = new SimpleFunctions({
  baseUrl: "https://simplefunctions.dev",
  apiKey: process.env.SF_API_KEY,
})

const world = await sf.world.get()

const markets = await sf.markets.search({
  query: "Iran oil Strait of Hormuz",
  limit: 5,
})

const brief = await sf.query.ask({
  q: [
    "Use current SimpleFunctions market context.",
    "Summarize the top Iran oil risk signals.",
    "Mention which markets moved and what would change the thesis.",
  ].join(" "),
})

console.log(world.asOf)
console.table(markets.markets?.map(market => ({
  ticker: market.ticker,
  title: market.title,
  price: market.price,
})))
console.log(brief.answer ?? brief)
For an embeddable agent version with policy, streaming, and trace/replay, use Agent SDK alpha or the SDK and Agent alpha quickstart.

What The SDK Is

The SDK is a typed wrapper over stable SimpleFunctions HTTP objects and the strict contract manifest. Use it when you want to build:
  • market-intelligence dashboards
  • internal research tools
  • macro policy monitors
  • election and legislation workflows
  • portfolio and thesis review tools
  • Agent SDK runtimes that need an identity-bearing client
The SDK is not:
  • the CLI
  • the Agent SDK
  • an MCP client
  • a browser runtime for long-lived API keys
  • a trading engine
  • a wrapper around every SimpleFunctions API route

Install

npm install @spfunctions/sdk@0.1.0-alpha.0
Node 18 or newer is required because the SDK uses the platform fetch API.

Authentication

Most useful SDK calls require a SimpleFunctions API key.
export SF_API_KEY="sf_..."
Then construct the client:
import { SimpleFunctions } from "@spfunctions/sdk"

const sf = new SimpleFunctions({
  baseUrl: "https://simplefunctions.dev",
  apiKey: process.env.SF_API_KEY,
})
The constructor also reads process.env.SF_API_KEY and process.env.SF_API_URL when explicit options are omitted. Do not expose a long-lived SF_API_KEY in browser code. Use the SDK from a server process, worker, backend job, notebook, or local agent harness.

No-key Bootstrap

The SDK is API-key-first, but strict manifest inspection works without a key:
const sf = new SimpleFunctions({ baseUrl: "https://simplefunctions.dev" })

const manifest = await sf.manifest.list()
const worldTool = await sf.manifest.get("world.read")
const legacyName = await sf.manifest.get("get_world_state")

console.log(manifest.schemaVersion) // "0.3.0-draft"
console.log(worldTool?.name)        // "world.read"
console.log(legacyName)             // null
No-key bootstrap is intentionally narrow. Data, research, user-data, and cost-bearing calls are preflighted against /api/contracts/tools metadata. If the contract has costEffect !== "none", sideEffect !== "none", authRequired: true, user_data permission, or access.anonymousAllowed: false, the SDK throws MissingApiKeyError before making the live request.

First Data Call

import { SimpleFunctions } from "@spfunctions/sdk"

const sf = new SimpleFunctions({
  baseUrl: "https://simplefunctions.dev",
  apiKey: process.env.SF_API_KEY,
})

const world = await sf.world.get()

console.log(world.asOf)
console.log(world.regime?.label)
console.log(world.salient?.map(item => item.label))
world.read is a real hosted data call. Its strict contract currently has:
{
  "name": "world.read",
  "sideEffect": "none",
  "costEffect": "api_cost",
  "access": { "anonymousAllowed": false }
}
So new SimpleFunctions().world.get() should fail with MissingApiKeyError unless SF_API_KEY is available in the environment.

Read And Research Surfaces

await sf.world.get()
await sf.world.delta({ since: "1h" })

await sf.markets.search({
  query: "Fed CPI",
  venue: "kalshi",
  limit: 10,
})

await sf.markets.discover({
  query: "oil geopolitics",
  limit: 5,
})

await sf.markets.get("KXRECESSION-26DEC31")
await sf.markets.history("KXRECESSION-26DEC31")

await sf.query.ask({
  q: "What are prediction markets saying about Fed cuts?",
})

await sf.econ.query({
  q: "unemployment rate",
  mode: "raw",
})

await sf.gov.query({
  q: "SAVE Act",
  mode: "raw",
})
These are read or research calls with sideEffect: "none". They still require identity when the strict contract marks them as cost-bearing.

Authenticated User Reads

await sf.theses.list()
await sf.theses.get("thesis-id")

await sf.portfolio.state()
await sf.portfolio.ticks.list({ limit: 5, envelope: true })
await sf.portfolio.trades.list({ limit: 5, envelope: true })

await sf.intents.list({ active: true })
await sf.watchlists.list()
await sf.alerts.list()
These calls require SF_API_KEY because they are account-scoped user-data reads.

User Writes In Alpha

The SDK alpha includes thesis write methods:
const thesis = await sf.theses.create({
  title: "Fed cuts by September",
  statement: "The target range will be lower after the September meeting.",
})

await sf.theses.signal(thesis.id, {
  type: "evidence",
  content: "New CPI print moved the relevant markets.",
})
These methods are not enabled as default Agent-callable tools. Their strict contracts are implemented, authenticated, and marked:
sideEffect: user_write
costEffect: api_cost
agent.callable: false

Request Metadata

SDK responses carry source metadata where the API provides it:
const world = await sf.world.get()

console.log(world.source?.endpoint)
console.log(world.source?.requestId)
console.log(world.source?.traceId)
Typed errors also carry request metadata:
import {
  MissingApiKeyError,
  PermissionDeniedError,
  SimpleFunctionsRateLimitError,
} from "@spfunctions/sdk"

try {
  await sf.theses.list()
} catch (error) {
  if (error instanceof MissingApiKeyError) {
    console.error(error.code, error.tool, error.reason)
  } else if (error instanceof PermissionDeniedError) {
    console.error(error.status, error.requestId)
  } else if (error instanceof SimpleFunctionsRateLimitError) {
    console.error("retry later", error.status)
  } else {
    throw error
  }
}
The SDK exports typed errors for missing or invalid keys, permission failures, validation failures, not-found responses, conflicts, rate limits, upstream failures, invalid JSON, and timeouts.

Pagination Helpers

Some authenticated reads return SimpleFunctions page envelopes:
import { getNextCursor, hasMore } from "@spfunctions/sdk"

let page = await sf.intents.list({ limit: 5 })

while (hasMore(page)) {
  page = await sf.intents.list({
    limit: 5,
    cursor: getNextCursor(page) ?? undefined,
  })
}

Contract Truth

The SDK uses /api/contracts/tools as its strict truth source.
curl https://simplefunctions.dev/api/contracts/tools
Current production manifest:
schemaVersion: 0.3.0-draft
active implemented tools: 21
Agent-callable read tools: 19
implemented but not Agent-callable writes: theses.create, theses.signal
Use canonical dotted names such as world.read, markets.search, and market.inspect. Do not treat /api/tools names such as get_world_state as SDK contract names. /api/tools is the broader hosted compatibility inventory.

Boundary With CLI And Agent SDK

SurfaceUse it for
@spfunctions/sdkTyped data, user reads/writes, contract inspection
@spfunctions/agent v0Governed direct tool execution in TypeScript
@spfunctions/agent/v1Alpha model loop, sessions, hooks, watch primitives
sf agent --toolCommand-line direct tool wrapper
/api/contracts/toolsCanonical SDK/Agent truth
/api/toolsBroad hosted compatibility inventory
MCP serverBroad agent-client adapter, not SDK truth

Not In SDK Alpha

The SDK alpha does not include:
  • live trading
  • direct venue order placement
  • browser long-lived API keys
  • every CLI command
  • every /api/public/* route
  • every MCP tool
  • events.*
  • market.related
  • auth.status
  • investigations.create
  • intents.propose
  • webhooks.create
  • live_trade
Those surfaces require separate contract, auth, side-effect, cost, and policy decisions before becoming SDK or Agent SDK surfaces.