Skip to main content
Every GET /v1/me response carries a membership block. It exists for one job: letting you decide whether to show this crew member an upgrade prompt.
It rides on the profile:read scope you already hold. No reconsent, no new scope, nothing to migrate.

Fields

source values

Gating an upgrade prompt

Branch on tier. Nothing else.
Don’t infer membership from anything else. Not from the presence of sea-time, not from vessel history, not from source. Vessel-covered Premium in particular is computed from the yacht’s subscription and its crew list — it is never a flag on the member’s own record, and any heuristic you build will report those crew as Free.

When we can’t tell you

If DSS cannot resolve membership, /v1/me returns service_unavailable (503) — never a tier of "free". Treat a failed call as unknown, not as Free: leave the prompt hidden and retry with backoff. Falling back to “show the upgrade prompt” puts it in front of members who are already paying, which is the failure this field exists to prevent.
If you run a sponsorship program, a member you have provisioned reads back as:
expires_at is the end of that member’s 12-month term. It is the same value the roster reports for the seat, so you can use either — the roster for bulk reconciliation, membership for a single member on a page render.
We never name another partner’s sponsor. A member sponsored by someone else reads as "source": "sponsored" with sponsored_by_you: false, expires_at: null, and no partner name. You learn that the member is covered — which is all you need to suppress the prompt — and nothing about who covers them.

Membership is not entitlement to act

membership tells you what to render. It is not an authorization decision and it does not change what your token can read: scopes still govern that, and a Free member’s sea-time is just as readable as a Premium member’s.