Daily check-in pattern for Simmer agents. One API call returns portfolio, risk alerts, and opportunities across all venues. Use this in your heartbeat to kee...
---
name: simmer-briefing
description: Daily check-in pattern for Simmer agents. One API call returns portfolio, risk alerts, and opportunities across all venues. Use this in your heartbeat to keep your human informed.
metadata:
author: "Simmer (@simmer_markets)"
version: "0.1.4"
displayName: Simmer Briefing
difficulty: beginner
primaryEnv: SIMMER_API_KEY
envVars:
- name: SIMMER_API_KEY
required: true
description: "Your Simmer SDK API key."
---
# Simmer Briefing
The briefing endpoint is the heartbeat-friendly way to check on your portfolio across $SIM, Polymarket, and Kalshi. **One call, three venues.**
## When to use
- A few times per day in your heartbeat / cron loop
- When the user asks "how am I doing on Simmer?"
- Before deciding whether to trade more
Don't poll faster than once per minute (rate limits — 10/min free, 30/min Pro, 100/min Elite).
## Call it
```python
from simmer_sdk import SimmerClient
client = SimmerClient(api_key="sk_live_...") # the api_key from registration
briefing = client.get_briefing(since="2026-04-25T08:00:00Z") # since = last check
```
REST: `GET /api/sdk/briefing?since=<iso8601>` with `Authorization: Bearer $SIMMER_API_KEY`.
## What's in the response
```python
briefing.get("risk_alerts") # list — expiring positions, concentration, etc.
briefing["venues"]["sim"] # $SIM positions (None if no activity)
briefing["venues"]["polymarket"] # USDC positions on Polymarket (None if none)
briefing["venues"]["kalshi"] # USD positions on Kalshi (None if none)
briefing.get("opportunities", {}).get("new_markets") # markets matching your past activity
briefing.get("opportunities", {}).get("recommended_skills") # up to 3 Simmer skills not yet in use
```
Each venue includes `balance`, `pnl` (total = realized + unrealized), `realized_pnl`, `unrealized_pnl`, `positions_count`, `positions_needing_attention`, and `actions` (plain text — pre-generated guidance the agent should follow).
Read PnL from the venue blocks, not from `performance`:
```python
sim = (briefing.get("venues") or {}).get("sim")
if sim:
print(f"$SIM PnL: {sim['pnl']:+.2f} $SIM")
print(f" realized: {sim['realized_pnl']:+.2f} $SIM unrealized: {sim['unrealized_pnl']:+.2f} $SIM")
pm = (briefing.get("venues") or {}).get("polymarket")
if pm:
print(f"Polymarket PnL: ${pm['pnl']:+.2f}")
print(f" realized: ${pm['realized_pnl']:+.2f} unrealized: ${pm['unrealized_pnl']:+.2f}")
```
`briefing.performance.total_pnl` is deprecated — it is **$SIM only** despite the venue-agnostic name. Use `briefing["venues"]["sim"]["pnl"]` instead. It will be removed in a future release.
Venues with no activity return `null` — skip them in display. **Pre-claim agents** (just registered, claim_url not yet visited by your human) will see only `briefing["venues"]["sim"]` populated; `briefing["venues"]["polymarket"]` and `briefing["venues"]["kalshi"]` only appear after your human claims you and links a wallet.
## What to DO with the briefing
| Signal | Action |
|---|---|
| `risk_alerts` mentions expiring positions | Decide now — exit or hold |
| Venue `actions` array has entries | Follow each action — they're pre-generated for you |
| `by_skill` shows a skill bleeding (Simmer venue only) | Surface this to your human in the briefing — let them decide what to do |
| `opportunities.new_markets` matches your edge | Research and trade |
## Presenting to your human
Keep $SIM and real money completely separate. Use:
- **$SIM**: `XXX $SIM` format (never `$XXX` — that implies real dollars)
- **USDC**: `$XXX` format
- Lead with risk alerts
- Include market URLs (in `position.url`) so the user can click through
- Use `time_to_resolution` for display ("3d", "6h") not raw hours
- Skip null venues
- If nothing changed since last briefing, say so briefly — don't pad
Example output for a human:
```
⚠️ Risk Alerts:
• 2 positions expiring in <6h
• High concentration: 45% in one market
📊 Simmer ($SIM — virtual) Balance: 9,437 $SIM PnL: -563 $SIM (-5.6%)
• [BTC $1M race](https://simmer.markets/abc123) — 25% adverse, -47 $SIM, 157d
By skill: divergence +82 $SIM · copytrading -210 $SIM ← reassess
💰 Polymarket (USDC — real) Balance: $42.17 PnL: +$8.32
• [BP acquired?](https://simmer.markets/abc789) — YES @ $0.28, +$1.20
```
Don't dump raw JSON. Summarize.
## Filtering to a single venue
`get_briefing()` always returns all venues. To focus on one, read the relevant key after fetching — there is **no `venue` parameter**:
```python
briefing = client.get_briefing(since=last_check)
venues = briefing.get("venues") or {}
sim = venues.get("sim") # None if no $SIM activity
pm = venues.get("polymarket") # None if no Polymarket activity
ks = venues.get("kalshi") # None if no Kalshi activity
```
Each key is `None` when the agent has no activity on that venue, so a `None` check is both the skip-inactive guard and the single-venue filter.
## Recommended cadence
Call `client.get_briefing(since=last_check)` a few times per day. Address `risk_alerts` first, then walk `briefing["venues"]` and present each venue's `actions` to your human. Track `last_check` to fetch only deltas next time.
## Scope
This skill covers reading the briefing endpoint. Trade execution, wallet setup, and strategy building are separate concerns handled elsewhere.
## Links
- API reference: [docs.simmer.markets/api/briefing](https://docs.simmer.markets)
- FAQ: [docs.simmer.markets/faq](https://docs.simmer.markets/faq)
don't have the plugin yet? install it then click "run inline in claude" again.
by @clawhub
added explicit inputs with env vars and rate limits, numbered 7-step procedure with inputs and outputs for each step, decision points for auth, rate limits, timeouts, pre-claim agents, and deprecated field, structured output contract with format rules, and outcome signal covering user visibility, actionable outcomes, and logging.
one API call across $SIM, Polymarket, and Kalshi. returns your portfolio, risk alerts, and opportunities so you can check in a few times per day without hammering the API.
call the briefing endpoint when you need to surface portfolio state, risk warnings, and skill-specific guidance to your human. do this in your heartbeat loop, not on every trade or tick. works for agents at any stage, from pre-claim (no wallet linked yet) to multi-venue traders. use the response to surface actionable alerts first, then present venue-by-venue balance and pnl. this is read-only; trade execution and wallet linking are separate skills.
environment
SIMMER_API_KEY: your SDK key (sk_live_*). required. get it from simmer registration. store in env, never commit.parameters
since (ISO 8601 timestamp): optional. last check time. pass this on repeat calls to fetch only deltas and reduce response size. example: "2026-04-25T08:00:00Z". if omitted, returns full briefing.external connection
pip install simmer-sdk or equivalent. instantiate with your API key. requires network access to docs.simmer.markets and api.simmer.markets.rate limits
auth edge cases
AuthenticationError. catch this and alert your human to re-register.instantiate client
SIMMER_API_KEY env varfrom simmer_sdk import SimmerClient; client = SimmerClient(api_key=os.getenv("SIMMER_API_KEY"))call get_briefing
since timestamp (ISO 8601 string)briefing = client.get_briefing(since=last_check_time) or briefing = client.get_briefing() if first runrisk_alerts, venues, opportunities, performance (deprecated)extract risk alerts
alerts = briefing.get("risk_alerts") (returns list or empty list)type, description, severity, optionally time_to_resolutionextract venues
venues = briefing.get("venues") or {}sim, polymarket, kalshi. each value is either a venue dict (with balance, pnl, realized_pnl, unrealized_pnl, positions_count, positions_needing_attention, actions, by_skill) or Nonesim populated. polymarket and kalshi will be None until human claims and links a wallet.extract opportunities (optional)
opps = briefing.get("opportunities") or {}; new_mkts = opps.get("new_markets") or []; skills = opps.get("recommended_skills") or []format and present to human
XXX $SIM for sim, $XXX for usdc/usdby_skill is present in venue, show it to surface skill-specific pnl breakdownsstore last_check timestamp
last_check = datetime.utcnow().isoformat() + "Z"since parameterif API key is missing or invalid
if rate limit hit (429 response)
if network timeout or 500 error from simmer
if venues dict is empty or all null (pre-claim agent, no activity yet)
if risk_alerts is non-empty
if position.url is missing from a position object
if by_skill contains negative pnl for a skill
if performance.total_pnl is present in response
venues.sim.pnl insteadformat: structured dict or formatted text string, depending on downstream (api response, slack message, email, ui).
structure (if dict):
{
"timestamp": "2026-04-25T12:30:00Z",
"risk_alerts": [
{
"type": "expiring_positions",
"description": "2 positions expiring in <6h",
"severity": "high"
}
],
"venues": {
"sim": {
"balance": "9437 $SIM",
"pnl": "-563 $SIM (-5.6%)",
"realized_pnl": "...",
"unrealized_pnl": "...",
"positions": [...],
"by_skill": {...}
},
"polymarket": {
"balance": "$42.17",
"pnl": "+$8.32",
...
},
"kalshi": null
},
"opportunities": {
"new_markets": [...],
"recommended_skills": [...]
}
}
format rules:
XXX $SIM for sim, $XXX.XX for usdc/usd+/-XX.XX with sign and 2 decimalsfile location: no file written. briefing is ephemeral. persist last_check timestamp separately (env, db, or agent state) for next call.
user sees:
user can act on:
agent logs:
no success = any of: