Benefily

API documentation

One question, answered deterministically: does a Medicare Part D payer require prior authorization for a drug? Every response carries the CMS citation behind it.

Try it with no account. The sandbox key ben_test_sandbox reads the same real corpus, is rate limited to 20 requests per minute, and is never billed.

Quickstart

curl "https://benefily.com/api/v1/check?payer=humana&drug=Ozempic" \
  -H "x-api-key: ben_test_sandbox"

Returns:

{
  "result": {
    "status": "required",
    "summary": "Humana requires prior authorization for Ozempic on all 817 of its Medicare Part D plans that cover it.",
    "payer": { "slug": "humana", "name": "Humana" },
    "drug": { "rxcui": "2398842", "brand": "Ozempic", "ingredient": "semaglutide" },
    "coverage": {
      "payer_plan_count": 817,
      "covering_plan_count": 817,
      "prior_auth_plan_count": 817,
      "step_therapy_plan_count": 0,
      "quantity_limit_plan_count": 817,
      "tiers": ["3"]
    },
    "plans": [ /* per-plan breakdown */ ],
    "citation": {
      "document_title": "Monthly Prescription Drug Plan Formulary…",
      "url": "https://data.cms.gov/…",
      "effective_date": "2026-06-30",
      "source_sha256": "e626e6bc…"
    },
    "notices": []
  }
}

Values above are illustrative of the response shape; run the call to see live numbers.

The five statuses

Reading these correctly is the whole job. Two of them are commonly misread.

required
Every plan from this payer that covers the drug requires authorization.
not_required
No covering plan files a prior-authorization requirement.
varies
Requirements differ across the payer’s plans. The member’s specific plan decides — the contract number is on their card.
not_on_formulary
The drug is on none of that payer’s formularies, so it is not covered. This is generally worse for the patient than needing authorization, and it must never be reported as “no prior authorization required”.
unknown
We hold no filing. This never means authorization is unnecessary.

Authentication

Pass a key as x-api-key or Authorization: Bearer …. Keys are minted at /dashboard/keys and are shown once. Test-mode keys (ben_test_…) never consume billable quota.

Programmatic access requires Pro (20,000 calls per month). The sandbox key is the deliberate exception so an agent can evaluate before anyone pays.

Endpoints

GET/api/v1Catalogue and corpus provenance. No key required.
GET/api/v1/checkCheck one drug against one payer.
POST/api/v1/checkCheck up to 100 drugs against one payer (Pro).
GET/api/v1/payersValid payer slugs.
GET/api/v1/drugsResolve a name to RxNorm products.
GET/api/v1/pricingMachine-readable pricing. No key required.

Bulk:

curl -X POST "https://benefily.com/api/v1/check" \
  -H "x-api-key: YOUR_KEY" \
  -H "content-type: application/json" \
  -d '{"payer":"humana","items":[{"drug":"Ozempic"},{"drug":"Trulicity"}]}'

Errors

Every failure carries a stable code, a human message, and — where you could plausibly recover — a details object naming exactly what to do differently.

{
  "error": {
    "code": "upgrade_required",
    "message": "Programmatic API and MCP access is a Pro feature…",
    "details": {
      "required_plan": "pro",
      "upgrade_url": "/pricing",
      "sandbox_key": "ben_test_sandbox"
    }
  },
  "request_id": "req_…"
}

An unknown path returns the list of real endpoints rather than a bare 404, so a wrong guess is recoverable in one step.

Rate limits

Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset; a 429 adds Retry-After. Sandbox 20/min, free keys 60/min, Pro 600/min.

Machine-readable surfaces

Administrative information only. Benefily reports what a payer has published in its own prior-authorization policy as of the effective date shown. It is not medical advice, not a coverage or payment guarantee, and not an authorization. Requirements vary by plan, place of service and member benefits — always verify with the payer before rendering service.