API Docs
Home Directory Docs Sign in Get API Key
PepKey API v2.0

The Peptide Provider Data API

Access verified data on 7,300+ peptide therapy providers across the United States. Power healthcare platforms, patient apps, research tools, and compliance workflows.

Base URL https://pepkey.org/api
🏥 Healthcare Platforms 📱 Patient-Facing Apps 🔬 Clinical Research Compliance & Credentialing 🤖 AI Health Assistants 📊 Analytics & Reporting
7,300+
Providers
45
Peptide Profiles
310
NPI Verified
50
States
No setup required for Free tier. Hit https://pepkey.org/api/providers right now — no key, no registration, no credit card.

Authentication #

The PepKey API uses API keys for authentication on paid plans. Free tier endpoints require no authentication. Pass your API key using the X-PepKey-Key request header on every request.

Free
$0 / mo
No API key required
100 requests/day
Basic provider fields
Score + stats endpoints
NPI data
Clinic tools
Start Free →
Pro
$149 / mo
API key in header
50,000 requests/day
Full score breakdown
NPI specialty + name
Questionnaires + inventory
Webhooks
Get Pro Key →

Using Your API Key

Include your key in the X-PepKey-Key header on all requests to authenticated endpoints. Keys are prefixed pk_live_ for production.

HTTP Header
X-PepKey-Key: pk_live_your_api_key_here
⚠️
Never expose your API key in client-side code. Always proxy requests through your backend. Your key grants access to your full rate limit and all plan features.

Key Security

If your key is compromised, rotate it immediately in the API dashboard. Keys can be revoked without affecting your plan. We recommend storing keys as environment variables:

Shell / .env
export PEPKEY_API_KEY="pk_live_your_key_here"

Rate Limits #

Rate limits are applied per API key (or per IP for unauthenticated requests). Limits reset on a rolling window — daily limits reset at midnight UTC, per-minute limits reset every 60 seconds.

Free
100
requests / day
10
requests / minute
Starter
5,000
requests / day
60
requests / minute
Pro
50,000
requests / day
300
requests / minute
Featured
200,000
requests / day
1,000
requests / minute

Rate Limit Headers

Every API response includes rate limit information in the headers:

Header Description Example
X-RateLimit-Limit Total requests allowed per day 5000
X-RateLimit-Remaining Requests remaining in current window 4876
X-RateLimit-Reset Unix timestamp when limit resets 1743984000
X-RateLimit-Minute-Limit Requests allowed per minute 60
X-RateLimit-Minute-Remaining Requests remaining this minute 58
Retry-After Seconds to wait (only on 429 responses) 34
💡
When you receive a 429 Too Many Requests, check the Retry-After header and implement exponential backoff. Repeated rapid retries after a 429 may result in a temporary IP ban.

Error Codes #

PepKey uses standard HTTP status codes. All error responses include a JSON body with error and message fields.

Status Code Description
200 ok Request succeeded
400 bad_request Invalid query parameters or malformed request
401 unauthorized Missing or invalid API key
403 forbidden Endpoint requires a higher plan (e.g., Pro endpoint with Starter key)
404 not_found Provider ID does not exist
429 rate_limit_exceeded You have exceeded your rate limit. Check Retry-After header
500 internal_error Server error. Please contact support
JSON — Error Response
{
  "error": "forbidden",
  "message": "The field 'score_breakdown' requires a Pro plan or higher.",
  "docs": "https://pepkey.org/api-docs.html#tier-fields",
  "upgrade_url": "https://pepkey.org/api-keys"
}

Endpoints #

GET /api/providers Free

Returns a paginated list of peptide therapy providers. All tiers can access this endpoint, but the fields returned vary by plan. Filter by state, city, tier, NPI verification status, and trust score range.

Query Parameters

