
How to Use the Grok Imagine Image 2.0 API on EvoLink
POST /v1/images/generations with model: "grok-imagine-image-2.0", store the returned task id, then query GET /v1/tasks/{task_id} until the task reaches completed or failed.image_urls to generate from text; include one to three public image URLs to edit or compose from references. For current pricing and interactive testing, use the Grok Imagine Image 2.0 model page. This article focuses on application flow, failure handling, storage, and model fallback rather than duplicating the complete parameter reference.What you will build
By the end of the guide, your application will be able to:
- create a text-to-image task;
- switch to reference editing without changing model IDs;
- use indexed references in a multi-image prompt;
- track an asynchronous task by ID;
- accept a completion callback safely;
- persist results before their 24-hour URLs expire;
- reconcile final usage and failed-task refunds;
- hand off to a fallback route when the workload or task outcome requires it.
Before you start
| Item | Current EvoLink contract |
|---|---|
| Base URL | https://api.evolink.ai |
| Create task | POST /v1/images/generations |
| Query task | GET /v1/tasks/{task_id} |
| Authentication | Authorization: Bearer YOUR_API_KEY |
| Model | grok-imagine-image-2.0 |
| Text-to-image | Omit image_urls |
| Image editing | Supply 1-3 public HTTP/HTTPS image URLs |
| Output | 1K/2K, Low/Medium, n=1-10 |
| Processing | Asynchronous task |
| Result lifetime | 24 hours |
Step 1: keep the API key server-side
For a shell test, set the key in an environment variable:
export EVOLINK_API_KEY="your_api_key"${EVOLINK_API_KEY}. Do not replace it with a real key inside code that will be committed.Step 2: create a text-to-image task
image_urls:curl --request POST "https://api.evolink.ai/v1/images/generations" \
--header "Authorization: Bearer ${EVOLINK_API_KEY}" \
--header "Content-Type: application/json" \
--data '{
"model": "grok-imagine-image-2.0",
"prompt": "Editorial product photograph of a teal glass perfume bottle on pale limestone, warm coastal morning light, restrained luxury art direction, no text or logos",
"size": "1:1",
"resolution": "1K",
"quality": "medium",
"n": 1
}'id immediately:{
"id": "task-unified-1757156493-imcg5zqt",
"model": "grok-imagine-image-2.0",
"object": "image.generation.task",
"progress": 0,
"status": "pending",
"type": "image",
"usage": {
"billing_rule": "per_call",
"credits_reserved": 3.06,
"user_group": "default"
}
}The reservation value above is a documentation example, not a price promise and not the final charge. Use the current model page for live pricing and the terminal task response for final usage.
Step 3: query the asynchronous task

