Personal data sharing lets one tenant offer selected identity or visitor data to another tenant. It is a deliberate, one-time workflow—not shared ownership and not continuous synchronization.
The source tenant retains its original record. On acceptance, the target tenant creates or updates a record that it owns. Later changes to the source are not automatically copied to the target through the current API.
Workflow
Source tenant: create offer → Target tenant: review → accept or decline
└────────────────────── withdraw while pending ──────────────────────┘
-
The source creates an offer from an identity or visitor and identifies the target tenant plus allowed attribute paths.
-
The target lists and retrieves incoming shares, then reviews the offered data.
-
The target accepts with an entity type, target external-ID key/value, and attribute mappings—or declines.
-
The source may withdraw a pending offer. Closing an offer removes the captured offer values from the operational workflow.
Use dryRun=true where available to validate a creation or acceptance request before writing target data.
Accept and reconcile deliberately
Use an optional source-side contractId to group related offers under the same business agreement or other logical grouping. Use a source-side correlationId to identify one business request, then retain it in both tenants' workflow records. A contract ID can span multiple offers; a correlation ID should let operators find the specific request without treating a person ID from one tenant as an ID in the other.
-
In the source tenant, create the offer with
POST /identity/{identityId}/shareorPOST /visitor/{visitorId}/share. Validate the request first withdryRun=truewhen appropriate. -
In the target tenant, list incoming shares and filter by
correlationId, then retrieve the individual share withGET /personalShare/incoming/{shareId}. Review the captured values and allowed attributes before acceptance. -
Accept with
POST /personalShare/incoming/{shareId}/accept. The request requires the targetentityType, target external-ID key and value, and attribute mappings. UsedryRun=trueto validate the target mapping before the final acceptance. -
Optionally save the source share ID, target share ID, target entity ID, target external ID, contract ID when used, correlation ID, accepted attributes, and acceptance time in your own reconciliation record. Re-read the incoming and outgoing share records to confirm their status and identifiers.
An accepted share creates or updates a record that belongs to the target tenant. It is not a synchronization link. Reconcile subsequent source changes through a new, authorized sharing workflow or through the organization's approved data process; never assume the target record will update itself.
Example: offer, accept, and verify
This example shares selected fields from an existing source identity to a pre-approved target tenant. Both tenants must have personal sharing enabled and the required roles. Use only attribute paths and mappings approved by the data owner; the example uses JSONPath selections for basic name fields and a correlation ID that is safe to log.
SOURCE_BASE_URL='https://<source-icap-host>/icap/v1/tenant/<sourceTenantId>'
TARGET_BASE_URL='https://<target-icap-host>/icap/v1/tenant/<targetTenantId>'
SOURCE_TOKEN='<source-access-token>'
TARGET_TOKEN='<target-access-token>'
SOURCE_IDENTITY_ID='<source-identity-id>'
CONTRACT_ID='contract-2026-prague'
CORRELATION_ID='share-demo-20260907-001'
Validate the source offer first. dryRun=true checks the request without creating an offer; repeat the same request without it to create the actual outgoing share.
SHARE_BODY="{
\"targetTenantId\": \"<targetTenantId>\",
\"contractId\": \"$CONTRACT_ID\",
\"correlationId\": \"$CORRELATION_ID\",
\"attributes\": [\"$.firstName\", \"$.lastName\"]
}"
curl --fail-with-body --silent --show-error \
--request POST "$SOURCE_BASE_URL/identity/$SOURCE_IDENTITY_ID/share?dryRun=true" \
--header "Authorization: Bearer $SOURCE_TOKEN" \
--header 'Content-Type: application/json' \
--data "$SHARE_BODY"
OUTGOING_SHARE_RESPONSE="$(curl --fail-with-body --silent --show-error \
--request POST "$SOURCE_BASE_URL/identity/$SOURCE_IDENTITY_ID/share" \
--header "Authorization: Bearer $SOURCE_TOKEN" \
--header 'Content-Type: application/json' \
--data "$SHARE_BODY")"
SOURCE_SHARE_ID="$(jq --exit-status --raw-output '.id' <<<"$OUTGOING_SHARE_RESPONSE")"
In the target tenant, retrieve the incoming offer by its safe correlation ID. Confirm that the selected values, source tenant, and status are expected before accepting it.
INCOMING_SHARES="$(curl --fail-with-body --silent --show-error \
--header "Authorization: Bearer $TARGET_TOKEN" \
"$TARGET_BASE_URL/personalShare/incoming?correlationId=$CORRELATION_ID&limit=10")"
TARGET_SHARE_ID="$(jq --exit-status --raw-output '.items[0].id' <<<"$INCOMING_SHARES")"
curl --fail-with-body --silent --show-error \
--header "Authorization: Bearer $TARGET_TOKEN" \
"$TARGET_BASE_URL/personalShare/incoming/$TARGET_SHARE_ID"
Validate the target mapping with dryRun=true, then accept it. The acceptance request requires the target record type, an external ID to create or match in the target tenant, and the source-to-target mappings.
ACCEPT_BODY="{
\"entityType\": \"Identity\",
\"externalIdKey\": \"sharedDemo\",
\"externalIdValue\": \"$CORRELATION_ID\",
\"attributes\": [
{ \"sourcePath\": \"$.firstName\", \"targetPath\": \"$.firstName\" },
{ \"sourcePath\": \"$.lastName\", \"targetPath\": \"$.lastName\" }
]
}"
curl --fail-with-body --silent --show-error \
--request POST "$TARGET_BASE_URL/personalShare/incoming/$TARGET_SHARE_ID/accept?dryRun=true" \
--header "Authorization: Bearer $TARGET_TOKEN" \
--header 'Content-Type: application/json' \
--data "$ACCEPT_BODY"
ACCEPTED_SHARE="$(curl --fail-with-body --silent --show-error \
--request POST "$TARGET_BASE_URL/personalShare/incoming/$TARGET_SHARE_ID/accept" \
--header "Authorization: Bearer $TARGET_TOKEN" \
--header 'Content-Type: application/json' \
--data "$ACCEPT_BODY")"
jq '{ id, status, entityType, entityId, sourceTenantId, sourceEntityId }' <<<"$ACCEPTED_SHARE"
An accepted incoming-share response identifies the target-owned entityId and has status: "accepted". Store it with SOURCE_SHARE_ID, TARGET_SHARE_ID, CONTRACT_ID when used, and CORRELATION_ID; do not use either tenant's person ID as the other tenant's ID. The exact permissions and complete response schemas are available in the API explorer.
Ownership and data minimization
Only share attributes that the target needs for its stated purpose. An offer may contain personal data, so limit access, log the business authorization in your application, and avoid putting sensitive values in identifiers or logs.
Target acceptance either creates a target-owned person record or updates one matched by the supplied target external ID. It does not change the source tenant's ownership and does not make two tenant records a single editable record.
Manage offers
-
Use
/personalShare/outgoingin the source tenant and/personalShare/incomingin the target tenant. Both list endpoints support paging and filters for status, last update, contractId, and correlationId. -
Filter by
contractIdto work with a related group of offers. -
filter by
correlationIdto find a specific business request. -
A share can be
created,pending,accepted,declined,withdrawn, orfailed.
Do not build a workflow around future update synchronization, durable share links, or expiry handling; those are not exposed by the current public API. Consult authentication and your tenant's role policy before exposing personal shares to operators. Endpoint details are in API Swagger (ICAP).