ParameterTypeDefaultPlanDescription
page integer 1 Free Page number (1-indexed)
per_page integer 20 Free Results per page. Max: Free=20, Starter=100, Pro=500
state string Free Two-letter state code (e.g. CA, TX, FL)
city string Free City name (URL-encoded). Case-insensitive partial match.
tier string Free Filter by provider tier: featured, verified, standard
search string Free Full-text search across name, city, and specialty
claimed boolean Starter Filter by claimed status (true / false)
npi_verified boolean Pro Filter to only NPI-verified providers
min_score integer Pro Minimum trust score (0–100)
max_score integer Pro Maximum trust score (0–100)
Response Example (Free Tier)
JSON
{
  "data": [
    {
      "id": "prov_8f3a2c1b",
      "name": "Dr. Sarah Chen, MD — Pacific Wellness Institute",
      "city": "Los Angeles",
      "state": "CA",
      "score": 87,
      "tier": "featured",
      "website": "https://pacificwellnessinstitute.com",
      "phone": "(310) 555-0142",
      "claimed": true
    },
    {
      "id": "prov_5d9e1f4a",
      "name": "Optimal Health & Longevity Center",
      "city": "San Diego",
      "state": "CA",
      "score": 74,
      "tier": "verified",
      "website": "https://optimalhealthcenter.com",
      "phone": "(619) 555-0287",
      "claimed": true
    },
    {
      "id": "prov_2b7c4d8e",
      "name": "BioRestore Performance Clinic",
      "city": "San Francisco",
      "state": "CA",
      "score": 62,
      "tier": "standard",
      "website": "https://biorestoreclinic.com",
      "phone": "(415) 555-0391",
      "claimed": false
    }
  ],
  "meta": {
    "page": 1,
    "per_page": 20,
    "total": 412,
    "total_pages": 21,
    "has_next": true,
    "has_prev": false
  }
}
Response Example (Starter Tier — additional fields)
JSON — Starter adds these fields per provider
{
  "id": "prov_8f3a2c1b",
  "name": "Dr. Sarah Chen, MD — Pacific Wellness Institute",
  "city": "Los Angeles",
  "state": "CA",
  "score": 87,
  "tier": "featured",
  "website": "https://pacificwellnessinstitute.com",
  "phone": "(310) 555-0142",
  "claimed": true,
  "google_review_score": 4.8,
  "google_review_count": 247,
  "npi_number": "1234567890",
  "npi_credential": "MD",
  "services": [
    "BPC-157",
    "TB-500",
    "Semaglutide",
    "CJC-1295/Ipamorelin",
    "NAD+ Therapy"
  ]
}
Response Example (Pro Tier — all fields)
JSON — Pro adds these additional fields
{
  "id": "prov_8f3a2c1b",
  "name": "Dr. Sarah Chen, MD — Pacific Wellness Institute",
  "city": "Los Angeles",
  "state": "CA",
  "score": 87,
  "tier": "featured",
  "website": "https://pacificwellnessinstitute.com",
  "phone": "(310) 555-0142",
  "claimed": true,
  "google_review_score": 4.8,
  "google_review_count": 247,
  "npi_number": "1234567890",
  "npi_credential": "MD",
  "npi_name": "CHEN, SARAH LI",
  "npi_specialty": "Internal Medicine",
  "npi_verified": true,
  "services": ["BPC-157", "TB-500", "Semaglutide", "CJC-1295/Ipamorelin", "NAD+ Therapy"],
  "google_place_id": "ChIJOwg_06VPwokRYv534QaPC8g",
  "score_breakdown": {
    "npi_verified": 25,
    "google_reviews": 22,
    "claimed": 15,
    "content_completeness": 15,
    "review_recency": 10
  },
  "score_summary": "High-trust provider with verified NPI credentials and strong recent review activity."
}
GET /api/providers/{id} Starter+

Returns the full detail record for a single provider. Includes all fields available at your plan tier. Provider IDs are stable and can be safely cached.

Path Parameters

