DiceplotsPlatforms → API

Diceplots API private beta

Three tiers, the same Rust engine. Free unauthenticated for casual integration, free registered for serious development, paid for production traffic. The first endpoint cohort is live — Strike, Compare, Strikes-to-kill, Cascades, plus Helpers discovery — with an OpenAPI 3 spec and Swagger UI at /api/v1/docs.

Try it in Swagger UI → Get a key Manage existing keys

Tiers

Tier Auth Rate limit Suitable for
Free unreg None — anonymous 30 requests / minute / IP Try-it-out, scripts, low-volume integrations.
Free reg Account + API key 300 requests / minute / key Personal projects, dev work, low-traffic apps.
Paid API key on a paid account 3,000 requests / minute / key Production traffic, embedded engine calls, latency-sensitive use.

Per-key limits are tracked by sliding-window in ETS; the free-unreg bucket is keyed by remote IP (with X-Forwarded-For handled at Caddy). On limit exceeded, the API returns 429 with a JSON body naming the resolved tier and the per-window cap. Paid-tier pricing and bulk-purchase contact are below.

Endpoints

Six routes under /api/v1/*. All POSTs take JSON bodies; all 2xx responses share an envelope { meta: { tier, engine_version, request_id }, result: ... }. Probabilities are returned as both a f64 approximation and a reduced-rational *_exact string ("p/q" or "p") — exactness is the product, don't round-trip through floats.

  • POST /api/v1/strike — distribution + kill probability for one expression. Same grammar as /strike/:slug; optional hp and per-damage-type resistances.
  • POST /api/v1/compare — two expressions at one HP, side-by-side distributions plus the signed kill_probability_delta. Sweep hp client-side to plot the crossover curve.
  • POST /api/v1/strikes-to-kill — expected strikes + cumulative kill curve up to max_strikes. The source field distinguishes exact-rational results from the f64 fallback path.
  • POST /api/v1/cascades — GWM-on-kill, PAM glaive, any cascade clause. Depth + queue HP are encoded in the expression itself (cascade N or cascade [HP1, HP2, …]). The same machinery that powers the cascade pillar.
  • GET /api/v1/helpers + /helpers/:name — discovery for every MCP-callable engine helper (Strike, Lancer attack, Daggerheart duality, Year Zero pool, …) with full arg schemas. Drives the MCP server too.

Examples

Anonymous (free_unreg, 30/min/IP):

$ curl -s https://diceplots.com/api/v1/strike \
    -H "content-type: application/json" \
    -d '{"expression":"2d6+5","hp":11}'

{
  "meta": {
    "tier": "free_unreg",
    "engine_version": "0.1.0+sha.91b3979",
    "request_id": "GUv8h4iY...XK"
  },
  "result": {
    "expression": "2d6+5",
    "min": 7, "max": 17,
    "mean": 12.0, "mean_exact": "12",
    "kill_probability": 0.7222,
    "kill_probability_exact": "13/18",
    "outcomes": [{"value":7,"probability":0.0277,"probability_exact":"1/36"}, ...]
  }
}

Authenticated (free_reg, 300/min/key):

$ curl -s https://diceplots.com/api/v1/compare \
    -H "Authorization: Bearer dp_live_..." \
    -H "content-type: application/json" \
    -d '{"a":"2d6+5","b":"1d12+5","hp":11}' \
  | jq '.result.kill_probability_delta_exact, .result.a.kill_probability_exact, .result.b.kill_probability_exact'

Helper discovery:

$ curl -s https://diceplots.com/api/v1/helpers | jq '.result.count, .result.helpers[0]'

$ curl -s https://diceplots.com/api/v1/helpers/strike | jq '.result.args'

Rate-limit body when exhausted:

HTTP/2 429
content-type: application/json

{
  "error": "rate_limited",
  "tier": "free_unreg",
  "limit_per_window": 30,
  "window_ms": 60000,
  "see": "https://diceplots.com/platforms/api"
}

Spec + Swagger UI

The full OpenAPI 3 document lives at /api/v1/openapi.json — point your generator at it for typed clients in any language. Interactive "Try it" lives at /api/v1/docs; the Authorize button accepts a bearer key so you can exercise the authenticated path against your account.

Accounts and keys

Sign up at /sign-up with email and password — confirmation link arrives in your inbox; the account is usable immediately at the free_reg tier. The account dashboard manages keys end-to-end: create, copy-once, revoke, last-used timestamps. Keys are bcrypt-hashed at rest with a public prefix for identification; the plaintext is shown exactly once at creation.

Paid-tier pricing is per-engagement — drop a line to tom@defensiblelogic.com with the rough call volume and integration shape and we'll come back with terms.

Want the engine without the network round-trip? License the engine directly — same Rust core, no API quota to manage.