Pointing the OpenAI SDK at api.sume.com: why Sora calls still fail
Changing only the base URL does not carry a Sora call to Sume. Five documented differences: model ids, body format, seconds and size, status words, download.

No, changing the OpenAI client's base URL to https://api.sume.com will not make a Sora videos call work, and I did not find a Sume page that says it should. Sume's /v1/videos follows the OpenRouter video wire, which differs from the OpenAI Videos API the guide documents: model ids, body format, the seconds and size fields, status words and the download call.
I did not test the OpenAI SDK against Sume. The differences below come from reading the two vendors' pages on 2026-10-08, and the script at the end lets you see Sume's answer to a Sora-shaped body for yourself.
Five differences
The OpenAI deprecations page also lists the Videos API as removed on September 24, 2026, so even a perfect shim would have nothing to talk to on the other side.
| Area | OpenAI Videos API | Sume /v1/videos |
|---|---|---|
| Model value | sora-2, sora-2-pro | a catalog id such as seedance-2 or wan-3.0, or sume/auto; else 404 model_not_found |
| Body | multipart/form-data | JSON |
| Length | seconds, a string | duration, an integer |
| Frame size | size, "1280x720" | resolution and aspect_ratio; size returns 400 unsupported_parameter |
| Status words | queued, in_progress, completed, failed | pending, in_progress, completed, failed, cancelled |
| Download | content endpoint with a variant | content endpoint that answers 302, with index |
What the SDK helper would hide
A helper such as create_and_poll loops until a status it knows. If Sume returned pending, a loop written for queued would not recognise it. Even a successful create would then fail at the download step, because Sume wants the key on the request to /content and answers 302.
The practical fix is the one in the mapping post: write a thin adapter in your own code that speaks Sume's wire and keep your call sites unchanged.
See the answer yourself
This sends a Sora-shaped body to Sume and prints the status code and the error text. Sume rejects it before any generation starts, so no job is created from this body. Set SUME_API_KEY first.
import json, os, urllib.error, urllib.request
def main():
body = {"model": "sora-2", "prompt": "A test", "seconds": "8", "size": "1280x720"}
req = urllib.request.Request(
"https://api.sume.com/v1/videos", method="POST", data=json.dumps(body).encode(),
headers={"Authorization": "Bearer " + os.environ["SUME_API_KEY"],
"Content-Type": "application/json"})
try:
urllib.request.urlopen(req)
except urllib.error.HTTPError as err:
print(err.code, err.read().decode())
main()Sources
Related posts
More in Developers
- Poll a Sume image job in Python: obey next_poll_after_seconds
When POST /v1/images returns 202, keep polling the status_url and sleep for next_poll_after_seconds. A short Python loop that stops on a terminal status.
- Poll or callback for 1,000 video jobs: request counts at 30 seconds
At a 30-second poll, 1,000 video jobs make 4,000 to 20,000 status requests by job time. A callback_url cuts that to 1,000 deliveries plus a sweep.
- Poll /v1/jobs/{id}/status, then /result, in Node with backoff
A 25-line Node function that polls a Sume job on its own next_poll_after_seconds, reads /result only when the job completed, and keeps the id on timeout.
- Polling a 5-minute video job: 150 GETs at 2 s, or 10 at 30 s
A five-minute Sume video job costs 150 status reads at a 2 s interval and 10 at 30 s. Poll /v1/videos with a loop that handles every status.
Written by Sume