ParameterTypeRequiredDescription
id string Required Provider ID (e.g. prov_8f3a2c1b)
Full Response Example (Pro)
JSON
{
  "id": "prov_8f3a2c1b",
  "slug": "pacific-wellness-institute-los-angeles-ca",
  "name": "Dr. Sarah Chen, MD — Pacific Wellness Institute",
  "practice_name": "Pacific Wellness Institute",
  "city": "Los Angeles",
  "state": "CA",
  "zip": "90024",
  "address": "10880 Wilshire Blvd, Suite 1400",
  "latitude": 34.0583,
  "longitude": -118.4426,
  "score": 87,
  "tier": "featured",
  "website": "https://pacificwellnessinstitute.com",
  "phone": "(310) 555-0142",
  "email": "[email protected]",
  "claimed": true,
  "claimed_at": "2026-01-14T09:22:11Z",
  "google_review_score": 4.8,
  "google_review_count": 247,
  "google_place_id": "ChIJOwg_06VPwokRYv534QaPC8g",
  "npi_number": "1234567890",
  "npi_credential": "MD",
  "npi_name": "CHEN, SARAH LI",
  "npi_specialty": "Internal Medicine",
  "npi_verified": true,
  "npi_verified_at": "2026-01-10T14:00:00Z",
  "services": [
    "BPC-157",
    "TB-500",
    "Semaglutide",
    "CJC-1295/Ipamorelin",
    "NAD+ Therapy",
    "Sermorelin",
    "PT-141"
  ],
  "accepts_telehealth": true,
  "consultation_types": ["in-person", "telehealth"],
  "score_breakdown": {
    "npi_verified": 25,
    "google_reviews": 22,
    "claimed": 15,
    "content_completeness": 15,
    "review_recency": 10
  },
  "score_summary": "High-trust provider with verified NPI credentials and strong recent review activity.",
  "pepkey_url": "https://pepkey.org/providers/pacific-wellness-institute-los-angeles-ca",
  "created_at": "2026-01-10T00:00:00Z",
  "updated_at": "2026-04-05T18:31:00Z"
}
GET /api/providers/{id}/score Free

Returns the trust score and score breakdown for a single provider. This endpoint is available on all tiers and is useful for embedding trust indicators in third-party products.

JSON — Score Response
{
  "id": "prov_8f3a2c1b",
  "name": "Dr. Sarah Chen, MD — Pacific Wellness Institute",
  "score": 87,
  "score_label": "High Trust",
  "score_color": "#10b981",
  "breakdown": {
    "npi_verified": {
      "points": 25,
      "max": 25,
      "description": "NPI number verified against NPPES registry"
    },
    "google_reviews": {
      "points": 22,
      "max": 25,
      "description": "247 Google reviews averaging 4.8★"
    },
    "claimed": {
      "points": 15,
      "max": 15,
      "description": "Provider has claimed and verified their listing"
    },
    "content_completeness": {
      "points": 15,
      "max": 20,
      "description": "Profile has website, phone, address, and services"
    },
    "review_recency": {
      "points": 10,
      "max": 15,
      "description": "Most recent review within 30 days"
    }
  },
  "computed_at": "2026-04-05T18:31:00Z"
}
GET /api/stats Free

Returns platform-wide statistics: total providers, state distribution, tier counts, average scores, and growth metrics. No authentication required.

JSON — Stats Response
{
  "total_providers": 7312,
  "npi_verified": 310,
  "claimed": 892,
  "featured": 47,
  "verified_tier": 1204,
  "standard_tier": 6061,
  "avg_score": 58.4,
  "states_covered": 50,
  "peptide_profiles": 45,
  "top_states": [
    { "state": "CA", "count": 987 },
    { "state": "TX", "count": 741 },
    { "state": "FL", "count": 612 },
    { "state": "NY", "count": 453 },
    { "state": "CO", "count": 318 }
  ],
  "last_updated": "2026-04-07T00:00:00Z",
  "providers_added_last_30d": 284
}
POST /api/lead Free

Records a lead event when a patient views or contacts a provider through your application. Used by PepKey Clinic and third-party integrations to track referral activity. No patient-identifying data is ever submitted — only the provider ID and optional lead metadata.

🔒
Privacy-first design. This endpoint accepts no patient-identifying information. Only provider IDs, anonymous session tokens, and interaction types are recorded.

Request Body

FieldTypeRequiredDescription
provider_id string Required The PepKey provider ID (e.g. prov_8f3a2c1b)
type string Required Lead type: view, contact_click, phone_click, website_click, directions
source string Optional Attribution source: directory, search, api, embed, or custom string
session_token string Optional Anonymous session identifier. Never tied to a patient identity. Used only for deduplication.
JSON — Request Body
{
  "provider_id": "prov_8f3a2c1b",
  "type": "contact_click",
  "source": "directory",
  "session_token": "anon_sess_7x9f2b"
}
JSON — Response
{
  "ok": true,
  "lead_id": "lead_4f2a8b3c",
  "recorded_at": "2026-04-07T12:31:00Z"
}
GET /api/leads/{provider_id} Starter+