id to the task endpoint. Do not include braces around the value:curl --request GET \
"https://api.evolink.ai/v1/tasks/task-unified-1757156493-imcg5zqt" \
--header "Authorization: Bearer ${EVOLINK_API_KEY}"processing, completed, or failed. A completed response includes results, structured result_data, and final usage:{
"id": "task-unified-1757156493-imcg5zqt",
"model": "grok-imagine-image-2.0",
"object": "image.generation.task",
"progress": 100,
"status": "completed",
"results": ["https://cdn.evolink.ai/images/generated-image.jpg"],
"result_data": [
{
"url": "https://cdn.evolink.ai/images/generated-image.jpg",
"mime_type": "image/jpeg"
}
],
"type": "image",
"usage": {
"credits_used": 3.06,
"cost": {
"credits": 3.06,
"cny": 0.31,
"usd": 0.05
}
}
}Those numeric values are example response values. Record the values returned by your own terminal task; do not use this example to calculate customer billing.
Step 4: add controlled polling
Polling should stop on a terminal status, back off between requests, and enforce an application timeout. The following server-side TypeScript example keeps the task workflow explicit:
type GrokTaskStatus = "processing" | "completed" | "failed";
type GrokTask = {
id: string;
status: GrokTaskStatus;
progress: number;
results?: string[];
error?: {
code: string;
message: string;
type: "task_error";
};
};
const API_BASE_URL = "https://api.evolink.ai";
async function getTask(apiKey: string, taskId: string): Promise<GrokTask> {
const response = await fetch(`${API_BASE_URL}/v1/tasks/${taskId}`, {
headers: { Authorization: `Bearer ${apiKey}` },
cache: "no-store",
});
if (!response.ok) {
throw new Error(`Task query failed with HTTP ${response.status}`);
}
return response.json() as Promise<GrokTask>;
}
async function waitForTask(
apiKey: string,
taskId: string,
timeoutMs = 180_000,
): Promise<GrokTask> {
const startedAt = Date.now();
let intervalMs = 2_000;
while (Date.now() - startedAt < timeoutMs) {
const task = await getTask(apiKey, taskId);
if (task.status === "completed" || task.status === "failed") {
return task;
}
await new Promise((resolve) => setTimeout(resolve, intervalMs));
intervalMs = Math.min(Math.round(intervalMs * 1.5), 10_000);
}
throw new Error("Grok Imagine Image 2.0 task timed out in the application");
}An application timeout is not proof that the upstream task failed. Before retrying generation, query the original task again or use an idempotency strategy in your own job layer. Otherwise, a client timeout can create duplicate billable tasks.
Step 5: switch to single-reference editing
image_urls to switch modes. Input images must be publicly accessible through HTTP or HTTPS; base64 and data URLs are not supported by the current contract. Supported extensions are JPEG, JPG, PNG, and WebP.curl --request POST "https://api.evolink.ai/v1/images/generations" \
--header "Authorization: Bearer ${EVOLINK_API_KEY}" \
--header "Content-Type: application/json" \
--data '{
"model": "grok-imagine-image-2.0",
"prompt": "Move the chair into a quiet rain-soaked garden room. Preserve the chair shape, teal upholstery, camera angle, and scale. Change only the environment and reflected light.",
"image_urls": [
"https://example.com/chair.webp"
],
"size": "4:3",
"resolution": "1K",
"quality": "medium",
"n": 1
}'Your application should validate count, protocol, file type, and server reachability before creating a paid task. A URL that works in a signed-in browser may still be inaccessible to the generation service.
Step 6: compose with multiple references
image_urls.curl --request POST "https://api.evolink.ai/v1/images/generations" \
--header "Authorization: Bearer ${EVOLINK_API_KEY}" \
--header "Content-Type: application/json" \
--data '{
"model": "grok-imagine-image-2.0",
"prompt": "Place the person from <IMAGE_0> in the architectural setting from <IMAGE_1>, carrying the blue sculptural bag from <IMAGE_2>. Preserve the outfit silhouette and match the late-afternoon direction of light.",
"image_urls": [
"https://example.com/person.webp",
"https://example.com/location.webp",
"https://example.com/bag.webp"
],
"size": "3:4",
"resolution": "2K",
"quality": "medium",
"n": 1
}'Store the exact array order with the prompt. If a user interface lets someone reorder uploads, update the array and index labels together.
Step 7: choose parameters by workflow stage
auto, 1K/2K resolution, Low/Medium quality, and n=1-10.| Parameter | Use it to decide | Production rule |
|---|---|---|
size | Delivery shape or model-selected auto | Validate against the documented ratio enum before submitting |
resolution | 1K draft/review vs 2K delivery candidate | Do not send 4K; the route does not support it |
quality | Low for faster/lower-cost exploration vs Medium for more detail | Evaluate the tier against the actual acceptance criterion |
n | Number of independent outputs | Cap it per product action and budget because each output is billed independently |
image_urls | Text-only generation vs reference editing | Omit entirely for text-to-image; accept at most three URLs |
Use a request allowlist rather than passing arbitrary client JSON directly to the API. This prevents unsupported fields, excessive batches, or internal callback URLs from reaching the route.
Step 8: use callbacks for production completion
callback_url when your application can expose a public HTTPS endpoint:{
"model": "grok-imagine-image-2.0",
"prompt": "A clean ecommerce product scene with soft daylight",
"callback_url": "https://your-domain.com/webhooks/evolink/image-task"
}The current contract says callbacks are sent after billing confirmation when a task is completed, failed, or cancelled. EvoLink waits up to 10 seconds and may retry a failed callback three times after 1, 2, and 4 seconds. A 2xx response marks delivery successful.
Design the receiver to be idempotent:
- authenticate the request using the mechanism your EvoLink account and webhook setup supports;
- validate the task ID and expected model;
- upsert by task ID rather than inserting a new result on every delivery;
- return 2xx after durable persistence;
- move slow downloads and review work to a queue;
- keep polling as a recovery path when webhook delivery cannot be confirmed.
The callback URL must use HTTPS and cannot point to localhost, private IP ranges, or an internal service address.
Step 9: save results before they expire
Completed image URLs remain available for 24 hours. Treat them as transfer URLs, not permanent application storage.
After completion:
- verify that the task belongs to the current account and job;
- download every item in
resultsorresult_data; - validate content type and file size;
- store the file in your own object storage;
- save the permanent URL and content hash;
- record the generation parameters and review state;
- apply your retention and deletion policy to reference inputs and outputs.
n is greater than one, expect independent result URLs in generation order. Do not persist only the first item unless your product intentionally selects one result.Step 10: handle failure and billing correctly
failed task is fully refunded, including upstream rejection, content moderation blocks, and timeouts.| Outcome | Application action | Billing action |
|---|---|---|
completed | Persist every result, run acceptance checks, mark the job complete | Store final usage and cost breakdown |
failed with retryable infrastructure error | Apply capped backoff or route to a verified fallback | Confirm final charge is zero/refunded |
failed with content-policy error | Show an actionable prompt/input message; do not blind-retry | Confirm refund and retain the error code |
| Application polling timeout | Re-query the same task before creating another | Do not assume timeout means refund or failure |
| Invalid request before task creation | Fix validation or permissions | No asynchronous task exists to reconcile |
failed status.Handle request-level HTTP errors before polling
Some failures happen before an asynchronous task is created. The current API reference documents these request-level responses:
| HTTP status | Documented meaning | Application response |
|---|---|---|
400 | Invalid request parameters or format | Validate the request allowlist, required fields, enums, URL count, and JSON shape before retrying |
401 | Authentication error | Check that the server sent a valid Bearer key; never expose the key in client logs |
402 | Insufficient quota | Stop automatic retries and direct the account owner to recharge or adjust the budget |
403 | Access denied | Verify account or route permissions instead of changing the prompt blindly |
429 | Request rate limit exceeded | Apply bounded exponential backoff and queue work; do not fan out immediate retries |
500 | Internal server error | Retry only under a capped infrastructure policy, then use a verified fallback if the job permits |
id. Request-level errors have no asynchronous task to query or refund record to reconcile.Step 11: add fallback routing

