curl cookbook
A sign shell function plus the most common request shapes. Copy the prelude once, reuse it everywhere.
Prelude
API_KEY="fb_live_EXAMPLE_xxxxxxxxxxxxxxxxxxxx"
ORG_ID="org_example_01HZYABCDEFGHJKMNPQRSTVWXY"
BASE="https://api.flowbeacon.ai/api/public/v1"
PREFIX="/api/public/v1"
# Request signer. Emits 't=<ts>,v1=<hex>' for "X-FB-Signature: ...".
sign() {
local method="$1" path="$2" body="$3" ts sig
ts=$(date +%s)
sig=$(printf '%s.%s.%s.%s' "$ts" "$method" "$path" "$body" \
| openssl dgst -sha256 -hmac "$API_KEY" -binary | xxd -p -c 256)
printf 't=%s,v1=%s' "$ts" "$sig"
}
Submit and wait
BODY="{\"scenario_ids\":[\"4729318\"],\"org_id\":\"$ORG_ID\"}"
SIG=$(sign POST "$PREFIX/evaluate" "$BODY")
RESP=$(curl -sS -X POST "$BASE/evaluate" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "X-FB-Signature: $SIG" \
-d "$BODY")
EVAL_ID=$(echo "$RESP" | jq -r '.data.evaluation_id')
MAX_ATTEMPTS=120
for ((attempt=1; attempt<=MAX_ATTEMPTS; attempt++)); do
SIG=$(sign GET "$PREFIX/evaluations/$EVAL_ID" "")
STATUS=$(curl -sS "$BASE/evaluations/$EVAL_ID" \
-H "Authorization: Bearer $API_KEY" \
-H "X-FB-Signature: $SIG" | jq -r '.data.status')
case "$STATUS" in complete|error) break ;; esac
if [[ "$attempt" -eq "$MAX_ATTEMPTS" ]]; then
echo "Timed out waiting for evaluation $EVAL_ID" >&2
exit 1
fi
sleep 2
done
Fetch per-scenario detail
SIG=$(sign GET "$PREFIX/scenarios/4729318/results" "")
curl -sS "$BASE/scenarios/4729318/results" \
-H "Authorization: Bearer $API_KEY" \
-H "X-FB-Signature: $SIG" | jq
Remediation
SIG=$(sign GET "$PREFIX/violations/4729318:SEC-5/remediation" "")
curl -sS "$BASE/violations/4729318:SEC-5/remediation" \
-H "Authorization: Bearer $API_KEY" \
-H "X-FB-Signature: $SIG" | jq
Health check (no auth, no signature)
curl -sS "$BASE/governance/health"
Register a webhook
BODY='{"url":"https://hooks.example.com/flowbeacon","events":["evaluation.complete"]}'
SIG=$(sign POST "$PREFIX/webhooks" "$BODY")
curl -sS -X POST "$BASE/webhooks" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "X-FB-Signature: $SIG" \
-d "$BODY" | jq
Tips
jqis the cleanest way to read responses; install withbrew install jq/apt install jq.- Avoid
\!in body strings (history expansion). Use double quotes plus\"for inner quotes. - Keep the
BODYvariable identical between signing and transport —printfwill not introduce trailing newlines, butechomight.