Returns aggregated lead statistics for a given provider. Available to the provider's claimed account or any Starter+ API key. Returns total lead counts broken down by type and time period — no individual-level data is ever exposed.

Path Parameters

ParameterTypeRequiredDescription
provider_id string Required Provider ID (e.g. prov_8f3a2c1b)

Query Parameters

ParameterTypeDefaultDescription
period string 30d Time period: 7d, 30d, 90d, all
JSON — Lead Stats Response
{
  "provider_id": "prov_8f3a2c1b",
  "period": "30d",
  "total_leads": 142,
  "by_type": {
    "view": 98,
    "contact_click": 21,
    "phone_click": 14,
    "website_click": 7,
    "directions": 2
  },
  "by_source": {
    "directory": 87,
    "search": 44,
    "api": 11
  },
  "period_start": "2026-03-08T00:00:00Z",
  "period_end": "2026-04-07T00:00:00Z"
}

Clinic API Coming Soon

The PepKey Clinic API powers the PepKey Clinic™ suite — patient management, anonymous medication tracking, pre-visit questionnaires, and encrypted cloud backups. These endpoints are in active development and will launch with PepKey Clinic.

🔒
Privacy architecture note: The Clinic API is designed so that PHI never reaches PepKey servers. Patient identities are stored only on clinic devices. PepKey receives only anonymous PKP IDs with no linkable identifiers. Encrypted backups are unreadable by PepKey — the clinic holds the only decryption key.
POST /api/clinic/register Coming Soon

Register a new clinic account. Returns a clinic ID and API credentials for the clinic portal.

POST /api/clinic/login Coming Soon

Authenticate a clinic session. Returns a signed JWT token for subsequent clinic API calls.

POST /api/clinic/patients Coming Soon

Create an anonymous patient record. Generates a PKP ID (PepKey Patient identifier) — a random, non-guessable token with no linkage to real-world identity. The clinic stores the name-to-PKP mapping locally only.

GET /api/clinic/patients/:pkp/meds Coming Soon

Retrieve the active medication list for an anonymous patient by PKP ID. Returns peptide regimen, doses, and schedule — all de-identified per HIPAA Safe Harbor (45 CFR § 164.514(b)).

POST /api/clinic/dispense Coming Soon

Record a dispense or prescription event for an anonymous patient. Logs compound, quantity, and date against the PKP ID — no patient name or identifying data stored.

GET /api/clinic/inventory Coming Soon

Retrieve current clinic inventory levels for tracked compounds. Supports automated reorder alerting and batch tracking.

POST /api/clinic/backup Coming Soon

Upload an AES-256-GCM encrypted backup of clinic data to PepKey cloud. PepKey stores the ciphertext only — the encryption key never leaves the clinic device. Meets HIPAA encryption safe harbor (45 CFR § 164.402).

Patient App API Coming Soon

The Patient API powers the PepKey patient-facing app. Patients authenticate using their anonymous PKP ID and a PIN — no email, no account, no identity exposure. This API enables patients to view their medication regimen, log doses, complete questionnaires, and review their providers.

👤
No-identity design. Patient login requires only a PKP ID (given by the clinic) and a 6-digit PIN. PepKey cannot identify who a patient is. IP addresses are stripped from all patient endpoints. No third-party analytics SDKs are loaded in the patient app.
POST /api/patient/login Coming Soon

Authenticate a patient session using PKP ID + 6-digit PIN. Returns a short-lived session token. No email, name, or identifying information required.

GET /api/patient/meds Coming Soon

Returns the patient's active medication list, dosing schedule, and instructions — as prescribed by their clinic.

POST /api/patient/questionnaire Coming Soon

Submit responses to pre-visit or ongoing health questionnaires. Answers are stored against the anonymous PKP ID and accessible to the clinic — never linked to a real identity on PepKey servers.

POST /api/patient/dose-log Coming Soon

Log a patient's self-reported dose event — timestamp, compound, and dose amount. Enables adherence tracking and side-effect monitoring by the clinic.

POST /api/patient/reviews Coming Soon

