Skip to main content
This is Moonbounce’s label-first experience. If you’re looking for the policy-first experience, switch using the version selector above.
Once you’ve crafted, tested, and published a label — in the dashboard or over the API — the last step is integration: classifying real content in production. The key fact to internalize is that you always evaluate against a specific published version — and that version is identified by a label_version_id. Evaluation never takes a label ID; a label with no versions has nothing to evaluate, and an empty label_version_ids list is rejected.

Get a label version id

Every time you publish, Moonbounce mints an immutable version with its own label_version_id. That id is your handle into production. Because the version it points to never changes, sending the same id always evaluates against the same frozen snapshot — which is what makes your results reproducible.

Send it to the evaluate API

To classify content you call the evaluate endpoint with one or more version ids. The request accepts an array, label_version_ids (up to 25 per request), so you can evaluate a piece of content against several labels at once.
Conceptually, the request carries the content you want to classify and the version ids to evaluate it against:
See the API Reference for the exact request and response shapes.

SDKs

The SDKs expose this under their beta namespace. The method and field names differ slightly per language: The request and response types are named EvaluateLabelsRequest and EvaluateLabelsResponse across all three SDKs.

JavaScript / TypeScript SDK

See the beta.evaluateLabels example.

Python SDK

See the beta.evaluate_labels example.

Go SDK

See the Beta().EvaluateLabels example.

Choose a response kind

The optional response kind accepts score, choice, ordinal, or priority: use responseKind in REST and TypeScript, response_kind in Python, or ResponseKind in Go. Omit it for the existing independent scores. Every mode retains the ordered per-version results, including job IDs and individual errors. Choice and ordinal require at least two versions. By default, they return abstained: true when no label evaluation has outcome TRUE. This uses the reported outcomes, including the evaluator’s threshold tolerance. An abstained result omits the winner, index, confidence, probabilities, and ordinal score. Set abstain: false in REST or TypeScript, abstain=False in Python, or .Abstain(false) on the Go request builder to force selection. Score and priority ignore this option. When a winner is selected, abstained is false. The probability maps are keyed by label version ID. The winning index is always the version’s zero-based position in label_version_ids. Choice ties select the lexicographically smallest version ID. Ordinal ties select the lowest request index. Ordinal uses the supplied order as the lowest-to-highest scale, so its weighted score can be fractional and differs from the winning index. Choice and ordinal first adjust each raw score p around its effective threshold t: q = sigmoid(logit(p) - logit(t)). Each threshold maps to the shared acceptance point q = 0.5. They then compute softmax(log(q)), equivalent to q / sum(q), to produce relative weights across the supplied alternatives. The independent results retain their original scores, outcomes, and thresholds. Effective thresholds must be finite and strictly between zero and one; otherwise the aggregate returns invalid_threshold. confidence measures distribution concentration using normalized entropy: zero for a uniform distribution, approaching one as one alternative dominates. It is not a calibrated probability that the answer is correct. With both thresholds at 0.5, raw label scores [0.9, 0.1] produce probabilities [0.9, 0.1] and confidence approximately 0.531. Zero scores receive zero weight. All-zero scores abstain by default; with abstention disabled, they return invalid_score because no distribution can be formed. For scores [0.7, 0.3] and thresholds [0.8, 0.2], the adjusted scores and normalized weights are approximately [0.368, 0.632], so the second label wins. For priority, the first supplied version has the highest priority. The server uses each label’s evaluated match outcome and effective threshold. If two labels score 0.6 and 0.95 at threshold 0.5, priority selects the first. When none match, the priority result has matched: false and omits the label, index, score, and threshold fields.
Check aggregateError in REST and TypeScript, aggregate_error in Python, or AggregateError in Go before using an aggregate. Choice and ordinal require every evaluation to succeed. Priority requires successful evaluations through the first match; a later failure does not invalidate that selection. An error before a potential priority winner prevents selection. Individual results remain available in either case. Evaluating any mode creates and bills the same per-version work.

Managing versions in production

Evaluation always requires an explicit label_version_id — it never tracks the newest version for you. That’s a deliberate safeguard, and it shapes how you roll out new versions.
You always pass an explicit label_version_id by design. Because evaluation never resolves “latest” on its own, editing or publishing a label in the web app can never change what your live production traffic evaluates against. Your production behavior only changes when you deliberately change the version id you send — nothing shifts under you.
Store the label_version_id in your application configuration — a config file or environment variable — rather than hardcoding it in your code. Adopting a new version then becomes a config change, with no code edit or logic redeploy. The recommended flow: publish a new version, test it against the label’s dataset, and once you’re confident, update the version id in your config to roll forward on your own schedule.

Where to next

Managing Labels via API

Create labels and immutable versions programmatically.

Labels, Versions & Datasets

Revisit how versions and immutability work.

We’d Love to Hear From You

Whether you have a suggestion, feedback, or a bug to report, here are the best ways to get in touch:
  • In the App: Use the Feedback button for direct suggestions.
  • On Slack: Reach out to the team in your shared channel.
  • With your AM: Talk to your dedicated account manager.
  • Via Email: Send a message to support@moonbounce.io.
  • Security, availability, or other incidents: Use the in-app Feedback button or email support@moonbounce.io. See Customer Feedback for what to include.