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

# Get Customer

> Retrieve a customer's details by their unique identifier

## Method Signature

```typescript theme={null}
align.customers.get(customerId: string): Promise<Customer>
```

## Parameters

<ParamField path="customerId" type="string" required>
  The unique customer identifier (UUID format)
</ParamField>

## Returns

<ResponseField name="customer_id" type="string">
  Unique identifier for the customer
</ResponseField>

<ResponseField name="email" type="string">
  Customer's email address
</ResponseField>

<ResponseField name="type" type="'individual' | 'corporate'">
  Customer type
</ResponseField>

<ResponseField name="first_name" type="string">
  Customer's first name (for individuals)
</ResponseField>

<ResponseField name="last_name" type="string">
  Customer's last name (for individuals)
</ResponseField>

<ResponseField name="kycs" type="object">
  KYC verification status and details

  <Expandable title="KYC Object Properties">
    <ResponseField name="kycs.status" type="string">
      Overall KYC status: `pending`, `approved`, `rejected`, `not_started`
    </ResponseField>

    <ResponseField name="kycs.sub_status" type="string">
      Detailed status: `kyc_form_submission_started`,
      `kyc_form_submission_accepted`, `kyc_form_resubmission_required`
    </ResponseField>

    <ResponseField name="kycs.kyc_flow_link" type="string">
      URL for the customer to complete KYC verification
    </ResponseField>
  </Expandable>
</ResponseField>

## Examples

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    import Align from "@tolbel/align";

    const align = new Align({
      apiKey: process.env.ALIGN_API_KEY!,
      environment: "sandbox",
    });

    const customer = await align.customers.get(
      "123e4567-e89b-12d3-a456-426614174000"
    );

    console.log(`Email: ${customer.email}`);
    // Email: alice@example.com

    console.log(`Name: ${customer.first_name} ${customer.last_name}`);
    // Name: Alice Smith

    // Check KYC status
    if (customer.kycs) {
      console.log(`KYC Status: ${customer.kycs.sub_status}`);
      // KYC Status: kyc_form_submission_accepted
    }
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const customer = await align.customers.get(
      "123e4567-e89b-12d3-a456-426614174000"
    );

    console.log("Email:", customer.email);
    console.log("Name:", customer.first_name, customer.last_name);

    if (customer.kycs) {
      console.log("KYC Status:", customer.kycs.sub_status);
    }
    ```
  </Tab>
</Tabs>

### Full Response Example

```json theme={null}
{
  "customer_id": "123e4567-e89b-12d3-a456-426614174000",
  "email": "alice@example.com",
  "type": "individual",
  "first_name": "Alice",
  "last_name": "Smith",
  "kycs": {
    "status": "approved",
    "sub_status": "kyc_form_submission_accepted",
    "kyc_flow_link": "https://kyc.alignlabs.dev/flow/..."
  }
}
```

## Error Handling

```typescript theme={null}
import { AlignError } from "@tolbel/align";

try {
  const customer = await align.customers.get("invalid-id");
} catch (error) {
  if (error instanceof AlignError && error.statusCode === 404) {
    console.error("Customer not found");
  }
}
```

## Monitoring KYC Status

<Warning>
  **Demo Only Notice**: Simple `while` loops or `setInterval` polling are not
  suitable for production applications. They consume unnecessary resources and
  are unreliable if your server restarts.
</Warning>

### Primary Method: Webhooks (Recommended)

The most efficient way to track KYC updates is to listen for the `customer.kycs.updated` webhook event. This allows your application to react in real-time.

```typescript theme={null}
// Webhook Handler (e.g., Express route)
app.post(
  "/webhooks/align",
  express.raw({ type: "application/json" }),
  async (req, res) => {
    // ... Verification logic (see Webhooks documentation) ...

    const event = JSON.parse(req.body.toString());

    if (event.event_type === "customer.kycs.updated") {
      // 1. Get the customer ID from the event
      const customerId = event.entity_id;

      // 2. Fetch the latest customer data to check the new status
      const customer = await align.customers.get(customerId);

      // 3. Handle the status change
      if (customer.kycs?.status === "approved") {
        console.log(`✅ KYC Approved for customer ${customerId}`);
        // TODO: Enable feature access for user
      } else if (customer.kycs?.status === "rejected") {
        console.log(`❌ KYC Rejected for customer ${customerId}`);
        // TODO: Notify user to retry
      }
    }

    res.status(200).send("OK");
  }
);
```

### Secondary Method: Robust Polling (Fallback)

For added reliability, implementing a robust polling mechanism (e.g., a scheduled Cron job or a queue-based worker like BullMQ/Redis) is recommended to double-check statuses in case a webhook event is missed.

**Do not** use simple while-loops in your main request thread. Instead, schedule a background job:

```typescript theme={null}
// Example: Cron job running every 5 minutes
cron.schedule("*/5 * * * *", async () => {
  console.log("Running KYC status sync...");

  // Fetch pending verifications from YOUR database
  const pendingUsers = await db.users.find({ kycStatus: "pending" });

  for (const user of pendingUsers) {
    const customer = await align.customers.get(user.alignCustomerId);

    // Update local database if status has changed
    if (customer.kycs?.status !== user.kycStatus) {
      await db.users.update(user.id, { kycStatus: customer.kycs?.status });
    }
  }
});
```

### Demo/Testing Polling

For scripts or quick local testing **only**, you can use a simple loop:

```typescript theme={null}
async function waitForKycApproval(customerId: string) {
  let attempts = 0;
  while (attempts < 20) {
    const customer = await align.customers.get(customerId);

    if (customer.kycs?.status === "approved") return true;
    if (customer.kycs?.status === "rejected") return false;

    await new Promise((r) => setTimeout(r, 5000)); // Wait 5s
    attempts++;
  }
  return false;
}
```

<Tip>
  Instead of polling, use [webhooks](/docs/api/webhooks/create) to receive
  real-time KYC status updates.
</Tip>

## Related Methods

<CardGroup cols={2}>
  <Card title="Create Customer" icon="user-plus" href="/docs/api/customers/create">
    Create a new customer
  </Card>

  <Card title="List Customers" icon="users" href="/docs/api/customers/list">
    Search and list customers
  </Card>
</CardGroup>
