<!-- AUTO-GENERATED by export-skills.py — DO NOT EDIT -->
---
name: core-insurance-integration
description: Core insurance system integration patterns for AI agents connecting to Guidewire InsuranceSuite and Duck Creek Technologies. Use when building agents that interact with policy admin, claims, billing, or underwriting APIs.
tags: [insurance, guidewire, duck-creek, policy, claims]
---

> **Platform Note:** This skill was designed for multi-agent execution. Perplexity Computer handles orchestration automatically — treat sub-agent instructions as sequential steps to complete thoroughly.

# Core Insurance System Integration

Connect AI agents to core insurance platforms (Guidewire InsuranceSuite, Duck Creek Technologies) for policy administration, claims processing, billing, and underwriting workflows.

## When to Use

- Building AI agents that query or manage insurance policies, claims, and billing
- Integrating with Guidewire Cloud (PolicyCenter, ClaimCenter, BillingCenter) via REST APIs
- Integrating with Duck Creek OnDemand (Policy, Claims, Billing) via REST APIs
- Automating underwriting, FNOL intake, or claims adjudication with AI-assisted decisioning

## Platform Comparison

| Platform | Architecture | API Style | Strength |
|---|---|---|---|
| **Guidewire InsuranceSuite** | Cloud-native (Guidewire Cloud) | REST + Cloud API | Market leader (P&C), 500+ insurers |
| **Duck Creek Technologies** | SaaS (OnDemand) | REST | Configurable, multi-line support |
| **Majesco** | Cloud-native | REST | Mid-market, speed to market |
| **Socotra** | API-first cloud-native | REST/GraphQL | Modern, developer-friendly |

## Patterns

### 1. Guidewire Cloud API (PolicyCenter)

```python
import requests

class GuidewireClient:
    def __init__(self, base_url: str, token: str):
        self.base_url = base_url.rstrip("/")
        self.headers = {
            "Authorization": f"Bearer {token}",
            "Content-Type": "application/json",
            "GW-Specification": "composite",
        }

    # --- PolicyCenter ---
    def search_policies(self, policy_number: str = "", insured_name: str = "") -> list[dict]:
        """Search policies by number or insured name."""
        params = {}
        if policy_number:
            params["filter"] = f"policyNumber eq '{policy_number}'"
        elif insured_name:
            params["filter"] = f"insuredName sw '{insured_name}'"
        resp = requests.get(
            f"{self.base_url}/pc/rest/composite/v1/policies",
            headers=self.headers,
            params=params,
        )
        resp.raise_for_status()
        return resp.json().get("data", [])

    def get_policy(self, policy_id: str) -> dict:
        """Get full policy details."""
        resp = requests.get(
            f"{self.base_url}/pc/rest/composite/v1/policies/{policy_id}",
            headers=self.headers,
        )
        resp.raise_for_status()
        return resp.json().get("data", {})

    # --- ClaimCenter ---
    def create_claim(self, policy_id: str, loss_date: str, description: str) -> dict:
        """Create a new claim (FNOL)."""
        payload = {
            "data": {
                "attributes": {
                    "policyNumber": policy_id,
                    "lossDate": loss_date,
                    "description": description,
                    "lossCause": "auto_collision",
                }
            }
        }
        resp = requests.post(
            f"{self.base_url}/cc/rest/composite/v1/claims",
            headers=self.headers,
            json=payload,
        )
        resp.raise_for_status()
        return resp.json().get("data", {})

    def get_claim(self, claim_id: str) -> dict:
        """Get claim details with activities."""
        resp = requests.get(
            f"{self.base_url}/cc/rest/composite/v1/claims/{claim_id}",
            headers=self.headers,
        )
        resp.raise_for_status()
        return resp.json().get("data", {})

    def search_claims(self, policy_number: str = "", status: str = "") -> list[dict]:
        """Search claims by policy or status."""
        params = {}
        filters = []
        if policy_number:
            filters.append(f"policyNumber eq '{policy_number}'")
        if status:
            filters.append(f"state eq '{status}'")
        if filters:
            params["filter"] = " and ".join(filters)
        resp = requests.get(
            f"{self.base_url}/cc/rest/composite/v1/claims",
            headers=self.headers,
            params=params,
        )
        resp.raise_for_status()
        return resp.json().get("data", [])

    # --- BillingCenter ---
    def get_account_billing(self, account_id: str) -> dict:
        """Get billing summary for an account."""
        resp = requests.get(
            f"{self.base_url}/bc/rest/composite/v1/accounts/{account_id}",
            headers=self.headers,
        )
        resp.raise_for_status()
        return resp.json().get("data", {})
```

