Skip to main content

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

  • jq is the cleanest way to read responses; install with brew install jq / apt install jq.
  • Avoid \! in body strings (history expansion). Use double quotes plus \" for inner quotes.
  • Keep the BODY variable identical between signing and transport — printf will not introduce trailing newlines, but echo might.