# Add Verified Contact
> Source: /api-reference/members/auth/verified-contact
> Sync verified contact and link reservations
> Endpoint: POST /members/me/auth/verified-contact

## Overview [#overview]

Call this endpoint after verifying a new email/phone via Clerk OTP to:
1. Add the contact to verified contacts (if unique)
2. Search for unlinked reservations matching this contact
3. Link matching reservations with appropriate financial handling
4. Return detailed results for client display

## Authentication [#authentication]

Requires a valid Clerk JWT token in the Authorization header.

## Request Body [#request-body]

<ParamField body="type" type="string" required>
  Contact type: "phone" or "email"
</ParamField>

<ParamField body="value" type="string" required>
  Phone number (E.164 format) or email address
</ParamField>

<ParamField body="claimReservationId" type="number">
  Optional specific reservation ID to claim during this verification
</ParamField>

<RequestExample>

```bash cURL
curl -X POST "http://localhost:3000/v1/members/me/auth/verified-contact" \
  -H "Authorization: Bearer YOUR_CLERK_JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "email",
    "value": "john.doe@example.com"
  }'
```

```typescript TypeScript
const response = await fetch('http://localhost:3000/v1/members/me/auth/verified-contact', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_CLERK_JWT',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    type: "email",
    value: "john.doe@example.com"
  })
});

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

```javascript Bruno
// From: /bruno/Members (Surface)/Me/Auth/Add Verified Contact.bru
POST {{host}}/members/me/auth/verified-contact
Authorization: Bearer {{clerkJwt}}
Content-Type: application/json

{
  "type": "email",
  "value": "john.doe@example.com"
}
```

</RequestExample>

## Response [#response]

<ResponseField name="contact" type="object" required>
  Contact sync result
  
  <Expandable title="properties">
    <ResponseField name="status" type="string" required>
      Contact status: "added", "exists", or "rejected"
    </ResponseField>
    
    <ResponseField name="reason" type="string">
      Additional context for the status
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="reservationsLinked" type="number" required>
  Number of reservations successfully linked
</ResponseField>

<ResponseField name="totalCreditIssued" type="number" required>
  Total CREDIT points issued for future checkouts
</ResponseField>

<ResponseField name="totalValidAwarded" type="number" required>
  Total VALID points awarded from escrow conversion
</ResponseField>

<ResponseField name="linkedReservations" type="array" required>
  Details of each linked reservation
  
  <Expandable title="array items">
    <ResponseField name="reservationId" type="number" required>
      Reservation ID
    </ResponseField>
    
    <ResponseField name="confirmationCode" type="string" required>
      Reservation confirmation code
    </ResponseField>
    
    <ResponseField name="propertyName" type="string" required>
      Property name
    </ResponseField>
    
    <ResponseField name="checkInDate" type="string" required>
      Check-in date
    </ResponseField>
    
    <ResponseField name="checkOutDate" type="string" required>
      Check-out date
    </ResponseField>
    
    <ResponseField name="financialOutcome" type="string" required>
      Financial result: "PENDING_FUTURE", "WITHIN_CLAIM_WINDOW", "CLAIM_WINDOW_EXPIRED"
    </ResponseField>
    
    <ResponseField name="pointsAwarded" type="number" required>
      Points awarded for this reservation
    </ResponseField>
    
    <ResponseField name="awardContext" type="string" required>
      Award context: "UNCLAIMED", "MEMBER_ENROLLED", "MEMBER_INELIGIBLE", "MEMBER_DIRECT", "MEMBER_INDIRECT"
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseExample>

```json 200 Response - Contact Added, Reservations Linked
{
  "contact": {
    "status": "added",
    "reason": "Contact successfully verified and added"
  },
  "reservationsLinked": 2,
  "totalCreditIssued": 1500,
  "totalValidAwarded": 2500,
  "linkedReservations": [
    {
      "reservationId": 12345,
      "confirmationCode": "ABC123",
      "propertyName": "Luxury Resort & Spa",
      "checkInDate": "2024-05-15",
      "checkOutDate": "2024-05-18",
      "financialOutcome": "PENDING_FUTURE",
      "pointsAwarded": 1500,
      "awardContext": "MEMBER_ENROLLED"
    },
    {
      "reservationId": 12346,
      "confirmationCode": "XYZ789",
      "propertyName": "Downtown Hotel",
      "checkInDate": "2024-03-10",
      "checkOutDate": "2024-03-12",
      "financialOutcome": "WITHIN_CLAIM_WINDOW",
      "pointsAwarded": 2500,
      "awardContext": "MEMBER_ENROLLED"
    }
  ]
}
```

```json 200 Response - Contact Already Exists
{
  "contact": {
    "status": "exists",
    "reason": "Contact already verified for this member"
  },
  "reservationsLinked": 0,
  "totalCreditIssued": 0,
  "totalValidAwarded": 0,
  "linkedReservations": []
}
```

```json 200 Response - Contact Rejected
{
  "contact": {
    "status": "rejected",
    "reason": "Contact is already verified by another member"
  },
  "reservationsLinked": 0,
  "totalCreditIssued": 0,
  "totalValidAwarded": 0,
  "linkedReservations": []
}
```

</ResponseExample>

## Financial Outcomes [#financial-outcomes]

Different financial outcomes based on reservation timing:

### PENDING_FUTURE [#pending_future]
- **When**: Checkout date is in the future
- **Action**: Issues CREDIT points for immediate spending
- **Points**: Available immediately in member wallet

### WITHIN_CLAIM_WINDOW [#within_claim_window]  
- **When**: Recently checked out (within claim window)
- **Action**: Converts escrow to VALID points
- **Points**: Added to lifetime/tier-eligible totals

### CLAIM_WINDOW_EXPIRED [#claim_window_expired]
- **When**: Old checkout beyond claim window
- **Action**: Link for data only, no points awarded
- **Points**: 0 (window missed)

## Award Contexts [#award-contexts]

Different scenarios based on member status at booking time:

### UNCLAIMED [#unclaimed]
- **When**: No member was linked at booking time
- **Award**: 1x points from escrow holding tank

### MEMBER_ENROLLED [#member_enrolled]  
- **When**: First-time linking for new member
- **Award**: One-time 1x award from Journey funding wallet

### MEMBER_INELIGIBLE [#member_ineligible]
- **When**: Late-joiner but signup bonus already used
- **Award**: 0x points (escrow voided)

### MEMBER_DIRECT [#member_direct]
- **When**: Member existed before booking, direct channel
- **Award**: 5x points multiplier

### MEMBER_INDIRECT [#member_indirect]
- **When**: Member existed before booking, non-direct channel  
- **Award**: 0x points (escrow voided)

## Related Endpoints [#related-endpoints]

- [Validate Auth](/api-reference/members/auth/validate) - Provision member account
- [Get OTP Status](/api-reference/members/auth/otp-status) - Check SMS delivery
