API key

Build

Decisions

Ask yes/no, multiple-choice and rating questions about a piece of text with paranine/laya-decision and get an answer with a probability for each option.

In one line

Ask yes/no, multiple-choice and rating questions about a piece of text and get an answer with a probability for each option, in one call, with no prompt to write and no output to parse.

The model is paranine/laya-decision, on its own endpoint, /v1/systemone, with the same key as every other model.

Example: route a support message

Input: a customer message, and a question about it.

Output (a real response):

{
  "model": "paranine/laya-decision",
  "answers": {
    "q_intent": {
      "type": "choice",
      "choice": "refund_request",
      "probabilities": { "refund_request": 0.978, "tracking_inquiry": 0.0161, "other": 0.0059 },
      "confidence": 0.8922,
      "answer_confidence": 0.978,
      "action": { "act_probability": 1.0 }
    }
  },
  "usage": {
    "input_tokens": 38,
    "output_tokens": 0,
    "state_tokens": 15,
    "state_tokens_dropped": 0,
    "truncated": false,
    "truncated_questions": []
  }
}

answers has one entry per question, under the name you gave it, and usage is what you're billed on. A response can carry other fields as well: read answers and usage.

What it costs: this request read 38 tokens. At the price below, a thousand requests like it cost about 38 paisa.

Pricing

Price
InputRs 9.94 per 1M tokens
OutputNone: a decision produces no output tokens

The count is in usage.input_tokens of every response. Each question reads your text separately, so the same text costs more with more questions: the message above was 38 input tokens with one question and 84 with two.

The request

POST /v1/systemone with your Paranine key, and exactly three fields:

FieldTypeWhat it is
modelstringparanine/laya-decision
statestringThe text to judge: a message, a transcript, a document excerpt.
questionsobject1 to 128 questions. You choose each name (it cannot be empty), and the answer comes back under the same name.

Each question has a type, instructions that say what you are asking, and for two of the types a criteria. type and instructions are required:

typeUse it forcriteriaIn the answer
choicePicking one optionRequired: the list of options, or an object of option and descriptionchoice (the option picked) and probabilities (one per option)
noulA yes/no questionNot needednoul, a number from 0 to 1
scoreA rating on your own scaleRequired: the levels, lowest firstscore (position on the scale, 0 = the first level), legend and probabilities

This endpoint does not stream, and it takes no max_tokens, temperature or other chat parameters. Sending one returns a 400.

Code

Put your API key in P9_API_KEY:

export P9_API_KEY="sk_p9_…"   # your API key

Each example sends the support message above and prints the answer.

curl -sS https://sovereign.paranine.com/v1/systemone \
  -H "Authorization: Bearer $P9_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "paranine/laya-decision",
    "state": "My order #49204 never arrived and I want a refund right now.",
    "questions": {
      "q_intent": {
        "type": "choice",
        "instructions": "Classify the request.",
        "criteria": ["refund_request", "tracking_inquiry", "other"]
      }
    }
  }'

All three question types

One request can carry several questions of different types about the same text:

curl -sS https://sovereign.paranine.com/v1/systemone \
  -H "Authorization: Bearer $P9_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "paranine/laya-decision",
    "state": "My order #49204 never arrived and I want a refund right now.",
    "questions": {
      "q_intent": {
        "type": "choice",
        "instructions": "Classify the request.",
        "criteria": ["refund_request", "tracking_inquiry", "other"]
      },
      "is_angry": {
        "type": "noul",
        "instructions": "Is the customer angry?"
      },
      "urgency": {
        "type": "score",
        "instructions": "How urgent is this?",
        "criteria": ["low", "medium", "high"]
      }
    }
  }'

The answers it returned (a real response; usage is left out here). The request read 126 input tokens, because each of the three questions reads the text:

{
  "q_intent": {
    "type": "choice",
    "choice": "refund_request",
    "probabilities": { "refund_request": 0.978, "tracking_inquiry": 0.0161, "other": 0.0059 },
    "confidence": 0.8922,
    "answer_confidence": 0.978,
    "action": { "act_probability": 1.0 }
  },
  "is_angry": {
    "type": "noul",
    "noul": 0.6656,
    "confidence": 0.6656,
    "answer_confidence": 0.6656,
    "action": { "act_probability": 1.0 }
  },
  "urgency": {
    "type": "score",
    "score": 0.7837,
    "legend": { "0": "low", "1": "medium", "2": "high" },
    "probabilities": { "0": 0.3944, "1": 0.4275, "2": 0.1781 },
    "confidence": 0.0556,
    "answer_confidence": 0.4275,
    "action": { "act_probability": 1.0 }
  }
}

score is a position on your scale, counted from 0: here 0.78, between low (0) and medium (1). legend maps each position back to your level names.

If you already use the OpenAI SDK

The SDK has no method for this endpoint, but its general post call works with the client you already have.

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://sovereign.paranine.com/v1",
    api_key=os.environ["P9_API_KEY"],
)

result = client.post(
    "/systemone",
    body={
        "model": "paranine/laya-decision",
        "state": "My order #49204 never arrived and I want a refund right now.",
        "questions": {
            "q_intent": {
                "type": "choice",
                "instructions": "Classify the request.",
                "criteria": ["refund_request", "tracking_inquiry", "other"],
            },
        },
    },
    cast_to=object,
)

answer = result["answers"]["q_intent"]
print(answer["choice"], answer["probabilities"][answer["choice"]])

Errors

A mistake in the request returns a 400 in the same format as every other Paranine error, with param naming the field. A question sent without instructions:

{
  "error": {
    "message": "instructions is required and must be a non-empty string",
    "type": "invalid_request_error",
    "param": "questions.is_angry.instructions",
    "code": "invalid_request_body"
  }
}
StatuscodeWhen
400malformed_jsonThe body is not valid JSON.
400invalid_request_bodyA field is missing or wrong. param names it.
400unknown_parameterThe request has a field this endpoint does not take, such as stream or max_tokens. param names it.
400endpoint_not_supportedA chat model was used on this endpoint, or this model on /v1/chat/completions.
401invalid_api_keyThe API key is wrong.
402insufficient_fundsYour balance or the key's credit cap cannot cover the request.
404model_not_foundThe model name does not exist.
429rate_limited_key, upstream_rate_limitedPast the key's rate limit, or the model is at capacity. Wait for Retry-After.
502, 503upstream_unavailableThe model is temporarily unavailable. Try again.

You're charged only for a 200. Responses carry an X-Request-Id header; quote it if you contact us.

With the OpenAI SDK these arrive as its usual errors (BadRequestError, AuthenticationError, NotFoundError), with the same code, and param where there is one.

Good to know

  • Keep the text short. The model reads up to 512 tokens per question, counting your text and the question together. Longer text is cut, not refused: the answer gets much less reliable, and the request takes much longer. Check usage.truncated on every response: when it is true, usage.truncated_questions lists the questions affected and usage.state_tokens_dropped says how much was left out.
  • For speed, send questions as separate requests. Inside one request the questions are answered one after another, so eight questions take about eight times as long as one. Separate requests are answered side by side, and cost the same: each question is billed for the tokens it reads either way. Use one request with several questions when you want the answers together and can wait.
  • English and other languages. The model handles English and other languages, including Urdu written in Arabic script. The first request in a language other than English can take noticeably longer.
  • Your usual limits apply. Requests count against the same key rate limit and the same balance as your other Paranine calls.

Something unclear or wrong on this page? Tell us. Machine-readable copies: llms.txt.