API Docs/Code Examples

Code Examples

End-to-end examples of the three-step async workflow: create a search via POST /v1/searches, poll GET /v1/searches/{job_id} until complete, then download each Parquet shard in the download_urls array. Pick the language that matches your stack using the tabs below. Each example paces its polling loop to the recommended 15–30 second cadence and handles both completed and failed terminal states.

Three-step async API workflow: create search, poll status, download Parquet shards

#!/bin/bash
set -e

API_KEY="${KEEPER_API_KEY:?set KEEPER_API_KEY in your environment}"
BASE="https://api.keeperhealth.com"

# 1. Create the search job
JOB_ID=$(curl -s -X POST "$BASE/v1/searches" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "npis": [1144218512],
    "billing_codes": ["99213", "99214"],
    "fee_schedules": [{"payer":"Cigna","plan":"PPO"}]
  }' | jq -r '.job_id')

echo "Job created: $JOB_ID"

# 2. Poll until terminal state (completed or failed).
# 15 attempts × 20 seconds = 5 minute cap, well inside the recommended
# 15-30s polling cadence.
for attempt in $(seq 1 15); do
  STATUS=$(curl -s -H "Authorization: Bearer $API_KEY" \
    "$BASE/v1/searches/$JOB_ID")
  STATE=$(echo "$STATUS" | jq -r '.status')

  echo "Attempt $attempt: $STATE"

  if [ "$STATE" = "completed" ]; then
    # `download_urls` is always an array — iterate every shard.
    i=0
    echo "$STATUS" | jq -r '.download_urls[]' | while read -r url; do
      curl -o "results-$i.parquet" "$url"
      i=$((i + 1))
    done
    echo "Results saved as results-*.parquet"
    exit 0
  elif [ "$STATE" = "failed" ]; then
    REASON=$(echo "$STATUS" | jq -r '.error')
    echo "Job failed: $REASON" >&2
    exit 1
  fi

  sleep 20
done

echo "Timed out waiting for job" >&2
exit 1

See also

Keeper Health API v1 · Questions? company@keeperhealth.com