Submit an anonymous patient review for a provider. Reviews are aggregated by PepKey for the provider's trust score calculation — no patient identity is ever linked to a review.

Field Reference #

Complete list of all fields returned in provider objects, with types, descriptions, and the minimum plan tier required to access each field.

FieldTypePlanDescription
idstringFreeUnique provider identifier. Format: prov_xxxxxxxx. Stable — safe to store.
slugstringStarterURL-safe unique identifier. Used in pepkey.org URLs.
namestringFreeFull display name including practice name.
practice_namestringStarterPractice or clinic name only (separate from provider name).
citystringFreeCity of primary practice location.
statestringFreeTwo-letter US state code.
zipstringStarter5-digit ZIP code of primary location.
addressstringStarterStreet address. May be approximate for unclaimed providers.
latitudefloatProGeographic latitude. Useful for proximity searches.
longitudefloatProGeographic longitude.
scoreintegerFreePepKey Trust Score. Integer from 0–100. See scoring methodology.
score_labelstringStarterHuman label: "High Trust", "Moderate Trust", "Low Trust".
score_breakdownobjectProPer-dimension breakdown of the trust score. See Score Breakdown.
score_summarystringProAI-generated one-sentence summary of score rationale.
tierstringFreeListing tier: featured, verified, or standard.
websitestringFreeProvider website URL. May be null if unclaimed and no website found.
phonestringFreePrimary contact phone number.
emailstringStarterContact email. Only present if claimed and provider has shared it.
claimedbooleanFreeWhether the provider has claimed their listing on PepKey.
claimed_atdatetimeProISO 8601 timestamp of when the listing was claimed.
google_review_scorefloatStarterAverage Google rating (1.0–5.0). Pulled from Google Places API.
google_review_countintegerStarterTotal number of Google reviews.
google_place_idstringProGoogle Place ID. Use to link directly to Google Maps listing.
npi_numberstringStarter10-digit National Provider Identifier from NPPES registry.
npi_credentialstringStarterCredential from NPI record (e.g. MD, DO, NP, PA-C).
npi_namestringProLegal name as registered in NPPES. Uppercase format.
npi_specialtystringProPrimary specialty from NPI taxonomy classification.
npi_verifiedbooleanProWhether NPI was successfully matched and verified against NPPES.
npi_verified_atdatetimeProTimestamp of last NPI verification check.
servicesarrayStarterArray of peptide/service names offered. Extracted from website and claimed profile.
accepts_telehealthbooleanStarterWhether the provider offers telehealth consultations.
consultation_typesarrayStarterModes: in-person, telehealth, phone.
pepkey_urlstringStarterCanonical PepKey profile URL.
created_atdatetimeStarterWhen the provider was first added to PepKey.
updated_atdatetimeStarterLast modification timestamp.

Tier Field Access #

The following table summarizes which field groups are included at each plan tier. All higher tiers include all lower-tier fields.

Field GroupFreeStarterPro
id, name, city, state
score, tier, website, phone, claimed
google_review_score, google_review_count
npi_number, npi_credential
services, accepts_telehealth, email
address, zip, slug, pepkey_url
npi_name, npi_specialty, npi_verified
score_breakdown, score_summary
latitude, longitude, google_place_id
claimed_at, npi_verified_at

Code Examples #

Ready-to-use examples for listing California providers and fetching a specific provider detail.

List Providers in California

cURL
curl -X GET "https://pepkey.org/api/providers?state=CA&per_page=20&tier=verified" \
  -H "X-PepKey-Key: pk_live_your_api_key_here" \
  -H "Accept: application/json"
Python
import os
import requests

PEPKEY_API_KEY = os.environ.get("PEPKEY_API_KEY")

headers = {
    "X-PepKey-Key": PEPKEY_API_KEY,
    "Accept": "application/json",
}

params = {
    "state": "CA",
    "per_page": 20,
    "tier": "verified",
    "page": 1,
}

response = requests.get(
    "https://pepkey.org/api/providers",
    headers=headers,
    params=params
)
response.raise_for_status()

data = response.json()
providers = data["data"]
meta = data["meta"]

print(f"Found {meta['total']} providers in CA ({meta['total_pages']} pages)")
for p in providers:
    print(f"  [{p['score']:>3}] {p['name']} — {p['city']}")