The integration should separate the product job from the provider-specific model ID:
type ImageRoute = "grok-imagine-image-2.0" | "gpt-image-2";
type ImageJob = {
prompt: string;
imageUrls: string[];
requiresMask: boolean;
requires4K: boolean;
};
function chooseImageRoute(job: ImageJob): ImageRoute {
if (job.requiresMask || job.requires4K || job.imageUrls.length > 3) {
return "gpt-image-2";
}
return "grok-imagine-image-2.0";
}This example is a contract-level starting policy, not a claim that one model produces better images. Add your own acceptance data, latency, cost, moderation, and availability observations before routing meaningful traffic.
Production handoff checklist
- API key stored in a server-side secret manager.
- Request body allowlist matches the current EvoLink docs.
- Model ID is centralized in route configuration.
- Reference images are public, validated, and limited to three.
- Multi-reference indexes match the persisted input order.
- Polling stops on completed/failed and uses backoff.
- Application timeouts do not automatically create duplicate tasks.
- Callback processing is idempotent and fast.
- Result files are copied before the 24-hour expiry.
- Final usage is stored separately from reserved credits.
- Failed-task refunds are reconciled.
- Retryable and non-retryable errors are separated.
- A tested fallback route exists for required capabilities or outages.
- Logs exclude API keys and sensitive reference URLs.
Frequently asked questions
Which endpoint creates a Grok Imagine Image 2.0 task?
POST https://api.evolink.ai/v1/images/generations with Bearer authentication and the required model and prompt fields.What model ID should I send?
grok-imagine-image-2.0 for the current EvoLink route.How do I switch from generation to editing?
image_urls for text-to-image or pass one to three URLs for editing.Can I send base64 image data?
No. The current contract accepts publicly accessible HTTP or HTTPS URLs and does not support base64 or data URLs.
How do I query the result?
id returned by the create call, then send GET https://api.evolink.ai/v1/tasks/{task_id} with the same Bearer authentication pattern.Should I poll or use a callback?
Use callbacks for normal production completion and polling as a recovery path. A simple server-side prototype may start with backoff polling.
How long do completed image links remain valid?
The current documentation says 24 hours. Copy completed files to permanent storage promptly.
Are failed tasks charged?
failed state is fully refunded according to the current EvoLink task documentation. A completed image rejected by your own quality review is not the same as an API failure.Can I request 4K or High quality?
No. This route currently supports 1K/2K and Low/Medium. Use a different verified route when 4K or High is a hard requirement.
Where can I compare Grok with another image route?
Sources
- EvoLink Grok Imagine Image 2.0 API documentation
- EvoLink task-status API documentation
- Grok Imagine Image 2.0 release and workflow guide
This guide reflects the EvoLink contract verified on August 12, 2026. Recheck the API documentation before shipping, especially model fields, output limits, callback behavior, and task-response schemas.


