curl --fail-with-body: keep Sume's error envelope in shell scripts

curl --fail drops the response body on a 4xx. --fail-with-body (curl 7.76.0+) keeps it, so a script can read Sume's error code and retryable flag.

5 min readSume
All posts

Use curl --fail-with-body. The curl manual says it returns exit code 22 on HTTP 400 or above like --fail, but still outputs and saves the response body; --fail alone suppresses the body. It was added in curl 7.76.0. Sume puts the reason in that body, in an error object with a code, retryable and next_action.

The difference

Without the body, a script sees only the exit code 22 and cannot tell a retry from a fix.

curl options on an error response (read 2026-10-04)
OptionExit code on HTTP 400 or moreBody kept
--fail22No
--fail-with-body22Yes
neither0Yes

Script

Sume's error envelope names a next_action such as fix_input, authenticate, add_funds, retry_later, poll_status, inspect_events or contact_support. The script maps it to an exit code your pipeline can branch on. It uses python3 to read JSON, so no extra tools are needed.

set -u
: "${SUME_API_KEY:?SUME_API_KEY is not set}"

curl -sS --fail-with-body -o resp.json \
  -X POST https://api.sume.com/v1/video-router/generate \
  -H "x-api-key: $SUME_API_KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: ${1:?usage: submit.sh <stable-key>}" \
  -d '{"model":"seedance-2.5","prompt":"A product clip on a desk","resolution":"720p","duration":4,"aspect_ratio":"9:16","mode":"async"}'
rc=$?

if [ "$rc" -eq 0 ]; then
  python3 -c 'import json; print(json.load(open("resp.json"))["data"]["request_id"])'
  exit 0
fi
if [ "$rc" -eq 22 ]; then
  python3 - <<'PY'
import json, sys
e = json.load(open("resp.json"))["error"]
print(f'{e["code"]} retryable={e.get("retryable")} next={e.get("next_action")} req={e.get("request_id")}', file=sys.stderr)
sys.exit(10 if e.get("retryable") else 11)
PY
  exit $?
fi
exit "$rc"

Exit codes in your pipeline

Exit 10 means retry later with the same key, 11 means fix the request or the account, and 22 never escapes. Anything else is a transport problem such as DNS or a timeout, and the same Idempotency-Key makes a retry safe. The full decision table is in the retry or fix function.

Version check

The manual says the flag arrived in 7.76.0, so check curl --version on the runner before relying on it.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume