User Documentation

PACS integration

ICAP can coordinate access data with connected Physical Access Control Systems (PACSs) through AIS. ICAP is the persistent system of record for the tenant's intended data: it can be the master for the data it owns across interconnected applications and PACSs. AIS performs the integration work; it can give applications a unified path to many PACSs, but it does not own or govern the canonical business data. Each PACS ultimately enforces its own capabilities.

Before you configure a PACS

Confirm that PACS integration is enabled for the tenant and that the PACS is supported and connected through your AIS integration of your tenant.

Registering an ICAP PACS record does not itself establish external connectivity.

Register a PACS through /pacs with its tenant-scoped pacsId, name, and optional configuration and mappings. Then use ICAP to list its discovered access units and card formats. These discovery results are the input for access-unit and card-type mappings.

Use this operational order for a new integration:

  1. Confirm that PACS integration is enabled for the tenant and that the user’s HIS tenant has connected the supported PACS.

  2. Register the ICAP PACS record with POST /pacs (PacsRegister). Use HIS (AIS) pacsId for the requets. A successful registration does not prove the external connection is usable.

  3. Read GET /pacs/{pacsId}/accessUnit and GET /pacs/{pacsId}/cardFormat (PacsCardFormatList) and retain the discovered identifiers.

  4. Map ICAP access units and card types only to those discovered identifiers. Test mappings in non-production before assigning physical credentials or production access.

  5. Select the identity and visitor propagation modes with the PACS administrator, then create a test identity or visitor assignment and monitor its transaction through completion.

Discover and map a PACS

The HIS tenant administrator must supply a PACS ID that is already connected through the HIS/AIS service. If it is not yet registered in ICAP, a caller with PacsRegister can register it with POST /pacs, supplying the required pacsId and name. Do not invent a PACS ID or register a production PACS merely to test this example.

List the available remote targets and formats. Both discovery calls require PacsCardFormatList permission in the current contract.

Bash
PACS_ID='<registered-pacs-id>'

curl --fail-with-body --silent --show-error \
  --header "Authorization: Bearer $TOKEN" \
  "$BASE_URL/pacs/$PACS_ID/accessUnit?limit=100"

curl --fail-with-body --silent --show-error \
  --header "Authorization: Bearer $TOKEN" \
  "$BASE_URL/pacs/$PACS_ID/cardFormat"

The access-unit response is paged; select an items[].id returned by this PACS. The card-format response contains the available formats and any format-specific constraints. For example:

JSON
{
  "items": [
    { "id": "<remoteAccessUnitId>", "name": "Level 3" }
  ],
  "limit": 100,
  "offset": 0,
  "total": 1
}

Create mapped business resources only with those returned values. This example creates an identity-eligible access unit and card type; replace the names and values with the selected discovery results.

Bash
REMOTE_ACCESS_UNIT_ID='<value from discovery>'
CARD_FORMAT='<value from discovery>'

curl --fail-with-body --silent --show-error \
  --request POST "$BASE_URL/accessUnit" \
  --header "Authorization: Bearer $TOKEN" \
  --header 'Content-Type: application/json' \
  --data "{
    \"name\": \"Level 3\",
    \"eligibleFor\": \"identity\",
    \"pacsMappings\": [
      { \"pacsId\": \"$PACS_ID\", \"accessUnitId\": \"$REMOTE_ACCESS_UNIT_ID\" }
    ]
  }"

curl --fail-with-body --silent --show-error \
  --request POST "$BASE_URL/cardType" \
  --header "Authorization: Bearer $TOKEN" \
  --header 'Content-Type: application/json' \
  --data "{
    \"name\": \"Employee PACS card\",
    \"eligibleFor\": \"identity\",
    \"pacsFormatMappings\": { \"$PACS_ID\": \"$CARD_FORMAT\" }
  }"

The create responses contain the ICAP resource IDs and version. Keep both values: later mapped-resource PATCH or removal needs the current version. A successful mapping only establishes ICAP's intended configuration; test an assignment and monitor its PACS transaction before relying on a door outcome.

Propagation modes

PACS configuration can set separate propagation modes for identities and visitors:

Mode

Intended behavior

off

Do not propagate this category.

mirror

Propagate eligible data without requiring a selected credential and access unit.

jit

Just In Time. Propagate when eligible data includes both a PACS-mapped credential and PACS-mapped access unit.

master

Use the PACS as the configured source for periodic import of that category.

