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

# Real Contact API

> Real Contact API is a comprehensive lead verification API that verifies and grades phone numbers, emails, and addresses. It returns Phone Activity Score, line type, name matches, and IP-based intelligence signals.

<Panel>
  <RequestExample>
    ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
    curl --request GET \
      --url "https://api.trestleiq.com/2.0/real_contact?name=John%20Doe&phone=4259853735&email=john.doe@example.com&ip_address=192.0.0.1" \
      --header "x-api-key: YOUR_API_KEY"
    ```

    ```javascript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
    const response = await fetch(
      "https://api.trestleiq.com/2.0/real_contact?name=John%20Doe&phone=4259853735&email=john.doe@example.com&ip_address=192.0.0.1",
      {
        headers: {
          "x-api-key": "YOUR_API_KEY",
        },
      }
    );
    const data = await response.json();
    ```

    ```javascript Node.js theme={"theme":{"light":"github-light","dark":"github-dark"}}
    import axios from "axios";

    const { data } = await axios.get(
      "https://api.trestleiq.com/2.0/real_contact?name=John%20Doe&phone=4259853735&email=john.doe@example.com&ip_address=192.0.0.1",
      {
        headers: {
          "x-api-key": "YOUR_API_KEY",
        },
      }
    );
    console.log(data);
    ```

    ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
    import requests

    headers = {"x-api-key": "YOUR_API_KEY"}
    params = {
        "name": "John Doe",
        "phone": "4259853735",
        "email": "john.doe@example.com",
        "ip_address": "192.0.0.1",
    }

    response = requests.get(
        "https://api.trestleiq.com/2.0/real_contact",
        params=params,
        headers=headers,
        timeout=30,
    )
    data = response.json()
    print(data)
    ```

    ```csharp C# theme={"theme":{"light":"github-light","dark":"github-dark"}}
    using var client = new HttpClient();
    client.DefaultRequestHeaders.Add("x-api-key", "YOUR_API_KEY");

    var response = await client.GetAsync("https://api.trestleiq.com/2.0/real_contact?name=John%20Doe&phone=4259853735&email=john.doe@example.com&ip_address=192.0.0.1");
    var body = await response.Content.ReadAsStringAsync();
    Console.WriteLine(body);
    ```

    ```go Go theme={"theme":{"light":"github-light","dark":"github-dark"}}
    package main

    import (
     "fmt"
     "io"
     "net/http"
    )

    func main() {
     req, _ := http.NewRequest("GET", "https://api.trestleiq.com/2.0/real_contact?name=John%20Doe&phone=4259853735&email=john.doe@example.com&ip_address=192.0.0.1", nil)
     req.Header.Set("x-api-key", "YOUR_API_KEY")

     resp, err := http.DefaultClient.Do(req)
     if err != nil {
      panic(err)
     }
     defer resp.Body.Close()

     body, _ := io.ReadAll(resp.Body)
     fmt.Println(string(body))
    }
    ```

    ```php PHP theme={"theme":{"light":"github-light","dark":"github-dark"}}
    <?php
    $curl = curl_init("https://api.trestleiq.com/2.0/real_contact?name=John%20Doe&phone=4259853735&email=john.doe@example.com&ip_address=192.0.0.1");
    curl_setopt($curl, CURLOPT_HTTPHEADER, ["x-api-key: YOUR_API_KEY"]);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

    $response = curl_exec($curl);
    curl_close($curl);

    echo $response;
    ```

    ```java Java theme={"theme":{"light":"github-light","dark":"github-dark"}}
    import java.net.URI;
    import java.net.http.HttpClient;
    import java.net.http.HttpRequest;
    import java.net.http.HttpResponse;

    public class RealContactExample {
      public static void main(String[] args) throws Exception {
        HttpRequest request =
            HttpRequest.newBuilder()
                .uri(
                    URI.create(
                        "https://api.trestleiq.com/2.0/real_contact?name=John%20Doe&phone=4259853735&email=john.doe@example.com&ip_address=192.0.0.1"))
                .header("x-api-key", "YOUR_API_KEY")
                .GET()
                .build();

        HttpResponse<String> response =
            HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println(response.body());
      }
    }
    ```
  </RequestExample>

  <ResponseExample>
    ```json Response Example theme={"theme":{"light":"github-light","dark":"github-dark"}}
    {
      "phone": {
        "contact_grade": "A",
        "is_valid": true,
        "activity_score": 95,
        "line_type": "Mobile",
        "name_match": true
      },
      "email": {
        "contact_grade": "A",
        "is_valid": true,
        "name_match": true
      },
      "address": {
        "is_valid": true,
        "name_match": true
      },
      "ip_address": {
        "trust_score": 92,
        "ip_distance_to_address": 12
      },
      "add_ons": {
        "litigator_checks": {
          "phone_is_litigator_risk": false
        },
        "email_checks": {
          "email_age_score": 95,
          "email_is_deliverable": true
        }
      },
      "warnings": [],
      "errors": null
    }
    ```
  </ResponseExample>
</Panel>

## Real Contact 2.0

```http theme={"theme":{"light":"github-light","dark":"github-dark"}}
GET https://api.trestleiq.com/2.0/real_contact?name=[insert_name]&phone=[insert_phone]&email=[insert_email]&address.street_line_1=[insert_street_line_1]&address.city=[insert_city]&address.state_code=[insert_state_code]&address.postal_code=[insert_postal_code]&address.country_code=[insert_country_code]&ip_address=[insert_ip_address]
```

<Warning>
  **Note:** Authentication must be provided via the `x-api-key` header. Query
  parameter authentication is not supported in v2.0.
</Warning>

## Query Parameters

<ParamField query="name" type="string" required>
  The name of the person to search. **Example:** `name=John Doe`
</ParamField>

<ParamField query="first_name" type="string">
  The first name of the person to search. **Example:** `first_name=John`
</ParamField>

<ParamField query="last_name" type="string">
  The last name of the person to search. **Example:** `last_name=Doe`
</ParamField>

<ParamField query="business.name" type="string">
  The business name to search. **Example:** `business.name=The Golden Company`
</ParamField>

<ParamField query="phone" type="string" required>
  The phone provided by the lead on the web form. **Example:**
  `phone=4259853735`
</ParamField>

<ParamField query="email" type="string">
  The email provided by the lead on the web form. **Example:**
  `email=john.doe@example.com`
</ParamField>

<ParamField query="address.street_line_1" type="string">
  The first line of the street part in the structured address. **Example:**
  `address.street_line_1=100 Syrws St`
</ParamField>

<ParamField query="address.street_line_2" type="string">
  The second line of the street part in the structured address. **Example:**
  `address.street_line_2=Apt 4B`
</ParamField>

<ParamField query="address.city" type="string">
  The name of the city in the structured address. **Example:**
  `address.city=Lynden`
</ParamField>

<ParamField query="address.state_code" type="string">
  The state code of the structured address. **Example:** `address.state_code=WA`
</ParamField>

<ParamField query="address.postal_code" type="string">
  The postal code of the structured address. **Example:**
  `address.postal_code=98229`
</ParamField>

<ParamField query="address.country_code" type="string (ISO-3166-2)">
  The ISO-3166 alpha-2 country code of the address. **Example:**
  `address.country_code=US`
</ParamField>

<ParamField query="ip_address" type="string">
  The IP address captured at the time of interaction (web form, sign up, etc.).
  **Example:** `ip_address=192.0.0.1`
</ParamField>

<ParamField query="add_ons" type="string">
  Request parameter to enable specific add-ons available for this endpoint. Add-ons incur additional charges. Please see [here](https://trestleiq.com/pricing/) for more details.

  * email\_checks\_deliverability: to enable email deliverability checks in the response
  * email\_checks\_age: to enable email age score in the response
  * litigator\_checks: to enable litigator checks in the response

  **Example:** `add_ons=litigator_checks,email_checks_deliverability`
</ParamField>

## Headers

<ParamField header="x-api-key" type="string" required>
  Your API key for authentication. **Example:** `{{ apiKey }}`
</ParamField>

## Response

<ResponseField name="phone" type="object">
  Phone verification and grading results.

  <Expandable title="phone object" defaultOpen>
    <ResponseField name="contact_grade" type="string or null">
      An A-F grade determining the quality of the lead and whether it is contactable. A Grade-F lead is a bad lead and should be deprioritized while a Grade-A lead is real and contactable and should be prioritized. Read up on contact grades in our [Knowledge Base article](https://trestleiq.com/knowledge-base/explain-real-contact-api-grading/).
    </ResponseField>

    <ResponseField name="is_valid" type="boolean or null">
      True if the phone number is valid.
    </ResponseField>

    <ResponseField name="activity_score" type="integer or null">
      Trestle's activity scores range from 0 to 100. A score of 100 means consistent activity in the last 12 months, and a score of 0 means a disconnected number or no activity has been seen in the past year.

      An activity score of 70 or above means there is a high confidence that the phone is connected, assigned to a subscriber, and someone has been taking calls consistently. An activity score of 30 or below means there is a high confidence that the phone is either disconnected or no one will answer the call when the number is dialed in. An activity score of 50 means Trestle doesn't have enough signals to predict whether the phone is connected or disconnected/inactive.

      If you want to filter leads based on the activity score, the following rules can be recommended:

      * Prioritize dialing good numbers with consistent activity: Scores 70 or above.
      * Weed out leads with disconnected/inactive numbers: Scores of 30 or below.
    </ResponseField>

    <ResponseField name="line_type" type="string or null">
      The line type of the phone number. Possible values:

      * `Landline` - Traditional wired phone line
      * `Mobile` - Wireless phone line
      * `FixedVOIP` - VOIP number connected to a physical address
      * `NonFixedVOIP` - VOIP number unconnected to a fixed physical address
      * `Premium` - Caller pays a premium for the call
      * `TollFree` - Callee pays for call
      * `Voicemail` - Voicemail-only service
      * `Other` - Line type is unclear
    </ResponseField>

    <ResponseField name="name_match" type="boolean or null">
      A match/no match indicator whether the name provided on the lead form matches to the input phone number according to our database. A match is a positive indicator that verifies the lead is real and is who he/she says they are.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="email" type="object">
  Email verification and grading results.

  <Expandable title="email object" defaultOpen>
    <ResponseField name="contact_grade" type="string or null">
      An A-F grade determining the quality of the lead and whether it is
      contactable via the email provided. Read up on contact grades in our
      [Knowledge Base
      article](https://trestleiq.com/knowledge-base/explain-real-contact-api-grading/).
    </ResponseField>

    <ResponseField name="is_valid" type="boolean or null">
      True if the email is valid.
    </ResponseField>

    <ResponseField name="name_match" type="boolean or null">
      A match/no match indicator whether the name provided on the lead form
      matches to the input email address according to our database.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="address" type="object">
  Address verification results.

  <Expandable title="address object" defaultOpen>
    <ResponseField name="is_valid" type="boolean or null">
      True if the address is valid.
    </ResponseField>

    <ResponseField name="name_match" type="boolean or null">
      A match/no match indicator whether the name provided on the lead form
      matches to the input address according to our database.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="ip_address" type="object or null">
  IP Trust Score and IP distance results. Returned when an IP address is
  provided in the request.

  <Expandable title="ip_address object" defaultOpen>
    <ResponseField name="trust_score" type="integer or null">
      The IP Trust Score is a 0–100 score that evaluates how legitimate an
      interaction appears based on the user's IP address. It factors in network
      type (VPN, proxy, data center vs. residential), IP reuse/sharing patterns,
      and geographic signals to determine whether the lead, contact, or signup
      is from an authentic source or potentially risky.
    </ResponseField>

    <ResponseField name="ip_distance_to_address" type="integer or null">
      The approximate distance (in miles) between the user's IP location and the
      provided address. This helps assess whether the user's location aligns
      with the provided contact details. This returns NULL values when
      confidence in the location accuracy of the IP address is low.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="add_ons" type="object or null">
  <Expandable title="Add Ons Object" defaultOpen>
    <ResponseField name="litigator_checks" type="object">
      <Expandable title="litigator_checks" defaultOpen>
        <ResponseField name="phone_is_litigator_risk" type="boolean or null">
          True if the phone subscriber is a TCPA litigator.
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="email_checks" type="object">
      <Expandable title="email_checks Object" defaultOpen>
        <ResponseField name="email_is_deliverable" type="boolean or null">
          True if the email is valid and deliverable.
        </ResponseField>

        <ResponseField name="email_age_score" type="integer or null">
          A 0-100 score indicating the longevity and activity-level of an email
          address.
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="errors" type="object(PartialError) or null">
  Error details in case of a partial error, or null if no errors occurred.

  <Expandable title="errors object" defaultOpen>
    <ResponseField name="name" type="string">
      Incomplete response due to external timeouts. **value:** "InternalError"
    </ResponseField>

    <ResponseField name="message" type="string">
      The error message. **value:** "Could not retrieve entire response"
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="warnings" type="string[]">
  Warnings returned as part of the response, if applicable.

  <Badge>Missing Input</Badge>
  <Badge>Missing Unit/Apt/Suite Number</Badge>
  <Badge>Invalid Address</Badge>
  <Badge>Invalid House/Building Number</Badge>
  <Badge>Invalid Unit/Apt/Suite Number</Badge>
  <Badge>Invalid Phone</Badge>
  <Badge>Lead is a Litigator. Must not be contacted.</Badge>
  <Badge>TimeoutError: Timeout getting response for litigator check. Partial response returned.</Badge>
  <Badge>Invalid Email</Badge>
  <Badge>Free Email Service Provider</Badge>
  <Badge>Tumbled Email</Badge>
  <Badge>Disposible Email</Badge>
  <Badge>Privacy Email</Badge>
  <Badge>Email is a spam trap</Badge>
  <Badge>Potential Junk Email</Badge>
  <Badge>Role Based Email</Badge>
  <Badge>Undeliverable Email</Badge>
  <Badge>Domain is a catch all and does not support validation</Badge>
  <Badge>MX forwarding detected. This email may route through a forwarding service.</Badge>
  <Badge>Could not validate email</Badge>
  <Badge>TimeoutError: Timeout getting a response from the email server for email deliverability check</Badge>
  <Badge>Input IP address is invalid. Please provide a valid IPv4 or IPv6 address</Badge>
  <Badge>Timeout getting response for IP information. Partial response returned</Badge>
</ResponseField>

<Danger>
  ## Error Responses

  ### 400 Bad Request

  The server cannot process the request due to client-side errors.

  Check for: Syntax errors in the request script, malformed JSON, or invalid parameters.

  ### 403 Forbidden

  The request is understood, but the server is refusing to fulfill it. Error responses include an `errorCode` field identifying the cause:

  * **Invalid API Key** (`INVALID_API_KEY`): The key is incorrect, deactivated, or missing from the request.

    Check for: Trailing spaces, syntax errors, incorrect character counts, or a missing `x-api-key` header.

  * **API Key Disabled (Portal Issue)** (`FORBIDDEN`): The key is inactive.

    Check for: Insufficient funds in your self-serve wallet or if a Trestle Admin manually deactivated your API key.

  * **API Key does not have Product Access (Portal Issue)** (`FORBIDDEN`): The API key is active, but it is not enabled for this product or API version.

    Check for: Incorrect endpoint, incorrect API version, or missing product access on the key.

  * **API Key Expired** (`FORBIDDEN`): The key has reached its end-of-life (primarily affects Trial users).

  ### 429 Too Many Requests

  You have sent too many requests in a given amount of time.

  * **Rate Limit Exceeded** (`RATE_LIMIT_EXCEEDED`): You have surpassed the queries-per-second (QPS) threshold for your tier.

  * **Quota Exceeded (Portal Issue)** (`QUOTA_EXCEEDED`): You have reached the total volume allowed for your current billing cycle. Upgrade your plan in the portal to resume service.

  ### 500 Internal Server Error

  An unexpected error occurred on the server side. Please contact support if this persists.

  See [Error handling](/guides/errors) for all error response bodies and codes.
</Danger>
