Marketing API v24 expiry runbook: replay the upload, not the render
When Meta's v24.0 window closes on October 6, 2026, fix uploads by replaying stored Sume job results. The same Idempotency-Key never bills a render twice.

On the day a Marketing API version closes, replay only the failed upload: fetch the stored result of each completed Sume job and send it to Meta again on the newer version. Do not resubmit the render. Meta lists v24.0 as available until October 6, 2026.
This works because Sume jobs are durable: a completed job keeps its result at GET /v1/jobs/{id}/result, and a submit retry with the same Idempotency-Key returns the original job and does not bill a second one.
Which side owns which step?
Split the pipeline into two stores: a render table keyed by Sume job id, and an upload table keyed by job id plus platform version.
| Step | Meta side | Sume side |
|---|---|---|
| Detect | Uploads fail on the closed version | Jobs stay completed; nothing to redo |
| Fix | Change the version setting to v25.0 | No change |
| Replay | Re-send the video to Meta | GET /v1/jobs/{id}/result for the stored artifact |
| Verify | Check one upload end to end | GET /v1/jobs/{id}/status shows terminal: true |
How do I replay safely?
Read each result once, and keep the Sume media URL from the result, not any raw provider URL: Sume documents its media URLs as the public output. If a result read answers 409 job_not_completed, the job is still running: poll status, never resubmit.
The sample reads a result for each stored job id.
import os
import requests
def result_artifacts(job_id: str) -> list:
r = requests.get(
f"https://api.sume.com/v1/jobs/{job_id}/result",
headers={"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"},
timeout=30,
)
if r.status_code == 409:
raise RuntimeError("job_not_completed: poll status, do not resubmit")
r.raise_for_status()
return r.json().get("result", {}).get("artifacts", [])
if __name__ == "__main__":
for job_id in ["job_123"]:
print(job_id, result_artifacts(job_id))What not to do
Do not retry the render because an upload failed, and do not reuse an idempotency key for a different payload: Sume answers 409 idempotency_conflict for that.
- Keep the upload log separate from the render log.
- Replay in small batches, so Meta-side throttling does not hide a real error.
Sources
Related posts
More in Developers
- Match STT results to file ids: the job echoes your Idempotency-Key
Sending 300 recordings to Sume STT? Set Idempotency-Key to your own file id. The job record returns it, so results map back after a crash or a retry.
- Match white balance across two AI product photos with Pillow
Two image models gave your product photos different color casts. Fix both with a gray-world gain in Pillow, check the channel means, and know when it fails.
- max_spend_usd is optional on Sume MCP: send it on every paid call
Sume enforces max_spend_usd only when you send it. Make your coding agent send it with dry_run and an idempotency_key. Wallet admission is the real gate.
- MCP 2026 roadmap lists audit trails: what Sume records for agents
The MCP 2026 roadmap names audit trails as an enterprise priority. Here is what Sume records for an agent's paid work today: jobs, receipts, the usage ledger.
Written by Sume