How partners integrate with us

Plansight's outbound REST API. Where the other integrations on this site are inbound — Plansight reading from external systems — the Open API is the inverse: partner systems calling into Plansight for read access to employer and plan data.

Direction: Outbound Auth: Bearer token Status: Production · Read-only Docs: SwaggerHub ↗ (Trevor's spec)
What it is

The public surface of the Plansight platform

Token-authenticated REST API that lets brokers' downstream systems (carriers, BI tools, broker-built dashboards) query employer and plan data programmatically. Read-only today; brokerage-isolated; throttled.

v1
URL-prefixed version (/v1/)
5
Data endpoints + healthcheck
100/min
Rate limit per token (Laravel throttle:100)
ES
Elasticsearch-backed employer search
🔑

Bearer token auth

Tokens generated in Plansight UI under Settings → Brokerage Info → API Keys. Token is a composite of brokerageId + apiToken — looking up by token also identifies the brokerage in one query.

🏢

Brokerage-isolated

Every query filters by the authenticated user's brokerageId. No way to see another brokerage's data even with a valid token. Cross-brokerage data leakage is not possible by design.

🔍

Search via Elasticsearch

The employer list endpoint queries Elasticsearch (not raw DB) so partners can search by name, tax ID, or partial match without needing exact identifiers.

Endpoints

The API surface

Five data endpoints plus a healthcheck. All under /v1/.

GET
/v1/healthcheck
Returns 200 OK. Used by partners to verify auth and connectivity.
GET
/v1/employer
List brokerage's employers. Optional filters: id, taxId, name, page, perPage. Default 10/page; max 100.
GET
/v1/employer/{groupId}/planTypes
Returns the list of insurance types (medical, dental, vision, life, etc.) that this employer has plan history for.
GET
/v1/employer/{groupId}/plans/{planType}
List all plans of a given type for an employer. Returns plan name, carrier, in-force dates, status, and custom fields.
GET
/v1/swagger/{planType}
Returns the field schema and metadata for a given plan type. Partners consume this to understand the shape of plan data per insurance line.

Read-only by design

The API is currently read-only — no POST / PUT / DELETE endpoints. Partners can pull data into their systems, but writes to Plansight remain through the UI and the inbound integrations (BenefitPoint, Employee Navigator). Adding write support is feasible but hasn't been needed by current partners.

Wiring

Authentication & connection

SettingValue / Source
Auth schemeBearer token in Authorization: Bearer {token} header
Token formatComposite of brokerageId + apiToken from the ApiToken table
Token storageapp/Models/ApiToken.php — DynamoDB composite keys, indexes on id and carrierId
Token issuancePlansight UI: Settings → Brokerage Info → API Keys
Rate limitLaravel throttle:100 middleware (100 requests/minute per token)
VersioningURL prefix /v1/. No deprecation policy formalized yet.
OpenAPI specswagger-api.json at repo root — manually maintained, not auto-generated
Codebase

Where it lives in the Plansight repo

FilePurpose
routes/api.php:15–236 API routes — healthcheck + 5 data endpoints
app/Http/Controllers/ApiController.php:42–85Pagination validator — extracts page/perPage with defaults
app/Http/Controllers/ApiController.php:87–192employerList() — Elasticsearch query builder, search filters, result mapping
app/Http/Controllers/ApiController.php:194–240+employerPlanTypes() and employerPlans() handlers
app/Models/ApiToken.php:10–14Token model — composite key (brokerageId + apiToken), DynamoDB indexes
app/Models/Group.phpapiAttributes + apiModel() method for API response mapping
swagger-api.jsonOpenAPI 3.0 spec — describes every route, params, response schema
app/Http/Controllers/RestController.phpGeneric REST CRUD base — used for internal admin APIs, not the public Open API

Notable design choices

Composite token = brokerage identity

Token is not a simple UUID but a concatenation of brokerageId + apiToken. Looking up a token also identifies the brokerage in one DynamoDB query. Slightly unusual but efficient.

Elasticsearch for search, not DB

The employer list endpoint queries Elasticsearch rather than the primary database — supports flexible name/taxId matching and faceted filtering. Trade-off: ES needs to stay in sync with employer data.

Manual OpenAPI spec

The swagger-api.json is hand-maintained, not generated from code. Keeps full control over what's exposed but creates a sync risk — endpoints can drift from spec if maintenance lapses.

Swagger endpoint per plan type

/v1/swagger/{planType} dynamically returns field metadata for the given plan type. Partners consume it programmatically rather than hardcoding the field list. Resilient to plan-type schema changes.

Things to verify

Items worth a developer's review

Strategic questions and edge cases more than code-level bugs. The API works in production; these are areas worth a product / platform decision when partners start putting more load on it.

🔒

Any authenticated broker user can mint an API token — no admin gate

app/Http/Controllers/Rest/App/ApiTokenController.php at line 34 (the create() method) calls auth()->user() and proceeds to mint a token without checking the user's role beyond the broker/carrier branch on lines 47-55. Today, any broker-side user with a Plansight session can POST /rest/app/apiToken and receive a working API token scoped to their entire brokerage. There's no "Brokerage Admin" role check. The intended behavior is that only Plansight admins (or at minimum brokerage admins) should be able to create tokens for their org. Worth adding a role guard at the top of create() + delete().

Security gap
📋

No deprecation strategy beyond URL prefix

API is at /v1/ but no formal policy for sunsetting endpoints, breaking changes, or v2 migration. Partners may build assumptions that constrain future changes. Worth defining a versioning + deprecation policy.

Strategic
📤

Read-only — no create / update endpoints

Partners can pull but not push. Limits use cases (e.g., a partner can't sync changes back to Plansight via API). Adding write support is feasible if a partner has a real need.

By design
🔔

No webhook / subscription model

All data fetches are polling. High-volume partners will hit rate limits or incur latency keeping data current. A webhook surface for "employer updated" / "plan changed" events would scale better.

Future
📐

swagger-api.json may drift from code

Manual spec maintenance creates drift risk. Worth considering: generate the spec from route annotations, OR make the spec the source of truth with code generation. Either reduces ongoing reconciliation.

Maintenance
📊

No usage analytics or metering

Tokens are issued, but no per-token usage tracking, no analytics dashboard, no billing model. As partner adoption grows this becomes increasingly important — both for capacity planning and for any future tiered access.

Future
⚠️

Error responses sparse in OpenAPI

Spec covers 200 / 401 / 422 but not 5xx specifics or domain errors. Partners building robust integrations need richer error documentation.

Note