Skip to content

Team and prescriber access

Invite people, manage practice access, and maintain prescriber profiles and licenses.

Updated View as Markdown

A practice key manages its practice. A platform key manages its connected practices. Use team:read for discovery and team:write for changes.

Team has one overview and three collections. All collection endpoints support cursor pagination.

Endpoint Purpose
GET /v1/practices/{practiceId}/team Counts of members, invitations, and prescribers
GET /v1/practices/{practiceId}/team/members Account roster, roles, location access, and prescriber connections
GET /v1/practices/{practiceId}/team/prescribers Clinical profiles and licenses, with state and review filters
GET /v1/practices/{practiceId}/team/invitations Invitations and your integration’s onboarding state

Memberships and clinician credentials are shared between Test and Live. A Test key can change the same Team records as a Live key. Use synthetic practices and people when testing Team changes. Your integration’s external identities remain separate for each mode.

Invite a person

Send Invite team member from your backend.

{
  "externalId": "provider_48291",
  "email": "jamie@example.test",
  "name": "Avery All-States Test",
  "role": "prescriber",
  "npi": "1234567893"
}

This example uses synthetic Test identity data. Replace it with the intended person for a Live invitation.

Choose owner, administrator, prescriber, or tester directly. You do not need to discover a role ID first. The reference includes optional profile and license fields.

Store person.id and person.invitation.id from the response. Reuse externalId and the same person details when retrying creation. An accepted invitation does not change existing access.

The recipient accepts with their verified Affinity account. An NPI identifies a clinician; it does not authenticate an account.

Track invitations

Use List invitations with externalId=provider_48291 to find your integration’s invitation. You can also filter by exact email or status: pending, expired, accepted, or revoked. Use Get invitation to follow one invitation and its person.nextActions.

  • Resend invitation keeps the same invitation ID and replaces the previous link.
  • Revoke invitation prevents acceptance and preserves history.
  • An accepted invitation requires a member access update instead of revocation.

Resend supports pending and expired invitations. The new link expires in seven days. If delivery returns 502, the invitation remains saved. Retry resend after resolving the delivery error.

The directory includes invitations sent from Clinic. Their userId, externalId, and person are null unless they belong to your integration and mode.

Manage locations

Use List locations to find each practice site’s name and loc_* identifier. Use status=active when selecting locations for a new Team invitation.

Create location adds a site with a unique name. Timezone is optional; omit it unless an integration needs an explicit override. Read location returns one site’s current details. Update location changes supplied fields and preserves omitted fields. Archive location retains the site and its historical associations.

Reads require locations:read. Writes require locations:write and Idempotency-Key. Add these scopes to a new practice or platform key in the dashboard. Existing keys do not gain these permissions automatically. Locations are shared between Test and Live for the same practice.

Manage member access

Use List members to search names or email addresses with search. Filter with role and status=active or status=disabled. Get member returns one member’s current access and account connection.

Send Update member access with the fields you want to change:

{
  "role": "administrator",
  "locationIds": [],
  "status": "active"
}

A supplied role replaces existing role assignments. Omitted fields stay unchanged. An empty locationIds array grants all practice locations. Use List locations to find location names and IDs. Supply active location IDs to restrict access to selected practice locations.

Set status to disabled to revoke practice access while preserving clinical records. Set it to active to restore access. Ownership changes require an active owner’s personal API key or a Clinic session. An owner must stay active with access to all locations. Promote another active owner before demoting the final owner.

Sign-in email, passwords, and account security remain in the person’s Affinity account settings.

Find prescribers

Use List prescribers with these filters:

Filter Values
search Part of the display name or legal name
npi Exact NPI
state Two-letter license state, such as TX
status Practice connection: active or inactive

Get prescriber returns the clinical profile and all submitted licenses, including their IDs. License records are optional clinician profile information. Signing requires an active account connection, Live practice access, and prescription eligibility; missing license records do not block headless or Clinic signing. The practice or EMR remains responsible for clinician credential verification.

Update a profile or license

Profile and license changes require an active, accepted prescriber account connection and active membership in the practice. A pending invitation alone cannot authorize edits to the clinician’s shared records.

Use Update prescriber for displayName, legalName, credentials, phone, or address. Omitted fields stay unchanged. NPI is immutable.

Use Add license to submit a state, license number, and optional future expiration. An exact repeat returns the existing license.

Use Update license with the license ID to correct details or renew its expiration:

{
  "expiresAt": "2030-12-31T23:59:59.000Z"
}

This updates only that license. Other licenses stay unchanged.

Clinical profiles and licenses are shared across every practice connected to that clinician. A change affects those practices in both Test and Live.

Use the correct identifier

Identifier Use
Invitation response person.id, or invitation userId Your integration’s mode-scoped person, used by orders after acceptance
Member id, or invitation memberId Manage access to this practice
Prescriber id Read or update the clinician’s clinical profile
License id Update one submitted license

A member ID or prescriber ID cannot substitute for the integration user ID. Each clinician needs a registered or accepted identity and current practice access.

Register without an invitation

Use POST /v1/practices/{practiceId}/users with team:write, Idempotency-Key, and identityAttestation: true. Supply a stable externalId, name, email, and role. Prescribers require an NPI. The returned id is the integration userId; memberId manages practice access. Registration preserves existing memberships and never restores disabled access.

A pending invitation by itself does not authorize API signing. The identity must have either an accepted invitation or a separate API registration, plus active practice and prescriber access. A clinician registered through the API can sign headlessly while a separate dashboard invitation is still pending. Invitation acceptance is not an additional gate for that registered identity.

Test registrations require synthetic .test emails and Affinity Test NPIs. Live requires approved integration and practice access. The practice is responsible for the NPI and license information it submits.

Sign an order

Your platform authenticates the clinician and collects their attestation to the complete order. Use the headless signing workflow with orders:sign. No Affinity login is required. Affinity checks current access, prescribing authority, and exact versions.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close