---
title: "Associate a practitioner with a specialty"
method: POST
path: "/practitioners/{practitionerId}/specialties"
tags: ["Practitioner"]
---

# Associate a practitioner with a specialty

`POST /practitioners/{practitionerId}/specialties`

Associates a practitioner with the specified specialty and returns the association details. Practitioner-level specialty is always attempted first; group, location, and network levels are best-effort. On success (200), the response includes all successfully created specialties per level and a 'notCreated' list for any level that could not be created (e.g. missing dependencies), so clients can fix and retry. 4xx is returned only when practitioner-level creation fails.

## Path parameters

- `practitionerId` string, required

## Headers

- `tenant-id` string, required

## Request body

- CreateTenantPractitionerSpecialtyRequest
  - `tenantSpecialtyId` string — ID of the specialty; required if practitionerRole is not provided
  - `tenantGroupPractitionerId` string — ID of the tenant group practitioner
  - `tenantGroupPractitionerLocationId` string — ID of the tenant group practitioner location
  - `networkId` string — ID of the tenant group network
  - `groupSpecialtyEffectiveDate` string — Group specialty date
  - `locationSpecialtyEffectiveDate` string — Location specialty date
  - `networkSpecialtyEffectiveDate` string — Network specialty date
  - `practitionerRole` string — Practitioner role; required if tenantSpecialtyId is not provided
  - `practitionerRoleEffectiveDate` string — Practitioner role date
  - `data` TenantPractitionerSpecialtySchema — Represents the specialty information for a healthcare provider. References the Specialty entity.
    - `effectiveDate` string, date, required — The date when the specialty became effective.
    - `terminationDate` string, date, required — The date when the specialty was terminated.
    - `isPrimary` boolean, required — Indicates if the specialty is primary.
  - `specialtyOrPractitionerRolePresent` boolean
  - `dataPresentWhenSpecialtyPresent` boolean

## Response `200`

Practitioner specialty created. Response includes created specialties per level and, when applicable, 'notCreated' listing levels that could not be created (e.g. missing group/location/network associations) with reason and message.

