Nardex
  • Learn
    • Long Narde
    • Backgammon
    • Theory
    • Blog
    • FAQ
  • Leaderboard
  • Analytics
  • Developers
    • Analytics API
    • Engine training
  • Project
    • Android app
    • About
    • Software
    • Privacy Policy
Log in
en
Nardex
LearnLeaderboardAnalytics
Log in

Learn

Long NardeBackgammonTheoryBlogFAQ

Developers

Analytics APIEngine training

Project

Android appAboutSoftwarePrivacy Policy
en

In this section

In this section ▸
  • Nardex vs gnubg vs XG
  • API quickstart
  • Reading analysis output

In this section

  • Nardex vs gnubg vs XG
  • API quickstart
  • Reading analysis output

Quickstart: Analyze a Backgammon Position via API (5 minutes)

In five minutes you will send your first request to the Nardex Analysis API and parse a structured evaluation: top alternatives, equity, win probabilities, and an error-grade label. The endpoint is synchronous — one HTTP round-trip per decision, no polling, no webhooks. Works for both backgammon and long narde.

Step 1 — Get an API key

The Analysis API is currently in private beta. Request access via the lead form on the developers page — you will receive an API key with the positions.analyze scope and a sample-rate quota suitable for evaluation. Rate-limit and pricing tiers are communicated when your access is provisioned.

Step 2 — Encode the position

Build a JSON body with four keys: game_type ("narde" or "backgammon"), position, decision, and context.

The position object is game-specific. For narde it's {"pips": [...]} — a 24-element signed-integer array indexed by game pip (index i = point i+1). Positive values are white (X) checkers, negative are black (O). Standard starting position: 15 white at game pip 24 (index 23), 15 black at game pip 12 (index 11). Backgammon uses the same shape.

{
  "game_type": "narde",
  "position": {
    "pips": [
       0,  0,  0, -1, -1,  1,
      -2,  1,  1,  1, -1, -8,
       0,  1,  0,  0,  0,  0,
       1, -1,  0, -1,  0,  9
    ]
  },
  "decision": {
    "type": "checker_play",
    "dice": [4, 2],
    "played": [
      { "from": 14, "to": 10 },
      { "from": 10, "to": 8 }
    ]
  },
  "context": {
    "player": "x",
    "match_state": null
  }
}

For checker plays, played is the sequence of moves the player chose. The API returns ranked alternatives so you can compare the played sequence against the engine's top picks. For cube decisions, replace the checker_play object with {"type": "cube_decision", "offer_made": true, "response": "take"}.

Step 3 — Send the curl request

POST the body to /api/v1/positions/analyze with bearer authentication:

curl -X POST https://nardex.ai/api/v1/positions/analyze \
  -H "Authorization: Bearer $NARDEX_KEY" \
  -H "Content-Type: application/json" \
  -d @request.json

JWT callers (browser SDK, signed-in dashboards) skip the Bearer header — the session itself is the authorization. API-key callers must hold the positions.analyze scope; otherwise the server returns 403.

Step 4 — Interpret the response

The response is a PositionAnalysis object:

{
  "alternatives": [
    {
      "play": [{ "from": 14, "to": 10 }, { "from": 10, "to": 8 }],
      "equity": 0.494,
      "probabilities": {
        "win": 0.700,
        "win_m": 0.258,
        "win_k": 0.062,
        "lose_m": 0.123,
        "lose_k": 0.029
      }
    }
  ],
  "chosen": null,
  "equity_loss": 0.0,
  "grade": "ok",
  "equity_kind": "money",
  "forced": false,
  "analysis_depth": "ply_zero"
}
  • alternatives — top-N candidate moves sorted by equity descending. Each includes play, equity, and a raw probabilities vector (win / win_m / win_k / lose_m / lose_k for narde — these are nested ordinal probabilities, not a 6-class softmax).
  • chosen — the alternative the player actually played, if it falls outside the top-N. null when the chosen play is already in the list.
  • equity_loss — best.equity − chosen.equity (≥ 0). The number the player "left on the table" by not picking the engine's top move.
  • grade — four-tier label (XG/GnuBG-inspired): ok, doubtful, error, blunder. Threshold buckets live server-side and are calibrated per game type.
  • equity_kind — which scale equity_loss is on. Losses with different equity_kind values must not be averaged together:
    • money — raw money equity — checker-play decisions in a money game.
    • match — money equity scaled for the match when the request supplied match_state (alternatives are scored in MWC, not raw equity); checker plays too.
    • match_emg — a cube decision graded off a real match-equity table (MET): the loss is in EMG (money-equivalent) units. The only cube scale that may be pooled with checker-play losses.
    • cube_dist — a cube decision on the constant-threshold path — what the server falls back to when no MET is in play (met_based: false). NOT an equity loss but the distance 2·|win_prob − threshold|: on a clinched cube it reaches ~3.0, an order of magnitude above a typical EMG loss.
  • forced — true when there was only one legal play (automatically excluded from PR / blunder-rate calculations).
  • analysis_depth — currently always "ply_zero"; deeper search ("ply_two", "ply_three") is on the roadmap.

Step 5 — Next steps

Now that the round-trip works, decide how to integrate Nardex into your app:

  • Compare Nardex against gnubg and XG on the comparison page — which engine fits your platform and license model.
  • Cache requests on your side. The server already memoizes by (position, decision, context, depth), but skipping the network round-trip saves real latency on hot paths.
  • Handle 429 (rate limit) with exponential back-off. A burst of evaluation calls during a match-import job is the most common cause. Also watch for 403, which means the key is missing the positions.analyze scope.
  • Switch to JWT auth once you embed Nardex in a browser dashboard — drop the API key from client code; the user's session is enough.

Frequently asked questions

Do I need to install anything?
No. The Analysis API is a hosted HTTP service. Any HTTP client (curl, fetch, requests, reqwest, http.HttpClient) works. There is no SDK to ship and no inference runtime to bundle with your app.
What are the rate limits?
Rate limits are scoped per API key and enforced server-side. A 429 response indicates you exceeded the bucket; back off and retry. Limits are tuned per beta cohort — exact values are communicated when your access is provisioned.
What latency should I expect?
End-to-end latency is dominated by the network round-trip from your region to the EU data center. The analysis itself, served from cache for repeated requests or freshly computed on a CUDA-accelerated GPU otherwise, is sub-second. Production benchmarks will accompany the public API release.
Can I authenticate with a JWT instead of an API key?
Yes. The endpoint accepts both JWT (browser/SDK sessions) and API-key Bearer auth. JWT callers are not gated by scopes — the session itself is the authorization. API-key callers must hold the positions.analyze scope.
What error codes can the endpoint return?
400 — unknown game_type or malformed body. 401 — missing or invalid credentials. 403 — API key lacks the positions.analyze scope. 429 — rate limit exceeded. 500 — internal analysis failure (logged server-side; please report).
Is the response cached?
Yes. The server memoizes by (game_type, position, decision, context, analysis_depth) — identical requests return instantly from the cache. There is no need to dedupe on the client unless you want to save the network round-trip.

Request beta access

Drop your email on the developers page — we will reach out with an API key, scope, and rate-limit details.

Request access →

Learn

  • Long Narde
  • Backgammon
  • Theory
  • Blog
  • FAQ

Developers

  • Analytics API
  • Engine training

Project

  • Android app
  • About
  • Software
  • Privacy Policy

Support

  • support@nardex.ai
© 2026 Nardex support@nardex.ai Long Narde and Backgammon with AI