Image generation API curl: inspect requests without an SDK
Curl makes a useful first integration check because it exposes the actual URL, headers, and JSON body. Use it to verify the API contract before introducing a framework. The commands below target a POSIX shell and require jq for JSON inspection. In Windows PowerShell, invoke curl.exe explicitly and adapt the shell quoting rather than copying Bash line continuation characters.
1. Write a request file
Create image-request.json with this content. Keeping JSON in a file avoids shell escaping problems when your prompt contains quotation marks, punctuation, or newlines. The route name is plural images; a singular /image/generations path is a different URL and is not the supported endpoint shown here.
{
"model": "nano-banana",
"prompt": "A clean product photograph of a green glass bottle, soft daylight",
"aspect_ratio": "4:3",
"n": 1
}
Set GENACE_API_KEY through your normal secret mechanism. Do not put a real key in the request file, a committed script, or a screenshot of a support request.
2. Submit and preserve both evidence files
curl --silent --show-error --fail-with-body \
--max-time 45 \
--dump-header image-response.headers \
--output image-accepted.json \
https://genace.ai/api/v1/images/generations \
--header "Authorization: Bearer $GENACE_API_KEY" \
--header 'Content-Type: application/json' \
--data-binary @image-request.json
jq '{job_id, state, model, credits_held}' image-accepted.json
A successful submission returns HTTP 202 and a job_id. It means a generation was accepted, not that an image is ready. If curl exits unsuccessfully, inspect the response file for the structured error object before proceeding. Do not extract an identifier from an error response and then chase a misleading status URL.
3. Observe the existing job
JOB_ID=$(jq -er '.job_id' image-accepted.json)
curl --silent --show-error --fail-with-body \
--max-time 45 \
--output image-status.json \
"https://genace.ai/api/v1/jobs/$JOB_ID?wait=30" \
--header "Authorization: Bearer $GENACE_API_KEY"
jq '{id, state, outputs, error}' image-status.json
jq -er 'select(.state == "succeeded") | .outputs[]? |
select(.type == "image") | .url' image-status.json
Repeat only the GET if the state is queued or running. The long poll can return before completion; it is a waiting budget for that HTTP request. Stop on succeeded, failed, or canceled. A failed job can arrive inside an HTTP 200 response, so curl’s success exit code alone is insufficient.
Common mistakes
Avoid --retry-all-errors on the POST while debugging. If a connection drops after acceptance, another submission can create another job. Keep the original response and investigate the uncertain outcome. Curl verbose output can expose the Authorization header, so sanitize diagnostics before sharing them. The response header file above records response headers without requiring a verbose request trace.
Also avoid using the status response’s job_id property: that response calls the identifier id. Do not extract output URLs until state is succeeded, and allow outputs to be null otherwise. These distinctions keep a diagnostic session from turning into repeated paid submissions.
Verification checklist
- Confirm the submitted body is valid JSON and uses the plural image path.
- Confirm the response status is 202 before reading
job_id. - Confirm terminal state and image output type before copying a URL.
- Remove local response files if they contain prompts or asset URLs you cannot retain.
Move to the Python image client for automation, or review image API fundamentals for the lifecycle behind these commands.
Continue with code and integration
Models covered on this page
Where these facts come from
- Editorial keyword hypothesis; search volume not measured
- codebase: src/app/api/v1/images/generations/route.ts
- codebase: src/ai/api/auth.ts
- codebase: src/ai/jobs/http.ts