Choose modes with the data owner and PACS administrator. jit is useful when provisioning should follow a complete access assignment; mirror can suit a PACS that needs person records before access is assigned. In master mode, the selected PACS—not ICAP—is the configured source for the imported category. Do not describe ICAP as the master for data governed by that import configuration.

Mapping and constraints

Map ICAP access units to discovered remote access units, and map card types to compatible PACS card formats. Optional attribute mappings copy selected identity, visitor, card-credential, or PIN-credential values between ICAP and AIS integration data.

Map identity and visitor attributes

Attribute mappings are configured on each PACS record in mappings. In each mapping block, the property name is a source JSONPath on the ICAP record and the value is the destination JSONPath in the AIS attributes for that PACS.

On the destination side, $.ext.<fieldName> addresses an extension field registered for that PACS in HIS, while $.self.<fieldName> addresses a native field registered for that PACS in HIS. On the ICAP source side, use $.extensionFields.<fieldName> for an ICAP extension field and $.<nativeFieldName> for an ICAP native attribute, such as $.firstName or $.lastName.

The following example sends both kinds of values: an identity's native first name and employee number, plus a visitor's native last name and sponsor:

JSON
{
  "mappings": {
    "identity": {
      "$.firstName": "$.self.firstName",
      "$.extensionFields.employeeNumber": "$.ext.employeeNumber"
    },
    "visitor": {
      "$.lastName": "$.self.lastName",
      "$.extensionFields.sponsor": "$.ext.sponsor"
    },
    "cardCredential": {},
    "pinCredential": {}
  }
}

In these JSONPaths, $ means the current object: the ICAP identity or visitor on the left, and the outgoing AIS attributes object on the right. extensionFields stores ICAP tenant-defined fields. ext is the AIS extension-attributes object used in this example, not a reserved ICAP field. Confirm destination objects and attributes with the PACS administrator.

To send values, employeeNumber must exist in the identity extensionFields and sponsor in the visitor extensionFields. Destination paths must match PACS-registered attributes. The identity block syncs identities; visitor syncs visitors with visit assignments. There is no visit block: visits provide context, not mapping sources.

Use valid JSONPaths that start with $.. ICAP validates syntax when saving the PACS configuration, but not source or destination existence or type compatibility. Mappings copy values as-is; they cannot format, convert, combine, or split them. Avoid duplicate destinations, and do not map ICAP-managed metadata such as IDs, versions, or audit timestamps.

Mappings supplement standard outbound person attributes; they do not select credentials or access units. Map only PACS-approved, supported attributes. If the PACS does not support the relevant extension fields, it can omit those mapped values.

A PACS can advertise limits such as unsupported credential types, photos, PINs, or field values. ICAP adapts outbound data to the configured and discovered capabilities, but an integration still requires testing in the intended PACS environment.

Monitor and recover downstream work

Changes that require PACS work can create PACS transactions. They are asynchronous: a successful ICAP API response confirms ICAP accepted the change, not that every downstream PACS has completed it.

Use GET /pacsTransaction to inspect transactions. Filter by PACS, entity, related entity, or operation as needed, and retain correlation data in your application so support teams can trace an outcome. Build workflow status around the transaction result rather than assuming immediate physical-access availability.

For a person or visitor change, start with GET /pacsTransaction?entityId=<identityId-or-visitorId>. Narrow further with pacsId, relatedEntityId, or one of the contract's operation values if necessary. Each returned transaction includes its PACS ID, entity IDs, status, result timestamp, and traceId.

Transaction status

Operational response

pending or running

Keep the requested physical-access state pending and poll or reconcile within the agreed operational window.

success

Mark the downstream operation complete for that PACS.

failed, partial, unsupported, unknown, or cancelled

Do not claim physical access is available. Inspect the PACS configuration, discovered mappings, selected credential and access unit, and transaction trace before changing or retrying the ICAP state.

For a failed or partial transaction, record the tenant ID, PACS ID, entity ID, related entity ID, operation, status, traceId, request time, and safe application correlation ID. Give those values to the PACS or HIS support owner together with the intended business outcome. Do not blindly resubmit a create or assignment: first determine whether ICAP's intended state already exists and whether the PACS needs a configuration correction. Re-test the corrected flow in a non-production tenant where available.

Operate safely

Update and deregister PACS records using their current version with If-Match. Review mappings after PACS configuration changes. The API reference lists the available management and discovery endpoints.