JavaScript (Node.js / fetch)
const PEPKEY_API_KEY = process.env.PEPKEY_API_KEY;

async function listCaliforniaProviders(page = 1) {
  const params = new URLSearchParams({
    state: 'CA',
    per_page: '20',
    tier: 'verified',
    page: String(page),
  });

  const response = await fetch(
    `https://pepkey.org/api/providers?${params}`,
    {
      headers: {
        'X-PepKey-Key': PEPKEY_API_KEY,
        'Accept': 'application/json',
      },
    }
  );

  if (!response.ok) {
    const err = await response.json();
    throw new Error(`PepKey API error: ${err.message}`);
  }

  const { data, meta } = await response.json();

  console.log(`Page ${meta.page} of ${meta.total_pages} — ${meta.total} total providers`);

  for (const provider of data) {
    console.log(`  [${provider.score}] ${provider.name} — ${provider.city}`);
  }

  return { data, meta };
}

listCaliforniaProviders().catch(console.error);
Ruby
require 'net/http'
require 'json'
require 'uri'

PEPKEY_API_KEY = ENV['PEPKEY_API_KEY']
BASE_URL = 'https://pepkey.org/api'

def list_providers(state:, tier: nil, page: 1, per_page: 20)
  uri = URI("#{BASE_URL}/providers")
  params = { state: state, page: page, per_page: per_page }
  params[:tier] = tier if tier
  uri.query = URI.encode_www_form(params)

  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true

  request = Net::HTTP::Get.new(uri)
  request['X-PepKey-Key'] = PEPKEY_API_KEY
  request['Accept'] = 'application/json'

  response = http.request(request)

  unless response.is_a?(Net::HTTPSuccess)
    error = JSON.parse(response.body)
    raise "PepKey API Error: #{error['message']}"
  end

  JSON.parse(response.body, symbolize_names: true)
end

result = list_providers(state: 'CA', tier: 'verified')
puts "Found #{result[:meta][:total]} providers in CA"
result[:data].each do |p|
  puts "  [#{p[:score]}] #{p[:name]} — #{p[:city]}"
end

Get a Single Provider Detail

cURL
curl -X GET "https://pepkey.org/api/providers/prov_8f3a2c1b" \
  -H "X-PepKey-Key: pk_live_your_api_key_here" \
  -H "Accept: application/json"
Python
import os
import requests

def get_provider(provider_id: str) -> dict:
    """Fetch full detail for a single PepKey provider."""
    response = requests.get(
        f"https://pepkey.org/api/providers/{provider_id}",
        headers={
            "X-PepKey-Key": os.environ["PEPKEY_API_KEY"],
            "Accept": "application/json",
        }
    )
    response.raise_for_status()
    return response.json()

provider = get_provider("prov_8f3a2c1b")

print(f"Name:       {provider['name']}")
print(f"Score:      {provider['score']}/100")
print(f"NPI:        {provider.get('npi_number', 'N/A')}")
print(f"Credential: {provider.get('npi_credential', 'N/A')}")
print(f"Services:   {', '.join(provider.get('services', []))}")
print(f"Telehealth: {provider.get('accepts_telehealth', False)}")
JavaScript
async function getProvider(providerId) {
  const response = await fetch(
    `https://pepkey.org/api/providers/${providerId}`,
    {
      headers: {
        'X-PepKey-Key': process.env.PEPKEY_API_KEY,
        'Accept': 'application/json',
      },
    }
  );

  if (response.status === 404) {
    throw new Error(`Provider ${providerId} not found`);
  }

  if (!response.ok) {
    const err = await response.json();
    throw new Error(`PepKey API: ${err.message}`);
  }

  return response.json();
}

const provider = await getProvider('prov_8f3a2c1b');

console.log('Name:', provider.name);
console.log('Score:', provider.score + '/100');
console.log('NPI:', provider.npi_number ?? 'N/A');
console.log('Services:', (provider.services ?? []).join(', '));
Ruby
require 'net/http'
require 'json'

