Claude Opus 5.5 is live on SeedRouter

Move an image integration to SeedRouter

Migrate a GPT Image 2 integration to SeedRouter by mapping request fields, handling asynchronous tasks, and validating URL-based image delivery.

Read as Markdown

An image API migration to SeedRouter requires checking the request and response contract, not just replacing the API key and base URL. GPT Image 2 uses familiar image-generation fields, but submission returns a task ID. Your application must save that ID, poll for completion, and read the finished image URLs.

The smallest useful migration is one text-to-image request from server-side code. Get that working before moving reference edits, masks, or a larger batch. Keep the existing integration available until the new path passes the same acceptance checks.

Which assumptions need to change?

Find the code that turns an image request into a usable file. It may currently expect an image in the initial response, decode a base64 field, or use a multipart upload. Those assumptions must be checked individually against the SeedRouter GPT Image 2 reference.

Existing assumptionSeedRouter contractApplication change
Submission returns the finished imageSubmission returns a task referenceSave id before waiting for output
Output is in the submission's data arrayCompleted task images are in output.dataRead results after completion
The client decodes b64_jsonImages are returned as hosted URLsDownload the returned URLs
Editing uploads file bytesReferences use images URL objectsMake input images accessible by URL
A separate edits path selects editingimages and mask select the operationUse the public generations endpoint
A client timeout means the image failedThe task may still be processingResume checking the saved ID

This is why a synchronous Images SDK call is not a drop-in replacement even if it accepts a configurable base URL. Keep the model settings you still need, but adapt the application code that waits for and consumes the result.

Map the request fields before moving code

Start with model, prompt, size, quality, and n. Use gpt-image-2 as the model ID. Send explicit dimensions such as 1024x1024 or use auto; do not carry over a separate resolution field or an aspect-ratio string as the size.

SeedRouter's OpenAPI document is a useful review companion. Compare the fields your application actually sends, including values supplied by an SDK, rather than checking only the arguments visible at the call site. Unknown fields are rejected.

For this model, style, response_format, and configurable input_fidelity are not accepted request fields. Remove those assumptions rather than hiding them inside a generic options object. The request also does not support stream or partial_images; the task status is how this integration reports progress.

Output settings have dependencies. If you request transparency, select PNG. Send output_compression only for JPEG, not PNG. A zero compression value is valid, so avoid a truthiness check that replaces it with a default. These are small details that a successful basic request will not exercise.

Replace the synchronous response assumption

The following Node.js example submits one request and prints its task ID. Set SEEDROUTER_API_KEY on the server; never place the key in browser code or a public environment variable.

const response = await fetch('https://api.seedrouter.ai/v1/images/generations', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.SEEDROUTER_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'gpt-image-2',
    prompt: 'A cobalt-blue ceramic mug on a pale gray tabletop.',
    size: '1024x1024',
    quality: 'low',
    n: 1,
  }),
  signal: AbortSignal.timeout(60000),
});
const task = await response.json();
if (!response.ok) {
  // Preserve a task reference if one accompanies an uncertain submission.
  if (typeof task.id === 'string') console.log('Task reference:', task.id);
  throw new Error(`Submission needs review: HTTP ${response.status}`);
}
if (typeof task.id !== 'string' || !task.id) throw new Error('Missing task ID.');
console.log(task.id); // Persist this ID with your application's image record.

Printing the ID is enough for a manual smoke test. In an application, store it before returning control to the user. Your image record can then remain pending while the user navigates elsewhere, and a later check can recover the result.

Use GET https://api.seedrouter.ai/v1/tasks/{id} with the same authorization header to check progress. On completed, read output.data[].url. On failed, handle the documented error and show an appropriate failure state. For a runnable example that persists progress, see batch submission and polling.

Do not attach the API key to the image-download request. Authorization belongs on the task API call, not on a separate fetch of a returned asset URL.

Move references and masks to URL inputs

An existing local-file workflow needs an extra preparation step: make the reference image available at an accessible HTTP(S) URL you control. Pass it as images: [{"image_url": "https://example.com/reference.png"}], replacing that address with your own. Do not send a file path, blob: URL, base64 data URL, or Files ID.

Check that the URL works without your browser's login cookies. A URL that opens only in your signed-in session is not a usable reference for this request. Keep the image accessible while the task is processing; do not revoke access immediately after submission.

A mask uses mask: {"image_url": "https://example.com/mask.png"} and requires reference images. It must match the dimensions of the first reference image. Review all media-input constraints before moving an existing editing flow, particularly file formats and file sizes.

What should the migration acceptance test cover?

Test the behavior your application relies on, including interruption. One successful image proves only that one request worked. It does not prove that your pending state survives a refresh or that a download failure will avoid duplicate generation.

  • Submit a text-only request and store the returned ID before polling.
  • Stop polling, restart it with that same ID, and verify no additional POST occurs.
  • Handle processing, completed, and failed as distinct states.
  • Download a completed image without sending the API authorization header.
  • Check a reference edit with an accessible URL, then check the failure handling for an inaccessible one.
  • Validate optional fields, including compression set to zero, using the published schema.
  • Confirm that account charges are read from usage history, not an invented task-response cost field.

Use mocked responses for repeatable failure and timeout tests. Make a small, deliberate live test only after those checks pass; real generations consume balance. If the submission result is uncertain, investigate before retrying it. A local exception is not proof that no task was accepted.

Frequently asked questions

Can I keep my existing prompts?

Yes, as a starting point, provided they meet the request constraints. Keep a few representative prompts for comparison, but do not expect identical images from repeated generations.

Do I need a new client library?

Not for the examples here. Standard HTTP requests are sufficient. Whatever client you choose must handle task submission and polling instead of expecting a finished image immediately.

Where do I find the final cost?

In account usage history. A completed task can include token usage, but its public response has no dollar-cost field. The pricing guide covers estimates.

Finish the migration at the application boundary

An image API migration is complete when the application handles the whole result lifecycle: accepted task, pending state, finished output, download, and failure. Keep the first change small, test the interruption cases, and move the remaining requests only after their input and output assumptions have been checked.

Related guides