Create images with Vietrouter API
Generate images from a prompt or edit a reference image through two JSON endpoints. Start with a simple request, then add parameters supported by your model.
Back to documentationConnect to the API
Send requests to your site's API URL with Content-Type: application/json and Authorization: Bearer YOUR_API_KEY. x-api-key is also supported.
Keep your API key on the server. Examples use environment variables and do not send requests on your behalf.
Base URLhttps://vietrouter.com.vn/v1
AuthorizationBearer $STALI_API_KEY
read -r -s -p "STALI_API_KEY: " STALI_API_KEY
export STALI_API_KEY
printf '\n'
curl -fsS https://vietrouter.com.vn/v1/models -H "Authorization: Bearer ${STALI_API_KEY:?STALI_API_KEY}"Choose an image model
Use req/gpt-image-2 or req/gemini-3.0-pro-image. Both image endpoints default to req/gpt-image-2 when model is omitted or empty.
| Model | Price per request |
|---|---|
req/gpt-image-2GPT Image 2 | ₫1,000 |
req/gemini-3.0-pro-imageGemini 3.0 Pro Image | ₫1,000 |
Call GET /v1/models for the current catalog and pricing.per_request. Your API key must allow the selected model.
View current pricingGenerate from a prompt
/v1/images/generationsapplication/jsonSend POST /v1/images/generations with model and a descriptive prompt. The example starts with n: 1 and size: 1024x1024. The endpoint returns JSON when processing finishes. stream is forced to false; this endpoint does not return an SSE stream.
The cURL examples use Bash on macOS, Linux or WSL. For Python, install the dependency with pip install requests. For Node.js, use version 18 or later, save the code as an .mjs file and use the built-in fetch.
curl --fail-with-body --dump-header image-response-headers.txt "https://vietrouter.com.vn/v1/images/generations" \
-H "Authorization: Bearer ${STALI_API_KEY:?STALI_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "req/gpt-image-2",
"prompt": "A small botanical robot tending a seedling, studio product photography, soft natural light, clean ivory background, no text",
"n": 1,
"size": "1024x1024"
}'Edit a reference image
/v1/images/editsapplication/jsonSend POST /v1/images/edits as JSON with a nonempty prompt and image. The image can be a data URL, a base64 string, or a public http(s) URL. For cURL, replace https://example.com/reference.png with your actual public image URL. For Python or Node.js, place reference.png in the directory where you run the example.
image_url, reference_image, ref_image and refImage are accepted aliases for image. Supply a string or an object {url: ...}; use only one image field per request. The edit endpoint accepts JSON, not multipart/form-data. Image URLs must be publicly accessible and contain no credentials; internal addresses are blocked. Reference images support PNG, JPEG, WebP and GIF. Do not call the SDK images.edit method directly if it sends multipart/form-data. This endpoint requires JSON; the Python requests and Node.js fetch examples use the required format.
curl --fail-with-body --dump-header image-response-headers.txt "https://vietrouter.com.vn/v1/images/edits" \
-H "Authorization: Bearer ${STALI_API_KEY:?STALI_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "req/gpt-image-2",
"prompt": "Keep the subject and composition, change the background to a warm ivory studio",
"image": "https://example.com/reference.png",
"n": 1,
"size": "1024x1024"
}'Parameters and limits
The full JSON request is limited to 20 MiB, including encoded images. Base64 increases payload size. Playground limits are separate.
| Parameter | Required | Meaning |
|---|---|---|
model | Optional | model: An image model ID. Defaults to req/gpt-image-2. |
prompt | Required | prompt: An image description or editing instructions. Edits require a nonempty string. |
image | Required for edits | Send POST /v1/images/edits as JSON with a nonempty prompt and image. The image can be a data URL, a base64 string, or a public http(s) URL. Reference images support PNG, JPEG, WebP and GIF. |
size | Optional | size: Examples use 1024x1024. Supported dimensions depend on the model and provider. |
n | Optional | n: Examples request 1 image. The value is forwarded to the provider; supported counts depend on the model. |
quality / response_format / output_format | Optional | quality, response_format and additional parameters are forwarded. Send only parameters supported by the model; the gateway does not guarantee every option takes effect. |
Read and save returned images
Read the data array in the JSON response. Depending on the provider, image content is in b64_json, b64Json or url. Additional fields can differ between models.
{
"data": [
{
"b64_json": "<base64 image bytes>"
}
]
}For base64, decode it to an image file or create a data URL with the MIME type matching the actual format. Do not assume every output is PNG. For a URL, use it to download or display the image. URL lifetime and access depend on the provider.
Save x-mientaymedia-request-id for troubleshooting. Successful responses include x-mientaymedia-model, x-mientaymedia-price-vnd-per-request and x-mientaymedia-cost-vnd headers.
Pricing per request
Image models are billed per request. Check pricing.per_request in GET /v1/models before running; account balance or API key spending limits can block a request. Tokens in the response or headers are not a basis for recalculating image model prices. A new request can incur a new charge.
Do not automatically resend after a timeout or disconnection: the earlier request may have been processed. Check Usage history and save the request ID for reference or support before deciding to call again.
BillingHandle errors carefully
Gateway errors use {type: "error", error: {type, message, ...}}. Read the HTTP status and error.message, and save the request ID when available.
| HTTP | Error | Action |
|---|---|---|
| 400 | invalid_request_error | Check JSON, model, endpoint, prompt and reference image. |
| 401 | authentication_error | Check the API key. |
| 402 | insufficient_balance / api_key_monthly_limit / outstanding_undercharge | Check balance, monthly limits or outstanding payments. |
| 403 | model_not_allowed | Check model permissions. |
| 413 | request_too_large | Reduce the total request size, including base64 data. The provider or model may impose a lower limit than the gateway JSON limit. |
| 429 | rate_limit_error | Slow down and follow Retry-After or retry_after_ms when present. |
| 502 / 503 | api_error / service_unavailable | The provider or service may be temporarily unavailable. |
Before sending a request
Check your API key, model permissions and current price. Send JSON to the correct endpoint, keep the payload small and start with one image. Handle both base64 and URL results, save the request ID and inspect the outcome before calling again.
- Check your API key and model permissions.
- Confirm the model and price in /v1/models.
- Check JSON, prompt and image data.
- Handle both base64 and URL output.
- Check Usage history; save the request ID for reference or support.