Build a custom OpenClaw skill that parses any bet slip — text, natural language, or screenshot — into structured JSON your agent can log, analyze, and act on. Zero API keys, zero dependencies, pure LLM comprehension.

Why Your Agent Needs a Bet Slip Parser

Every betting agent eventually hits the same wall: data entry. You placed a bet on DraftKings, another on FanDuel, maybe a Polymarket position too. Now your bankroll tracker is out of sync, your CLV calculations are stale, and your P&L report is fiction.

The problem isn’t the tracking tools — it’s the gap between placing a bet and logging it. Sportsbook apps don’t export bet slips in machine-readable formats. You get a confirmation screen, maybe a screenshot, maybe a text notification that says “Your bet has been placed” with odds buried in a paragraph.

This guide builds bet-slip-parser — a utility skill that sits at the seam between human bet placement and agent-readable data. It takes whatever you’ve got — a pasted confirmation, a natural language description (“I just bet $50 on the Lakers -3.5 at -110 on DraftKings”), or a screenshot of your bet slip — and outputs a clean JSON object that every other skill in your stack can consume.

What You’re Building

The bet-slip-parser skill teaches your OpenClaw agent four operations:

  1. Parse text bet slip — Extract structured data from pasted sportsbook confirmation text
  2. Parse natural language bet — Convert a casual bet description into structured JSON
  3. Parse screenshot bet slip — Use LLM vision to read a bet slip image and extract fields
  4. Validate parsed output — Run regex checks to ensure odds, stakes, and bet types are well-formed

The skill uses no external dependencies. It relies on the LLM’s native text comprehension, optional vision capabilities, and basic bash validation. It runs anywhere OpenClaw runs.

Prerequisites

  • OpenClaw installed and running — Any channel (WhatsApp, Telegram, Discord, WebChat)
  • LLM with vision support (optional) — Required only for screenshot parsing (Claude, GPT-4o)
  • bash — Pre-installed on macOS and all Linux distributions

The JSON Schema Behind the Parser

Every bet slip, regardless of source, gets normalized into this schema:

{
  "source": "draftkings",
  "bet_type": "spread",
  "legs": [
    {
      "selection": "Los Angeles Lakers",
      "market": "spread",
      "line": -3.5,
      "odds_american": -110,
      "odds_decimal": 1.909,
      "odds_implied": 0.524
    }
  ],
  "stake": 50.00,
  "currency": "USD",
  "potential_payout": 95.45,
  "combined_odds_american": -110,
  "timestamp": "2026-03-21T14:30:00Z",
  "raw_input": "original text or 'screenshot'"
}

For parlays, legs contains multiple entries and combined_odds_american reflects the parlay price. For single bets, legs has one entry and combined_odds_american matches the leg odds.

The Complete SKILL.md

Create the skill directory:

mkdir -p ~/.openclaw/skills/bet-slip-parser

Create ~/.openclaw/skills/bet-slip-parser/SKILL.md with this content:

---
name: bet-slip-parser
description: "Parse bet slips from text, natural language, or screenshots into structured JSON. Extracts stake, odds, bet type, selection, and sportsbook. Supports singles, parlays, teasers, and SGPs. Use when asked to parse, log, or read a bet slip."
metadata:
  openclaw:
    emoji: "🎫"
    requires:
      bins: ["bash"]
---

# Bet Slip Parser

Extract structured betting data from any bet slip format — pasted text, natural language, or screenshots.

# When to Use

Use this skill when the user:
- Pastes a bet confirmation or bet slip text
- Describes a bet they placed in natural language
- Shares a screenshot of a bet slip from any sportsbook
- Asks to "log this bet" or "parse this bet slip"
- Wants to convert a bet description into structured data
- Says "I just bet..." or "I placed a bet on..."

# Supported Bet Types

| Bet Type | Keywords |
|----------|----------|
| Moneyline | moneyline, ML, to win, h2h |
| Spread | spread, point spread, handicap, ATS, -3.5 |
| Total | total, over, under, O/U |
| Parlay | parlay, accumulator, multi, combo |
| Teaser | teaser, adjusted spread |
| Same-Game Parlay | SGP, same game, same-game |
| Prop | prop, player prop, over 24.5 pts |
| Future | future, outright, to win championship |

# Supported Sportsbooks

Identify the sportsbook from branding, URLs, or mentions:

