The only way to remove an external identifier — update_patient never removes.
DELETE
/
v1
/
patients
/
{patient_id}
/
external-identifiers
import olira
from olira import ExternalIdentifierMatcher
olira.init(api_key="YOUR_API_KEY")
# system + value — exactly one identifier
one = ExternalIdentifierMatcher(system="my-crm", value="CRM-4471")
# system only — every identifier for that system
# (system="epic" unlinks every connected Epic instance)
all_for_system = ExternalIdentifierMatcher(system="epic")
# integration_id only — every identifier owned by one instance (one hospital)
one_hospital = ExternalIdentifierMatcher(integration_id="66f0a1...")
# system + integration_id — that system on that instance only
epic_at_hospital = ExternalIdentifierMatcher(system="epic", integration_id="66f0a1...")
result = olira.remove_patient_external_identifiers(
patient_id="8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82",
identifiers=[one],
)
print(result.removed, result.skipped)
using Olira;
OliraModule.Init(apiKey: "YOUR_API_KEY");
// System + Value — exactly one identifier
var one = new ExternalIdentifierMatcher { System = "my-crm", Value = "CRM-4471" };
// System only — every identifier for that system
// (System = "epic" unlinks every connected Epic instance)
var allForSystem = new ExternalIdentifierMatcher { System = "epic" };
// IntegrationId only — every identifier owned by one instance (one hospital)
var oneHospital = new ExternalIdentifierMatcher { IntegrationId = "66f0a1..." };
// System + IntegrationId — that system on that instance only
var epicAtHospital = new ExternalIdentifierMatcher { System = "epic", IntegrationId = "66f0a1..." };
var result = OliraModule.RemovePatientExternalIdentifiers(
patientId: "8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82",
identifiers: [one]);
Console.WriteLine($"{result.Removed} {result.Skipped}");
DELETE /v1/patients/8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82/external-identifiers
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"identifiers": [{ "system": "my-crm", "value": "CRM-4471" }]
}
ExternalIdentifierMutationResult(
patient_id="8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82",
added=0,
removed=1,
skipped=0,
external_identifiers=[],
)
{
"error": true,
"status_code": 401,
"error_type": "authentication_error",
"message": "Could not validate credentials",
"details": [
{
"type": "authentication_error",
"message": "Could not validate credentials"
}
],
"timestamp": "2026-05-06T12:00:00+00:00"
}
{
"error": true,
"status_code": 403,
"error_type": "authorization_error",
"message": "Insufficient OAuth scope for this endpoint",
"details": [
{
"type": "authorization_error",
"message": "Insufficient OAuth scope for this endpoint"
}
],
"timestamp": "2026-05-06T12:00:00+00:00"
}
{
"error": true,
"status_code": 404,
"error_type": "not_found_error",
"message": "Patient not found",
"details": [
{
"type": "not_found_error",
"message": "Patient not found"
}
],
"timestamp": "2026-05-06T12:00:00+00:00"
}
{
"error": true,
"status_code": 422,
"error_type": "validation_error",
"message": "Request validation failed (1 error)",
"details": [
{
"type": "missing",
"message": "Field required",
"field": "patient_id",
"location": ["body", "patient_id"],
"input_value": null
}
],
"timestamp": "2026-05-06T12:00:00+00:00"
}
{
"error": true,
"status_code": 429,
"error_type": "server_error",
"message": "Rate limit exceeded",
"details": [
{
"type": "rate_limit",
"message": "Too many requests; retry after backoff"
}
],
"timestamp": "2026-05-06T12:00:00+00:00"
}
{
"error": true,
"status_code": 500,
"error_type": "internal_server_error",
"message": "An internal server error occurred",
"details": [
{
"type": "internal_server_error",
"message": "An unexpected error occurred while processing your request"
}
],
"timestamp": "2026-05-06T12:00:00+00:00"
}
olira.remove_patient_external_identifiers(
patient_id: str,
identifiers: list[ExternalIdentifierMatcher],
) -> ExternalIdentifierMutationResult
OliraModule.RemovePatientExternalIdentifiers(
string patientId,
IReadOnlyList<ExternalIdentifierMatcher> identifiers,
) // -> ExternalIdentifierMutationResult
api:manage-patients
Each entry is a matcher: system + value (one row); system only (every identifier for that system — system=epic unlinks every connected Epic instance, use integration_id alone to drop one hospital); integration_id only (that instance); system + integration_id (that system on that instance). Can match ANY identifier, including one owned by a platform integration: this is a deliberate, irreversible unlink, and under linked_only import mode the patient immediately stops receiving further data from that integration. Idempotent — a matcher that matches nothing is skipped, not an error.
Parameters
str
required
Olira patient id.
list[ExternalIdentifierMatcher]
required
Matchers — a filter, not a full identifier. Construct with any of the shapes below. Rows match every field you set. At least one field is required. value without system is rejected (422).
Hide ExternalIdentifierMatcher
Hide ExternalIdentifierMatcher
str | None
System name, e.g. epic. Alone: every identifier for that system. system=“epic” unlinks every connected Epic instance — use integration_id alone to drop one hospital.
str | None
Value in that system. Requires system. With system: exactly one identifier (the common case).
str | None
Platform-assigned integration instance id. Alone: every identifier owned by that instance. With system: that system on that instance only.
Returns
ExternalIdentifierMutationResult
str
Olira patient id.
int
Always 0 for this call.
int
Number of identifiers removed.
int
Number of matchers that matched nothing.
list[ExternalIdentifier]
The patient’s full external identifier list after the mutation.
Raises
| Exception | When |
|---|---|
AuthError | HTTP 401 or 403 — invalid API key or insufficient OAuth scope for this endpoint. |
ValidationError | HTTP 400, 404, or 422 — malformed JSON, unknown patient, or validation failure (message includes response excerpt). |
ServerError | HTTP 409 (e.g. conflicting external identifier) or repeated 5xx after retries; includes status_code when applicable. |
RateLimitError | HTTP 429 — rate limited; check retry_after (seconds). |
NetworkError | Connection timeout, DNS failure, or read error after retries. |
import olira
from olira import ExternalIdentifierMatcher
olira.init(api_key="YOUR_API_KEY")
# system + value — exactly one identifier
one = ExternalIdentifierMatcher(system="my-crm", value="CRM-4471")
# system only — every identifier for that system
# (system="epic" unlinks every connected Epic instance)
all_for_system = ExternalIdentifierMatcher(system="epic")
# integration_id only — every identifier owned by one instance (one hospital)
one_hospital = ExternalIdentifierMatcher(integration_id="66f0a1...")
# system + integration_id — that system on that instance only
epic_at_hospital = ExternalIdentifierMatcher(system="epic", integration_id="66f0a1...")
result = olira.remove_patient_external_identifiers(
patient_id="8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82",
identifiers=[one],
)
print(result.removed, result.skipped)
using Olira;
OliraModule.Init(apiKey: "YOUR_API_KEY");
// System + Value — exactly one identifier
var one = new ExternalIdentifierMatcher { System = "my-crm", Value = "CRM-4471" };
// System only — every identifier for that system
// (System = "epic" unlinks every connected Epic instance)
var allForSystem = new ExternalIdentifierMatcher { System = "epic" };
// IntegrationId only — every identifier owned by one instance (one hospital)
var oneHospital = new ExternalIdentifierMatcher { IntegrationId = "66f0a1..." };
// System + IntegrationId — that system on that instance only
var epicAtHospital = new ExternalIdentifierMatcher { System = "epic", IntegrationId = "66f0a1..." };
var result = OliraModule.RemovePatientExternalIdentifiers(
patientId: "8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82",
identifiers: [one]);
Console.WriteLine($"{result.Removed} {result.Skipped}");
DELETE /v1/patients/8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82/external-identifiers
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"identifiers": [{ "system": "my-crm", "value": "CRM-4471" }]
}
ExternalIdentifierMutationResult(
patient_id="8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82",
added=0,
removed=1,
skipped=0,
external_identifiers=[],
)
{
"error": true,
"status_code": 401,
"error_type": "authentication_error",
"message": "Could not validate credentials",
"details": [
{
"type": "authentication_error",
"message": "Could not validate credentials"
}
],
"timestamp": "2026-05-06T12:00:00+00:00"
}
{
"error": true,
"status_code": 403,
"error_type": "authorization_error",
"message": "Insufficient OAuth scope for this endpoint",
"details": [
{
"type": "authorization_error",
"message": "Insufficient OAuth scope for this endpoint"
}
],
"timestamp": "2026-05-06T12:00:00+00:00"
}
{
"error": true,
"status_code": 404,
"error_type": "not_found_error",
"message": "Patient not found",
"details": [
{
"type": "not_found_error",
"message": "Patient not found"
}
],
"timestamp": "2026-05-06T12:00:00+00:00"
}
{
"error": true,
"status_code": 422,
"error_type": "validation_error",
"message": "Request validation failed (1 error)",
"details": [
{
"type": "missing",
"message": "Field required",
"field": "patient_id",
"location": ["body", "patient_id"],
"input_value": null
}
],
"timestamp": "2026-05-06T12:00:00+00:00"
}
{
"error": true,
"status_code": 429,
"error_type": "server_error",
"message": "Rate limit exceeded",
"details": [
{
"type": "rate_limit",
"message": "Too many requests; retry after backoff"
}
],
"timestamp": "2026-05-06T12:00:00+00:00"
}
{
"error": true,
"status_code": 500,
"error_type": "internal_server_error",
"message": "An internal server error occurred",
"details": [
{
"type": "internal_server_error",
"message": "An unexpected error occurred while processing your request"
}
],
"timestamp": "2026-05-06T12:00:00+00:00"
}
⌘I
import olira
from olira import ExternalIdentifierMatcher
olira.init(api_key="YOUR_API_KEY")
# system + value — exactly one identifier
one = ExternalIdentifierMatcher(system="my-crm", value="CRM-4471")
# system only — every identifier for that system
# (system="epic" unlinks every connected Epic instance)
all_for_system = ExternalIdentifierMatcher(system="epic")
# integration_id only — every identifier owned by one instance (one hospital)
one_hospital = ExternalIdentifierMatcher(integration_id="66f0a1...")
# system + integration_id — that system on that instance only
epic_at_hospital = ExternalIdentifierMatcher(system="epic", integration_id="66f0a1...")
result = olira.remove_patient_external_identifiers(
patient_id="8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82",
identifiers=[one],
)
print(result.removed, result.skipped)
using Olira;
OliraModule.Init(apiKey: "YOUR_API_KEY");
// System + Value — exactly one identifier
var one = new ExternalIdentifierMatcher { System = "my-crm", Value = "CRM-4471" };
// System only — every identifier for that system
// (System = "epic" unlinks every connected Epic instance)
var allForSystem = new ExternalIdentifierMatcher { System = "epic" };
// IntegrationId only — every identifier owned by one instance (one hospital)
var oneHospital = new ExternalIdentifierMatcher { IntegrationId = "66f0a1..." };
// System + IntegrationId — that system on that instance only
var epicAtHospital = new ExternalIdentifierMatcher { System = "epic", IntegrationId = "66f0a1..." };
var result = OliraModule.RemovePatientExternalIdentifiers(
patientId: "8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82",
identifiers: [one]);
Console.WriteLine($"{result.Removed} {result.Skipped}");
DELETE /v1/patients/8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82/external-identifiers
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"identifiers": [{ "system": "my-crm", "value": "CRM-4471" }]
}
ExternalIdentifierMutationResult(
patient_id="8a4fde23-0f1b-4c2a-9d7e-b36c1a5f0e82",
added=0,
removed=1,
skipped=0,
external_identifiers=[],
)
{
"error": true,
"status_code": 401,
"error_type": "authentication_error",
"message": "Could not validate credentials",
"details": [
{
"type": "authentication_error",
"message": "Could not validate credentials"
}
],
"timestamp": "2026-05-06T12:00:00+00:00"
}
{
"error": true,
"status_code": 403,
"error_type": "authorization_error",
"message": "Insufficient OAuth scope for this endpoint",
"details": [
{
"type": "authorization_error",
"message": "Insufficient OAuth scope for this endpoint"
}
],
"timestamp": "2026-05-06T12:00:00+00:00"
}
{
"error": true,
"status_code": 404,
"error_type": "not_found_error",
"message": "Patient not found",
"details": [
{
"type": "not_found_error",
"message": "Patient not found"
}
],
"timestamp": "2026-05-06T12:00:00+00:00"
}
{
"error": true,
"status_code": 422,
"error_type": "validation_error",
"message": "Request validation failed (1 error)",
"details": [
{
"type": "missing",
"message": "Field required",
"field": "patient_id",
"location": ["body", "patient_id"],
"input_value": null
}
],
"timestamp": "2026-05-06T12:00:00+00:00"
}
{
"error": true,
"status_code": 429,
"error_type": "server_error",
"message": "Rate limit exceeded",
"details": [
{
"type": "rate_limit",
"message": "Too many requests; retry after backoff"
}
],
"timestamp": "2026-05-06T12:00:00+00:00"
}
{
"error": true,
"status_code": 500,
"error_type": "internal_server_error",
"message": "An internal server error occurred",
"details": [
{
"type": "internal_server_error",
"message": "An unexpected error occurred while processing your request"
}
],
"timestamp": "2026-05-06T12:00:00+00:00"
}