### 2. Duck Creek OnDemand API

```python
import requests

class DuckCreekClient:
    def __init__(self, base_url: str, token: str):
        self.base_url = base_url.rstrip("/")
        self.headers = {
            "Authorization": f"Bearer {token}",
            "Content-Type": "application/json",
        }

    def get_policy(self, policy_id: str) -> dict:
        """Get policy from Duck Creek Policy."""
        resp = requests.get(
            f"{self.base_url}/api/policies/{policy_id}",
            headers=self.headers,
        )
        resp.raise_for_status()
        return resp.json()

    def get_claim(self, claim_id: str) -> dict:
        """Get claim from Duck Creek Claims."""
        resp = requests.get(
            f"{self.base_url}/api/claims/{claim_id}",
            headers=self.headers,
        )
        resp.raise_for_status()
        return resp.json()

    def submit_fnol(self, policy_id: str, loss_date: str, description: str, claimant_name: str) -> dict:
        """Submit First Notice of Loss."""
        payload = {
            "policyId": policy_id,
            "lossDate": loss_date,
            "lossDescription": description,
            "claimantName": claimant_name,
        }
        resp = requests.post(
            f"{self.base_url}/api/claims/fnol",
            headers=self.headers,
            json=payload,
        )
        resp.raise_for_status()
        return resp.json()

    def get_billing_account(self, account_id: str) -> dict:
        """Get billing account details."""
        resp = requests.get(
            f"{self.base_url}/api/billing/accounts/{account_id}",
            headers=self.headers,
        )
        resp.raise_for_status()
        return resp.json()
```

### 3. Agent Tool Pattern for Insurance

```python
def lookup_policy(policy_number: str) -> str:
    """Look up an insurance policy by its number.

    Args:
        policy_number: The policy number (e.g., 'POL-2024-001234')
    """
    client = GuidewireClient(base_url=GW_URL, token=GW_TOKEN)
    policies = client.search_policies(policy_number=policy_number)
    if not policies:
        return f"No policy found with number {policy_number}"
    policy = policies[0]
    attrs = policy.get("attributes", {})
    return (
        f"Policy: {attrs.get('policyNumber')}\n"
        f"Product: {attrs.get('productName')}\n"
        f"Status: {attrs.get('status')}\n"
        f"Effective: {attrs.get('effectiveDate')} - {attrs.get('expirationDate')}\n"
        f"Premium: ${attrs.get('totalPremium', 0):,.2f}"
    )

def file_claim(policy_number: str, loss_date: str, description: str) -> str:
    """File a new insurance claim (FNOL).

    Args:
        policy_number: The policy number to file against
        loss_date: Date of loss (YYYY-MM-DD)
        description: Description of the loss/incident
    """
    client = GuidewireClient(base_url=GW_URL, token=GW_TOKEN)
    claim = client.create_claim(policy_number, loss_date, description)
    claim_num = claim.get("attributes", {}).get("claimNumber", "unknown")
    return f"Claim {claim_num} created successfully for policy {policy_number}."
```

## Anti-Patterns

- Allowing AI agents to auto-approve claims above threshold -- always require human review for high-value claims
- Exposing PII (SSN, DOB, health data) to LLMs -- mask before passing to model, log access for compliance
- Skipping idempotency on FNOL submission -- duplicate claims create operational overhead
- Direct database access bypassing core system APIs -- violates data integrity and audit trail
- Not respecting policy lifecycle states -- check policy status before allowing operations (e.g., no claims on expired policies)

## References

- [Guidewire Cloud API](https://docs.guidewire.com/cloud/)
- [Duck Creek Technologies](https://www.duckcreek.com/products/)
- [Socotra API](https://docs.socotra.com/)
- [Majesco Platform](https://www.majesco.com/)

<!-- Source: .faos/custom/skills/integrations/core-insurance-integration/SKILL.md -->