| Sportsbook | Identifiers |
|------------|-------------|
| DraftKings | draftkings, dk, DK Sportsbook |
| FanDuel | fanduel, fd, FD Sportsbook |
| BetMGM | betmgm, mgm, BetMGM Sportsbook |
| Caesars | caesars, czr, Caesars Sportsbook |
| Pinnacle | pinnacle, pin |
| Bet365 | bet365, b365 |
| BetRivers | betrivers, rivers |
| PointsBet | pointsbet |
| Polymarket | polymarket, poly |
| Kalshi | kalshi |

If the sportsbook cannot be identified, set source to "unknown".

# Operations

### 1. Parse Text Bet Slip

When the user pastes sportsbook confirmation text, extract all fields and output JSON.

Extraction steps:
1. Identify sportsbook from text branding or URL
2. Identify bet type from keywords (see table above)
3. Extract team/player/event selections
4. Extract odds — convert to American if decimal or fractional
5. Extract stake amount and currency
6. Calculate potential payout if not shown
7. Extract timestamp if available

Odds conversion formulas (use inline when needed):

```bash
## Decimal to American
echo "$DECIMAL_ODDS" | python3 -c "
import sys
d = float(sys.stdin.read().strip())
if d >= 2.0:
    print(f'+{round((d - 1) * 100)}')
else:
    print(f'{round(-100 / (d - 1))}')"

## Fractional (e.g. 3/2) to American
echo "3/2" | python3 -c "
import sys
n, d = map(int, sys.stdin.read().strip().split('/'))
dec = (n / d) + 1
if dec >= 2.0:
    print(f'+{round((dec - 1) * 100)}')
else:
    print(f'{round(-100 / (dec - 1))}')"

## American to implied probability
echo "-110" | python3 -c "
import sys
odds = int(sys.stdin.read().strip())
if odds < 0:
    prob = abs(odds) / (abs(odds) + 100)
else:
    prob = 100 / (odds + 100)
print(f'{prob:.4f}')"

## American to decimal
echo "-110" | python3 -c "
import sys
odds = int(sys.stdin.read().strip())
if odds < 0:
    dec = 1 + (100 / abs(odds))
else:
    dec = 1 + (odds / 100)
print(f'{dec:.3f}')"
```

### 2. Parse Natural Language Bet

When the user describes a bet casually, extract the same fields.

Examples of natural language inputs and how to parse them:

- "I bet $100 on the Lakers ML at +150 on DraftKings"
  → source: draftkings, bet_type: moneyline, selection: Los Angeles Lakers, odds: +150, stake: 100
- "Put $25 on over 48.5 in Chiefs-Ravens at -110"
  → bet_type: total, selection: Over 48.5, odds: -110, stake: 25
- "Parlayed Lakers ML and Chiefs -3.5, $50 to win $320 on FanDuel"
  → bet_type: parlay, 2 legs, stake: 50, potential_payout: 320, source: fanduel

Always ask for missing critical fields:
- If no stake mentioned, ask "How much did you bet?"
- If no odds mentioned, ask "What were the odds?"
- If no sportsbook mentioned, set source to "unknown"

### 3. Parse Screenshot Bet Slip

When the user shares an image of a bet slip:

1. Identify sportsbook from app branding/colors (DraftKings=green/black, FanDuel=blue/white, BetMGM=gold/black, Caesars=dark blue)
2. Read all visible text on the bet slip
3. Extract: event name, bet type, selection, odds, stake, potential payout
4. For parlays, extract each individual leg
5. Output in the standard JSON schema

Note: Screenshot parsing requires the LLM to have vision capabilities. If vision is not available, ask the user to paste the bet slip as text instead.

### 4. Validate Parsed Output

After parsing, validate the extracted data:

```bash
## Validate American odds format (must be + or - followed by digits)
echo "$ODDS" | grep -qE '^[+-][0-9]+$' && echo "VALID" || echo "INVALID: odds must be +NNN or -NNN"

## Validate stake is positive number
echo "$STAKE" | grep -qE '^[0-9]+(\.[0-9]{1,2})?$' && echo "VALID" || echo "INVALID: stake must be positive number"

## Validate bet type
echo "$BET_TYPE" | grep -qE '^(moneyline|spread|total|parlay|teaser|sgp|prop|future)$' && echo "VALID" || echo "INVALID: unknown bet type"

## Cross-check: potential payout should match odds × stake
echo "$STAKE $ODDS" | python3 -c "
import sys
parts = sys.stdin.read().strip().split()
stake, odds = float(parts[0]), int(parts[1])
if odds > 0:
    payout = stake + (stake * odds / 100)
else:
    payout = stake + (stake * 100 / abs(odds))
print(f'Expected payout: {payout:.2f}')"
```

