ZevAuth
Sign up

API reference

Member attestation

For Zev partners: attest that a signed-in member is a verified member — student, professional or builder — through Zev Access.

Member attestation lets a partner organization tell Zev who one of their members is, so every Zev product can offer that member the benefits of Zev Access. A partner attests its verified members — today student, professional and builder.

Before it works

Three conditions, all enforced on Zev’s side. Attestation is refused, with a message saying which, until every one holds:

  1. Your workspace is enrolled in a program. A Zev admin enables it for an approved partner. Nothing you can do in the console turns it on.
  2. Your app is a verified Sign-in app. The same domain and entity verification behind going live. Attestation pauses if that verification lapses, and resumes when it is restored.
  3. The member has connected with ZevID. They complete Sign in with ZevID and approve the consent screen. Only then can you attest them. An account that exists only in your own database cannot be attested.

Where to find the accountId

accountId is the member’s ZevID account UUID — the identifier ZevID issued for the person, not one you invent. After a member signs in with ZevID, it appears on their user in this API, under externalAccounts, on the entry whose provider is zevid:

curl https://api.zevauth.net/v1/users/user_123 \
  -H "Authorization: Bearer sk_live_..."
{
  "id": "user_123",
  "email": "member@example.com",
  "externalAccounts": [
    {
      "provider": "zevid",
      "providerAccountId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
      "email": "member@example.com",
      "verified": true,
      "revoked": false
    }
  ]
}

Pass that providerAccountId as accountId. ZevID rejects any other format (for example an old zid_... string) with a 400.

Test and live

Attestation is live only. It writes a real fact onto a real ZevID account that every Zev product reads, so there is no test form: a test key calling these endpoints is refused before the request leaves ZevAuth, with a message saying so. Build and rehearse the member’s sign-in in your test environment as usual; attest them only from your live app once it is verified.

Attest

POST /v1/partner/affiliations/attest

Server-side only, with your secret key. You send who the member is; you never send which workspace they belong to. That is taken from your key.

curl -X POST https://api.zevauth.net/v1/partner/affiliations/attest \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "accountId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
    "memberRef": "MEMBER-2023-0451",
    "attributes": { "matriculationYear": 2023, "graduationYear": 2027, "institution": "Example University" }
  }'
FieldRequiredMeaning
accountIdyesThe member’s ZevID account UUID, from their zevid entry in externalAccounts (see above).
memberRefnoYour own member identifier. Stored for you; never shown to products or other partners.
typenoWhich program to attest, if your workspace holds more than one. Omit it when you have one.
attributesnoProgram facts. Conventions are per program type, below.
expiresAtsometimesISO 8601 end date. Optional when a graduationYear or your program default supplies one; required otherwise. See End dates.

Re-attesting the same member refreshes their attributes and expiry, and reactivates a lapsed one. When your workspace runs a single program, its type is inferred and you can leave type out; send it only when the workspace holds more than one.

End dates

Every affiliation has an end date, so benefits expire on their own rather than lingering. The date comes from the first of these that applies: the expiresAt you send, a graduationYear in attributes (for students), or your program’s default. If none of them does, the attest is refused with a 400 — send an expiresAt.

Your program also has a maximum membership length, agreed with Zev and measured from the member’s first attestation (for example four years). Send shorter end dates freely; a date beyond the maximum is refused with a 400 that names the member’s last allowed date. Re-attesting does not extend it, even after a revoke and a re-attest.

Attribute conventions

TypeAttributes
studentmatriculationYear, graduationYear, institution
professionalWhatever your agreement defines.
buildertier (member or lead), chapter, role

Revoke

POST /v1/partner/affiliations/revoke

The member left, was removed, or their membership lapsed. Revoking is allowed even while a program is suspended, because reducing access is never blocked.

curl -X POST https://api.zevauth.net/v1/partner/affiliations/revoke \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "accountId": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d" }'

As with attest, add type only if your workspace holds more than one program.

Reporting

GET /v1/partner/affiliations/report

Totals for your program, computed by ZevID. Server-side only, with your secret key; the workspace is taken from the key, so you only ever see your own numbers.

curl https://api.zevauth.net/v1/partner/affiliations/report \
  -H "Authorization: Bearer sk_live_..."
{
  "attested": 1240,
  "active": 1097,
  "claimedAtLeastOne": 823,
  "claimsByOffer": [
    { "offerKey": "spotify", "title": "Spotify Premium", "claims": 611 }
  ],
  "activeOverTime": [
    { "month": "2026-08", "active": 1042 },
    { "month": "2026-09", "active": 1097 }
  ]
}

Add ?type=<program> to narrow to one program when your workspace holds more than one; omit it when you have a single program.

What attestation is not

An affiliation is a fact Zev stores about a person, read by Zev products. It is not a role, an organization, or user metadata in your own ZevAuth project, and it does not appear in your users’ tokens. If you need your own authorization data, use organizations or publicMetadata; those are yours. Attestation is for the Zev-wide member benefits your partnership is about.

Offers, packs and the claiming of them all live in ZevID and on the member’s ZevID account — ZevAuth does not model them. See Zev Access.

The member sees their affiliations on their ZevID account and can remove any of them; benefits expire on their own at the attested expiry.

Updated at, Wednesday, October 21, 2026