> ## 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.

# Authenticated SDK surfaces

> User-scoped SDK wrappers for theses, portfolio, intents, execution, watchlists, and alert rules.

Authenticated SDK reads require an API key:

```ts theme={null}
import { SimpleFunctions } from "@spfunctions/sdk"

const sf = new SimpleFunctions({
  apiKey: process.env.SF_API_KEY,
  baseUrl: process.env.SF_API_URL,
})
```

## Theses

```ts theme={null}
const theses = await sf.theses.list({ status: "active", limit: 10 })
const thesis = await sf.theses.get("thesis-id")
```

## Portfolio

```ts theme={null}
const state = await sf.portfolio.state()
const ticks = await sf.portfolio.ticks.list({ limit: 10, envelope: true })
const trades = await sf.portfolio.trades.list({ limit: 10, envelope: true })
```

## Intents

```ts theme={null}
const intents = await sf.intents.list({ active: true })
const intent = await sf.intents.get("intent-id")
const created = await sf.intents.create({
  action: "buy",
  venue: "kalshi",
  marketId: "KXFED-27APR-T3.50",
  marketTitle: "Fed target rate",
  direction: "yes",
  targetQuantity: 1,
  maxPrice: 32,
  autoExecute: true,
})
const canceled = await sf.intents.cancel(created.id)
```

`intents.create` and `intents.cancel` are live-trade side-effect tools. Use them only with API keys that are meant to mutate execution state.

## Execution

```ts theme={null}
const placed = await sf.execution.place({
  ticker: "KXFED-27APR-T3.50",
  action: "buy",
  quantity: 1,
  limitPrice: 32,
})

const polyPlaced = await sf.execution.place({
  venue: "polymarket",
  tokenId: "POLYMARKET_CLOB_TOKEN_ID",
  action: "buy",
  quantity: 1,
  limitPrice: 32,
})
```

`execution.place` is the canonical Kalshi and Polymarket live execution wrapper. It ensures a usable runtime before creating the executable intent unless you pass `runtime: { mode: "none" }`. Polymarket requires a CLOB token id and an explicit limit price. The legacy `live_trade` name is an Agent compatibility alias, not the SDK method.

## Watchlists and alerts

```ts theme={null}
const watched = await sf.watchlists.list({ limit: 20 })
const addedWatch = await sf.watchlists.add({ ticker: "KXFED-27APR-T3.50" })
const alerts = await sf.alerts.list({ status: "active", limit: 20 })
const createdAlert = await sf.alerts.create({
  watch: addedWatch.object.id,
  type: "price_above",
  threshold: 60,
  idempotencyKey: "agent-run-123:fed-alert",
})
```

`watchlists.list()` and `alerts.list()` are user-scoped reads with `sideEffect: none`.
`watchlists.add()` is a governed `user_write` wrapper over the idempotent `/api/watch`
upsert keyed by user and canonical object. `alerts.create()` is also governed
`user_write`: the API accepts an explicit idempotency key and also derives a semantic
key from watched object, condition, severity, delivery channels, and webhook endpoint.
Those keys are backed by DB unique indexes, so normal retries and concurrent duplicate
alert creation return the existing rule instead of creating duplicates.
