Claude API Sentiment Analysis: A Working API Example
Claude API Sentiment Analysis: A Working Example
If you're looking for a Claude API sentiment analysis example, the short answer is: send Claude the text plus a tightly scoped instruction asking for a structured sentiment label (and optionally a confidence score and reasoning), and parse the JSON it returns. Claude is well suited to this because it handles nuance — sarcasm, mixed sentiment, domain-specific language — better than keyword-based or classic ML sentiment models, without requiring you to train anything.
This article walks through a real, copy-pasteable example: the prompt structure, the output schema, how to batch requests for review pipelines, and how to wire it into an HTTPS endpoint you can call from any backend. We'll use the Messages API format, which is what Claude (and Claude-compatible services like SubToAPI) expose.
Why use an LLM instead of a traditional sentiment classifier
Traditional sentiment APIs (lexicon-based or small fine-tuned models) are fast and cheap but struggle with:
- Sarcasm and irony ("great, another outage")
- Mixed sentiment in one message (praises the product, complains about support)
- Domain-specific vocabulary (medical, legal, financial text)
- Multilingual input without separate models per language
Claude handles all of these out of the box because it's reasoning over meaning, not just word polarity. The tradeoff is latency and cost per call, so for very high-volume pipelines you'd typically batch or sample rather than classify every single row in real time.
The core prompt pattern
The reliable way to get machine-readable sentiment output is to constrain the response format explicitly and ask for JSON only.
You are a sentiment classification engine. Analyze the sentiment of the
text below and respond with ONLY a JSON object, no other text.
Schema:
{
"sentiment": "positive" | "negative" | "neutral" | "mixed",
"confidence": number between 0 and 1,
"reasoning": "one sentence explanation"
}
Text: "{{user_text}}"
Putting the schema directly in the prompt, rather than relying on the model to guess the format, is the single biggest factor in getting consistent parseable output.
Example request
Here's a working example using SubToAPI's Messages endpoint, which proxies Claude behind a standard API key (sub_live_...) so you don't need to manage Claude account credentials directly:
curl https://api.subtoapi.app/v1/messages \
-H "Authorization: Bearer $SUBTOAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4",
"max_tokens": 200,
"messages": [
{
"role": "user",
"content": "You are a sentiment classification engine. Respond with ONLY JSON matching this schema: {\"sentiment\": \"positive|negative|neutral|mixed\", \"confidence\": number, \"reasoning\": string}. Text: \"The onboarding was smooth but customer support never replied to my ticket.\""
}
]
}'
Expected response body (sentiment payload inside the message content):
{
"sentiment": "mixed",
"confidence": 0.86,
"reasoning": "Positive experience with onboarding is offset by a negative experience with unresponsive support."
}
Note how Claude correctly identifies mixed sentiment rather than forcing it into positive or negative — this is exactly the kind of nuance that keyword-based tools miss.
Wiring it into a backend function
A minimal Node.js wrapper for a sentiment-analysis endpoint:
async function analyzeSentiment(text) {
const res = await fetch("https://api.subtoapi.app/v1/messages", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.SUBTOAPI_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
model: "claude-sonnet-4",
max_tokens: 200,
messages: [{
role: "user",
content: `You are a sentiment classification engine. Respond with ONLY JSON: {"sentiment": "positive|negative|neutral|mixed", "confidence": number, "reasoning": string}. Text: "${text.replace(/"/g, '\\"')}"`
}]
})
});
const data = await res.json();
const raw = data.content[0].text;
return JSON.parse(raw);
}
Wrap this in a try/catch around JSON.parse — even with a strict schema, occasionally a model adds a stray sentence. If that happens, a quick regex to extract the {...} block before parsing is a reasonable fallback.
Batch processing for review and feedback pipelines
If you're analyzing support tickets, app reviews, or survey responses in bulk, don't send one request per row synchronously in a loop — that's slow and easy to rate-limit. Instead:
- Collect texts into batches of 10–20.
- Send one request per batch asking for an array of results, each tagged with an
idso you can map back to the source row. - Run batches concurrently with a small concurrency limit (3–5 in flight).
Example batch prompt:
Analyze sentiment for each item below. Respond with ONLY a JSON array,
one object per item, in the same order, using this schema:
{"id": string, "sentiment": "positive|negative|neutral|mixed", "confidence": number}
Items:
1. id=r1: "Loved the new dashboard redesign."
2. id=r2: "Checkout kept failing on mobile."
3. id=r3: "It's fine, does what it says."
This cuts your request count dramatically compared to one call per review, which matters for both latency and cost at scale.
Adding tool use for structured extraction
For higher reliability than prompt-based JSON, you can define sentiment classification as a tool with a strict input schema, and have Claude call it instead of writing free text. This guarantees schema-valid output at the protocol level rather than relying on the model to follow instructions. See /docs/tools for the tool definition format if you want to go this route for production pipelines.
Streaming for real-time dashboards
If you're building a live sentiment feed (e.g., monitoring social mentions or support chat sentiment as it comes in), streaming responses token-by-token isn't usually necessary for short JSON outputs — the whole response arrives fast enough. Streaming is more useful when combining sentiment analysis with longer generated summaries. See /docs/streaming if you extend this pattern that way.
Getting set up
If you already have Claude access and want a stable HTTPS endpoint with application API keys instead of juggling console credentials, SubToAPI turns your existing access into a sub_live_... key you can drop into any backend, with per-key usage metadata so you can track exactly how much your sentiment pipeline is costing. Check /docs/quickstart to get a key running in a few minutes, or /docs/messages for the full Messages API reference. Plans start at €9/month on the Solo tier, with Team and Scale tiers for multi-seat usage — see /pricing. A free trial is available at /signup.
Frequently Asked Questions
Is Claude accurate enough for production sentiment analysis? Yes, especially for nuanced or mixed-sentiment text. For simple binary positive/negative classification at very high volume, a smaller dedicated model may be cheaper, but Claude outperforms rule-based tools on sarcasm, context, and domain-specific language.
How do I keep Claude's sentiment output consistent? Always specify an explicit JSON schema in the prompt, ask for "ONLY JSON, no other text," and validate/parse defensively with a regex fallback for edge cases.
Can I analyze sentiment for text in languages other than English? Yes. Claude handles multilingual input natively, so you can send non-English text directly in the same prompt structure without a separate translation step.