Migrating from Runware
Point your Runware client at Parsec with a new key and a new base URL.
Parsec answers Runware’s task API at its own address. Moving over is two
changes: the API key and the base URL. Task payloads, Runware’s model ids,
getResponse polling, webhooks and error codes stay as they are. The
Runware compatibility page lists what is served
in detail.
1. Create a key
Create a key in the console and add credit under Billing. Keep it next to your Runware key rather than in place of it, so you can switch back by configuration alone (see Roll out).
export PARSEC_API_KEY=…
2. Change the base URL
| Transport | Runware | Parsec |
|---|---|---|
| WebSocket | wss://ws-api.runware.ai/v1 | wss://platform.parseclab.ai/v1 |
| REST | https://api.runware.ai/v1 | https://platform.parseclab.ai/v1 |
Both transports live at the same path, /v1. Keep the /v1: the SDKs expect
the base URL to include it.
JavaScript: @runware/sdk
The current SDK takes wsBaseUrl for the WebSocket (its default) and
httpBaseUrl for REST:
import { createClient } from "@runware/sdk";
const runware = await createClient({
apiKey: process.env.PARSEC_API_KEY,
wsBaseUrl: "wss://platform.parseclab.ai/v1",
});
await runware.connect(); // the WebSocket transport needs this, as on Runware
const [image] = await runware.run({
model: "google:4@3",
positivePrompt: "A watercolor lighthouse at dusk",
width: 1344,
height: 768,
});
For REST, which suits serverless functions, set transport and
httpBaseUrl instead and skip connect():
const runware = await createClient({
apiKey: process.env.PARSEC_API_KEY,
transport: "rest",
httpBaseUrl: "https://platform.parseclab.ai/v1",
});
JavaScript: @runware/sdk-js
The earlier SDK takes the WebSocket address as url, on both Runware and
RunwareServer:
import { RunwareServer } from "@runware/sdk-js";
const runware = new RunwareServer({
apiKey: process.env.PARSEC_API_KEY,
url: "wss://platform.parseclab.ai/v1",
});
const images = await runware.requestImages({
model: "google:4@3",
positivePrompt: "A watercolor lighthouse at dusk",
width: 1344,
height: 768,
});
Python: runware
The Python SDK takes the WebSocket address as url:
import os
from runware import Runware, IImageInference
runware = Runware(api_key=os.environ["PARSEC_API_KEY"], url="wss://platform.parseclab.ai/v1")
await runware.connect()
images = await runware.imageInference(requestImage=IImageInference(
model="google:4@3",
positivePrompt="A watercolor lighthouse at dusk",
width=1344,
height=768,
))
HTTP
Replace the host; the key goes in the Authorization header or in a leading
authentication task, as on Runware:
- curl https://api.runware.ai/v1 \
- -H "Authorization: Bearer $RUNWARE_API_KEY" \
+ curl https://platform.parseclab.ai/v1 \
+ -H "Authorization: Bearer $PARSEC_API_KEY" \
-H "Content-Type: application/json" \
-d '[{"taskType": "imageInference", "taskUUID": "a770f077-f413-47de-9dac-be0b26a35da6",
"model": "google:4@3", "positivePrompt": "A watercolor lighthouse at dusk"}]'
If you call the API with Python’s built-in urllib, set a User-Agent
header: requests that send urllib’s default (Python-urllib/3.x) are
refused with a 403 before they reach the API. requests, httpx,
aiohttp and the SDKs are not affected.
Your own WebSocket client
Connect to wss://platform.parseclab.ai/v1 and send the same messages you
send Runware: an authentication task first, ping to keep the connection
open, then task arrays. The connection closes after 120 seconds without a
message.
3. Keep your model ids
Runware’s model ids work unchanged, so model needs no edit for the models
Parsec serves: Nano Banana 2, 2.1, Pro and 2 Lite, Grok Imagine images, and
Grok Imagine video 1 and 1.5. The full table is on the
compatibility page. A model Parsec does not serve
is refused with unsupportedModel, and the message lists what is served.
4. Check what else names Runware
The base URL is usually the only place, but look for these too:
- Webhooks.
webhookURLworks as on Runware. Deliveries come from Parsec, with the user agentparsec-gateway-webhook; if your receiver allowlists Runware’s addresses or user agent, allow these as well. A delivery can arrive twice, so dedupe ontaskUUIDandimageUUID/videoUUID. - Output URLs. Results are served from
https://platform.parseclab.ai/v1/outputs/…, for 7 days by default (ttlsets 60 seconds to 30 days). Allow the host if you have a content security policy or an image proxy allowlist, and copy files you keep. - Uploaded images. Images uploaded to Runware and referenced by UUID are not on Parsec. Send the image itself, a data URI or a URL instead.
- Other task types. Parsec serves
imageInference,videoInference,getResponse,authenticationandping. If you also use Runware for, say, upscaling or background removal, keep a Runware client for those tasks. - Costs.
includeCostreports Parsec’s price, which is the provider’s list price. Usage and balance are in the console.
5. Roll out
Read the base URL and key from configuration, so moving over (and back) is a deploy setting rather than a code change:
const runware = await createClient({
apiKey: process.env.IMAGE_API_KEY,
wsBaseUrl: process.env.IMAGE_API_WS_URL, // wss://platform.parseclab.ai/v1
});
Before switching production traffic:
- Send one request per model you use with
includeCost: true, and check the result and its cost. - If you use
webhookURL, send one task with a webhook pointed at your receiver and confirm it is accepted. - Move a share of traffic, for example one service or one worker pool, watch the error codes (they are Runware’s, listed on the compatibility page), then move the rest.