Register user
/v1/practices/{practiceId}/usersRequires team:write and Idempotency-Key. Registers a practice member without an invitation. Test requires synthetic .test emails and Affinity Test NPIs. Live requires approved integration and practice access. Identity attestation records the integration's assertion; it does not verify login email or clinical credentials. Existing memberships and verified provider records are preserved. Use the returned user ID for orders and signing.
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": "administrator",
"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"
],
"identityAttestation": true
}curl -X POST 'https://api.affinityrx.com/v1/practices/{practiceId}/users' \
-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.
{
"object": "registered_user",
"id": "user_01j2y8m6jcc9tt24af5pw9x1bc",
"practiceId": "prac_01j2y8m6jcc9tt24af5pw9x1bc",
"memberId": "mbr_01j2y8m6jcc9tt24af5pw9x1bc",
"prescriberId": "prov_01j2y8m6jcc9tt24af5pw9x1bc",
"externalId": "<string>",
"livemode": false
}{
"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": 422,
"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": 503,
"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@]+$
namestringrequiredrolestringrequiredAllowed: "administrator", "prescriber", "clinical_staff", "billing", "developer"
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
identityAttestationbooleanrequiredAllowed: true
Response specifications
200Successful response
application/json
objectstringrequiredAllowed: "registered_user"
idstringrequiredPattern: ^user_[0-7][0-9a-hjkmnp-tv-z]{25}$
practiceIdstringrequiredPattern: ^prac_[0-7][0-9a-hjkmnp-tv-z]{25}$
memberIdstringrequiredPattern: ^mbr_[0-7][0-9a-hjkmnp-tv-z]{25}$
prescriberIdstring | nullrequiredShow prescriberId fields
Any of · 1: string
string
Pattern: ^prov_[0-7][0-9a-hjkmnp-tv-z]{25}$
Any of · 2: null
null
externalIdstringrequiredlivemodebooleanrequired400HTTP 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
422Validation error
application/json
codestringrequireddataobjectdetailstringrequiredinstancestringrequiredrequestIdstringrequiredstatusintegerrequiredMinimum: 400
Maximum: 599
titlestringrequiredtraceIdstringtypestringrequiredFormat: uri
429Too many requests
application/json
codestringrequireddataobjectdetailstringrequiredinstancestringrequiredrequestIdstringrequiredstatusintegerrequiredMinimum: 400
Maximum: 599
titlestringrequiredtraceIdstringtypestringrequiredFormat: uri
503HTTP 503
application/json
codestringrequireddataobjectdetailstringrequiredinstancestringrequiredrequestIdstringrequiredstatusintegerrequiredMinimum: 400
Maximum: 599
titlestringrequiredtraceIdstringtypestringrequiredFormat: uri