Survey & review analysis API

Find out what customers say about delivery, price, support and quality, in every review and survey answer

Send the free-text answers from your surveys or reviews. For each one, spinf returns whether it is positive, mixed or negative, and how the customer feels about each topic you name. Count the results by segment and track them over time, for every response instead of a hand-read sample.

Read the quickstart
Cost at scale

1M responses for about $32

On spinf-12b, our optimized Gemma 4 12B, only input is billed, at $0.09 per million tokens: the content once per call, each question's own tokens, and one empty floor per question. The scores are free.

Combine use cases in the same call

Code sentiment, aspects and themes, and check each answer against your content policy in the same call: the answer is read once, and each extra question adds only its own tokens.

responses1,000,000× tokens each (about)350= tokens350M× $0.09 / 1M$31.50

Assumes 120-token answers, 8 questions and aspects, batched calls. The first 50M tokens are free. Gemma is a trademark of Google LLC.

Pricing details
On demand · self-serve

$0.09 per million input tokens · the scores are free

Why spinf

Calibrated answers for survey & review analysis, at any scale

Every aspect at once

Aspect-based sentiment: one template with a placeholder asks about delivery, support, quality and price in the same call.

Numbers you can count

Probabilities over your own answers add up cleanly into shares, trends and segments, and each comes with a baseline (the same question with no text) so different questions can be compared.

Every response

Cheap enough to code every answer of every wave, and to re-code the archive when the codebook changes.

Live example

One review, a full aspect grid

Overall sentiment, and one template asked for four aspects. The bars show p; the tick shows the floor, the same question with no review.

Content
Customer review: Delivery was two days late and the box arrived dented, but support sent a replacement right away and the blender itself is excellent. Would buy again.

Overall, the review is (positive, mixed, or negative):

positive

0.77

mixed

0.20

negative

0.04

How does the customer feel about the {aspect} (positive, negative, or not mentioned)?

delivery

positive

0.19

negative

0.80

not mentioned

0.01

packaging

positive

0.08

negative

0.91

not mentioned

0.01

customer support

positive

0.98

negative

0.01

not mentioned

0.01

product quality

positive

0.97

negative

0.01

not mentioned

0.02

import os
import requests

resp = requests.post(
    "https://api.spinf.com/v1/score",
    headers={"Authorization": f"Bearer {os.environ['SPINF_API_KEY']}"},
    json={
      "model": "spinf-12b",
      "messages": [
        {
          "role": "user",
          "content": "Customer review:\nDelivery was two days late and the box arrived dented, but support sent a replacement right away and the blender itself is excellent. Would buy again."
        }
      ],
      "scoring": {
        "queries": [
          {
            "id": "overall",
            "template": "\n\nOverall, the review is (positive, mixed, or negative):{?}",
            "options": [
              " positive",
              " mixed",
              " negative"
            ]
          },
          {
            "id": "aspect",
            "template": "\n\nHow does the customer feel about the {aspect} (positive, negative, or not mentioned)?\nAnswer:{?}",
            "options": [
              " positive",
              " negative",
              " not mentioned"
            ],
            "combinations": [
              {
                "aspect": "delivery"
              },
              {
                "aspect": "packaging"
              },
              {
                "aspect": "customer support"
              },
              {
                "aspect": "product quality"
              }
            ]
          }
        ]
      }
    },
)
for query in resp.json()["results"][0]["queries"]:
    for combo in query["combinations"]:
        print(query["id"], combo["values"], [(o["text"], o["p"], o["floor_p"]) for o in combo["options"]])

A live call to spinf-12b, with no examples: late delivery and a dented box read negative, support and the product positive, in one call.

The API call behind this example, the docs and the benchmark code are easier to read on a larger screen. Start free now, and pick it up on your laptop.

Benchmark · synthetic and public reviews

Overall and per-aspect sentiment, measured

Measured on 125 synthetic customer reviews (625 aspect labels) labelled by a language model and checked blind by a second model, and on two public review datasets, with no examples and with 4 or 8 labelled examples placed in the prompt.

96%

correct overall sentiment (3)

125 synthetic reviews · 8 examples in the prompt
94%

correct per-aspect sentiment

625 synthetic labels · 8 examples · 84% with no examples (calibrated)
97%

correct polarity · public product reviews

300 reviews · no examples needed (calibrated)
89%

correct aspects · SemEval-2014 restaurants

1,166 public labels · 4 examples · 83% with no examples (calibrated) · spinf-31b: 90% with 8 examples

The public datasets are the better guide: synthetic reviews are cleaner than real feedback. Measure on a coded sample of your own responses before relying on the numbers.

Test sets, questions and code on GitHub: reproduce it with your own key

The questions matter: iterate on yours

As with any language model, the wording of the questions and a few labelled examples change the results a lot. With spinf that is cheap to get right: try a few wordings and example sets on a few hundred of your own items for cents, and keep the best. How to write questions

How it works

From questions to numbers

Self-serve on the on-demand API: sign up, create a key and send your first batch in minutes.

1

Turn the codebook into questions

One closed question per code or theme, and templates with placeholders for aspects. Add a few coded answers as examples when the codes are subtle.

2

Score every response

Send each wave in batches on the on-demand API: many answers per call, the questions shared.

3

Count and compare

Aggregate probabilities into shares per segment and over time, and pull the answers behind any number.

FAQ

Survey & review analysis: questions, answered

More in the docs and the guides: aspect-based sentiment analysis and coding open-ended survey responses, or .

Yes: every code is a question with the answers you choose. Placeholders ask the same question for every aspect or product, and examples in the content teach the subtle codes.

Only input is billed. A 120-token answer with eight questions is a few hundred tokens: a million answers cost a few tens of dollars.

Yes: any text works, from app store reviews to support chats and NPS comments. Keep the same questions across sources to compare them.

No. Content sent for scoring is processed in memory and not stored by default, and it is never used to train models.
Try it on your data

The first 50M tokens are on us

Sign up, create a key and score your first batch in minutes.