SnapRx SnapRx
  • Features
  • How It Works
  • Pricing
  • FAQ
Download App

API Documentation

Base URL: https://api.snaprx.co

Overview

The SnapRx API is a RESTful JSON API built with FastAPI. All endpoints return JSON responses. Authentication uses JWT bearer tokens. Most public endpoints (search, prices, coupons, recalls) work without authentication.

Format

JSON (application/json)

Auth

Bearer Token (JWT)

Rate Limit

60 req/min global; per-route limits vary

Versioning

URL path (/v1/)

System

GET /health

Health check. Returns API version.

GET /health/ready

Readiness probe. Verifies database and Redis connectivity.

Authentication

Auth endpoints use the /auth prefix (no /v1). All authenticated endpoints require a Bearer token in the Authorization header:

Request Header
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
POST /auth/register

Create a new user account. Password requires 8+ chars, uppercase, lowercase, and digit.

Request Body
{
  "email": "user@example.com",
  "password": "SecurePass1",
  "full_name": "Jane Doe",
  "zip_code": "10001",
  "timezone": "America/New_York"
}
Response 201
{
  "user": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "email": "user@example.com",
    "full_name": "Jane Doe",
    "zip_code": "10001",
    "timezone": "America/New_York",
    "is_verified": false,
    "created_at": "2026-03-05T12:00:00Z"
  },
  "access_token": "eyJhbGciOi...",
  "refresh_token": "eyJhbGciOi...",
  "token_type": "bearer"
}
POST /auth/login

Authenticate and receive access + refresh tokens. Rate limited: 10/min.

Response 200
{
  "access_token": "eyJhbGciOi...",
  "refresh_token": "eyJhbGciOi...",
  "token_type": "bearer",
  "expires_in": 1800
}
POST /auth/refresh

Exchange a refresh token for a new access token.

POST /auth/oauth

Authenticate via Google or Apple OAuth. Provide provider ("google" or "apple") and provider_token.

POST /auth/logout

Revoke the current refresh token. Requires authentication.

POST /auth/forgot-password

Request a password reset email. Always returns 200 to prevent email enumeration.

GET /auth/me

Get the current authenticated user's profile. Requires authentication.

Drugs & Search

GET /v1/drugs/search?q={query}

Search for medications by name. Uses spell correction, pg_trgm fuzzy matching, and RxNorm API fallback. q must be at least 2 characters. No authentication required.

Response 200
{
  "query": "metformin",
  "corrected_query": null,
  "results": [
    {
      "id": "8939a932-4b0a-41c8-bd6e-...",
      "name": "Metformin",
      "generic_name": "metformin",
      "brand_names": ["Glucophage"],
      "manufacturer_type": "generic",
      "drug_class": "Biguanide",
      "form": "tablet",
      "dosage": "500mg",
      "rxcui": null
    }
  ],
  "total": 1
}
GET /v1/drugs/autocomplete?q={query}

Fast autocomplete suggestions for drug names. Returns up to 10 suggestions.

GET /v1/drugs/{drug_id}

Get detailed drug information including uses, side effects, warnings, contraindications, available dosages, and storage instructions. drug_id must be a UUID.

GET /v1/drugs/{drug_id}/label

Get the full FDA label information for a drug from openFDA.

Price Comparison

GET /v1/prices/compare?name={drug_name}&quantity={qty}

Compare pharmacy prices for a medication. Provide at least one of: drug_id (UUID), name (string), or ndc (string). Optional: quantity (default 30), location (ZIP code), include_mail_order, include_membership.

Response 200
{
  "drug": {
    "id": "8939a932-...",
    "name": "Metformin",
    "generic_name": "metformin",
    "dosage": "500mg",
    "form": "tablet"
  },
  "quantity": 30,
  "days_supply": 30,
  "prices": [
    {
      "pharmacy": {
        "id": "c5b90b53-...",
        "slug": "cvs",
        "name": "CVS Pharmacy",
        "pharmacy_type": "RETAIL"
      },
      "price": "3.60",
      "retail_price": "29.69",
      "price_type": "coupon",
      "savings_pct": 87.8
    }
  ],
  "lowest_price": "3.60",
  "highest_price": "36.29",
  "potential_savings": "32.69",
  "total_pharmacies": 5
}
GET /v1/prices/best?name={drug_name}&quantity={qty}

Get just the single best price for a drug.

GET /v1/prices/pharmacies

List all pharmacy chains with pricing data. Supports pharmacy_type filter (RETAIL, MAIL_ORDER, ONLINE).

Coupons

GET /v1/coupons/search?drug_name={name}&quantity={qty}

Search for available coupons. Provide drug_name or drug_id. Optional: quantity (default 30), source (goodrx, singlecare, rxsaver).

Response 200
{
  "drug_name": "Metformin",
  "drug_id": "8939a932-...",
  "quantity": 30,
  "coupons": [
    {
      "id": "b9939129-...",
      "source": "goodrx",
      "coupon_type": "discount_card",
      "bin_number": "015995",
      "pcn": "GDC",
      "group_number": "GDC10406",
      "member_id": "GOO00100406",
      "price": "3.23",
      "retail_price": "32.30",
      "savings_pct": 90.0,
      "pharmacy": { "name": "Costco Pharmacy" }
    }
  ],
  "lowest_price": "3.23",
  "potential_savings": "29.07",
  "total": 21
}
GET /v1/coupons/{coupon_id}

