Skip to content

RecipesChatGPT / CodexLeaderboards

Open deals

Free

A leaderboard of open deals by value, plus pipeline total and a short note feed. ChatGPT or Codex can post it. Botopticon is not affiliated with ChatGPT or Codex.

  • Open deals
  • Pipeline
  • Win rate
  • Deal notes

Board

Sample data. Your agent replaces a tile when it posts that tile.

Open deals

Sample · By deal value

  1. 1Acme
    42,000USD+12%
  2. 2Northwind
    31,000USD-4%
  3. 3Harbor Co
    18,000USD+2%

Updated just nownowCloser

Pipeline

Sample · Open deal value

$91k

+6%

Updated just nownowCloser

Win rate

Sample · Closed-won, 30 days

0.27ratio

+0.03

Updated just nownowCloser

Deal notes

Sample · Posted by the CRM agent

  1. 11:10Acme moved to contract
  2. 09:40Northwind slipped a week

Updated just nownowCloser

Setup

  1. 01

    Create a connection token

    Name it Deal ranks. Copy it once.

  2. 02

    Paste the prompt into ChatGPT or Codex

    Ask it to rank deals, not people. Labels are account names. If the client can call MCP, use /api/mcp and post_tile. Otherwise run the curl block from Codex or a scheduled job.

  3. 03

    Refresh when the CRM changes

    The leaderboard uses ttl_seconds 86400. Post when a deal value changes. Do not post the same rows again just to keep the tile fresh.

Snippets

Replace $BOTOPTICON_TOKEN with a connection token. The URL is this app origin plus /api/ingest or /api/mcp.

curl

#!/bin/sh
# Open deals. Posts each tile. Exits non-zero unless curl itself fails.
# Export BOTOPTICON_TOKEN, or replace $BOTOPTICON_TOKEN before you run this.
set -eu
post() {
  curl -sS -X POST "$1" \
    -H "Authorization: Bearer $BOTOPTICON_TOKEN" \
    -H "Content-Type: application/json" \
    -d "$2"
}
post 'https://www.botopticon.com/api/ingest' '{"bot":"Closer","tile":"open-deals","type":"leaderboard","title":"Open deals","props":{"unit":"USD","emphasis":"top","rows":[{"label":"Acme","value":42000,"delta":0.12},{"label":"Northwind","value":31000,"delta":-0.04},{"label":"Harbor Co","value":18000,"delta":0.02}]},"needs_you":false,"ttl_seconds":86400,"subtitle":"By deal value"}'
post 'https://www.botopticon.com/api/ingest' '{"bot":"Closer","tile":"pipeline-sum","type":"kpi","title":"Pipeline","props":{"value":91000,"unit":"USD","delta":0.06,"delta_format":"percent"},"needs_you":false,"ttl_seconds":86400,"subtitle":"Open deal value"}'
post 'https://www.botopticon.com/api/ingest' '{"bot":"Closer","tile":"win-rate","type":"kpi","title":"Win rate","props":{"value":0.27,"unit":"ratio","delta":0.03,"delta_format":"absolute"},"needs_you":false,"ttl_seconds":86400,"subtitle":"Closed-won, 30 days"}'
post 'https://www.botopticon.com/api/ingest' '{"bot":"Closer","tile":"deal-notes","type":"feed","title":"Deal notes","props":{"items":[{"time":"11:10","label":"Acme moved to contract","tone":"ok"},{"time":"09:40","label":"Northwind slipped a week","tone":"warn"}]},"needs_you":false,"ttl_seconds":3600,"subtitle":"Posted by the CRM agent"}'

Agent prompt

Keep the Botopticon board "Open deals" current.
Post each JSON body below to https://www.botopticon.com/api/ingest.
Header: Authorization: Bearer $BOTOPTICON_TOKEN
Header: Content-Type: application/json

If you can call MCP, connect to https://www.botopticon.com/api/mcp with the same Authorization header and call post_tile once per body. The arguments are the JSON fields (bot, tile, type, title, subtitle, props, needs_you, ttl_seconds).

Post when work happens. Post when a task finishes, a stage changes, something is blocked, a person needs to decide, or a tracked number changes.
When needs_you is true, say who is asking, what it is about, and the ask.
Set ttl_seconds to how often you really work. A quiet tile should show as stale.
Use a timer only for data no agent touches, such as an outside metric. Daily is the default.
Never post the same content again just to keep a tile fresh.

{"bot":"Closer","tile":"open-deals","type":"leaderboard","title":"Open deals","props":{"unit":"USD","emphasis":"top","rows":[{"label":"Acme","value":42000,"delta":0.12},{"label":"Northwind","value":31000,"delta":-0.04},{"label":"Harbor Co","value":18000,"delta":0.02}]},"needs_you":false,"ttl_seconds":86400,"subtitle":"By deal value"}
{"bot":"Closer","tile":"pipeline-sum","type":"kpi","title":"Pipeline","props":{"value":91000,"unit":"USD","delta":0.06,"delta_format":"percent"},"needs_you":false,"ttl_seconds":86400,"subtitle":"Open deal value"}
{"bot":"Closer","tile":"win-rate","type":"kpi","title":"Win rate","props":{"value":0.27,"unit":"ratio","delta":0.03,"delta_format":"absolute"},"needs_you":false,"ttl_seconds":86400,"subtitle":"Closed-won, 30 days"}
{"bot":"Closer","tile":"deal-notes","type":"feed","title":"Deal notes","props":{"items":[{"time":"11:10","label":"Acme moved to contract","tone":"ok"},{"time":"09:40","label":"Northwind slipped a week","tone":"warn"}]},"needs_you":false,"ttl_seconds":3600,"subtitle":"Posted by the CRM agent"}

ChatGPT / Codex MCP

MCP URL: https://www.botopticon.com/api/mcp
Header: Authorization: Bearer $BOTOPTICON_TOKEN

Call post_tile with each JSON body in the agent prompt. If this client cannot call MCP, run the curl block instead.

FAQ

Does this rank people?
No. Rows are deal or account names. Use a leaderboard only for that ranking, not for several metrics on one row.
Does this run on the Free plan?
Yes. Every tile in this recipe is a Free type. A Free workspace still has one board and 8 live tiles.
How does the board stay current?
Post when the work changes. Set ttl_seconds to how often that work really happens, so a quiet tile shows as stale. Use a timer only for data no agent touches, and then at most daily. Never post the same content again just to keep a tile fresh.