# Output Rules

1. Always output a valid JSON object matching the schema
2. All odds must include American format (convert if needed)
3. Include decimal and implied probability for each leg
4. If a field cannot be extracted, set it to null — never guess
5. For parlays, each leg must be a separate entry in the legs array
6. Always include the raw_input field with the original text or "screenshot"
7. Potential payout must be calculated if not explicitly stated
8. Timestamp should be ISO 8601 format; use current time if not on the slip

# Error Handling

- If the input is ambiguous and multiple interpretations exist, present options and ask the user to clarify
- If the image is too blurry or cropped, ask for a clearer screenshot or text input
- If odds format is unrecognized, ask the user to specify (American, decimal, or fractional)
- If the bet type cannot be determined, default to "moneyline" for single selection and "parlay" for multiple selections
- Always show the parsed JSON and ask "Does this look right?" before passing to downstream skills

Test It

Restart OpenClaw (or wait for hot-reload if your version supports it), then try these prompts:

PromptExpected Behavior
“I bet $50 on the Lakers -3.5 at -110 on DraftKings”Parses to JSON with spread bet, stake 50, odds -110, source draftkings
“Parse this bet slip: FanDuel — Parlay — Chiefs ML + Over 48.5 — $25 to win $150”Extracts 2-leg parlay, calculates combined odds from payout
[Screenshot of a DraftKings bet slip]Uses vision to extract all fields from the image
“I put a hundred on Djokovic to win Wimbledon at +350”Parses future bet, stake 100, odds +350, source unknown
“Log this bet: 2u on PHI -1.5 (-120) BetMGM”Recognizes unit-based stake, asks for unit value, outputs JSON

Your agent reads the SKILL.md, identifies the input type (text, natural language, or screenshot), extracts the fields using text comprehension or vision, validates the output, and returns structured JSON.

How It Works Under the Hood

OpenClaw skills are not plugins that execute code directly. The SKILL.md is a set of instructions that the LLM (Claude, GPT, etc.) reads and follows at runtime.

When you paste a bet slip or describe a bet, this is what happens:

User message → OpenClaw Gateway
  → LLM reads system prompt + active skills
  → LLM matches bet slip content to bet-slip-parser skill
  → LLM extracts fields using text comprehension (or vision for screenshots)
  → LLM runs bash validation commands for odds/stake format
  → LLM computes missing fields (payout, implied probability, odds conversions)
  → LLM formats output as JSON schema
  → User confirms parsed data

The skill is unique among OpenClaw skills because it’s primarily LLM-native — it relies on the model’s reading comprehension rather than curl commands or API calls. The bash validation step catches formatting errors, but the heavy lifting is text extraction and normalization performed by the LLM itself.

Extending the Skill

Auto-Log to Bankroll Manager

Chain bet-slip-parser with bankroll-manager so every parsed bet gets logged automatically:

{
  "cron": "manual",
  "prompt": "Parse this bet slip and log it to my bankroll. Use bet-slip-parser to extract the data, then bankroll-manager to record it."
}

This turns a two-step process (parse → manually log) into a single command: “log this bet” plus a screenshot.

Chain with Other Skills

The bet-slip-parser outputs structured JSON that downstream skills consume directly:

  • bankroll-manager — Accepts parsed bet JSON, logs to SQLite, updates P&L
  • clv-tracker — Takes placement odds from the parsed slip, compares to closing line later
  • ev-calculator — Uses the extracted odds plus your estimated true probability to compute expected value
  • odds-converter — Already built into the parser, but can extend with exotic formats (Hong Kong, Indonesian, Malay)

Batch Import

For users catching up on unlogged bets, create a batch mode:

"Parse all these bets:
1. $50 Lakers ML +150 DK
2. $25 Chiefs -3.5 -110 FD
3. $100 Over 215.5 -105 BetMGM"

The agent parses each line independently and outputs a JSON array.

Full Skill Series

This guide is part of the AgentBets OpenClaw Skills series. We’re building a complete library of betting-specific OpenClaw skills that map to the four layers of the Agent Betting Stack:

  • Layer 1 — Identity: Agent reputation tracking via Moltbook
  • Layer 2 — Wallet: Bankroll management, balance checking across platforms
  • Layer 3 — Trading: Odds scanning, Polymarket monitoring, Kalshi tracking, arbitrage detection
  • Layer 4 — Intelligence: EV calculation, Kelly sizing, CLV tracking, news sentiment

Each skill is a standalone SKILL.md you can install independently or compose into a full autonomous betting pipeline.

What’s Next