A Hurl file for a Sume job: submit, poll until terminal, fetch

A plain-text Hurl file chains submit, a retrying status poll on data.terminal, and the result read. Run it in CI with hurl --variable and an Idempotency-Key.

5 min readSume
All posts

A Hurl file can run a whole Sume job lifecycle as a smoke test: one POST to submit, one GET that retries until data.terminal is true, one GET for the result. Hurl's entry options include retry and retry-interval, which its docs describe as the way to do polling, and [Captures] with jsonpath pulls the job id out of the first response (read 2026-10-04).

The Sume side is from Jobs and results: submit with mode: "async" and an Idempotency-Key, poll the status URL until terminal, then read /result, which only answers 200 for a completed job.

What does the file look like?

Pass the key and an idempotency value as variables so nothing secret lives in the file. This job costs real credits, so use a development workspace or a small prompt.

POST https://api.sume.com/v1/image-1.0/generate
x-api-key: {{api_key}}
Idempotency-Key: {{idem}}
{
  "prompt": "Matte black bottle on marble",
  "mode": "async"
}
HTTP 202
[Captures]
job_id: jsonpath "$.data.request_id"

GET https://api.sume.com/v1/jobs/{{job_id}}/status
x-api-key: {{api_key}}
[Options]
retry: 60
retry-interval: 3s
HTTP 200
[Asserts]
jsonpath "$.data.terminal" == true
jsonpath "$.data.sume_status" == "completed"

GET https://api.sume.com/v1/jobs/{{job_id}}/result
x-api-key: {{api_key}}
HTTP 200

How do you run it?

hurl --test --variable api_key="$SUME_API_KEY" --variable idem="smoke-$(date +%F)" sume-job.hurl. A stable idem per day means a re-run of the same CI job replays the original job rather than paying again.

What does each part decide?

Hurl settings for a Sume poll, with the Sume contract behind each, read 2026-10-04
Hurl lineWhySume basis
HTTP 202 on submitAsync submit returns an envelope, not a resultCommunication modes
retry: 60, retry-interval: 3sCaps the wait at about 3 minutesClient-side deadline; the job is not canceled when it ends
jsonpath data.terminal == trueStops on any terminal stateterminal covers completed, failed, canceled
Second assert on sume_statusFails the test on failed or canceledResult read answers 409 job_not_completed otherwise

Where does a smoke test like this fall short?

  • The retry window is a client budget. When it expires the job keeps running and billing, so a flaky CI that times out repeatedly can leave paid jobs behind.
  • Hurl's fixed interval ignores next_poll_after_seconds; keep the interval at or above what the status payload suggests.
  • Video jobs routinely outlast three minutes. Use this for image or short jobs, and a webhook for long ones.

How do you keep the smoke test cheap?

Pick the cheapest job that exercises the route you ship, and set the spend ceiling at the account level rather than trusting the test. A stable idem value means a CI re-run replays the same job; change the suffix only when you want a new paid job. Run it on a schedule instead of on every commit, and keep one Hurl file per route family so a failure names the surface that broke.

Hurl writes a report you can archive. Keep the job id in it, since the id is what Sume support and the /events timeline need to explain a surprise.

What next?

Add a second file for the failure path, such as a 402 on a workspace with no credit, using the codes in Errors and rate limits.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume