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

# Unfreeze Card

> Reactivate a frozen card to resume transaction authorizations

## Overview

Reactivates a frozen card, restoring full functionality and allowing transaction authorizations to resume. This endpoint reverses the freeze action, changing the card status from `FROZEN` back to `ACTIVE`.

<Info>
  **Immediate Restoration**

  Unfreezing a card takes effect immediately. The card can be used for transactions within seconds of successful unfreezing.
</Info>

## When to Use

<CardGroup cols={2}>
  <Card title="Issue Resolved" icon="circle-check">
    Suspicious activity has been investigated and resolved
  </Card>

  <Card title="Card Found" icon="magnifying-glass-plus">
    Previously misplaced card has been located
  </Card>

  <Card title="Resume Spending" icon="credit-card">
    User wants to enable the card after voluntary freeze
  </Card>

  <Card title="Subscription Payment" icon="repeat">
    Need to unfreeze before recurring payment date
  </Card>
</CardGroup>

## Authentication

This endpoint requires authentication via Bearer token:

```bash theme={null}
Authorization: Bearer YOUR_ACCESS_TOKEN
```

## Request

### Headers

<ParamField header="x-client-key" type="string" required>
  Your public API client key
</ParamField>

<ParamField header="x-us-env" type="boolean" default={false}>
  Set to `true` to route requests to the US backend environment
</ParamField>

<ParamField header="Authorization" type="string" required>
  Bearer token for authentication
</ParamField>

### Request Example

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://dev.api.baanx.com/v1/card/unfreeze \
    -H "x-client-key: YOUR_CLIENT_KEY" \
    -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://dev.api.baanx.com/v1/card/unfreeze', {
    method: 'POST',
    headers: {
      'x-client-key': 'YOUR_CLIENT_KEY',
      'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
    }
  });

  const result = await response.json();
  console.log(result);
  ```

  ```python Python theme={null}
  import requests

  url = "https://dev.api.baanx.com/v1/card/unfreeze"
  headers = {
      "x-client-key": "YOUR_CLIENT_KEY",
      "Authorization": "Bearer YOUR_ACCESS_TOKEN"
  }

  response = requests.post(url, headers=headers)
  print(response.json())
  ```

  ```typescript TypeScript theme={null}
  interface UnfreezeCardResponse {
    success: boolean;
  }

  const unfreezeCard = async (): Promise<UnfreezeCardResponse> => {
    const response = await fetch('https://dev.api.baanx.com/v1/card/unfreeze', {
      method: 'POST',
      headers: {
        'x-client-key': 'YOUR_CLIENT_KEY',
        'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
      }
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    return await response.json();
  };
  ```
</CodeGroup>

## Response

### Success Response

<ResponseField name="success" type="boolean">
  Indicates whether the card was successfully unfrozen

  **Value:** Always `true` on successful unfreeze
</ResponseField>

<ResponseExample>
  ```json 200 - Success theme={null}
  {
    "success": true
  }
  ```
</ResponseExample>

## Error Responses

<ResponseExample>
  ```json 400 - Bad Request theme={null}
  {
    "message": "Card is not frozen"
  }
  ```

  ```json 401 - Unauthorized theme={null}
  {
    "message": "Not authenticated"
  }
  ```

  ```json 403 - Forbidden theme={null}
  {
    "message": "Not authorized"
  }
  ```

  ```json 404 - Card Not Found theme={null}
  {
    "message": "Card not found"
  }
  ```

  ```json 498 - Invalid Client Key theme={null}
  {
    "message": "Invalid client key"
  }
  ```

  ```json 499 - Missing Client Key theme={null}
  {
    "message": "Missing client key"
  }
  ```

  ```json 500 - Internal Server Error theme={null}
  {
    "message": "Internal server error"
  }
  ```
</ResponseExample>

## What Happens When a Card is Unfrozen?

<Steps>
  <Step title="Status Change">
    The card status changes from `FROZEN` to `ACTIVE` immediately
  </Step>

  <Step title="Transaction Authorization">
    The card can now authorize transactions including:

    * Point-of-sale purchases (online and in-store)
    * ATM withdrawals
    * Recurring subscription payments
    * Pre-authorized transactions
  </Step>

  <Step title="Immediate Availability">
    Transactions can be processed within seconds. Payment processors typically recognize the status change within 1-2 seconds.
  </Step>
</Steps>

## Common Error Scenarios

<AccordionGroup>
  <Accordion title="Card Not Frozen">
    **Error:** `400 Bad Request`

    **Message:** `"Card is not frozen"`

    **Cause:** Attempting to unfreeze a card that is already `ACTIVE` or `BLOCKED`

    **Solution:** Check card status first using `GET /v1/card/status` before attempting to unfreeze
  </Accordion>

  <Accordion title="Cannot Unfreeze BLOCKED Card">
    **Error:** `400 Bad Request`

    **Cause:** Card has `BLOCKED` status (permanently disabled)

    **Solution:** Blocked cards cannot be unfrozen. User must order a new card via `POST /v1/card/order`
  </Accordion>

  <Accordion title="Missing Authentication">
    **Error:** `401 Unauthorized`

    **Cause:** Missing or invalid Bearer token

    **Solution:** Ensure valid access token is included in Authorization header
  </Accordion>
</AccordionGroup>

## Use Case Examples

### Card Found After Loss

```typescript theme={null}
async function handleCardFound() {
  try {
    await unfreezeCard();

    console.log('Card unfrozen and ready to use');

    notifyUser({
      title: 'Card Active',
      message: 'Your card has been unfrozen and is ready for transactions.'
    });

    await refreshCardStatus();
  } catch (error) {
    console.error('Failed to unfreeze card:', error);
    showError('Unable to unfreeze card. Please try again or contact support.');
  }
}
```

### Scheduled Unfreeze Before Subscription

```typescript theme={null}
async function prepareForSubscriptionPayment(subscriptionDate: Date) {
  const now = new Date();
  const hoursUntilPayment = (subscriptionDate.getTime() - now.getTime()) / (1000 * 60 * 60);

  if (hoursUntilPayment <= 24) {
    const card = await getCardStatus();

    if (card.status === 'FROZEN') {
      await unfreezeCard();

      console.log('Card unfrozen for upcoming subscription payment');

      notifyUser({
        title: 'Card Unfrozen',
        message: `Your card has been unfrozen for your subscription payment scheduled for ${subscriptionDate.toLocaleDateString()}`
      });
    }
  }
}
```

### Safe Unfreeze with Status Check

```typescript theme={null}
async function unfreezeCardSafely() {
  try {
    const card = await getCardStatus();

    if (card.status === 'ACTIVE') {
      console.log('Card is already active');
      return { success: true, alreadyActive: true };
    }

    if (card.status === 'BLOCKED') {
      throw new Error('Card is blocked and cannot be unfrozen. Please order a new card.');
    }

    if (card.status === 'FROZEN') {
      await unfreezeCard();
      return { success: true, alreadyActive: false };
    }

    throw new Error(`Unknown card status: ${card.status}`);
  } catch (error) {
    console.error('Failed to unfreeze card:', error);
    throw error;
  }
}
```

## Best Practices

### User Confirmation

```typescript theme={null}
async function promptCardUnfreeze() {
  const confirmed = await showConfirmDialog({
    title: 'Unfreeze Card?',
    message: 'Your card will be activated and ready for transactions immediately.',
    confirmText: 'Unfreeze Card',
    cancelText: 'Keep Frozen'
  });

  if (confirmed) {
    try {
      await unfreezeCard();
      showSuccessMessage('Card is now active');

      await refreshCardStatus();
    } catch (error) {
      showErrorMessage('Failed to unfreeze card. Please try again.');
    }
  }
}
```

### Status Verification

```typescript theme={null}
async function unfreezeAndVerify() {
  await unfreezeCard();

  await new Promise(resolve => setTimeout(resolve, 500));

  const card = await getCardStatus();

  if (card.status !== 'ACTIVE') {
    console.warn('Card status is not ACTIVE after unfreeze operation');
    throw new Error('Card unfreeze verification failed');
  }

  return card;
}
```

### UI State Management

```typescript theme={null}
function CardControls({ cardStatus }: { cardStatus: CardStatus }) {
  const [isUnfreezing, setIsUnfreezing] = useState(false);

  const handleUnfreeze = async () => {
    setIsUnfreezing(true);
    try {
      await unfreezeCard();
      onStatusChange('ACTIVE');
    } catch (error) {
      console.error('Unfreeze failed:', error);
      showError('Failed to unfreeze card');
    } finally {
      setIsUnfreezing(false);
    }
  };

  return (
    <button
      onClick={handleUnfreeze}
      disabled={isUnfreezing || cardStatus === 'ACTIVE' || cardStatus === 'BLOCKED'}
    >
      {isUnfreezing ? 'Unfreezing...' : 'Unfreeze Card'}
    </button>
  );
}
```

## Freeze/Unfreeze Toggle Component

```typescript theme={null}
function CardFreezeToggle() {
  const [card, setCard] = useState<CardStatus | null>(null);
  const [isProcessing, setIsProcessing] = useState(false);

  useEffect(() => {
    loadCardStatus();
  }, []);

  const loadCardStatus = async () => {
    const status = await getCardStatus();
    setCard(status);
  };

  const toggleFreeze = async () => {
    if (!card) return;

    setIsProcessing(true);
    try {
      if (card.status === 'ACTIVE') {
        await freezeCard();
        setCard({ ...card, status: 'FROZEN' });
      } else if (card.status === 'FROZEN') {
        await unfreezeCard();
        setCard({ ...card, status: 'ACTIVE' });
      }
    } catch (error) {
      console.error('Toggle freeze failed:', error);
      showError('Operation failed. Please try again.');
    } finally {
      setIsProcessing(false);
    }
  };

  if (!card) return <div>Loading...</div>;

  if (card.status === 'BLOCKED') {
    return <div>Card is blocked. Order a new card.</div>;
  }

  return (
    <div>
      <p>Status: {card.status}</p>
      <button onClick={toggleFreeze} disabled={isProcessing}>
        {isProcessing
          ? 'Processing...'
          : card.status === 'ACTIVE'
          ? 'Freeze Card'
          : 'Unfreeze Card'}
      </button>
    </div>
  );
}
```

## Testing

### Sandbox Testing

```typescript theme={null}
describe('Card Unfreeze Flow', () => {
  it('should unfreeze frozen card', async () => {
    await freezeCard();

    const statusBefore = await getCardStatus();
    expect(statusBefore.status).toBe('FROZEN');

    const result = await unfreezeCard();
    expect(result.success).toBe(true);

    const statusAfter = await getCardStatus();
    expect(statusAfter.status).toBe('ACTIVE');
  });

  it('should allow transactions after unfreeze', async () => {
    await freezeCard();
    await unfreezeCard();

    const transaction = await attemptTransaction({ amount: 10.00 });
    expect(transaction.status).toBe('CONFIRMED');
  });

  it('should fail to unfreeze already active card', async () => {
    const card = await getCardStatus();
    expect(card.status).toBe('ACTIVE');

    await expect(unfreezeCard()).rejects.toThrow('Card is not frozen');
  });
});
```

## Important Notes

<Warning>
  **Cannot Unfreeze BLOCKED Cards**

  Cards with `BLOCKED` status are permanently disabled and cannot be unfrozen. These cards require replacement via `POST /v1/card/order`.
</Warning>

<Info>
  **Real-Time Effect**

  Card unfreezing takes effect immediately. Payment processors recognize the status change within 1-2 seconds, allowing near-instant transaction processing.
</Info>

<Note>
  **Idempotency**

  Calling this endpoint on an already active card will return a `400 Bad Request` error. Check card status first if unsure of the current state.
</Note>

## Related Endpoints

* `POST /v1/card/freeze` - Freeze an active card to prevent transactions
* `GET /v1/card/status` - Check current card status
* `GET /v1/card/transactions` - View transaction history
* `POST /v1/card/order` - Order a replacement card (for blocked cards)
