curl --request POST \
--url https://api.samsa.ai/public/v1/prompts/improve \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"prompt": "a red fox in the snow at dawn",
"target": "image"
}
'import requests
url = "https://api.samsa.ai/public/v1/prompts/improve"
payload = {
"prompt": "a red fox in the snow at dawn",
"target": "image"
}
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({prompt: 'a red fox in the snow at dawn', target: 'image'})
};
fetch('https://api.samsa.ai/public/v1/prompts/improve', 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/prompts/improve",
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([
'prompt' => 'a red fox in the snow at dawn',
'target' => 'image'
]),
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/prompts/improve"
payload := strings.NewReader("{\n \"prompt\": \"a red fox in the snow at dawn\",\n \"target\": \"image\"\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/prompts/improve")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"prompt\": \"a red fox in the snow at dawn\",\n \"target\": \"image\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.samsa.ai/public/v1/prompts/improve")
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 \"prompt\": \"a red fox in the snow at dawn\",\n \"target\": \"image\"\n}"
response = http.request(request)
puts response.read_body{
"improved_prompt": "<string>",
"target": "image",
"language": "<string>",
"credits_charged": 123
}{
"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"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}Improve a prompt
Rewrite a short prompt into a detailed prompt for an image or a video generation. Synchronous, 1 credit per call. Coming soon.
curl --request POST \
--url https://api.samsa.ai/public/v1/prompts/improve \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"prompt": "a red fox in the snow at dawn",
"target": "image"
}
'import requests
url = "https://api.samsa.ai/public/v1/prompts/improve"
payload = {
"prompt": "a red fox in the snow at dawn",
"target": "image"
}
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({prompt: 'a red fox in the snow at dawn', target: 'image'})
};
fetch('https://api.samsa.ai/public/v1/prompts/improve', 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/prompts/improve",
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([
'prompt' => 'a red fox in the snow at dawn',
'target' => 'image'
]),
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/prompts/improve"
payload := strings.NewReader("{\n \"prompt\": \"a red fox in the snow at dawn\",\n \"target\": \"image\"\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/prompts/improve")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"prompt\": \"a red fox in the snow at dawn\",\n \"target\": \"image\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.samsa.ai/public/v1/prompts/improve")
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 \"prompt\": \"a red fox in the snow at dawn\",\n \"target\": \"image\"\n}"
response = http.request(request)
puts response.read_body{
"improved_prompt": "<string>",
"target": "image",
"language": "<string>",
"credits_charged": 123
}{
"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"
}
}{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The provided API key is invalid, expired, or revoked.",
"request_id": "8f14e45fceea167a5a36dedd4bea2543",
"param": "aspect_ratio"
}
}503 service_unavailable with
the message Prompt improvement is not available yet. Nothing is charged, and the
call does not count against your rate limit. The behaviour below applies from
launch.prompt for a target of image or video. The call is
synchronous and returns 200 OK with the improved_prompt. It costs
1 credit, charged before the AI model runs and refunded automatically if the
provider fails. Requires any one of the images.generate, images.edit, or
videos.generate scopes. See the overview for the
idempotency rules and the order of checks.
Example
curl -X POST https://api.samsa.ai/public/v1/prompts/improve \
-H "Authorization: Bearer $SAMSA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1c2a3e-improve-bicycle" \
-d '{ "prompt": "a red bicycle in a park", "target": "image" }'
curl -X POST https://api.samsa.ai/public/v1/prompts/improve \
-H "Authorization: Bearer $SAMSA_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "prompt": "a red bicycle rolling through a park", "target": "video", "language": "de" }'
{
"improved_prompt": "A glossy red city bicycle leaning against a wooden bench in a sunlit park, autumn leaves on the path, soft morning light, shallow depth of field, photorealistic",
"target": "image",
"language": null,
"credits_charged": 1
}
improved_prompt as the prompt of
POST /images/generations or
POST /videos/generations.
Retrying with an Idempotency-Key
Repeat the call with the same Idempotency-Key and the same body within 24
hours, and you get the stored result back — with no second charge. The replay carries
the header Idempotency-Replayed: true:
HTTP/1.1 200 OK
Idempotency-Replayed: true
Content-Type: application/json
{ "improved_prompt": "A glossy red city bicycle …", "target": "image", "language": null, "credits_charged": 1 }
credits_charged reports the charge of the original call; the replay itself costs
nothing. Without the header, every call is a new charge. A key whose first call
failed replays that error, so use a new key for a new paid attempt.
Errors
Today, while the endpoint is not enabled, an authenticated call returns only503 service_unavailable. From launch, the call can return:
| Status | Code | When |
|---|---|---|
401 | invalid_api_key / invalid_token | Missing, unknown, expired, or revoked API key (invalid_api_key) or OAuth access token (invalid_token). |
402 | insufficient_credits / insufficient_team_credits / insufficient_unallocated_credits | The balance this credential can spend is below 1 credit. Nothing is charged and the model does not run. Organizations with at least one active team get the team-aware codes (budget-exempt system organizations excepted). |
402 | subscription_inactive | The organization has no usable subscription. |
403 | missing_scope | The credential has none of images.generate, images.edit, videos.generate. |
409 | idempotency_key_reused | The Idempotency-Key was already used with a different body. |
409 | idempotency_in_progress | A call with this Idempotency-Key is still running. |
422 | validation_error | prompt is shorter than 3 or longer than 5000 characters or breaks a prompt rule, target is not image or video, language is not a valid language tag, or the Idempotency-Key header is invalid. |
429 | rate_limited | Per-key rate window exceeded. |
500 | refund_pending | The provider failed and the refund could not be confirmed yet. Samsa retries it automatically. |
502 | provider_error | The AI provider failed. The credit was refunded. |
503 | service_unavailable | Prompt improvement is not enabled yet (today, every call). From launch: Samsa could not confirm the idempotency state or the billing outcome. No prompt was delivered, and a credit taken is refunded automatically. |
Idempotency-Key whose first call failed returns that same error again,
with Idempotency-Replayed: true. The X-Request-ID response header identifies the
call for support.Authorizations
Organization API key (Authorization: Bearer samsa_sk_...) or OAuth 2.1 access token (Authorization: Bearer samsa_at_...).
Headers
Optional. 1-255 printable ASCII characters; see the operation description.
255Body
POST /prompts/improve body — improve ONE prompt for an image or a video generation.
Cost = 1 credit per improved prompt, charged before the AI call and refunded automatically when the
AI provider fails (502 provider_error). Send an Idempotency-Key header to retry safely: the same key
with the same body within 24 hours returns the same result and never charges twice.
The prompt to improve: 3 to 5000 characters after trimming (the characters < and >, line breaks and backslashes are not allowed — the same rules as every Samsa prompt).
What the improved prompt is for: image (text-to-image) or video (text-to-video).
image, video Optional BCP-47 / ISO 639-1 language tag of the improved prompt (e.g. en, de, fr). Omitted: the improved prompt keeps the language of the input prompt.
63"de"
Response
Successful Response
POST /prompts/improve 200 body.
The improved prompt.
The target of the request.
image, video The requested language tag (canonical BCP-47 form), or null when none was requested.
Credits charged for this improved prompt (always 1; a replayed idempotent call reports the charge of its key — it is never charged twice).