def get_provider(provider_id)
  uri = URI("https://pepkey.org/api/providers/#{provider_id}")
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true

  request = Net::HTTP::Get.new(uri)
  request['X-PepKey-Key'] = ENV['PEPKEY_API_KEY']
  request['Accept'] = 'application/json'

  response = http.request(request)

  if response.code == '404'
    raise "Provider #{provider_id} not found"
  end

  unless response.is_a?(Net::HTTPSuccess)
    error = JSON.parse(response.body)
    raise "PepKey API Error: #{error['message']}"
  end

  JSON.parse(response.body, symbolize_names: true)
end

provider = get_provider('prov_8f3a2c1b')
puts "#{provider[:name]} (Score: #{provider[:score]}/100)"
puts "Services: #{Array(provider[:services]).join(', ')}"

Handling Pagination

Python — Iterate all pages
import os
import requests
import time

def iter_all_providers(state=None, per_page=100):
    """Generator that yields every provider, handling pagination automatically."""
    headers = {
        "X-PepKey-Key": os.environ["PEPKEY_API_KEY"],
        "Accept": "application/json",
    }
    page = 1

    while True:
        params = {"page": page, "per_page": per_page}
        if state:
            params["state"] = state

        resp = requests.get(
            "https://pepkey.org/api/providers",
            headers=headers,
            params=params
        )

        # Handle rate limits gracefully
        if resp.status_code == 429:
            retry_after = int(resp.headers.get("Retry-After", 60))
            print(f"Rate limited. Waiting {retry_after}s...")
            time.sleep(retry_after)
            continue

        resp.raise_for_status()
        body = resp.json()

        for provider in body["data"]:
            yield provider

        meta = body["meta"]
        if not meta["has_next"]:
            break

        page += 1

# Usage
for provider in iter_all_providers(state="TX"):
    print(provider["name"], provider["score"])

Webhooks #

🔒
Pro plan required. Webhooks are available on the Pro ($149/mo) and Featured plans. Configure your endpoint in the API dashboard.

PepKey sends real-time webhook notifications when provider data changes. Configure a HTTPS endpoint URL in your dashboard and PepKey will POST signed JSON payloads to your server.

Event Types

provider.score_changed
Fired when a provider's PepKey Trust Score changes by more than ±3 points. Useful for monitoring your provider network or alerting patients.
provider.created
Fired when a new provider is added to the PepKey directory. Use this to keep a local cache in sync or notify your team.
provider.claimed
Fired when a provider claims their listing. The claimed_at field is populated at this point.
provider.npi_verified
Fired when a provider's NPI number is successfully verified against the NPPES registry. The NPI fields are populated at this point.
provider.tier_changed
Fired when a provider moves between listing tiers (e.g. standard → verified, or verified → featured). Includes previous_tier and new_tier.

Webhook Payload

JSON — Webhook Payload Example
{
  "id": "evt_9x2b1c3d",
  "event": "provider.score_changed",
  "created_at": "2026-04-07T04:00:12Z",
  "data": {
    "provider_id": "prov_8f3a2c1b",
    "name": "Dr. Sarah Chen, MD — Pacific Wellness Institute",
    "previous_score": 82,
    "new_score": 87,
    "delta": 5,
    "reason": "New Google reviews boosted review score component"
  }
}

Signature Verification

Every webhook includes a X-PepKey-Signature header containing an HMAC-SHA256 signature of the raw request body using your webhook secret.

Python — Verify Webhook Signature
import hmac
import hashlib
import os
from flask import Flask, request, abort

app = Flask(__name__)
WEBHOOK_SECRET = os.environ["PEPKEY_WEBHOOK_SECRET"]