Get details for a specific coupon.

POST /v1/coupons/saved

Save a coupon to your wallet. Requires authentication.

Drug Interactions

POST /v1/interactions/check

Check drug-drug interactions for a list of medications. Rate limited: 20/min.

Request Body
{
  "drugs": ["warfarin", "aspirin"]
}
Response 200
{
  "medications_checked": ["warfarin", "aspirin"],
  "total_interactions": 1,
  "interactions": [
    {
      "drug_a": "Warfarin",
      "drug_b": "Aspirin",
      "severity": "major",
      "description": "Increased bleeding risk. NSAIDs inhibit platelets.",
      "clinical_effects": "May increase anticoagulant effect and hemorrhage risk.",
      "management": "Avoid combination. Monitor INR if necessary.",
      "source": "fda"
    }
  ],
  "critical_alerts": [...],
  "severity_counts": { "major": 1, "moderate": 0, "minor": 0 },
  "risk_level": "high"
}
GET /v1/interactions/quick?drug_a={name}&drug_b={name}

Quick check for interactions between two specific drugs.

Pharmacies

GET /v1/pharmacies/nearby?zip_code={zip}&radius_miles={mi}

Search for pharmacies near a location. Provide either zip_code or latitude/longitude. Optional: radius_miles (default 10, max 100), pharmacy_type (retail, mail_order, online, 24hr), limit (default 20).

GET /v1/pharmacies/chains

List all active pharmacy chains with location counts and website URLs.

GET /v1/pharmacies/{pharmacy_id}

Get detailed info for a specific pharmacy location.

FDA Recalls

GET /v1/recalls/?drug_name={name}

Search FDA enforcement recalls by drug name. Data sourced from openFDA in real-time. Optional: limit (default 10).

GET /v1/recalls/check/{drug_name}

Check if a specific drug has any active (Ongoing) FDA recalls. Returns has_active_recall boolean and list of active recalls.

Bottle Scanning

POST /v1/scan/bottle

Scan a prescription bottle label. Provide image_base64 (base64-encoded image) or raw_text (OCR text). Uses Google Cloud Vision with Tesseract fallback. Rate limited: 10/min.

Response 200
{
  "success": true,
  "drug_name": "LISINOPRIL",
  "dosage": "10 MG",
  "form": "tablet",
  "quantity": 30,
  "directions": "Take 1 tablet by mouth once daily",
  "ndc": "68180051401",
  "matched_drug": {
    "id": "7fdcbac4-...",
    "name": "Lisinopril"
  },
  "confidence": 0.87,
  "warnings_detected": []
}
POST /v1/scan/pill

Identify a pill by imprint, color, and shape. imprint is required. Optional: color, shape.

Response 200
{
  "success": true,
  "matches": [
    {
      "drug_name": "Oxycodone/Acetaminophen",
      "strength": "10/325 mg",
      "manufacturer": "Mallinckrodt",
      "imprint": "M523",
      "color": "white",
      "shape": "oval",
      "ndc": "00406-0523",
      "confidence": 0.70,
      "image_url": "https://data.lhncbc.nlm.nih.gov/..."
    }
  ]
}
GET /v1/scan/pill/suggest?q={imprint_query}

Autocomplete pill imprints. Returns suggestions matching the query with drug name, strength, color, shape, and manufacturer.

Medications Cabinet

GET /v1/medications

List all medications in the user's cabinet. Requires authentication.

POST /v1/medications

Add a medication to the user's cabinet with dosage schedule. Requires authentication.

Compliance & Legal

GET /v1/compliance/controlled-substance/{dea_schedule}

Get controlled substance restrictions for a DEA schedule (I through V). Public endpoint.

GET /v1/legal/documents

List the current version of every legal document. Public endpoint.

GET /v1/legal/documents/{type}

Get a specific legal document. Valid types: tos, privacy_policy, hipaa_notice, discount_card_terms, arbitration_agreement.

App & Waitlist

POST /v1/app/version-check

Check if the client app version requires an update. Fields: platform ("ios" or "android"), current_version (semver string).

POST /v1/waitlist

Join the waitlist. Provide email in the request body.

Error Responses

All errors follow a consistent envelope format:

Error Response
{
  "error": {
    "type": "invalid_request_error",
    "code": "validation_error",
    "detail": "Human-readable error message",
    "errors": [
      { "field": "body.email", "message": "Field required" }
    ]
  }
}
Status Code Meaning
400Bad Request — invalid input or missing required parameters
401Unauthorized — missing or invalid token
403Forbidden — insufficient permissions
404Not Found — resource doesn't exist
409Conflict — resource already exists
422Validation Error — request body schema validation failed
429Too Many Requests — rate limit exceeded (Retry-After header included)
500Internal Server Error

Rate Limiting

Rate limit headers are included in every response:

Rate Limit Headers
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 42
X-RateLimit-Reset: 1711000000
Scope Limit
Global (all endpoints)60 req/min per IP
Auth: register5 req/min per IP
Auth: login10 req/min per IP
Auth: forgot-password3 req/min per IP
Interactions: check20 req/min per IP
Scan: bottle, pill10 req/min per IP
SnapRx SnapRx

Smarter medication management for everyone.

Product

  • Features
  • Compare
  • Download

Resources

  • FAQ
  • API Docs
  • Status

Legal

  • Privacy Policy
  • Terms of Service
  • HIPAA Notice

© 2026 SnapRx. All rights reserved.