> ## Documentation Index
> Fetch the complete documentation index at: https://casparser.in/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Portfolio Connect SDK

> Drop-in React widget for portfolio import. PDF upload, Gmail inbox, CDSL OTP — all in one modal.

Portfolio Connect is a white-label UI widget for importing Indian portfolios. One component handles file upload, Gmail import, and CDSL OTP fetch.

<Card title="Live Demo" icon="eye" href="https://connect.casparser.in">
  Try the widget at connect.casparser.in
</Card>

<Tabs>
  <Tab title="Upload PDF">
    Drag and drop CAS PDFs or browse files
  </Tab>

  <Tab title="Gmail Import">
    Import CAS files directly from email via OAuth
  </Tab>

  <Tab title="CDSL OTP">
    Fetch live demat holdings via OTP verification
  </Tab>
</Tabs>

### Supported Statements

| Statement               | Covers                                                                           | Methods                                                         |
| ----------------------- | -------------------------------------------------------------------------------- | --------------------------------------------------------------- |
| **CAMS / KFintech CAS** | Mutual Funds (Demat + Non-Demat)                                                 | PDF upload, Email request via KFintech, Gmail Inbox integration |
| **CDSL eCAS**           | All holdings (CDSL + NSDL): Stocks, ETFs, Bonds, SGBs, Demat/Non-Demat MFs, AIFs | PDF upload, OTP fetch, Gmail Inbox integration                  |
| **NSDL eCAS**           | All holdings (NSDL + CDSL): Stocks, ETFs, Bonds, SGBs, Demat/Non-Demat MFs, AIFs | PDF upload, Gmail Inbox integration                             |

<Note>
  **Cross-depository coverage:** Both CDSL and NSDL eCAS statements contain holdings from **both** depositories, not just the issuing depository.
</Note>

## Installation

<Tabs>
  <Tab title="npm">
    ```bash theme={null}
    npm install @cas-parser/connect
    ```
  </Tab>

  <Tab title="yarn">
    ```bash theme={null}
    yarn add @cas-parser/connect
    ```
  </Tab>

  <Tab title="CDN">
    ```html theme={null}
    <script src="https://cdn.jsdelivr.net/npm/@cas-parser/connect/dist/portfolio-connect.standalone.min.js"></script>
    ```
  </Tab>
</Tabs>

## Quick Start

### React / Next.js

```jsx theme={null}
import { PortfolioConnect } from '@cas-parser/connect';

function App() {
  return (
    <PortfolioConnect
      accessToken="your_access_token"
      config={{
        enableGenerator: true,   // MF email fetch
        enableCdslFetch: true,   // CDSL OTP fetch
        enableInbox: true,       // Gmail inbox import
      }}
      onSuccess={(data) => console.log(data.holdings)}
    >
      {({ open }) => <button onClick={open}>Import Investments</button>}
    </PortfolioConnect>
  );
}
```

### Vanilla JavaScript

```html theme={null}
<script src="https://cdn.jsdelivr.net/npm/@cas-parser/connect/dist/portfolio-connect.standalone.min.js"></script>
<button id="import-btn">Import Portfolio</button>

<script>
document.getElementById('import-btn').onclick = async () => {
  try {
    const { data, metadata } = await PortfolioConnect.open({
      accessToken: 'your_access_token',
      config: { enableCdslFetch: true }
    });
    console.log('Holdings:', data.holdings);
  } catch (error) {
    if (error.message === 'Widget closed by user') {
      console.log('User cancelled');
    } else {
      console.error('Error:', error.message);
    }
  }
};
</script>
```

## Access Tokens

<Warning>
  **Never expose your API key to the frontend.** Generate short-lived access tokens from your backend.
</Warning>

```python theme={null}
# Backend: Generate access token
import requests

response = requests.post(
    "https://api.casparser.in/v1/token",
    headers={"x-api-key": "your_api_key"},
    json={"expiry_minutes": 60}
)
access_token = response.json()["access_token"]
# Pass this at_ prefixed token to your frontend
```

Access tokens:

* Are prefixed with `at_` for easy identification
* Valid for up to 60 minutes
* Can be used in place of API keys on all v4 endpoints
* Cannot be used to generate other access tokens

## Response Data

See full schema: [Response Schema](/learn/response-schema)

```typescript theme={null}
interface ParsedData {
  meta: {
    cas_type: 'CAMS_KFINTECH' | 'CDSL' | 'NSDL';
    statement_period: {
      from: string;  // YYYY-MM-DD
      to: string;    // YYYY-MM-DD
    };
    generated_at: string;  // ISO 8601
  };
  investor: {
    name: string;
    pan: string;
    email?: string;
    mobile?: string;
    address?: string;
    pincode?: string;
    cas_id?: string;
  };
  summary: {
    total_value: number;
    accounts: {
      demat: { count: number; total_value: number };
      mutual_funds: { count: number; total_value: number };
      insurance: { count: number; total_value: number };
      nps: { count: number; total_value: number };
    };
  };
  demat_accounts: Array<DematAccount>;
  mutual_funds: Array<MutualFundFolio>;
  insurance: {
    life_insurance_policies: Array<LifeInsurancePolicy>;
  };
  nps: Array<NPSAccount>;
}
```

## Security

| Feature            | Details                                    |
| ------------------ | ------------------------------------------ |
| **Data Hosting**   | 100% India-hosted (DigitalOcean Bangalore) |
| **Encryption**     | TLS 1.3 in transit, AES-256 at rest        |
| **Data Retention** | PDFs deleted immediately after parsing     |
| **Credentials**    | We never store user passwords              |

<Card title="Full Configuration Guide" icon="book" href="/sdk/configuration">
  Complete configuration options, events, error handling, and framework examples
</Card>
