curl https://compute.prentis.ai/v1/accounts/my-account/datasets/support-chats:getUploadEndpoint \
-H "Authorization: Bearer $PRENTIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"filenameToSize": {"train.jsonl": "2142208"}}'
# Then upload the file to the URL in the response -- no API key on this request:
curl -X PUT --upload-file train.jsonl "<filenameToSignedUrl[train.jsonl]>"import requests
url = "https://compute.prentis.ai/v1/accounts/{account}/datasets/{dataset}:getUploadEndpoint"
payload = {
"filenameToSize": {},
"resumable": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({filenameToSize: {}, resumable: true})
};
fetch('https://compute.prentis.ai/v1/accounts/{account}/datasets/{dataset}:getUploadEndpoint', 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/{dataset}:getUploadEndpoint",
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([
'filenameToSize' => [
],
'resumable' => true
]),
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/{dataset}:getUploadEndpoint"
payload := strings.NewReader("{\n \"filenameToSize\": {},\n \"resumable\": true\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/{dataset}:getUploadEndpoint")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"filenameToSize\": {},\n \"resumable\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://compute.prentis.ai/v1/accounts/{account}/datasets/{dataset}:getUploadEndpoint")
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 \"filenameToSize\": {},\n \"resumable\": true\n}"
response = http.request(request)
puts response.read_body{
"uploadSession": {
"name": "accounts/my-account/uploadSessions/01K7AWZ8C4E6G8J0L2N4Q6S8U0",
"sessionId": "01K7AWZ8C4E6G8J0L2N4Q6S8U0",
"targetKind": "UPLOAD_TARGET_KIND_DATASET_VERSION",
"files": [
{
"filename": "train.jsonl",
"declaredBytes": "2142208"
}
],
"state": "UPLOAD_SESSION_STATE_OPEN",
"expireTime": "2026-10-10T08:40:05Z"
},
"filenameToSignedUrl": {
"train.jsonl": "https://…signed upload URL…"
},
"version": {
"name": "accounts/my-account/datasets/support-chats/versions/1",
"versionNo": 1,
"state": "DATASET_VERSION_STATE_UPLOADING"
}
}{
"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>"
}
}Get an upload URL
Step two. Declare the one file this version consists of and its size; the response carries a signed URL to PUT the file to. The URL is valid for an hour and is returned only here. Call it again on a READY dataset to upload a corrected file as a new version — jobs keep the version they were started with.
curl https://compute.prentis.ai/v1/accounts/my-account/datasets/support-chats:getUploadEndpoint \
-H "Authorization: Bearer $PRENTIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"filenameToSize": {"train.jsonl": "2142208"}}'
# Then upload the file to the URL in the response -- no API key on this request:
curl -X PUT --upload-file train.jsonl "<filenameToSignedUrl[train.jsonl]>"import requests
url = "https://compute.prentis.ai/v1/accounts/{account}/datasets/{dataset}:getUploadEndpoint"
payload = {
"filenameToSize": {},
"resumable": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({filenameToSize: {}, resumable: true})
};
fetch('https://compute.prentis.ai/v1/accounts/{account}/datasets/{dataset}:getUploadEndpoint', 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/{dataset}:getUploadEndpoint",
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([
'filenameToSize' => [
],
'resumable' => true
]),
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/{dataset}:getUploadEndpoint"
payload := strings.NewReader("{\n \"filenameToSize\": {},\n \"resumable\": true\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/{dataset}:getUploadEndpoint")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"filenameToSize\": {},\n \"resumable\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://compute.prentis.ai/v1/accounts/{account}/datasets/{dataset}:getUploadEndpoint")
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 \"filenameToSize\": {},\n \"resumable\": true\n}"
response = http.request(request)
puts response.read_body{
"uploadSession": {
"name": "accounts/my-account/uploadSessions/01K7AWZ8C4E6G8J0L2N4Q6S8U0",
"sessionId": "01K7AWZ8C4E6G8J0L2N4Q6S8U0",
"targetKind": "UPLOAD_TARGET_KIND_DATASET_VERSION",
"files": [
{
"filename": "train.jsonl",
"declaredBytes": "2142208"
}
],
"state": "UPLOAD_SESSION_STATE_OPEN",
"expireTime": "2026-10-10T08:40:05Z"
},
"filenameToSignedUrl": {
"train.jsonl": "https://…signed upload URL…"
},
"version": {
"name": "accounts/my-account/datasets/support-chats/versions/1",
"versionNo": 1,
"state": "DATASET_VERSION_STATE_UPLOADING"
}
}{
"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>"
}
}Uploading the file
PUT the file’s bytes to the URL infilenameToSignedUrl. Send no Authorization header on
that request — the URL carries its own signature, and it expires after an hour. Then call
Validate an upload with the uploadSession.name
from this response.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.
64The dataset's id, as chosen when it was created.
64Body
The one file this version consists of, mapped to its size in bytes. A version is exactly one JSON Lines file, of at most 1 GiB; a larger one is refused before any URL is issued (DATASET_TOO_LARGE).
Show child attributes
Show child attributes
Accepted for compatibility; uploads are a single PUT either way.