curl "https://compute.prentis.ai/v1/accounts/my-account/datasets?datasetId=support-chats" \
-H "Authorization: Bearer $PRENTIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"displayName": "Support chats"}'import os
import time
import requests
BASE = "https://compute.prentis.ai/v1/accounts/my-account"
HEADERS = {"Authorization": f"Bearer {os.environ['PRENTIS_API_KEY']}"}
path = "train.jsonl"
# 1. Create the dataset.
requests.post(f"{BASE}/datasets", params={"datasetId": "support-chats"},
headers=HEADERS, json={"displayName": "Support chats"}).raise_for_status()
# 2. Ask for an upload URL, then PUT the file straight to it.
up = requests.post(f"{BASE}/datasets/support-chats:getUploadEndpoint", headers=HEADERS,
json={"filenameToSize": {path: str(os.path.getsize(path))}})
up.raise_for_status()
with open(path, "rb") as f:
requests.put(up.json()["filenameToSignedUrl"][path], data=f).raise_for_status()
# 3. Validate, and wait for the verdict.
requests.post(f"{BASE}/datasets/support-chats:validateUpload", headers=HEADERS,
json={"uploadSession": up.json()["uploadSession"]["name"]}).raise_for_status()
while (ds := requests.get(f"{BASE}/datasets/support-chats", headers=HEADERS).json())["state"] \
== "DATASET_STATE_VALIDATING":
time.sleep(5)
print(ds["state"])const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({displayName: '<string>'})
};
fetch('https://compute.prentis.ai/v1/accounts/{account}/datasets', 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://compute.prentis.ai/v1/accounts/{account}/datasets",
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([
'displayName' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"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://compute.prentis.ai/v1/accounts/{account}/datasets"
payload := strings.NewReader("{\n \"displayName\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://compute.prentis.ai/v1/accounts/{account}/datasets")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"displayName\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://compute.prentis.ai/v1/accounts/{account}/datasets")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"displayName\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"name": "accounts/my-account/datasets/support-chats",
"datasetId": "support-chats",
"displayName": "Support chats",
"source": "DATASET_SOURCE_UPLOAD",
"state": "DATASET_STATE_CREATING",
"createTime": "2026-10-10T07:40:00Z",
"updateTime": "2026-10-10T07:40:00Z"
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"code": "INVALID_REQUEST",
"param": "<string>"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"code": "INVALID_REQUEST",
"param": "<string>"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"code": "INVALID_REQUEST",
"param": "<string>"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"code": "INVALID_REQUEST",
"param": "<string>"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"code": "INVALID_REQUEST",
"param": "<string>"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"code": "INVALID_REQUEST",
"param": "<string>"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"code": "INVALID_REQUEST",
"param": "<string>"
}
}Create a dataset
Step one of three. This creates an empty dataset; the file goes next, straight to storage through a signed URL from getUploadEndpoint, and validateUpload then checks it. Your data never passes through this API.
curl "https://compute.prentis.ai/v1/accounts/my-account/datasets?datasetId=support-chats" \
-H "Authorization: Bearer $PRENTIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"displayName": "Support chats"}'import os
import time
import requests
BASE = "https://compute.prentis.ai/v1/accounts/my-account"
HEADERS = {"Authorization": f"Bearer {os.environ['PRENTIS_API_KEY']}"}
path = "train.jsonl"
# 1. Create the dataset.
requests.post(f"{BASE}/datasets", params={"datasetId": "support-chats"},
headers=HEADERS, json={"displayName": "Support chats"}).raise_for_status()
# 2. Ask for an upload URL, then PUT the file straight to it.
up = requests.post(f"{BASE}/datasets/support-chats:getUploadEndpoint", headers=HEADERS,
json={"filenameToSize": {path: str(os.path.getsize(path))}})
up.raise_for_status()
with open(path, "rb") as f:
requests.put(up.json()["filenameToSignedUrl"][path], data=f).raise_for_status()
# 3. Validate, and wait for the verdict.
requests.post(f"{BASE}/datasets/support-chats:validateUpload", headers=HEADERS,
json={"uploadSession": up.json()["uploadSession"]["name"]}).raise_for_status()
while (ds := requests.get(f"{BASE}/datasets/support-chats", headers=HEADERS).json())["state"] \
== "DATASET_STATE_VALIDATING":
time.sleep(5)
print(ds["state"])const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({displayName: '<string>'})
};
fetch('https://compute.prentis.ai/v1/accounts/{account}/datasets', 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://compute.prentis.ai/v1/accounts/{account}/datasets",
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([
'displayName' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"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://compute.prentis.ai/v1/accounts/{account}/datasets"
payload := strings.NewReader("{\n \"displayName\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://compute.prentis.ai/v1/accounts/{account}/datasets")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"displayName\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://compute.prentis.ai/v1/accounts/{account}/datasets")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"displayName\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"name": "accounts/my-account/datasets/support-chats",
"datasetId": "support-chats",
"displayName": "Support chats",
"source": "DATASET_SOURCE_UPLOAD",
"state": "DATASET_STATE_CREATING",
"createTime": "2026-10-10T07:40:00Z",
"updateTime": "2026-10-10T07:40:00Z"
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"code": "INVALID_REQUEST",
"param": "<string>"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"code": "INVALID_REQUEST",
"param": "<string>"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"code": "INVALID_REQUEST",
"param": "<string>"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"code": "INVALID_REQUEST",
"param": "<string>"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"code": "INVALID_REQUEST",
"param": "<string>"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"code": "INVALID_REQUEST",
"param": "<string>"
}
}{
"error": {
"message": "<string>",
"type": "invalid_request_error",
"code": "INVALID_REQUEST",
"param": "<string>"
}
}Authorizations
Authorization: Bearer <your API key> -- the same key as inference. A key reaches the account it belongs to and no other.
Path Parameters
Your account id -- the one in the console's address bar (my-account for this key). It must be the account the key belongs to.
64Query Parameters
The id to give the dataset: lowercase letters, digits and hyphens, up to 64. It becomes part of the dataset's name and can never be changed or reused, even after the dataset is deleted. Leave it out to derive one from displayName.
64Body
A human-readable name for the dataset, up to 128 characters.
128Response
Created.
DATASET_SOURCE_UPLOAD, DATASET_SOURCE_JOB_OUTPUT, DATASET_SOURCE_SPLIT DATASET_STATE_CREATING, DATASET_STATE_UPLOADING, DATASET_STATE_VALIDATING, DATASET_STATE_READY, DATASET_STATE_FAILED, DATASET_STATE_DELETED Show child attributes
Show child attributes
Show child attributes
Show child attributes