Skip to main content

Megacall (Batch Operations)

Run multiple analysis types in a single API call for efficiency.

Why Use Megacall?​

A single request is faster than multiple requests for each kind of analysis. It is also more cost effective: each check in a megacall is charged at 10% less than the same check called on its own, and a check that returns null is not charged. See Billing.

First-Pass Screening​

Every check in a megacall (comment score, spam, relevance and dogwhistle) is classified first by a fast first-pass screen, run once for the whole request:

  • A check the screen clears is answered straight from the screen, with no full assessment. It has the same shape as any other answer, but its finding lists and reasoning are empty, since there is nothing to explain.
  • A comment the screen is confident is spam is answered as spam straight away. The response has spam_check filled in and every other check null, and only the spam check is charged. Spam is deleted, not coached, so there is nothing to gain from running the other checks. Its reasoning says it was classified by first-pass screening.
  • A comment the screen suspects is spam (spam_check.suspected_spam is true) is not spam. The other checks still run and are returned as usual, and spam_check.suggestion tells the commenter what to change. Send the comment back for revision with the suggestion, together with any other feedback, rather than deleting it. See Spam Detection.
  • A check the screen flags, or is unsure about, gets the full assessment, which explains the problem and, for the comment score, suggests improvements.

A megacall that asked for spam, relevance and comment score, for a comment answered as spam:

{
"comment_score": null,
"spam_check": {
"is_spam": true,
"confidence": 0.96,
"reasoning": "Classified as spam by first-pass screening.",
"suspected_spam": false,
"suggestion": ""
},
"relevance_check": null,
"dogwhistle_check": null,
"perspective": null
}

So a null check in a megacall response means either that it was not requested, or that the comment was answered as spam. When spam_check.is_spam is true, do not expect the other results. Only is_spam being true does this: when spam_check.suspected_spam is true, every requested check is returned. The spam answer is only short-circuited like this when spam was one of the checks requested.

Perspective-compatible scoring (run_perspective) is not part of this screen; it is scored on its own, as on the standalone endpoint.

For the comment score, your comment health levels also decide how cautious the screen is.

Selecting Which Checks to Run​

Each analysis type is optional. Only request what you need to minimize latency and cost.

Pass an options object with boolean flags to select analyses:

ParameterAnalysis
includeSpam: trueSpam detection
includeRelevance: trueOn-topic and banned topics check
includeCommentScore: trueFull quality analysis
includeDogwhistle: trueCoded language detection
includePerspectiveAnalyzeComment: truePerspective-compatible analyzeComment scoring

Results are null for any analysis not requested, and for every analysis except spam when the comment is answered as spam.

Basic Usage​

const result = await client.megacall({
comment: "This is a test comment",
articleId: articleId,
includeSpam: true,
includeRelevance: true,
includeCommentScore: true,
includeDogwhistle: true,
});

// Access results (null if not requested)
if (result.spam_check) {
console.log(`Is spam: ${result.spam_check.is_spam}`);
}

if (result.relevance_check) {
console.log(`On topic: ${result.relevance_check.on_topic.on_topic}`);
}

if (result.comment_score) {
console.log(`Comment health: ${result.comment_score.overall_score}`);
}

if (result.dogwhistle_check) {
console.log(`Dogwhistles detected: ${result.dogwhistle_check.detection.dogwhistles_detected}`);
}

With Additional Parameters​

const result = await client.megacall({
comment: "Comment text here",
articleId: articleId,
includeSpam: true,
includeRelevance: true,
includeDogwhistle: true,
bannedTopics: ["politics", "religion"],
sensitiveTopics: ["controversial topic"],
dogwhistleExamples: ["known coded phrase"],
});

With Comment Health Tolerances​

The comment score in a megacall is judged under the comment health levels you pass in tolerances, like a standalone comment score. Any item you leave out is standard; nothing is saved on your API key. Tolerances are used only when the comment score is requested.

Act on comment_score.exceeds_tolerance rather than comment_score.toxicity_score alone.

const result = await client.megacall({
comment: "Comment text here",
articleId: articleId,
includeCommentScore: true,
tolerances: { profanity: "relaxed", quality: "strict", threat: "zero_tolerance" },
});

if (result.comment_score?.exceeds_tolerance) {
// Coach the commenter
}

Handling Stale Article Contexts​

Article context IDs are tied to the API key that created them. If you rotate your key, previously stored IDs no longer resolve, and megacall raises ArticleContextNotFoundError (or ArticleContextNotFoundException in PHP). Regenerate the context, store the new ID, and retry the call.

import { RespectifyClient, ArticleContextNotFoundError } from "@respectify/client";

async function evaluateWithRetry(comment: string, articleUrl: string, articleId: string) {
try {
return await client.megacall({ comment, articleId, includeCommentScore: true });
} catch (err) {
if (!(err instanceof ArticleContextNotFoundError)) throw err;
const fresh = await client.initTopicFromUrl(articleUrl);
// Store fresh.article_id so later requests reuse it.
return await client.megacall({
comment,
articleId: fresh.article_id,
includeCommentScore: true,
});
}
}
tip

Avoid retry loops — initTopic is a paid call. Retry once, store the new ID, and let later requests reuse it.