- AssociatePractitionerSpecialtyResponse
  - `practitionerSpecialty` TenantPractitionerSpecialtyResponse
    - `id` string
    - `tenantPractitionerId` string
    - `tenantSpecialtyId` string
    - `createdAt` string, date
    - `updatedAt` string, date
    - `data` JsonNode
      - `empty` boolean
      - `valueNode` boolean
      - `containerNode` boolean
      - `missingNode` boolean
      - `array` boolean
      - `object` boolean
      - `nodeType` 'ARRAY' | 'BINARY' | 'BOOLEAN' | 'MISSING' | 'NULL' | 'NUMBER' | 'OBJECT' | 'POJO' | 'STRING'
      - `pojo` boolean
      - `number` boolean
      - `integralNumber` boolean
      - `floatingPointNumber` boolean
      - `short` boolean
      - `int` boolean
      - `long` boolean
      - `float` boolean
      - `double` boolean
      - `bigDecimal` boolean
      - `bigInteger` boolean
      - `textual` boolean
      - `boolean` boolean
      - `null` boolean
      - `binary` boolean
  - `groupPractitionerSpecialty` TenantGroupPractitionerSpecialtyResponse
    - `id` string
    - `tenantGroupPractitionerId` string
    - `specialtyId` string
    - `data` JsonNode
      - `empty` boolean
      - `valueNode` boolean
      - `containerNode` boolean
      - `missingNode` boolean
      - `array` boolean
      - `object` boolean
      - `nodeType` 'ARRAY' | 'BINARY' | 'BOOLEAN' | 'MISSING' | 'NULL' | 'NUMBER' | 'OBJECT' | 'POJO' | 'STRING'
      - `pojo` boolean
      - `number` boolean
      - `integralNumber` boolean
      - `floatingPointNumber` boolean
      - `short` boolean
      - `int` boolean
      - `long` boolean
      - `float` boolean
      - `double` boolean
      - `bigDecimal` boolean
      - `bigInteger` boolean
      - `textual` boolean
      - `boolean` boolean
      - `null` boolean
      - `binary` boolean
  - `groupPractitionerLocation` GroupPractitionerLocationResponse1
    - `id` string
    - `tenantGroupLocationId` string
    - `tenantGroupPractitionerId` string
    - `data` JsonNode
      - `empty` boolean
      - `valueNode` boolean
      - `containerNode` boolean
      - `missingNode` boolean
      - `array` boolean
      - `object` boolean
      - `nodeType` 'ARRAY' | 'BINARY' | 'BOOLEAN' | 'MISSING' | 'NULL' | 'NUMBER' | 'OBJECT' | 'POJO' | 'STRING'
      - `pojo` boolean
      - `number` boolean
      - `integralNumber` boolean
      - `floatingPointNumber` boolean
      - `short` boolean
      - `int` boolean
      - `long` boolean
      - `float` boolean
      - `double` boolean
      - `bigDecimal` boolean
      - `bigInteger` boolean
      - `textual` boolean
      - `boolean` boolean
      - `null` boolean
      - `binary` boolean
  - `groupLocationSpecialty` TenantGroupLocationSpecialtyResponse
    - `id` string
    - `tenantGroupLocationId` string
    - `tenantSpecialtyId` string
    - `data` JsonNode
      - `empty` boolean
      - `valueNode` boolean
      - `containerNode` boolean
      - `missingNode` boolean
      - `array` boolean
      - `object` boolean
      - `nodeType` 'ARRAY' | 'BINARY' | 'BOOLEAN' | 'MISSING' | 'NULL' | 'NUMBER' | 'OBJECT' | 'POJO' | 'STRING'
      - `pojo` boolean
      - `number` boolean
      - `integralNumber` boolean
      - `floatingPointNumber` boolean
      - `short` boolean
      - `int` boolean
      - `long` boolean
      - `float` boolean
      - `double` boolean
      - `bigDecimal` boolean
      - `bigInteger` boolean
      - `textual` boolean
      - `boolean` boolean
      - `null` boolean
      - `binary` boolean
  - `groupPractitionerLocationSpecialty` GroupPractitionerLocationSpecialtyResponse
    - `id` string
    - `groupPractitionerLocationId` string
    - `practitionerSpecialtyId` string
    - `data` JsonNode
      - `empty` boolean
      - `valueNode` boolean
      - `containerNode` boolean
      - `missingNode` boolean
      - `array` boolean
      - `object` boolean
      - `nodeType` 'ARRAY' | 'BINARY' | 'BOOLEAN' | 'MISSING' | 'NULL' | 'NUMBER' | 'OBJECT' | 'POJO' | 'STRING'
      - `pojo` boolean
      - `number` boolean
      - `integralNumber` boolean
      - `floatingPointNumber` boolean
      - `short` boolean
      - `int` boolean
      - `long` boolean
      - `float` boolean
      - `double` boolean
      - `bigDecimal` boolean
      - `bigInteger` boolean
      - `textual` boolean
      - `boolean` boolean
      - `null` boolean
      - `binary` boolean
  - `groupLocationParticipationSpecialty` TenantGroupLocationParticipationSpecialtyResponse
    - `id` string
    - `tenantGroupLocationEnrollmentId` string
    - `tenantGroupLocationSpecialtyId` string
    - `data` JsonNode
      - `empty` boolean
      - `valueNode` boolean
      - `containerNode` boolean
      - `missingNode` boolean
      - `array` boolean
      - `object` boolean
      - `nodeType` 'ARRAY' | 'BINARY' | 'BOOLEAN' | 'MISSING' | 'NULL' | 'NUMBER' | 'OBJECT' | 'POJO' | 'STRING'
      - `pojo` boolean
      - `number` boolean
      - `integralNumber` boolean
      - `floatingPointNumber` boolean
      - `short` boolean
      - `int` boolean
      - `long` boolean
      - `float` boolean
      - `double` boolean
      - `bigDecimal` boolean
      - `bigInteger` boolean
      - `textual` boolean
      - `boolean` boolean
      - `null` boolean
      - `binary` boolean
  - `groupPractitionerLocationNetworkSpecialty` TenantGroupPractitionerLocationNetworkSpecialtyResponse
    - `id` string
    - `tenantGroupLocationPractitionerNetworkId` string
    - `tenantGroupPractitionerLocationSpecialtyId` string
    - `data` JsonNode
      - `empty` boolean
      - `valueNode` boolean
      - `containerNode` boolean
      - `missingNode` boolean
      - `array` boolean
      - `object` boolean
      - `nodeType` 'ARRAY' | 'BINARY' | 'BOOLEAN' | 'MISSING' | 'NULL' | 'NUMBER' | 'OBJECT' | 'POJO' | 'STRING'
      - `pojo` boolean
      - `number` boolean
      - `integralNumber` boolean
      - `floatingPointNumber` boolean
      - `short` boolean
      - `int` boolean
      - `long` boolean
      - `float` boolean
      - `double` boolean
      - `bigDecimal` boolean
      - `bigInteger` boolean
      - `textual` boolean
      - `boolean` boolean
      - `null` boolean
      - `binary` boolean
  - `groupPractitionerNetwork` TenantGroupPractitionerNetworkResponse
    - `id` string
    - `tenantGroupPractitionerId` string
    - `contractedNetworkId` string
    - `networkId` string
    - `data` JsonNode
      - `empty` boolean
      - `valueNode` boolean
      - `containerNode` boolean
      - `missingNode` boolean
      - `array` boolean
      - `object` boolean
      - `nodeType` 'ARRAY' | 'BINARY' | 'BOOLEAN' | 'MISSING' | 'NULL' | 'NUMBER' | 'OBJECT' | 'POJO' | 'STRING'
      - `pojo` boolean
      - `number` boolean
      - `integralNumber` boolean
      - `floatingPointNumber` boolean
      - `short` boolean
      - `int` boolean
      - `long` boolean
      - `float` boolean
      - `double` boolean
      - `bigDecimal` boolean
      - `bigInteger` boolean
      - `textual` boolean
      - `boolean` boolean
      - `null` boolean
      - `binary` boolean
  - `groupPractitionerLocationNetwork` TenantGroupLocationPractitionerNetworkResponse
    - `id` string
    - `groupPractitionerLocationId` string
    - `networkId` string
    - `contractId` string
    - `practitionerSpecialtyId` string
    - `sourceFileId` string
    - `data` JsonNode
      - `empty` boolean
      - `valueNode` boolean
      - `containerNode` boolean
      - `missingNode` boolean
      - `array` boolean
      - `object` boolean
      - `nodeType` 'ARRAY' | 'BINARY' | 'BOOLEAN' | 'MISSING' | 'NULL' | 'NUMBER' | 'OBJECT' | 'POJO' | 'STRING'
      - `pojo` boolean
      - `number` boolean
      - `integralNumber` boolean
      - `floatingPointNumber` boolean
      - `short` boolean
      - `int` boolean
      - `long` boolean
      - `float` boolean
      - `double` boolean
      - `bigDecimal` boolean
      - `bigInteger` boolean
      - `textual` boolean
      - `boolean` boolean
      - `null` boolean
      - `binary` boolean
  - `notCreated` SpecialtyNotCreated[] — Specialty associations that could not be created (e.g. missing dependencies). Empty when all requested levels succeeded.
    - `level` 'GROUP' | 'LOCATION' | 'NETWORK_GROUP' | 'NETWORK_LOCATION', required
    - `reason` 'MISSING_DEPENDENCY' | 'DOWNSTREAM_ERROR' | 'CONFLICT' | 'VALIDATION_ERROR', required
    - `message` string, required — User-facing message explaining what went wrong and how to fix it

## Other responses

- `400` — Bad request - Invalid input
- `401` — Unauthorized - Authentication required
- `403` — Forbidden - Insufficient permissions
- `404` — Practitioner or specialty not found
- `409` — Conflict - Practitioner already associated with specialty
- `500` — Internal server error

---

[API](https://skmtc.net/certifyos/apis/certify-api-layer.md) · [All operations](https://skmtc.net/certifyos/apis/certify-api-layer/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/certifyos/certify-api-layer/versions/3d27e9019c7b/schema)
