Invite team member
/v1/practices/{practiceId}/team/invitationsRequires team:write on the practice key or its platform key. Use roles to combine administrator, prescriber, clinical_staff, billing, or developer presets. Ownership uses the protected owner designation. The singular role field remains available for single-role assignments. Creates a real organization invitation and optional prescriber setup. The recipient must accept with their Affinity account. Repeating the same external identity retries pending invitation delivery. Accepted invitations do not change existing access. Team membership is shared between Test and Live; the external identity is mode-scoped. Keys cannot accept invitations. Headless registration and signing use separate endpoints.
Request example
Replace example values with your Test data. Check the field rules below before you send a request.
{
"externalId": "<string>",
"email": "<string>",
"name": "<string>",
"role": "owner",
"roles": [
"owner"
],
"profileDetails": {
"firstName": "<string>",
"middleName": "<string>",
"lastName": "<string>",
"namePrefix": "<string>",
"nameSuffix": "<string>",
"fax": "<string>",
"specialties": [
{
"code": "<string>",
"description": "<string>",
"primary": false
}
],
"addresses": [
{
"purpose": "<string>",
"line1": "<string>",
"line2": "<string>",
"city": "<string>",
"state": "<string>",
"postalCode": "<string>",
"country": "<string>",
"phone": "<string>",
"fax": "<string>"
}
],
"otherNames": [
{
"name": "<string>",
"credentials": "<string>",
"type": "<string>"
}
],
"identifiers": [
{
"identifier": "<string>",
"issuer": "<string>",
"state": "<string>",
"description": "<string>"
}
],
"endpoints": [
{
"endpoint": "<string>",
"type": "<string>",
"description": "<string>",
"use": "<string>",
"affiliation": "<string>"
}
],
"certifications": [
{
"name": "<string>",
"issuer": "<string>",
"expiresAt": "<string>"
}
]
},
"npi": "<string>",
"licenses": [
{
"state": "<string>",
"licenseNumber": "<string>",
"expiresAt": "<string>"
}
],
"legalName": "<string>",
"displayName": "<string>",
"credentials": "<string>",
"address": {
"city": "<string>",
"country": "<string>",
"line1": "<string>",
"line2": "<string>",
"postalCode": "<string>",
"state": "<string>"
},
"phone": "<string>",
"locationIds": [
"loc_01j2y8m6jcc9tt24af5pw9x1bc"
]
}curl -X POST 'https://api.affinityrx.com/v1/practices/{practiceId}/team/invitations' \
-H "Authorization: Bearer $AFFINITY_API_KEY" \
-H 'Affinity-Version: 2026-09-28' \
-H 'Idempotency-Key: <Idempotency-Key>' \
-H 'Content-Type: application/json' \
--data @request.jsonResponse example
These examples show the body structure. Values can differ. Select a status code to see its response.
{
"person": {
"id": "user_01j2y8m6jcc9tt24af5pw9x1bc",
"object": "team_person",
"externalId": "<string>",
"email": "<string>",
"name": "<string>",
"status": "<string>",
"invitation": {
"id": "invite_01j2y8m6jcc9tt24af5pw9x1bc",
"status": "accepted",
"expiresAt": "<string>",
"roles": [
{
"id": "role_01j2y8m6jcc9tt24af5pw9x1bc",
"name": "<string>",
"key": "<string>"
}
]
},
"account": {
"accountId": "<string>",
"emailVerified": false,
"membershipId": "mbr_01j2y8m6jcc9tt24af5pw9x1bc",
"membershipStatus": "<string>",
"roles": [
{
"id": "role_01j2y8m6jcc9tt24af5pw9x1bc",
"name": "<string>",
"key": "<string>"
}
],
"prescriberConnection": {
"status": "<string>",
"provider": {
"id": "prov_01j2y8m6jcc9tt24af5pw9x1bc",
"name": "<string>",
"legalName": "<string>",
"credentials": "<string>",
"phone": "<string>",
"address": {
"line1": null,
"line2": null,
"city": null,
"state": null,
"postalCode": null,
"country": null
},
"npi": "<string>",
"practiceStatus": "<string>",
"licenses": [
{
"id": null,
"state": null,
"licenseNumber": null,
"expiresAt": null
}
]
}
}
},
"nextActions": [
"<string>"
]
},
"delivery": "sent"
}{
"code": "<string>",
"data": "<string>",
"detail": "<string>",
"instance": "<string>",
"requestId": "<string>",
"status": 400,
"title": "<string>",
"traceId": "<string>",
"type": "<string>"
}{
"code": "<string>",
"data": "<string>",
"detail": "<string>",
"instance": "<string>",
"requestId": "<string>",
"status": 401,
"title": "<string>",
"traceId": "<string>",
"type": "<string>"
}{
"code": "<string>",
"data": "<string>",
"detail": "<string>",
"instance": "<string>",
"requestId": "<string>",
"status": 403,
"title": "<string>",
"traceId": "<string>",
"type": "<string>"
}{
"code": "<string>",
"data": "<string>",
"detail": "<string>",
"instance": "<string>",
"requestId": "<string>",
"status": 404,
"title": "<string>",
"traceId": "<string>",
"type": "<string>"
}{
"code": "<string>",
"data": "<string>",
"detail": "<string>",
"instance": "<string>",
"requestId": "<string>",
"status": 409,
"title": "<string>",
"traceId": "<string>",
"type": "<string>"
}{
"code": "<string>",
"data": "<string>",
"detail": "<string>",
"instance": "<string>",
"requestId": "<string>",
"status": 429,
"title": "<string>",
"traceId": "<string>",
"type": "<string>"
}{
"code": "<string>",
"data": "<string>",
"detail": "<string>",
"instance": "<string>",
"requestId": "<string>",
"status": 502,
"title": "<string>",
"traceId": "<string>",
"type": "<string>"
}Implementation specification
Use these field types and limits to build your integration. Download the OpenAPI document for the complete contract.
Path parameters
practiceIdstringrequiredPattern: ^prac_[0-7][0-9a-hjkmnp-tv-z]{25}$
Headers
Affinity-VersionstringSelects the HTTP API contract for this request only. When omitted, API-key requests use their service account’s stored version. Does not change the stored default.
Pin requests to 2026-09-28.
Idempotency-KeystringrequiredRequest body specification application/json
externalIdstringrequiredemailstringrequiredPattern: ^[^\s@]+@[^\s@]+\.[^\s@]+$
namestringrequiredrolestring | nullShow role fields
Any of · 1: string
string
Allowed: "owner", "administrator", "prescriber", "clinical_staff", "billing", "developer"
Any of · 2: null
null
rolesstring[] | nullShow roles fields
Any of · 1: string[]
Array items · string
string
Allowed: "owner", "administrator", "prescriber", "clinical_staff", "billing", "developer"
Any of · 2: null
null
profileDetailsobject | nullShow profileDetails fields
Any of · 1: object
firstNamestring | nullShow firstName fields
Any of · 1: string
string
Any of · 2: null
null
middleNamestring | nullShow middleName fields
Any of · 1: string
string
Any of · 2: null
null
lastNamestring | nullShow lastName fields
Any of · 1: string
string
Any of · 2: null
null
namePrefixstring | nullShow namePrefix fields
Any of · 1: string
string
Any of · 2: null
null
nameSuffixstring | nullShow nameSuffix fields
Any of · 1: string
string
Any of · 2: null
null
faxstring | nullShow fax fields
Any of · 1: string
string
Any of · 2: null
null
specialtiesobject[] | nullShow specialties fields
Any of · 1: object[]
Array items · object
codestringrequireddescriptionstringrequiredprimarybooleanrequiredAny of · 2: null
null
addressesobject[] | nullShow addresses fields
Any of · 1: object[]
Array items · object
purposestringrequiredline1stringrequiredline2stringrequiredcitystringrequiredstatestringrequiredpostalCodestringrequiredcountrystringrequiredphonestringrequiredfaxstringrequiredAny of · 2: null
null
otherNamesobject[] | nullShow otherNames fields
Any of · 1: object[]
Array items · object
namestringrequiredcredentialsstringrequiredtypestringrequiredAny of · 2: null
null
identifiersobject[] | nullShow identifiers fields
Any of · 1: object[]
Array items · object
identifierstringrequiredissuerstringrequiredstatestringrequireddescriptionstringrequiredAny of · 2: null
null
endpointsobject[] | nullShow endpoints fields
Any of · 1: object[]
Array items · object
endpointstringrequiredtypestringrequireddescriptionstringrequiredusestringrequiredaffiliationstringrequiredAny of · 2: null
null
certificationsobject[] | nullShow certifications fields
Any of · 1: object[]
Array items · object
namestringrequiredissuerstringrequiredexpiresAtstringrequiredAny of · 2: null
null
Any of · 2: null
null
npistring | nullShow npi fields
Any of · 1: string
string
Any of · 2: null
null
licensesobject[] | nullShow licenses fields
Any of · 1: object[]
Array items · object
statestringrequiredlicenseNumberstringrequiredexpiresAtstring | null | nullShow expiresAt fields
Any of · 1: string | null
Any of · 1: string
string
Any of · 2: null
null
Any of · 2: null
null
Any of · 2: null
null
legalNamestring | null | nullShow legalName fields
Any of · 1: string | null
Any of · 1: string
string
Any of · 2: null
null
Any of · 2: null
null
displayNamestring | null | nullShow displayName fields
Any of · 1: string | null
Any of · 1: string
string
Any of · 2: null
null
Any of · 2: null
null
credentialsstring | null | nullShow credentials fields
Any of · 1: string | null
Any of · 1: string
string
Any of · 2: null
null
Any of · 2: null
null
addressobject | null | nullShow address fields
Any of · 1: object | null
Any of · 1: object
citystringrequiredcountrystringrequiredline1stringrequiredline2string | nullShow line2 fields
Any of · 1: string
string
Any of · 2: null
null
postalCodestringrequiredstatestringrequiredAny of · 2: null
null
Any of · 2: null
null
phonestring | null | nullShow phone fields
Any of · 1: string | null
Any of · 1: string
string
Any of · 2: null
null
Any of · 2: null
null
locationIdsstring[] | nullShow locationIds fields
Any of · 1: string[]
Array items · string
string
Pattern: ^loc_[0-7][0-9a-hjkmnp-tv-z]{25}$
Any of · 2: null
null
Response specifications
200Successful response
application/json
personobjectrequiredNo additional properties
Show person fields
idanyrequiredShow id fields
All of · 1: any
any
Pattern: ^user_[0-7][0-9a-hjkmnp-tv-z]{25}$
objectstringrequiredAllowed: "team_person"
externalIdstringrequiredemailstring | nullrequiredShow email fields
Any of · 1: string
string
Any of · 2: null
null
namestring | nullrequiredShow name fields
Any of · 1: string
string
Any of · 2: null
null
statusstringrequiredinvitationobject | nullrequiredShow invitation fields
Any of · 1: object
idanyrequiredShow id fields
All of · 1: any
any
Pattern: ^invite_[0-7][0-9a-hjkmnp-tv-z]{25}$
statusstringrequiredAllowed: "accepted", "declined", "pending", "expired", "revoked"
expiresAtstringrequiredrolesobject[]requiredShow roles fields
Array items · object
idanyrequiredShow id fields
All of · 1: any
any
Pattern: ^role_[0-7][0-9a-hjkmnp-tv-z]{25}$
namestringrequiredkeystring | nullrequiredShow key fields
Any of · 1: string
string
Any of · 2: null
null
Any of · 2: null
null
accountobject | nullrequiredShow account fields
Any of · 1: object
accountIdstringrequiredemailVerifiedbooleanrequiredmembershipIdanyrequiredShow membershipId fields
All of · 1: any
any
Pattern: ^mbr_[0-7][0-9a-hjkmnp-tv-z]{25}$
membershipStatusstringrequiredrolesobject[]requiredShow roles fields
Array items · object
idanyrequiredShow id fields
All of · 1: any
any
Pattern: ^role_[0-7][0-9a-hjkmnp-tv-z]{25}$
namestringrequiredkeystring | nullrequiredShow key fields
Any of · 1: string
string
Any of · 2: null
null
prescriberConnectionobject | nullrequiredShow prescriberConnection fields
Any of · 1: object
statusstringrequiredproviderobjectrequiredNo additional properties
Show provider fields
idanyrequiredShow id fields
All of · 1: any
any
Pattern: ^prov_[0-7][0-9a-hjkmnp-tv-z]{25}$
namestringrequiredlegalNamestringrequiredcredentialsstring | nullrequiredShow credentials fields
Any of · 1: string
string
Any of · 2: null
null
phonestring | nullrequiredShow phone fields
Any of · 1: string
string
Any of · 2: null
null
addressobject | nullrequiredShow address fields
Any of · 1: object
line1stringrequiredline2string | nullShow line2 fields
Any of · 1: string
string
Any of · 2: null
null
citystringrequiredstatestringrequiredpostalCodestringrequiredcountrystringrequiredAny of · 2: null
null
npistringrequiredpracticeStatusstringrequiredlicensesobject[]requiredShow licenses fields
Array items · object
idanyrequiredShow id fields
All of · 1: any
any
Pattern: ^lic_[0-7][0-9a-hjkmnp-tv-z]{25}$
statestringrequiredlicenseNumberstringrequiredexpiresAtstring | nullrequiredShow expiresAt fields
Any of · 1: string
string
Any of · 2: null
null
Any of · 2: null
null
Any of · 2: null
null
nextActionsstring[]requiredShow nextActions fields
Array items · string
string
deliverystringrequiredAllowed: "sent", "already_accepted"
400HTTP 400
application/json
codestringrequireddataobjectdetailstringrequiredinstancestringrequiredrequestIdstringrequiredstatusintegerrequiredMinimum: 400
Maximum: 599
titlestringrequiredtraceIdstringtypestringrequiredFormat: uri
401Unauthorized
application/json
codestringrequireddataobjectdetailstringrequiredinstancestringrequiredrequestIdstringrequiredstatusintegerrequiredMinimum: 400
Maximum: 599
titlestringrequiredtraceIdstringtypestringrequiredFormat: uri
403Forbidden
application/json
codestringrequireddataobjectdetailstringrequiredinstancestringrequiredrequestIdstringrequiredstatusintegerrequiredMinimum: 400
Maximum: 599
titlestringrequiredtraceIdstringtypestringrequiredFormat: uri
404Not found
application/json
codestringrequireddataobjectdetailstringrequiredinstancestringrequiredrequestIdstringrequiredstatusintegerrequiredMinimum: 400
Maximum: 599
titlestringrequiredtraceIdstringtypestringrequiredFormat: uri
409Conflict
application/json
codestringrequireddataobjectdetailstringrequiredinstancestringrequiredrequestIdstringrequiredstatusintegerrequiredMinimum: 400
Maximum: 599
titlestringrequiredtraceIdstringtypestringrequiredFormat: uri
429Too many requests
application/json
codestringrequireddataobjectdetailstringrequiredinstancestringrequiredrequestIdstringrequiredstatusintegerrequiredMinimum: 400
Maximum: 599
titlestringrequiredtraceIdstringtypestringrequiredFormat: uri
502HTTP 502
application/json
codestringrequireddataobjectdetailstringrequiredinstancestringrequiredrequestIdstringrequiredstatusintegerrequiredMinimum: 400
Maximum: 599
titlestringrequiredtraceIdstringtypestringrequiredFormat: uri