Two Minute Toolkit TwoMinuteFootball Field
Slide Deck Quality Football Field Charts in 2 minutes or less

Football Field Chart HTTP API

POST a small JSON description and get back a deck-ready PNG (or SVG). The endpoint is open and CORS-enabled, so it works from browsers, scripts, CI and anywhere else you can make an HTTP call. The same JSON opens in the builder.

POST https://www.twominutetoolkit.com/api/render/footballfield
Fair use: rate-limited to 20 requests a minute per IP (bursts capped at 5 a second), shared across every Two Minute tool, with a 64 KB body cap. No key or sign-up needed.

Try it

Open in builder

Code samples

Live preview

Click Render to call the API.

Request body

FieldTypeDescription
titlestringHeading shown top-left of the chart at 22px bold. Every chart has one title row; an empty string hides it.
max 140 chars · default "Valuation summary"
widthintegerChart width in pixels (640–2400, default 1280, which suits a 16:9 slide). PNG output renders at 2x. Height is computed from the number of rows.
640–2400 · default 1280
palettestring[]Hex colours. Every bar takes the FIRST palette colour unless the row sets its own colour, so a brand colour as the first entry recolours the whole chart. Default: indigo, sky, emerald, amber, red, gray.
max 12 items · default ["#4f46e5","#0ea5e9","#10b981","#f59e0b","#ef4444","#6b7280"]
rowsrequiredobject[]The valuation methods, top to bottom (1–12; extra rows are dropped with a warning). Each row is one horizontal bar from low to high on the shared axis, e.g. { "method": "Trading comps", "detail": "8.0x–10.0x EV/EBITDA", "low": 42, "high": 51 }. A row whose low is above its high is swapped and reported as a warning.
max 12 items
markersobject[]Optional vertical dashed reference lines across every row (0–3), each labelled at the top with its label and value, e.g. [{ "label": "Current price", "value": 45.1 }, { "label": "Offer", "value": 52 }]. Default: none.
max 3 items · default []
rangeobjectOptional shaded band behind every row, e.g. the implied valuation range: { "low": 48, "high": 55, "label": "Implied range" }. Its label and values are shown above the band. Omit for none (the default).
prefixstringText put before every value, default "$". Use "€", "£" or "" (none), e.g. "" for multiples.
max 6 chars · default "$"
suffixstringText put after every value, default "" (none). E.g. "m" for $ millions, "/sh" for per share, "x" for multiples, "%" for percentages.
max 6 chars · default ""
decimalsintegerDecimal places for every value (0–3), e.g. 2 shows 45.10. Omit (the default) to show each value as given, rounded to at most 2 decimals.
0–3
showValuesbooleanPrint the low and high values just outside each end of every bar. Default true.
default true
axisMinnumberOptional left end of the value axis, e.g. 30. Omit (recommended) and the axis starts at a round number slightly below the smallest value. Bars beyond the axis are cut off with a warning.
-1000000000000–1000000000000
axisMaxnumberOptional right end of the value axis, e.g. 70. Omit (recommended) and the axis ends at a round number slightly above the largest value.
-1000000000000–1000000000000

rows[] item

FieldTypeDescription
methodrequiredstringMethod name shown left of the bar at 14px bold, e.g. "DCF (perpetuity growth)" or "52-week trading range". Wraps to two lines when long.
max 60 chars
detailstringOptional muted line under the method name with the key assumption, e.g. "8.0x–10.0x EV/EBITDA" or "WACC 9–11%, g 2–3%". Omit for none.
max 80 chars
lownumberLow end of the range, in the chart's units (the prefix and suffix are added for display), e.g. 42 for $42/share or 1250 for $1,250m. Numeric strings are accepted.
-1000000000000–1000000000000
highnumberHigh end of the range, in the same units as low, e.g. 58. Swapped with low (and warned) if it is the smaller.
-1000000000000–1000000000000
colorstringOptional hex colour for this bar, e.g. "#0ea5e9" to set one method apart (such as the 52-week range). Default: the first palette colour.
max 40 chars

markers[] item

FieldTypeDescription
labelrequiredstringMarker name shown above its line, followed by the formatted value, e.g. "Current price" or "Offer price".
max 40 chars
valuenumberWhere the line sits on the value axis, in the chart's units, e.g. 45.1.
-1000000000000–1000000000000
colorstringOptional hex colour for the line and its label. Default: dark slate for the first marker, red for the second, gray for the third.
max 40 chars

range

FieldTypeDescription
lownumberLow end of the shaded band, e.g. 48.
-1000000000000–1000000000000
highnumberHigh end of the shaded band, e.g. 55.
-1000000000000–1000000000000
labelstringOptional name shown above the band before its values, e.g. "Implied range" or "Proposed offer range".
max 40 chars

Endpoints

  • POST /api/render/footballfield returns image/png; add ?format=svg for SVG.
  • GET /footballfield.png?d=<payload> and /footballfield.svg?d=<payload> render a chart from a link. The payload is the JSON body, raw-deflated and base64url-encoded. Nothing is stored: links are permanent and cached for a year.
  • /footballfield#d=<payload> opens the same chart in the builder for editing.
  • GET /api/render/footballfield?demo=1 returns the demo chart.
  • GET /api/schema/footballfield returns the JSON Schema, for code generators and AIs.

Errors and adjustments

Input is lenient where the intent is clear: numeric strings become numbers, out-of-range values are clamped, and unknown fields are ignored. Adjustments are listed in the X-Render-Warnings header. Anything unclear returns a 400 that says how to fix it:

{
  "error": "Invalid payload",
  "issues": [{ "path": "tasks", "message": "must be an array" }],
  "example": { … }
}

Calling from an AI assistant?

Use the hosted MCP server instead. It gives Claude, Cursor and other MCP clients a create_football_field tool that returns the image plus image, SVG and edit links. See the MCP page →