Why is my TTS job slow? Read the Sume job events timeline

GET /v1/jobs/{id}/events returns a sanitized lifecycle timeline. Use it to tell queue wait from generation time and failed webhook deliveries.

5 min readSume
All posts

To find out why a Sume TTS job was slow, call GET /v1/jobs/{id}/events. It returns a sanitized timeline of the job lifecycle, so you can see when the job was created, queued and started, when generation was submitted, when it finished, and whether a webhook delivery failed or is retrying. Raw provider URLs, provider task ids, callback signatures and secrets are left out.

That one list answers most slow-job tickets: was it waiting in the queue, was it generating, or did the audio finish and only your callback fail?

Which events can you see?

The Sume OpenAPI spec defines the event types, each with a source of sume or webhook, a status and a timestamp.

Job event types, Sume spec read 2026-10-04
Event typeWhat it tells you
job.createdThe request was accepted
job.queuedThe job is waiting for capacity
job.startedWork began
generation.submittedGeneration was sent; cancel is no longer possible
job.completed, job.failed, job.canceledTerminal outcome
webhook.deliveryA callback attempt, with status such as succeeded, failed or retrying

How do you read a slow job?

Compare the timestamps between neighbouring events. A long gap between job.queued and job.started is waiting. A long gap after generation.submitted is generation. If job.completed is early but you saw nothing, look at the webhook.delivery rows; a failed one points at your receiver, and you can redeliver the webhook without a rerun.

  • Use the limit query parameter to cap how many events you pull.
  • Log the job id with your own request id so you can fetch the timeline later.
  • Do not treat the timeline as an SLA; it is for debugging.

What does the call look like?

Print the events in order:

import os, requests

H = {"Authorization": "Bearer " + os.environ["SUME_API_KEY"]}
job_id = os.environ["JOB_ID"]

r = requests.get(
    f"https://api.sume.com/v1/jobs/{job_id}/events",
    headers=H, params={"limit": 50}, timeout=30,
)
r.raise_for_status()
for e in r.json()["data"]["events"]:
    print(e["created_at"], e["type"], e["status"], e["message"])

What next?

If the timeline shows the job is still in flight, keep polling status rather than resubmitting; see what to do when a sync wait times out. For the polling loop itself, async TTS polling on Sume has a complete example.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume