Request presigned upload URLs for a new model's images
curl --request POST \
--url https://api.samsa.ai/public/v1/models/prepare \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Acme Brand Style",
"category": "style",
"files": [
{
"filename": "logo.png",
"content_type": "image/png",
"size": 204800
}
],
"instruction": "<string>"
}
'import requests
url = "https://api.samsa.ai/public/v1/models/prepare"
payload = {
"name": "Acme Brand Style",
"category": "style",
"files": [
{
"filename": "logo.png",
"content_type": "image/png",
"size": 204800
}
],
"instruction": "<string>"
}
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({
name: 'Acme Brand Style',
category: 'style',
files: [{filename: 'logo.png', content_type: 'image/png', size: 204800}],
instruction: '<string>'
})
};
fetch('https://api.samsa.ai/public/v1/models/prepare', 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://api.samsa.ai/public/v1/models/prepare",
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([
'name' => 'Acme Brand Style',
'category' => 'style',
'files' => [
[
'filename' => 'logo.png',
'content_type' => 'image/png',
'size' => 204800
]
],
'instruction' => '<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://api.samsa.ai/public/v1/models/prepare"
payload := strings.NewReader("{\n \"name\": \"Acme Brand Style\",\n \"category\": \"style\",\n \"files\": [\n {\n \"filename\": \"logo.png\",\n \"content_type\": \"image/png\",\n \"size\": 204800\n }\n ],\n \"instruction\": \"<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://api.samsa.ai/public/v1/models/prepare")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Acme Brand Style\",\n \"category\": \"style\",\n \"files\": [\n {\n \"filename\": \"logo.png\",\n \"content_type\": \"image/png\",\n \"size\": 204800\n }\n ],\n \"instruction\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.samsa.ai/public/v1/models/prepare")
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 \"name\": \"Acme Brand Style\",\n \"category\": \"style\",\n \"files\": [\n {\n \"filename\": \"logo.png\",\n \"content_type\": \"image/png\",\n \"size\": 204800\n }\n ],\n \"instruction\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"uploads": [
{
"key": "<string>",
"upload_url": "<string>",
"index": 123
}
],
"expires_in": 3600
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}Entraînement de modèles
Préparer un upload de modèle
Demande des presigned URLs PUT pour les images de référence d’un nouveau modèle (upload en deux étapes).
POST
/
models
/
prepare
Request presigned upload URLs for a new model's images
curl --request POST \
--url https://api.samsa.ai/public/v1/models/prepare \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Acme Brand Style",
"category": "style",
"files": [
{
"filename": "logo.png",
"content_type": "image/png",
"size": 204800
}
],
"instruction": "<string>"
}
'import requests
url = "https://api.samsa.ai/public/v1/models/prepare"
payload = {
"name": "Acme Brand Style",
"category": "style",
"files": [
{
"filename": "logo.png",
"content_type": "image/png",
"size": 204800
}
],
"instruction": "<string>"
}
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({
name: 'Acme Brand Style',
category: 'style',
files: [{filename: 'logo.png', content_type: 'image/png', size: 204800}],
instruction: '<string>'
})
};
fetch('https://api.samsa.ai/public/v1/models/prepare', 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://api.samsa.ai/public/v1/models/prepare",
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([
'name' => 'Acme Brand Style',
'category' => 'style',
'files' => [
[
'filename' => 'logo.png',
'content_type' => 'image/png',
'size' => 204800
]
],
'instruction' => '<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://api.samsa.ai/public/v1/models/prepare"
payload := strings.NewReader("{\n \"name\": \"Acme Brand Style\",\n \"category\": \"style\",\n \"files\": [\n {\n \"filename\": \"logo.png\",\n \"content_type\": \"image/png\",\n \"size\": 204800\n }\n ],\n \"instruction\": \"<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://api.samsa.ai/public/v1/models/prepare")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Acme Brand Style\",\n \"category\": \"style\",\n \"files\": [\n {\n \"filename\": \"logo.png\",\n \"content_type\": \"image/png\",\n \"size\": 204800\n }\n ],\n \"instruction\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.samsa.ai/public/v1/models/prepare")
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 \"name\": \"Acme Brand Style\",\n \"category\": \"style\",\n \"files\": [\n {\n \"filename\": \"logo.png\",\n \"content_type\": \"image/png\",\n \"size\": 204800\n }\n ],\n \"instruction\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"uploads": [
{
"key": "<string>",
"upload_url": "<string>",
"index": 123
}
],
"expires_in": 3600
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}Première étape du flux presigned upload pour les fichiers volumineux. Envoie le
name du modèle,
sa category et les métadonnées des 1 à 10 files que tu vas uploader (le premier fichier est
la couverture). La réponse renvoie un id de modèle et un upload_url PUT presigné par
fichier. Envoie chaque fichier avec PUT sur son URL, puis appelle
POST /models/{id}/complete avec les clés
uploadées pour lancer le traitement. Nécessite le scope models.write.
Utilise ce flux en deux étapes quand les images sont trop volumineuses pour être envoyées inline. Pour les petites images
ou les URLs distantes,
POST /models est plus simple.
Le content_type de chaque fichier vaut l’une des valeurs image/jpeg, image/png, image/webp ;
fournis la size (≤ 10 Mo) quand tu la connais.Autorisations
Organization API key as a bearer token: Authorization: Bearer samsa_sk_....
Corps
application/json
POST /models/prepare body — request presigned PUT URLs for large files.
Required string length:
1 - 100Exemple:
"Acme Brand Style"
Model category — one of style, object, person, setting.
Options disponibles:
style, object, person, setting Exemple:
"style"
Metadata for the 1-10 files you will upload (first = cover).
Required array length:
1 - 10 elementsShow child attributes
Show child attributes
Optional free-text guidance for how to use the model.
Maximum string length:
8000
