Sora content rules vs Sume generation_rejected: read the job events
A prompt Sora refused may behave differently on Sume. How a rejection shows up as generation_rejected, which events to read, and why you must not assume parity.

When a prompt that Sora accepted fails on Sume, the job ends as failed with an error category such as generation_rejected, and GET /v1/jobs/{id}/events tells you what happened in order. Do not assume the two systems reject the same prompts: they are different models with different providers, and I found no page that states parity.
OpenAI's video guide, read 2026-10-08, lists its content restrictions: copyrighted characters and music, real people, and content unsuitable for audiences under 18. Sume's docs list job error categories, not a content policy, so test your own prompt set.
Where a rejection lands
Sume documents these job error categories: validation, auth, quota, queue, generation_unavailable, generation_rejected, generation_timeout, runtime_unavailable, worker_timeout and internal. For generation_rejected the docs say to examine the events and correct the unsupported input. The job object from GET /v1/jobs/{id}/status carries an error with category, stage, retryable, retry_after_seconds, public_reason and next_action; the OpenAPI document gives generation_rejected, image_content_rejected and content_policy_rejected as example public_reason values.
| Category | Meaning for your pipeline | Suggested handling |
|---|---|---|
| validation | the request shape is wrong | fix the body |
| generation_rejected | the generation step refused the input | change the input |
| generation_unavailable | the model could not take work | try later or another model |
| generation_timeout | the model ran too long | retry once, then switch model |
| internal | Sume side fault | retry with the same Idempotency-Key |
Read the timeline
The events endpoint returns a snapshot with a data object holding request_id, job_id and an events array. Each event has id, type, source, status, message, created_at and data. This script prints the timeline for one job; set JOB_ID.
import json, os, urllib.request
def main():
req = urllib.request.Request(
"https://api.sume.com/v1/jobs/" + os.environ["JOB_ID"] + "/events",
headers={"Authorization": "Bearer " + os.environ["SUME_API_KEY"]})
body = json.load(urllib.request.urlopen(req))
for event in body["data"]["events"]:
print(event["created_at"], event["type"], event["status"], event["message"])
main()A practical test set
Before you flip traffic, replay the prompts your users sent in the last month, with real-person names and brand names removed from the log, and count how many end as generation_rejected. That number belongs in your replacement scorecard next to latency and cost.
Show users a plain message for this category and keep the raw event text in your logs only. Never auto-retry a rejected prompt; it will be rejected again and, if the job reserved credits, it adds noise to your spend review.
Sources
Related posts
More in Developers
- Sora download_content vs Sume /content: the 302 and two 409 errors
OpenAI's content endpoint took variant=video, thumbnail or spritesheet. Sume's /content redirects with a 302 and returns two different 409s. How to branch.
- Sora input_reference image: upload with uploadFile, use frame_images
OpenAI took the first-frame image as multipart input_reference. Sume wants an HTTPS URL: upload with the SDK's uploadFile, then pass it as frame_images.
- Sora jobs in flight at shutdown: reconcile, then resubmit to Sume
OpenAI's page gives the removal date but not in-flight jobs. Mark every unfinished Sora row, then resubmit its prompt to Sume with a key built from the old id.
- Measure your own render time on Sume from job event timestamps
No published Sora timing carries over. Read GET /v1/jobs/{id}/events, diff created, started and completed, and keep your own queue and render split per model.
Written by Sume