curl --request POST \
--url https://api.meshapi.ai/v1/evaluate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "typesafe/jev-1.13",
"questions": {
"department": {
"criteria": {
"billing": "Payments, refunds and invoices",
"technical": "Bugs, outages and integration problems"
},
"instructions": "Which team should handle this ticket?",
"type": "choice"
},
"needs_human": {
"instructions": "Probability that this needs a human reply.",
"type": "noul"
},
"urgency": {
"criteria": [
"Can wait a week",
"Within a day",
"Immediately"
],
"instructions": "How urgently does this need a reply?",
"type": "score"
}
},
"state": {
"plan": "pro",
"subject": "Refund for order 4821 never arrived"
}
}
'import requests
url = "https://api.meshapi.ai/v1/evaluate"
payload = {
"model": "typesafe/jev-1.13",
"questions": {
"department": {
"criteria": {
"billing": "Payments, refunds and invoices",
"technical": "Bugs, outages and integration problems"
},
"instructions": "Which team should handle this ticket?",
"type": "choice"
},
"needs_human": {
"instructions": "Probability that this needs a human reply.",
"type": "noul"
},
"urgency": {
"criteria": ["Can wait a week", "Within a day", "Immediately"],
"instructions": "How urgently does this need a reply?",
"type": "score"
}
},
"state": {
"plan": "pro",
"subject": "Refund for order 4821 never arrived"
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'typesafe/jev-1.13',
questions: {
department: {
criteria: {
billing: 'Payments, refunds and invoices',
technical: 'Bugs, outages and integration problems'
},
instructions: 'Which team should handle this ticket?',
type: 'choice'
},
needs_human: {instructions: 'Probability that this needs a human reply.', type: 'noul'},
urgency: {
criteria: ['Can wait a week', 'Within a day', 'Immediately'],
instructions: 'How urgently does this need a reply?',
type: 'score'
}
},
state: {plan: 'pro', subject: 'Refund for order 4821 never arrived'}
})
};
fetch('https://api.meshapi.ai/v1/evaluate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.meshapi.ai/v1/evaluate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => 'typesafe/jev-1.13',
'questions' => [
'department' => [
'criteria' => [
'billing' => 'Payments, refunds and invoices',
'technical' => 'Bugs, outages and integration problems'
],
'instructions' => 'Which team should handle this ticket?',
'type' => 'choice'
],
'needs_human' => [
'instructions' => 'Probability that this needs a human reply.',
'type' => 'noul'
],
'urgency' => [
'criteria' => [
'Can wait a week',
'Within a day',
'Immediately'
],
'instructions' => 'How urgently does this need a reply?',
'type' => 'score'
]
],
'state' => [
'plan' => 'pro',
'subject' => 'Refund for order 4821 never arrived'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.meshapi.ai/v1/evaluate"
payload := strings.NewReader("{\n \"model\": \"typesafe/jev-1.13\",\n \"questions\": {\n \"department\": {\n \"criteria\": {\n \"billing\": \"Payments, refunds and invoices\",\n \"technical\": \"Bugs, outages and integration problems\"\n },\n \"instructions\": \"Which team should handle this ticket?\",\n \"type\": \"choice\"\n },\n \"needs_human\": {\n \"instructions\": \"Probability that this needs a human reply.\",\n \"type\": \"noul\"\n },\n \"urgency\": {\n \"criteria\": [\n \"Can wait a week\",\n \"Within a day\",\n \"Immediately\"\n ],\n \"instructions\": \"How urgently does this need a reply?\",\n \"type\": \"score\"\n }\n },\n \"state\": {\n \"plan\": \"pro\",\n \"subject\": \"Refund for order 4821 never arrived\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.meshapi.ai/v1/evaluate")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"typesafe/jev-1.13\",\n \"questions\": {\n \"department\": {\n \"criteria\": {\n \"billing\": \"Payments, refunds and invoices\",\n \"technical\": \"Bugs, outages and integration problems\"\n },\n \"instructions\": \"Which team should handle this ticket?\",\n \"type\": \"choice\"\n },\n \"needs_human\": {\n \"instructions\": \"Probability that this needs a human reply.\",\n \"type\": \"noul\"\n },\n \"urgency\": {\n \"criteria\": [\n \"Can wait a week\",\n \"Within a day\",\n \"Immediately\"\n ],\n \"instructions\": \"How urgently does this need a reply?\",\n \"type\": \"score\"\n }\n },\n \"state\": {\n \"plan\": \"pro\",\n \"subject\": \"Refund for order 4821 never arrived\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.meshapi.ai/v1/evaluate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"typesafe/jev-1.13\",\n \"questions\": {\n \"department\": {\n \"criteria\": {\n \"billing\": \"Payments, refunds and invoices\",\n \"technical\": \"Bugs, outages and integration problems\"\n },\n \"instructions\": \"Which team should handle this ticket?\",\n \"type\": \"choice\"\n },\n \"needs_human\": {\n \"instructions\": \"Probability that this needs a human reply.\",\n \"type\": \"noul\"\n },\n \"urgency\": {\n \"criteria\": [\n \"Can wait a week\",\n \"Within a day\",\n \"Immediately\"\n ],\n \"instructions\": \"How urgently does this need a reply?\",\n \"type\": \"score\"\n }\n },\n \"state\": {\n \"plan\": \"pro\",\n \"subject\": \"Refund for order 4821 never arrived\"\n }\n}"
response = http.request(request)
puts response.read_body{
"id": "eval_2f9c4a1b8d3e5f7a6c0b9d2e",
"model": "typesafe/jev-1.13",
"answers": {
"department": {
"type": "choice",
"choice": "billing",
"probabilities": {
"billing": 1,
"technical": 0
},
"confidence": 1
},
"urgency": {
"type": "score",
"score": 1.3,
"legend": {
"0": "Can wait a week",
"1": "Within a day",
"2": "Immediately"
},
"probabilities": {
"0": 0.01,
"1": 0.68,
"2": 0.31
},
"confidence": 0.53
},
"needs_human": {
"type": "noul",
"noul": 0.8
}
},
"usage": {
"input_tokens": 396,
"output_tokens": 64,
"total_tokens": 460
}
}Make a structured decision
Get a typed answer with a calibrated probability, instead of prose to parse.
Send your application state plus named questions. Each question declares its
own type: choice picks one of your options and reports a probability for each,
score rates against an ordered scale, and noul returns a single probability.
noul is a probability in [0, 1], not a true/false — despite the name.
The answers come back keyed by your own question names. This endpoint is beta: it rides an upstream path we do not control, so the contract may change.
curl --request POST \
--url https://api.meshapi.ai/v1/evaluate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "typesafe/jev-1.13",
"questions": {
"department": {
"criteria": {
"billing": "Payments, refunds and invoices",
"technical": "Bugs, outages and integration problems"
},
"instructions": "Which team should handle this ticket?",
"type": "choice"
},
"needs_human": {
"instructions": "Probability that this needs a human reply.",
"type": "noul"
},
"urgency": {
"criteria": [
"Can wait a week",
"Within a day",
"Immediately"
],
"instructions": "How urgently does this need a reply?",
"type": "score"
}
},
"state": {
"plan": "pro",
"subject": "Refund for order 4821 never arrived"
}
}
'import requests
url = "https://api.meshapi.ai/v1/evaluate"
payload = {
"model": "typesafe/jev-1.13",
"questions": {
"department": {
"criteria": {
"billing": "Payments, refunds and invoices",
"technical": "Bugs, outages and integration problems"
},
"instructions": "Which team should handle this ticket?",
"type": "choice"
},
"needs_human": {
"instructions": "Probability that this needs a human reply.",
"type": "noul"
},
"urgency": {
"criteria": ["Can wait a week", "Within a day", "Immediately"],
"instructions": "How urgently does this need a reply?",
"type": "score"
}
},
"state": {
"plan": "pro",
"subject": "Refund for order 4821 never arrived"
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'typesafe/jev-1.13',
questions: {
department: {
criteria: {
billing: 'Payments, refunds and invoices',
technical: 'Bugs, outages and integration problems'
},
instructions: 'Which team should handle this ticket?',
type: 'choice'
},
needs_human: {instructions: 'Probability that this needs a human reply.', type: 'noul'},
urgency: {
criteria: ['Can wait a week', 'Within a day', 'Immediately'],
instructions: 'How urgently does this need a reply?',
type: 'score'
}
},
state: {plan: 'pro', subject: 'Refund for order 4821 never arrived'}
})
};
fetch('https://api.meshapi.ai/v1/evaluate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.meshapi.ai/v1/evaluate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => 'typesafe/jev-1.13',
'questions' => [
'department' => [
'criteria' => [
'billing' => 'Payments, refunds and invoices',
'technical' => 'Bugs, outages and integration problems'
],
'instructions' => 'Which team should handle this ticket?',
'type' => 'choice'
],
'needs_human' => [
'instructions' => 'Probability that this needs a human reply.',
'type' => 'noul'
],
'urgency' => [
'criteria' => [
'Can wait a week',
'Within a day',
'Immediately'
],
'instructions' => 'How urgently does this need a reply?',
'type' => 'score'
]
],
'state' => [
'plan' => 'pro',
'subject' => 'Refund for order 4821 never arrived'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.meshapi.ai/v1/evaluate"
payload := strings.NewReader("{\n \"model\": \"typesafe/jev-1.13\",\n \"questions\": {\n \"department\": {\n \"criteria\": {\n \"billing\": \"Payments, refunds and invoices\",\n \"technical\": \"Bugs, outages and integration problems\"\n },\n \"instructions\": \"Which team should handle this ticket?\",\n \"type\": \"choice\"\n },\n \"needs_human\": {\n \"instructions\": \"Probability that this needs a human reply.\",\n \"type\": \"noul\"\n },\n \"urgency\": {\n \"criteria\": [\n \"Can wait a week\",\n \"Within a day\",\n \"Immediately\"\n ],\n \"instructions\": \"How urgently does this need a reply?\",\n \"type\": \"score\"\n }\n },\n \"state\": {\n \"plan\": \"pro\",\n \"subject\": \"Refund for order 4821 never arrived\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.meshapi.ai/v1/evaluate")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"typesafe/jev-1.13\",\n \"questions\": {\n \"department\": {\n \"criteria\": {\n \"billing\": \"Payments, refunds and invoices\",\n \"technical\": \"Bugs, outages and integration problems\"\n },\n \"instructions\": \"Which team should handle this ticket?\",\n \"type\": \"choice\"\n },\n \"needs_human\": {\n \"instructions\": \"Probability that this needs a human reply.\",\n \"type\": \"noul\"\n },\n \"urgency\": {\n \"criteria\": [\n \"Can wait a week\",\n \"Within a day\",\n \"Immediately\"\n ],\n \"instructions\": \"How urgently does this need a reply?\",\n \"type\": \"score\"\n }\n },\n \"state\": {\n \"plan\": \"pro\",\n \"subject\": \"Refund for order 4821 never arrived\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.meshapi.ai/v1/evaluate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"typesafe/jev-1.13\",\n \"questions\": {\n \"department\": {\n \"criteria\": {\n \"billing\": \"Payments, refunds and invoices\",\n \"technical\": \"Bugs, outages and integration problems\"\n },\n \"instructions\": \"Which team should handle this ticket?\",\n \"type\": \"choice\"\n },\n \"needs_human\": {\n \"instructions\": \"Probability that this needs a human reply.\",\n \"type\": \"noul\"\n },\n \"urgency\": {\n \"criteria\": [\n \"Can wait a week\",\n \"Within a day\",\n \"Immediately\"\n ],\n \"instructions\": \"How urgently does this need a reply?\",\n \"type\": \"score\"\n }\n },\n \"state\": {\n \"plan\": \"pro\",\n \"subject\": \"Refund for order 4821 never arrived\"\n }\n}"
response = http.request(request)
puts response.read_body{
"id": "eval_2f9c4a1b8d3e5f7a6c0b9d2e",
"model": "typesafe/jev-1.13",
"answers": {
"department": {
"type": "choice",
"choice": "billing",
"probabilities": {
"billing": 1,
"technical": 0
},
"confidence": 1
},
"urgency": {
"type": "score",
"score": 1.3,
"legend": {
"0": "Can wait a week",
"1": "Within a day",
"2": "Immediately"
},
"probabilities": {
"0": 0.01,
"1": 0.68,
"2": 0.31
},
"confidence": 0.53
},
"needs_human": {
"type": "noul",
"noul": 0.8
}
},
"usage": {
"input_tokens": 396,
"output_tokens": 64,
"total_tokens": 460
}
}Authorizations
Enter your MeshAPI key (rsk_...) or, for the admin-keys endpoints, a dashboard session token — sent as Authorization: Bearer <token>.
Headers
Dated version of the API contract to pin this request to. Omit it and the request is served under 2026-08 — the oldest supported version, so an existing integration is never moved by a release. A malformed or unsupported value is rejected with 400 invalid_api_version rather than falling back silently. The version actually served is echoed as X-Mesh-Version on every response, including errors.
2026-08, 2026-09 Body
Request body for POST /v1/evaluate.
Which model decides. Use an id from GET /v1/models.
The application state to judge — free text, or any JSON object or array. Every question is answered against this same state.
The questions to answer, keyed by your own name for each. Those names are the keys of the answers you get back.
Your own labels for this request, echoed back on the usage row and available as a filter and a group-by dimension in the usage API. String keys to string values. Never put personal or sensitive data here — tags are stored with the usage record and are not redacted.
Show child attributes
Show child attributes
{ "env": "prod", "feature": "summariser" }
A stable, anonymised identifier for the end user making this request, recorded on the usage row and available as a filter and a group-by dimension in the usage API. Supersedes the deprecated user field. Use an opaque id, not an email address or a name.
256Response
Typed answers, one per question
Response body for POST /v1/evaluate.
This evaluation's id, eval_ followed by 24 hex.
The model id you asked for, not the provider's.
One answer per question, keyed by the names you sent.
Tokens as the provider reported them — what the request is billed on.
Show child attributes
Show child attributes