SQLite: add a sume_job_id column to rows that used sora-2 snapshots

OpenAI removed the Videos API and every sora-2 snapshot on Sept 24, 2026. A migration that tags old rows, then re-renders each once through Sume.

4 min readSume
All posts

Add two nullable columns, sume_job_id and idempotency_key, put a unique index on the key, and re-render only the rows whose model still names a sora-2 id and whose sume_job_id is empty. OpenAI's deprecations page lists the Videos API and five model ids as removed on September 24, 2026, with no replacement named, so any table that stored those ids now points at a service that no longer answers.

Which stored ids are dead

The page notified the removal on March 24, 2026. If your rows hold a dated snapshot, the match must include it; a LIKE 'sora-2%' filter catches all five.

Removed OpenAI video ids and dates (OpenAI deprecations page, read 2026-10-07)
IdRemoved
sora-22026-09-24
sora-2-pro2026-09-24
sora-2-2025-10-062026-09-24
sora-2-2025-12-082026-09-24
sora-2-pro-2025-10-062026-09-24

The migration

The key is built from the row id, so it is stable. A job that crashes between the submit and the UPDATE reruns with the same Idempotency-Key, and Sume's docs say a replay returns the original job instead of starting a second one. SQLite allows many NULLs in a unique index, so unmigrated rows do not collide.

import sqlite3

db = sqlite3.connect(":memory:")
db.execute("CREATE TABLE renders (id INTEGER PRIMARY KEY, model TEXT, prompt TEXT)")
db.execute("INSERT INTO renders (model, prompt) VALUES ('sora-2-pro-2025-10-06', 'harbor at dawn')")

db.execute("ALTER TABLE renders ADD COLUMN sume_job_id TEXT")
db.execute("ALTER TABLE renders ADD COLUMN idempotency_key TEXT")
db.execute("CREATE UNIQUE INDEX renders_idem ON renders (idempotency_key)")

todo = db.execute(
    "SELECT id, prompt FROM renders WHERE model LIKE 'sora-2%' AND sume_job_id IS NULL"
).fetchall()
for row_id, prompt in todo:
    key = f"sora-port-{row_id}"  # stable per row: a crashed rerun sends the same key
    db.execute("UPDATE renders SET idempotency_key = ? WHERE id = ?", (key, row_id))
    # POST /v1/videos with header Idempotency-Key: key, then store the id it returns
    db.execute("UPDATE renders SET sume_job_id = ? WHERE id = ?", ("job_from_submit", row_id))
print(db.execute("SELECT id, sume_job_id, idempotency_key FROM renders").fetchall())

Limits to plan for

The sample does not call the API; the comment marks where POST /v1/videos goes. A re-render is a new generation, not a recovery of the old clip: /v1/videos returns 400 for seed, so you cannot reproduce the old output, and the model, length and look will differ. Pick the model from GET /v1/videos/models using the supported_durations and supported_resolutions your rows need.

Reuse a key only for an identical payload. If you change the prompt for a row, give it a new key, or the API answers 409 idempotency_conflict.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume