# Number Lookup

> Validate phone numbers and get carrier information before sending messages

Number Lookup allows you to validate phone numbers and retrieve carrier information before sending messages. This helps you:

- **Validate numbers** before adding them to your contact list
- **Identify line types** (mobile, landline, VoIP) for better channel selection
- **Get carrier information** for cost estimation and fraud prevention
- **Determine available channels** (SMS, WhatsApp) for each number

## API Call

Use the `/v1/introspect/phone` endpoint to look up phone number information.

### Request

```bash
curl -X POST https://api.zavu.dev/v1/introspect/phone \
  -H "Authorization: Bearer $ZAVUDEV_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumber": "+14155551234"
  }'
```

### Response

```json
{
  "phoneNumber": "+14155551234",
  "validNumber": true,
  "countryCode": "US",
  "nationalFormat": "(415) 555-1234",
  "lineType": "mobile",
  "carrier": {
    "name": "Verizon Wireless",
    "type": "mobile"
  },
  "availableChannels": ["sms", "whatsapp"]
}
```

### Response Fields

| Field | Type | Description |
|-------|------|-------------|
| `phoneNumber` | string | The queried phone number in E.164 format |
| `validNumber` | boolean | Whether the number is valid |
| `countryCode` | string | ISO 3166-1 alpha-2 country code |
| `nationalFormat` | string | Number formatted for the local country |
| `lineType` | string | Type of line: `mobile`, `landline`, `voip`, `toll_free`, `unknown` |
| `carrier` | object | Carrier information (name and type) |
| `availableChannels` | array | Channels available for messaging: `sms`, `whatsapp` |

## SDK Usage

### TypeScript

```typescript
import Zavudev from '@zavudev/sdk';

const zavu = new Zavudev({
  apiKey: process.env['ZAVUDEV_API_KEY'], // This is the default and can be omitted
});

const result = await zavu.introspect.validatePhone({
  phoneNumber: "+14155551234",
});

if (result.validNumber) {
  console.log("Valid number from:", result.countryCode);
  console.log("Line type:", result.lineType);
  console.log("Carrier:", result.carrier?.name);
  console.log("Available channels:", result.availableChannels.join(", "));
} else {
  console.log("Invalid phone number");
}
```

## Line Types

The `lineType` field indicates the type of phone line:

| Type | Description |
|------|-------------|
| `mobile` | Mobile/cellular phone |
| `landline` | Fixed landline phone |
| `voip` | Voice over IP service (Google Voice, Skype, etc.) |
| `toll_free` | Toll-free number (1-800, etc.) |
| `unknown` | Unable to determine |

## Available Channels

The `availableChannels` array is determined dynamically based on the line type:

| Line Type | SMS | WhatsApp | Notes |
|-----------|-----|----------|-------|
| `mobile` | Yes | Yes | Full messaging support |
| `voip` | Yes | No | VoIP can receive SMS but WhatsApp requires a real mobile number |
| `toll_free` | Yes | No | Toll-free numbers support SMS only |
| `landline` | No | No | Landlines cannot receive text messages |
| `unknown` | Yes | No | Conservative: SMS is more universal |

> **Tip:**
> Use the `availableChannels` array to determine which messaging channels you can use for each number. If a channel is not in the array, messages to that channel will fail.

```typescript
const result = await zavu.introspect.validatePhone({
  phoneNumber: "+14155551234",
});

// Check available channels before sending
if (result.availableChannels.includes("whatsapp")) {
  // WhatsApp is available - this is a mobile number
  await zavu.messages.send({
    to: "+14155551234",
    channel: "whatsapp",
    text: "Hello via WhatsApp!",
  });
} else if (result.availableChannels.includes("sms")) {
  // Fall back to SMS
  await zavu.messages.send({
    to: "+14155551234",
    channel: "sms",
    text: "Hello via SMS!",
  });
} else {
  // No messaging channels available (landline)
  console.error("This number cannot receive messages");
}
```

> **Warning:**
> If `availableChannels` is empty, the number cannot receive any messages. This typically happens with landline numbers or invalid numbers.

## Use Cases

### Pre-send Validation

Validate numbers before sending messages to reduce failed deliveries:

```typescript
const result = await zavu.introspect.validatePhone({
  phoneNumber: customerPhone,
});

if (!result.validNumber) {
  throw new Error("Invalid phone number provided");
}

// Safe to send message
await zavu.messages.send({
  to: customerPhone,
  text: "Your order has shipped!",
});
```

### Channel Selection

Choose the best channel based on line type:

```typescript
const result = await zavu.introspect.validatePhone({
  phoneNumber: customerPhone,
});

// Use WhatsApp for mobile, SMS for others
const channel = result.lineType === "mobile"
  && result.availableChannels.includes("whatsapp")
    ? "whatsapp"
    : "sms";

await zavu.messages.send({
  to: customerPhone,
  channel: channel,
  text: "Hello!",
});
```

### Fraud Prevention

Identify potentially fraudulent numbers by checking line type:

```typescript
const result = await zavu.introspect.validatePhone({
  phoneNumber: userPhone,
});

// Flag VoIP numbers for additional verification
if (result.lineType === "voip") {
  console.warn("VoIP number detected - consider additional verification");
}
```

## Pricing

Number lookup requests are billed separately from messaging. See our [pricing page](https://zavu.dev/pricing) for current rates.

> **Info:**
> Lookup results are cached for 24 hours. Subsequent lookups for the same number within this period will use the cached result.

## Error Handling

### Invalid Phone Number Format

```json
{
  "code": "bad_request",
  "message": "Invalid phone number format. Use E.164 format (e.g., +14155551234)"
}
```

### Rate Limit Exceeded

```json
{
  "code": "rate_limit_exceeded",
  "message": "Too many requests. Please try again later."
}
```

> **Warning:**
> Always include proper error handling in your integration to gracefully handle API errors.