def verify_pepkey_signature(payload_bytes: bytes, signature: str) -> bool:
    expected = hmac.new(
        WEBHOOK_SECRET.encode(),
        payload_bytes,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(f"sha256={expected}", signature)

@app.route("/webhooks/pepkey", methods=["POST"])
def pepkey_webhook():
    sig = request.headers.get("X-PepKey-Signature", "")

    if not verify_pepkey_signature(request.get_data(), sig):
        abort(401, "Invalid signature")

    event = request.get_json()
    event_type = event["event"]

    if event_type == "provider.score_changed":
        provider_id = event["data"]["provider_id"]
        delta = event["data"]["delta"]
        print(f"Score changed for {provider_id}: {delta:+d} points")

    return {"received": True}, 200
💡
Respond quickly. PepKey expects a 2xx response within 5 seconds. For heavy processing, acknowledge the webhook immediately and handle it asynchronously (e.g. with a job queue).

Live API Explorer #

Try the API in real time. This calls the live PepKey API — no key needed for free tier queries.

Live Request
GET /api/providers
State: Results:
https://pepkey.org/api/providers?state=CA&per_page=3
Click ▶ Run to make a live API request...
🔓
The Live Explorer uses the Free tier (no API key). You'll see the base fields for each provider. Get a Starter or Pro key to unlock NPI data, score breakdowns, and more.

Plans & Pricing #

All plans include access to the full provider directory. Upgrade to unlock premium fields, higher rate limits, webhooks, and dedicated support.

Free
$0 /mo
Rate Limits
100 req / day
10 req / min
Data Access
Basic fields only
Up to 20 per page
Score endpoint
Stats endpoint
NPI data
Google reviews
Score breakdown
Webhooks
Clinic Tools
Patient app
Charting templates
Support
Community / docs
Starter Popular
$49 /mo
Rate Limits
5,000 req / day
60 req / min
Data Access
All free fields
Up to 100 per page
Score endpoint
Stats endpoint
NPI number + credential
Google review data
Score breakdown
Webhooks
Clinic Tools Coming Soon
Patient app access
Charting templates
Support
Email support
Pro
$149 /mo
Rate Limits
50,000 req / day
300 req / min
Data Access
All starter fields
Up to 500 per page
Score endpoint
Stats endpoint
Full NPI data
Google review data
Score breakdown
Webhooks (Pro+)
Clinic Tools Coming Soon
Pre-visit questionnaires
Auto-routing + inventory
Support
Priority email support
Featured
$299 /mo
Rate Limits
200,000 req / day
1,000 req / min
Data Access
All Pro fields
Unlimited per page
Score endpoint
Stats endpoint
Full NPI data
Google review data
Score breakdown
Webhooks + custom events
Clinic Tools Coming Soon
Full API access
Priority placement
Support
Dedicated Slack channel
💳
All plans are billed monthly. Cancel anytime. Annual billing available at 2 months free. Contact us for volume or enterprise pricing.

Changelog #

All notable changes to the PepKey API. We follow semantic versioning and maintain backward compatibility within major versions.

v2.1
April 2026
  • New POST /api/lead — Lead tracking endpoint for recording anonymous patient engagement events.
  • New GET /api/leads/{provider_id} — Aggregated lead stats for providers and Starter+ keys.
  • New /api/stats now includes peptide_profiles count (45 profiles) and updated totals (7,300+ providers, 310 NPI verified).
  • New Clinic API endpoints previewed (Coming Soon): /api/clinic/register, /api/clinic/patients, /api/clinic/backup.
  • New Patient App API endpoints previewed (Coming Soon): /api/patient/login, /api/patient/meds, /api/patient/dose-log.
  • Improved Pricing updated: Featured tier now $299/mo with API access + priority placement. Starter/Pro include clinic tool access.
v2.0
March 2026
  • New Introduced score_breakdown and score_summary fields (Pro+). Per-dimension trust score explanations.
  • New Added /api/providers/{id}/score endpoint — available on Free tier for all providers.
  • New Webhooks launched for Pro and Featured plans. Five event types: score_changed, created, claimed, npi_verified, tier_changed.
  • New accepts_telehealth and consultation_types fields added to Starter+.
  • New npi_name and npi_specialty fields added to Pro tier from NPPES taxonomy.
  • Improved /api/search now supports a state filter parameter.
  • Improved Pagination meta object now includes has_next and has_prev boolean fields.
  • Improved Rate limit headers are now included in all responses, including 429s.
  • Breaking The reviews field has been renamed to google_review_count. The old field will be removed in v3.0.
  • Breaking The rating field has been renamed to google_review_score.
v1.0
March 2026
  • New Initial public API launch. Endpoints: /api/providers, /api/providers/{id}, /api/stats, /api/search.
  • New Free, Starter, and Pro tiers with tiered field access.
  • New 7,300+ providers across all 50 US states at launch.
  • New PepKey Trust Score (0–100) based on NPI verification, Google reviews, claimed status, and content completeness.
  • New NPI verification against the NPPES registry — automated nightly checks.