webcapture Get a free key

Poll an async PDF render with curl

The same two-call shape as the sync recipe, with a between step: the ticket's poll url is looped until the status leaves queued and rendering.

?wait=false makes the POST answer at once with a 202 ticket: id, status queued, and two urls, poll and download. The loop below asks the poll url once a second; ready means the download url has the document. A failed render ends the loop with the endpoint's error in the poll body.

The recipe

ORIGIN="https://webcapture.io"

TICKET=$(curl -sS -X POST "$ORIGIN/v1/convert?wait=false" \
  -H "Authorization: Bearer wc_your_key" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/"}')
echo "$TICKET"
# {"id": "cnv_02b8c9d9", "status": "queued",
#  "poll": ".../v1/conversions/cnv_02b8c9d9",
#  "download": ".../v1/conversions/cnv_02b8c9d9.pdf"}

POLL=$(printf '%s' "$TICKET" | sed -E 's/.*"poll": *"([^"]+)".*/\1/')
DOWNLOAD=$(printf '%s' "$TICKET" | sed -E 's/.*"download": *"([^"]+)".*/\1/')

while :; do
  ROW=$(curl -sS -H "Authorization: Bearer wc_your_key" "$POLL")
  STATUS=$(printf '%s' "$ROW" | sed -E 's/.*"status": *"([^"]+)".*/\1/')
  [ "$STATUS" = "queued" ] || [ "$STATUS" = "rendering" ] || break
  sleep 1
done
[ "$STATUS" = "ready" ] || { echo "render failed: $ROW" >&2; exit 1; }

curl -sS -H "Authorization: Bearer wc_your_key" -o page.pdf "$DOWNLOAD"

The guard after the loop turns a failed render into exit 1 with the endpoint's own message, so a cron job sees the difference between a slow page and a broken one. A ready row adds attempts and bytes to the status, so the caller knows the document's size before it downloads; the one-second pace is the endpoint's guidance for interactive scripts, and batch jobs can poll less often.

Same-key GET: 401 without it; 404 for another key.

The fields this recipe uses

Related

Method

Source: convert field reference, checked 2026-10-05. Corrections.