Evaluation modes and examples
Use this same endpoint and Bearer API key for both modes. Send either useCase + input or state + questions. Do not mix them or send model. MCP tool nexscope_jev_evaluate accepts the same body.
Custom mode accepts non-empty text, an object, or an array as state and 1–32 questions. Instructions are required strings (up to 4,000 characters). Choice accepts 2–255 options; Score accepts 2–32 ordered text levels. Criterion descriptions allow up to 2,000 characters. Question and choice IDs use 1–64 letters, digits, underscores, or hyphens. Keyword, evidence, fact, and candidate IDs use the same format and must be unique within their respective arrays.
The whole serialized request must fit within 16,000 UTF-8 bytes, even when individual fields are within their limits. One call counts as one request, including a keyword batch. No data is fetched automatically. Only submit context you are authorized to share with TypeSafe.
Custom questions
Evaluate all three question types together. Each question reads the same state independently. Questions cannot depend on another answer in the same request.
{
"state": {
"product": "750ml insulated steel water bottle",
"keyword": "hiking water bottle"
},
"questions": {
"relevant": {
"type": "noul",
"instructions": "Is the keyword relevant to this product?"
},
"intent": {
"type": "choice",
"instructions": "Classify the search intent.",
"criteria": {
"purchase": "Looking for a product to buy",
"research": "Looking for information",
"other": "Neither"
}
},
"fit": {
"type": "score",
"instructions": "Rate keyword fit using only the product description.",
"criteria": [
"Unrelated",
"Weak fit",
"Good fit",
"Direct fit"
]
}
}
}
Response guardrails
Checks response risks and severity. Returns pass, review, or block.
{
"useCase": "response_guardrails",
"input": {
"content": "Never share your password with anyone."
}
}
IP risk triage
Flags possible IP concerns. Always returns review; it is not legal clearance.
{
"useCase": "ip_risk_triage",
"input": {
"text": "A product description using a third-party brand name."
}
}
SEO relevance
Supply query and at least one of title, metaDescription, or contentExcerpt. Scores relevance, not rankings or search volume.
{
"useCase": "seo_relevance",
"input": {
"query": "insulated hiking bottle",
"title": "Insulated steel water bottle for hiking"
}
}
Evidence check
Assesses only sourceText. An optional quote must occur after whitespace normalization; otherwise quote_not_found is returned without a model call.
{
"useCase": "evidence_check",
"input": {
"claim": "The bottle holds 750ml.",
"sourceText": "Capacity: 750ml. Material: steel.",
"quote": "Capacity: 750ml."
}
}
Keyword business relevance
1–10 keywords per call. exclusions is required and may be empty. Optional serpEvidence contains up to 30 supplied excerpts; keywordId must reference a keyword in this request. Labels: relevant, irrelevant, uncertain.
{
"useCase": "keyword_business_relevance",
"input": {
"businessDescription": "We sell reusable hiking bottles.",
"exclusions": [
"Disposable bottles"
],
"keywords": [
{
"id": "k1",
"keyword": "steel hiking bottle"
}
],
"serpEvidence": [
{
"id": "e1",
"keywordId": "k1",
"source": "Supplied search result excerpt",
"text": "Reusable steel bottles for outdoor use."
}
]
}
}
Keyword cluster fit
Compare 1–10 keywords with 1–5 candidate representatives. This evaluates topic/page fit; it does not build an entire clustering workflow. Labels: same_page, separate_page, uncertain. candidateId can be null. The candidate ID no_candidate is reserved.
{
"useCase": "keyword_cluster_fit",
"input": {
"keywords": [
{
"id": "k1",
"keyword": "insulated hiking bottle"
}
],
"candidates": [
{
"id": "c1",
"keyword": "hiking water bottles"
}
]
}
}
Amazon keyword product fit
Evaluate 1–10 keywords using 1–30 supplied product facts. Fact sources: title, bullet, attribute, description. Labels: match, partial, conflict, unknown. Supported marketplaces: US, UK, DE, FR, JP, CA, IT, ES, MX, IN.
{
"useCase": "amazon_keyword_product_fit",
"input": {
"marketplace": "US",
"productFacts": [
{
"id": "f1",
"source": "title",
"value": "750ml insulated steel water bottle"
}
],
"keywords": [
{
"id": "k1",
"keyword": "steel water bottle"
}
]
}
}
Read a custom response
The Nexscope envelope remains code / msg / data. Custom mode returns data.useCase = custom, policyVersion = jev-custom-v1, decision = evaluated, empty reasonCodes and checks, and answers under data.result.answers. Evaluated confirms that answers are available; it does not approve an action. Use your own decision thresholds. Token usage is not exposed.
{
"code": 0,
"msg": "success",
"data": {
"useCase": "custom",
"policyVersion": "jev-custom-v1",
"model": "<resolved model>",
"decision": "evaluated",
"reasonCodes": [],
"checks": {},
"result": {
"answers": {
"relevant": {
"type": "noul",
"noul": 0.92
},
"intent": {
"type": "choice",
"choice": "purchase",
"confidence": 0.9,
"probabilities": {
"purchase": 0.9,
"research": 0.08,
"other": 0.02
}
},
"fit": {
"type": "score",
"score": 2.8,
"confidence": 0.9,
"probabilities": {
"0": 0,
"1": 0,
"2": 0.2,
"3": 0.8
},
"legend": {
"0": "Unrelated",
"1": "Weak fit",
"2": "Good fit",
"3": "Direct fit"
}
}
}
}
}
}
The values above are illustrative. Noul is the probability of yes, not a Boolean. Score is the probability-weighted average of zero-based levels and may be fractional. Keyword presets return rows in data.result.rows, keyed by input ID, with labels, confidence, and reasonCodes; evidenceRefs identify supplied context, not independently verified sources. Keyword policy version is jev-keyword-tools-v1; original presets retain jev-evaluation-v1.
Errors and limits
Check the response code before reading data. 99001: invalid parameters; fix the request. 99009: shared quota exceeded; wait before retrying. 13007: evaluation unavailable, timeout, or invalid upstream answer; no usable decision is returned. An active subscription is required. Each evaluation has a 10-second upstream deadline and no automatic upstream retry.
This is the Nexscope API contract. It uses TypeSafe internally and intentionally applies the limits above; it is not an unrestricted passthrough of the TypeSafe API.