export BASE=https://client-api.stg.future-demand.com/api/v3
export FD_USER=you@partner.com
export FD_PASS='...'
Auth — sign in and stash tokens
RESP=$(curl -s -X POST "$BASE/auth" \
-H "Content-Type: application/json" \
-d "{\"username\":\"$FD_USER\",\"password\":\"$FD_PASS\"}")
export FD_ACCESS_TOKEN=$(echo "$RESP" | jq -r .AccessToken)
export FD_ID_TOKEN=$(echo "$RESP" | jq -r .IdToken)
export FD_REFRESH_TOKEN=$(echo "$RESP" | jq -r .RefreshToken)
# Extract the first partner-id from cognito:groups
export FD_PARTNER_ID=$(echo "$FD_ID_TOKEN" | cut -d. -f2 | base64 -d 2>/dev/null \
| jq -r '."cognito:groups"[]' | grep -E '^(partner-id-|fd[0-9]+)' | head -1)
echo "Signed in as $FD_USER, partner $FD_PARTNER_ID"
alias fd='curl -s -H "Authorization: Bearer $FD_ACCESS_TOKEN" -H "X-Preferred-Partner-Id: $FD_PARTNER_ID"'
Refresh
curl -s -X POST "$BASE/auth/refresh_token" \
-H "Content-Type: application/json" \
-d "{\"token\":\"$FD_REFRESH_TOKEN\"}" \
| jq
Partner / profile
fd "$BASE/partners/" | jq
fd "$BASE/profile/" | jq
fd "$BASE/features/" | jq
fd "$BASE/permissions" | jq
Events — list and detail
fd "$BASE/events/?page=1&limit=5&descending=false" | jq
EID=$(fd "$BASE/events/?limit=1" | jq -r '.items[0].id')
echo "Picked $EID"
fd "$BASE/events/$EID" | jq
fd "$BASE/events/$EID/statistics" | jq
fd "$BASE/events/$EID/benchmark" | jq
fd "$BASE/events/$EID/sales-graph" | jq
fd "$BASE/events/$EID/tickets" | jq
fd "$BASE/events/$EID/clusters" | jq
fd "$BASE/events/$EID/campaigns?limit=10" | jq
Affinity recommendations
fd "$BASE/events/$EID/suggested_tcs?budget=5000&goal=tickets" | jq
fd "$BASE/events/$EID/campaigns_expected_value?budget=5000&goal=tickets" | jq
fd "$BASE/events/$EID/budget_min_max?runtime_in_days=14" | jq
fd "$BASE/events/$EID/default_campaigns_parameters" | jq
fd "$BASE/setup_processes/call_to_action/?goal=tickets&has_pixel=true&lead_form_id=" | jq
Wave — campaigns lifecycle
# Read existing draft (404 = no draft)
fd "$BASE/setup_processes/$EID" | jq
# Create draft
fd -X POST "$BASE/setup_processes/$EID" \
-H "Content-Type: application/json" \
-d '{
"goal": "tickets",
"total_budget": 5000,
"start_date": "2026-05-25",
"end_date": "2026-06-12",
"tc_run_id": 42,
"creatives": {},
"targeting": {}
}' | jq
# Update (debounced autosave in a real UI)
fd -X PUT "$BASE/setup_processes/$EID" \
-H "Content-Type: application/json" \
-d '{ "goal": "tickets", "total_budget": 6000, "start_date": "2026-05-25", "end_date": "2026-06-12", "tc_run_id": 42, "creatives": {}, "targeting": {} }' | jq
# Publish
fd -X POST "$BASE/setup_processes/$EID/boost" | jq
# Edit one published cluster
fd -X POST "$BASE/campaigns_setup" \
-H "Content-Type: application/json" \
-d "{
\"eid\": \"$EID\",
\"tc\": \"family_outings_munich\",
\"tc_run_id\": 42,
\"audience_id\": \"aud_777\",
\"creatives\": {},
\"targeting\": {}
}" | jq
# Cancel / reset
fd -X DELETE "$BASE/setup_processes/$EID?cancel=true" | jq
fd -X PUT "$BASE/events/$EID/reset_campaigns_setup" | jq
Wave — Package Builder
# Create package
PKG=$(fd -X POST "$BASE/package_builder/packages" \
-H "Content-Type: application/json" \
-d '{
"num_packages": 3,
"n_top_events": 3,
"event_ids": [12345],
"package_title": "Test",
"targeting_mode": "lookalike",
"filters": {}
}' | jq -r .id)
echo "Created $PKG"
# Poll status
while true; do
STATUS=$(fd "$BASE/package_builder/packages/$PKG" | jq -r .status)
echo "$(date +%T) — $STATUS"
case "$STATUS" in DONE|FAILED|EXPIRED) break;; esac
sleep 5
done
# Download cluster CSV
fd "$BASE/package_builder/packages/$PKG/family_outings_munich/customer_list" \
-o family_outings_munich.csv
# Backhaul evaluation
fd "$BASE/package_builder/packages/$PKG/backhaul_evaluation_details" | jq
fd -X PUT "$BASE/package_builder/packages/$PKG/backhaul_evaluation_details" \
-H "Content-Type: application/json" \
-d '{
"backhaul_evaluation_attribution_window": 14,
"backhaul_evaluation_model": "EVENTS_FROM_PACKAGE",
"email_sent_date": "2026-06-01"
}' | jq
fd "$BASE/package_builder/packages/$PKG/backhaul_evaluation" | jq
Attribution
fd "$BASE/campaign_results/?eid=$EID&partner_id=$FD_PARTNER_ID" | jq
fd "$BASE/events/$EID/attribution_model" | jq
Messages / Notifications
fd "$BASE/messages/partner/?limit=10&page=1" | jq
fd "$BASE/messages/totalunread" | jq
fd "$BASE/notifications/?limit=10" | jq
fd "$BASE/notifications/stats" | jq
Sales — manual ingest
fd -X POST "$BASE/ingest/transaction_summary" \
-H "Content-Type: application/json" \
-d "{
\"eid\": \"$EID\",
\"from\": \"2026-06-01\",
\"to\": \"2026-06-12\",
\"tickets\": [
{ \"type\": \"standard\", \"sold\": 412, \"revenue\": 18540 }
]
}" | jq
File upload — XLSX ingest
curl -s -X POST "$BASE/ingest/transaction_summary/from_excel?eid=$EID" \
-H "Authorization: Bearer $FD_ACCESS_TOKEN" \
-H "X-Preferred-Partner-Id: $FD_PARTNER_ID" \
-F "file=@./sales.xlsx" \
| jq
Media upload (note: no /v3 prefix)
# /media is on the API host but WITHOUT /v3
MEDIA_BASE="${BASE%/v3}"
curl -s -X POST "$MEDIA_BASE/media" \
-H "Authorization: Bearer $FD_ACCESS_TOKEN" \
-H "X-Preferred-Partner-Id: $FD_PARTNER_ID" \
-F "file=@./creative.jpg" \
| jq
Health
curl -s "$BASE/status/" | jq # no auth