curl --request POST \
--url https://gateway.prem.io/typesafe/v1/systemone \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "<string>",
"state": "<string>",
"questions": {},
"images": [
"<string>"
],
"samples": 123,
"steps": 123,
"provider": "<string>",
"videos": [
"data:video/mp4;base64,<base64-encoded-mp4>"
]
}
'import requests
url = "https://gateway.prem.io/typesafe/v1/systemone"
payload = {
"model": "<string>",
"state": "<string>",
"questions": {},
"images": ["<string>"],
"samples": 123,
"steps": 123,
"provider": "<string>",
"videos": ["data:video/mp4;base64,<base64-encoded-mp4>"]
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: '<string>',
state: '<string>',
questions: {},
images: ['<string>'],
samples: 123,
steps: 123,
provider: '<string>',
videos: ['data:video/mp4;base64,<base64-encoded-mp4>']
})
};
fetch('https://gateway.prem.io/typesafe/v1/systemone', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://gateway.prem.io/typesafe/v1/systemone",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => '<string>',
'state' => '<string>',
'questions' => [
],
'images' => [
'<string>'
],
'samples' => 123,
'steps' => 123,
'provider' => '<string>',
'videos' => [
'data:video/mp4;base64,<base64-encoded-mp4>'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://gateway.prem.io/typesafe/v1/systemone"
payload := strings.NewReader("{\n \"model\": \"<string>\",\n \"state\": \"<string>\",\n \"questions\": {},\n \"images\": [\n \"<string>\"\n ],\n \"samples\": 123,\n \"steps\": 123,\n \"provider\": \"<string>\",\n \"videos\": [\n \"data:video/mp4;base64,<base64-encoded-mp4>\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://gateway.prem.io/typesafe/v1/systemone")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"<string>\",\n \"state\": \"<string>\",\n \"questions\": {},\n \"images\": [\n \"<string>\"\n ],\n \"samples\": 123,\n \"steps\": 123,\n \"provider\": \"<string>\",\n \"videos\": [\n \"data:video/mp4;base64,<base64-encoded-mp4>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://gateway.prem.io/typesafe/v1/systemone")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"<string>\",\n \"state\": \"<string>\",\n \"questions\": {},\n \"images\": [\n \"<string>\"\n ],\n \"samples\": 123,\n \"steps\": 123,\n \"provider\": \"<string>\",\n \"videos\": [\n \"data:video/mp4;base64,<base64-encoded-mp4>\"\n ]\n}"
response = http.request(request)
puts response.read_body{}{
"status": 400,
"error": "Some error message",
"message": null,
"env": "development",
"log": {
"request_id": "req_1234567890"
},
"support_id": "support_uuidv7-something-else",
"data": {},
"validator": {
"email": "Invalid email address",
"password": "Password is required"
}
}{
"status": 401,
"error": "Some error message",
"message": null,
"env": "development",
"log": {
"request_id": "req_1234567890"
},
"support_id": "support_uuidv7-something-else",
"data": {},
"validator": {
"email": "Invalid email address",
"password": "Password is required"
}
}{
"status": 403,
"error": "Some error message",
"message": null,
"env": "development",
"log": {
"request_id": "req_1234567890"
},
"support_id": "support_uuidv7-something-else",
"data": {},
"validator": {
"email": "Invalid email address",
"password": "Password is required"
}
}{
"status": 404,
"error": "Some error message",
"message": null,
"env": "development",
"log": {
"request_id": "req_1234567890"
},
"support_id": "support_uuidv7-something-else",
"data": {},
"validator": {
"email": "Invalid email address",
"password": "Password is required"
}
}{
"status": 400,
"error": "Some error message",
"message": null,
"env": "development",
"log": {
"request_id": "req_1234567890"
},
"support_id": "support_uuidv7-something-else",
"data": {},
"validator": {
"email": "Invalid email address",
"password": "Password is required"
}
}{
"status": 400,
"error": "Some error message",
"message": null,
"env": "development",
"log": {
"request_id": "req_1234567890"
},
"support_id": "support_uuidv7-something-else",
"data": {},
"validator": {
"email": "Invalid email address",
"password": "Password is required"
}
}{
"status": 400,
"error": "Some error message",
"message": null,
"env": "development",
"log": {
"request_id": "req_1234567890"
},
"support_id": "support_uuidv7-something-else",
"data": {},
"validator": {
"email": "Invalid email address",
"password": "Password is required"
}
}Decisions
Answer typed decision questions with probabilities over a TypeSafe-compatible API.
curl --request POST \
--url https://gateway.prem.io/typesafe/v1/systemone \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "<string>",
"state": "<string>",
"questions": {},
"images": [
"<string>"
],
"samples": 123,
"steps": 123,
"provider": "<string>",
"videos": [
"data:video/mp4;base64,<base64-encoded-mp4>"
]
}
'import requests
url = "https://gateway.prem.io/typesafe/v1/systemone"
payload = {
"model": "<string>",
"state": "<string>",
"questions": {},
"images": ["<string>"],
"samples": 123,
"steps": 123,
"provider": "<string>",
"videos": ["data:video/mp4;base64,<base64-encoded-mp4>"]
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: '<string>',
state: '<string>',
questions: {},
images: ['<string>'],
samples: 123,
steps: 123,
provider: '<string>',
videos: ['data:video/mp4;base64,<base64-encoded-mp4>']
})
};
fetch('https://gateway.prem.io/typesafe/v1/systemone', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://gateway.prem.io/typesafe/v1/systemone",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => '<string>',
'state' => '<string>',
'questions' => [
],
'images' => [
'<string>'
],
'samples' => 123,
'steps' => 123,
'provider' => '<string>',
'videos' => [
'data:video/mp4;base64,<base64-encoded-mp4>'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://gateway.prem.io/typesafe/v1/systemone"
payload := strings.NewReader("{\n \"model\": \"<string>\",\n \"state\": \"<string>\",\n \"questions\": {},\n \"images\": [\n \"<string>\"\n ],\n \"samples\": 123,\n \"steps\": 123,\n \"provider\": \"<string>\",\n \"videos\": [\n \"data:video/mp4;base64,<base64-encoded-mp4>\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://gateway.prem.io/typesafe/v1/systemone")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"<string>\",\n \"state\": \"<string>\",\n \"questions\": {},\n \"images\": [\n \"<string>\"\n ],\n \"samples\": 123,\n \"steps\": 123,\n \"provider\": \"<string>\",\n \"videos\": [\n \"data:video/mp4;base64,<base64-encoded-mp4>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://gateway.prem.io/typesafe/v1/systemone")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"<string>\",\n \"state\": \"<string>\",\n \"questions\": {},\n \"images\": [\n \"<string>\"\n ],\n \"samples\": 123,\n \"steps\": 123,\n \"provider\": \"<string>\",\n \"videos\": [\n \"data:video/mp4;base64,<base64-encoded-mp4>\"\n ]\n}"
response = http.request(request)
puts response.read_body{}{
"status": 400,
"error": "Some error message",
"message": null,
"env": "development",
"log": {
"request_id": "req_1234567890"
},
"support_id": "support_uuidv7-something-else",
"data": {},
"validator": {
"email": "Invalid email address",
"password": "Password is required"
}
}{
"status": 401,
"error": "Some error message",
"message": null,
"env": "development",
"log": {
"request_id": "req_1234567890"
},
"support_id": "support_uuidv7-something-else",
"data": {},
"validator": {
"email": "Invalid email address",
"password": "Password is required"
}
}{
"status": 403,
"error": "Some error message",
"message": null,
"env": "development",
"log": {
"request_id": "req_1234567890"
},
"support_id": "support_uuidv7-something-else",
"data": {},
"validator": {
"email": "Invalid email address",
"password": "Password is required"
}
}{
"status": 404,
"error": "Some error message",
"message": null,
"env": "development",
"log": {
"request_id": "req_1234567890"
},
"support_id": "support_uuidv7-something-else",
"data": {},
"validator": {
"email": "Invalid email address",
"password": "Password is required"
}
}{
"status": 400,
"error": "Some error message",
"message": null,
"env": "development",
"log": {
"request_id": "req_1234567890"
},
"support_id": "support_uuidv7-something-else",
"data": {},
"validator": {
"email": "Invalid email address",
"password": "Password is required"
}
}{
"status": 400,
"error": "Some error message",
"message": null,
"env": "development",
"log": {
"request_id": "req_1234567890"
},
"support_id": "support_uuidv7-something-else",
"data": {},
"validator": {
"email": "Invalid email address",
"password": "Password is required"
}
}{
"status": 400,
"error": "Some error message",
"message": null,
"env": "development",
"log": {
"request_id": "req_1234567890"
},
"support_id": "support_uuidv7-something-else",
"data": {},
"validator": {
"email": "Invalid email address",
"password": "Password is required"
}
}Zero Data Retention
This is a Zero Data Retention route. Prem sends the request to a trusted partner. Prem does not keep your prompts or completions, and the partner does not keep them. Your content is plaintext at the Prem API Gateway and at the partner. There is no client-side encryption and no Trusted Execution Environment. See ZDR vs Confidential.Base URL
https://gateway.prem.io/typesafe/v1/systemone
Authorization: Bearer header. The key must have the chats.completion scope. No client KEK is used on this route.
curl https://gateway.prem.io/typesafe/v1/systemone \
-H "Authorization: Bearer $PREM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "dgemma", "state": "x", "questions": {"a": {"type": "noul", "instructions": "y"}}}'
Request shape
The request uses a TypeSafe-compatible API, so the official TypeSafe client works against this route. Set its base URL tohttps://gateway.prem.io/typesafe. The client appends /v1/systemone and /v1/models.
import { choice, noul, score, TypeSafeClient } from "@typesafe-ai/sdk";
const client = new TypeSafeClient({
apiKey: process.env.PREM_API_KEY,
baseURL: "https://gateway.prem.io/typesafe",
defaultModel: "dgemma",
});
const res = await client.systemOne({
state: "Customer says: 'I was charged twice for one subscription this month.'",
questions: {
category: choice("What is this ticket about?", { billing: null, technical: null, other: null }),
urgent: noul("Is this request urgent?"),
severity: score("How severe is this issue?", ["not severe", "mild", "moderate", "severe", "critical"] as const),
},
});
console.log(res.answers.category.choice, res.answers.urgent.noul, res.answers.severity.score);
| Field | Required | Description |
|---|---|---|
model | yes | Model name from GET /typesafe/v1/models. |
state | yes | The context the questions are asked about. A string, object, array, number, boolean, or null. |
questions | yes | A map of question id to a typed question. |
images | no | At most one base64 image data URL. |
videos | no | At most one base64 MP4 data URL. A dgemma extension. |
samples | no | Number of reads to average. |
steps | no | Number of denoising steps. |
provider | no | Pin the request to one of the model’s configured backends. |
type, instructions, and criteria:
type | criteria | Answer field |
|---|---|---|
choice | A map of 1 to 26 labels to descriptions | choice, probabilities, confidence |
noul | Optional. Descriptions for the two outcomes | noul |
score | An ordered list of 2 to 10 levels | score, legend, probabilities, confidence |
Response shape
| Field | Description |
|---|---|
model | The resolved model name. |
answers | One entry per question id, keyed by the id that you sent. |
usage | input_tokens and output_tokens for the request. |
diagnostics | Engine detail for the call. Informational, and it can change. |
answers by your own question ids. A noul answer puts its scalar in noul; a noul answer has no probabilities field. A score answer reports the probability-weighted mean over the zero-indexed levels.
probabilities are normalized scores over the supplied labels. They are not calibrated correctness estimates, and label order can change the prediction. See the guide’s current limits.Media input
Useimages or videos, not both in one request.
imagesholds at most one base64 image data URL. The image is placed ahead of the state.videosholds at most one base64 MP4 data URL, up to 10 MiB, 30 seconds, and 1920 x 1080 pixels. Four frames are sampled and audio is not processed. This is adgemmaextension and is not part of the base request shape. Use a raw JSON request if your HTTP client does not expose the field.
Streaming
This route is non-streaming. Astream field is not supported. The call returns one JSON object.
Model availability
Send a model thatGET /typesafe/v1/models returns for your API key. dgemma is served through this route and is not available on the chat completions routes. A chat model on this route returns a validation error. See Models & Pricing.
Limits
- Up to 16 questions per request.
choiceholds 1 to 26 criteria.scoreholds 2 to 10 levels.- At most one image or one video per request.
- Questions are independent. One question cannot read another question or its answer.
- Up to 4 concurrent requests per key before a 429.
Related
Decisions guide
ZDR security boundary
Authorizations
Send your access token as header Authorization: Bearer {accessToken}
Your API key that starts with sk_live or sk_test. You can create yours at go.prem.io/api-keys.
Body
SystemOne decision request.
Model name, as listed by GET /typesafe/v1/models.
Context the questions are asked about.
Map of question id to a typed question.
Show child attributes
Show child attributes
Optional. At most one base64 image data URL.
Optional. Pin the request to one of the model's configured backends. Omit to let the platform choose.
Optional dgemma extension: one inline MP4, up to 10 MiB, 30 seconds and 1920 x 1080 pixels. Four frames are sampled; audio is not processed. Cannot be combined with images. Use a raw JSON request if your SDK does not expose this field.
1^data:video/mp4;base64,Response
A decision with per-question answers and probabilities.
The response is of type object.