Shell script
Convert a file from the command line with curl and jq, with cleanup on failure.
convt-api.sh takes a file and a target format and saves every output in the current directory. It needs Bash, curl 7.76 or newer and jq.
#!/usr/bin/env bash
# usage: convt-api.sh <file> <input-format> <target-format>
set -euo pipefail
API=${CONVT_API:-https://convt-api-production.up.railway.app}
FILE=$1 FROM=$2 TO=$3
AUTH="Authorization: Bearer ${CONVT_API_KEY:?set CONVT_API_KEY}"
BYTES=$(wc -c < "$FILE" | tr -d ' ')
api() { curl -sS --fail-with-body -H "$AUTH" "$@"; }
RESERVED=$(api "$API/v1/jobs" -H "Content-Type: application/json" \
-d "$(jq -n --arg from "$FROM" --arg to "$TO" --argjson bytes "$BYTES" \
'{input_format: $from, target_format: $to, input_bytes: $bytes}')")
JOB=$(jq -r .job.id <<< "$RESERVED")
# Release the reservation if anything below fails.
trap 'api -X POST "$API/v1/jobs/$JOB/cancel" > /dev/null || true' ERR
curl -sS --fail-with-body -X PUT -T "$FILE" "$(jq -r .upload_url <<< "$RESERVED")"
api -X POST "$API/v1/jobs/$JOB/start" > /dev/null
for _ in $(seq 660); do
JOB_JSON=$(api "$API/v1/jobs/$JOB")
STATUS=$(jq -r .status <<< "$JOB_JSON")
case $STATUS in succeeded|failed|cancelled) break ;; esac
sleep 1
done
if [ "$STATUS" != succeeded ]; then
echo "job $JOB $STATUS: $(jq -r '.error_code // "timed out"' <<< "$JOB_JSON")" >&2
false
fi
# Outputs are named input.<ext>; save them under the input's own name.
STEM=$(basename "${FILE%.*}")
api "$API/v1/jobs/$JOB/download" | jq -r '.outputs[] | "\(.name)\t\(.url)"' |
while IFS=$'\t' read -r NAME URL; do
NAME=$(basename "$NAME")
NAME=${NAME/#input/$STEM}
curl -sS --fail-with-body -o "$NAME" "$URL"
echo "saved $NAME"
done
$ chmod +x convt-api.sh
$ ./convt-api.sh slides.pptx pptx pdf
saved slides.pdf
The input format is an argument because shell scripts have no clean way to map extensions. Find ids on the Formats page or with curl https://convt-api-production.up.railway.app/v1/formats.