Resources

Plans

Browse the HMO plan catalogue. Every plan is returned in the Universal Plan Schema, regardless of the source HMO's internal format.

Plans are the browseable inventory. Use GET /v1/plans for a paginated, filterable list and GET /v1/plans/:id for a single plan's detail. For personalised ranking against a specific user profile, use POST /v1/quotes instead.

Requires an API key with the insurance:read scope. Legacy keys without an explicit scope list are granted all scopes for backwards compatibility.

List plans#

GET/v1/plans

Returns active plans across every HMO Pierflow has currently distributing. Cursor-paginated; default page size 50, max 200.

Query parameters

ParameterDescription
cursorPagination cursor from a previous response.
limitPage size, 1–200. Defaults to 50.
statusDRAFT | ACTIVE | WITHDRAWN. Defaults to ACTIVE.
scopeINDIVIDUAL | FAMILY | EMPLOYEE_GROUP | STUDENT | OTHER.
provider_slugRestrict to one HMO (e.g. reliance-hmo).
stateUser's state — filters plans without coverage there.
lgaUser's LGA. Used alongside state.
max_monthly_premium_ngnMaximum monthly premium in NGN minor units (kobo).
age_in_yearsDrops plans whose age bands don't cover this age.
bash
bash
curl https://sandbox.api.pierflow.com/v1/plans?scope=INDIVIDUAL&max_monthly_premium_ngn=1000000&age_in_years=28 \
  -H "Authorization: Bearer $PIERFLOW_KEY"

Response

200 OK
json
{
  "items": [
    {
      "id": "plan_b3f9c21a",
      "external_id": "REL-SILVER-IND",
      "name": "Silver Plan",
      "scope": "INDIVIDUAL",
      "status": "ACTIVE",
      "billing_frequency": "MONTHLY",
      "hmo": { "slug": "reliance-hmo", "name": "Reliance HMO" },
      "pricing": {
        "individual_monthly": 850000,
        "age_bands": [
          { "min_age": 18, "max_age": 35, "monthly": 850000 },
          { "min_age": 36, "max_age": 50, "monthly": 1100000 }
        ]
      },
      "coverage": {
        "outpatient":   { "covered": true, "limit": 20000000, "co_pay_percent": 0 },
        "inpatient":    { "covered": true, "limit": 100000000, "co_pay_percent": 10 },
        "maternity":    { "covered": true, "limit": 30000000, "waiting_period_days": 270 },
        "dental":       { "covered": false },
        "telemedicine": { "covered": true, "unlimited": true }
      },
      "exclusions": ["HIV/AIDS treatment", "Cosmetic surgery"],
      "waiting_periods": { "general": 30, "maternity": 270, "pre_existing": 365 },
      "last_synced_at": "2026-06-08T08:00:00.000Z",
      "last_verified_at": "2026-06-08T07:55:00.000Z",
      "is_stale": false
    }
  ],
  "next_cursor": "plan_xyz123"
}
Money is always in NGN minor units (kobo). 850000 kobo = ₦8,500. The same convention applies to every monetary field across the API.

Retrieve a plan#

GET/v1/plans/:planId

Same shape as a single item in the list response. Returns 404 if the plan belongs to an HMO that isn't currently distributing — suspended or pending providers are hidden.

bash
bash
curl https://sandbox.api.pierflow.com/v1/plans/plan_b3f9c21a \
  -H "Authorization: Bearer $PIERFLOW_KEY"

Freshness#

Every plan carries three time signals so the fintech UI can show honest data:

FieldMeaning
last_synced_atWhen the HMO last pushed this plan to Pierflow.
last_verified_atWhen Pierflow last asked the HMO to re-confirm the plan is unchanged. Present after a live verify call.
is_staleTrue when the soft TTL has elapsed since the last sync. Surface a 'data may be stale' hint when true.

For binding actions — enrollment, locking a quote — Pierflow performs a live verification with the HMO before proceeding. Browse responses use the cached view; quote responses freeze numbers for 24 hours.