Using Grok API (xAI) with Live Web Search to Perform Skip Trace Automation in C# .NET

Simple C# Console Application demonstrates how to programmatically utilize the Grok API with Live Web Search.

Below I am structuring a question pattern into a JSON payload. Then using an HTTP Client to submit the payload to Grok’s endpoint https://api.x.ai/v1/responses. Result content is then parsed, sanitized, and displayed.

Model used grok-4-1-fast-reasoning
Temperature used 0.0

This example:
Uses HttpClient
Sends a Grok chat request
Enables web search
Prints the final response

Full working C# Console App example that calls Grok (xAI) API and sends a JSON payload enabling web search. Must replace (Your-Grok-API-Key), with your own key.

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml;
using Formatting = Newtonsoft.Json.Formatting;
 
namespace Grok_API_WithWebSearch_Skip_Tracing
{
    internal class Program
    {
        static async Task Main(string[] args)
        {
            /////////////////////////////////////////////////////////////////////
            //SKIP Trace automation example using GROK API with Live Web Search//
            //Model: grok-4-1-fast-reasoning/////////////////////////////////////
            //This program uses Nuget Package: Newtonsoft.Json///////////////////
            /////////////////////////////////////////////////////////////////////
 
            string apiKey = "(Your-Grok-API-Key)"; // <-- Replace this with your key
            string endpoint = "https://api.x.ai/v1/responses";
 
//Structure your question//
//"What is the best Phone Number for [Business Name] in [City], [State], [Zip]?  Please respond with Phone Number only or 'Not found' if unavailable."//
            string question = "What is the best Phone Number for Boathouse in Chattanooga, TN?  Please respond with Phone Number only or 'Not found' if unavailable.";
 
            Console.WriteLine("Asking Grok,");
            Console.WriteLine(question);
            Console.WriteLine();
 
            //Create JSON payload//
            var payload = new
            {
                model = "grok-4-1-fast-reasoning",
                input = question,
                tools = new object[]
                {
                new { type = "web_search" }
                },
                tool_choice = "auto",
                temperature = 0.0
            };
            string jsonPayload = JsonConvert.SerializeObject(payload, Formatting.Indented);
 
            //Start Timer//
            DateTime start_time = DateTime.Now;
 
            using (var client = new HttpClient())
            {
                client.DefaultRequestHeaders.Add("Authorization", $"Bearer {apiKey}");
                var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
                HttpResponseMessage response = await client.PostAsync(endpoint, content);
                string result = await response.Content.ReadAsStringAsync();
 
                try
                {
                    JObject parsed = JObject.Parse(result);
                    var outputArray = parsed["output"] as JArray;
                    string assistantText = null;
                    foreach (var item in outputArray)
                    {
                        var contentArray = item["content"] as JArray;
                        if (contentArray != null)
                        {
                            foreach (var block in contentArray)
                            {
                                if ((string)block["type"] == "output_text")
                                {
                                    assistantText = (string)block["text"];
                                    break;
                                }
                            }
                        }
                        if (assistantText != null) break;
                    }
                    if (assistantText != null)
                    {
                        // Regex pattern for phone number (simple US-style)
                        string phonePattern = @"\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}";
 
                        // Extract Phone Number//
                        Match phoneMatch = Regex.Match(assistantText, phonePattern);
                        string phoneNumber = phoneMatch.Success ? phoneMatch.Value : "Not found";
 
                        //Output Phone Number//
                        Console.ForegroundColor = ConsoleColor.Yellow;
                        Console.WriteLine("Grok Response,");
                        Console.WriteLine(NormalizePhoneNumber(phoneNumber));
                        Console.ResetColor();
                        Console.WriteLine();
 
                        //Stop Timer//
                        DateTime end_time = DateTime.Now;
                        Console.WriteLine("Time elapsed : " 
+ (end_time - start_time).TotalSeconds.ToString("F2") + " seconds");
                        Console.WriteLine();
                    }
                }
                catch (Exception ex)
                {
                    Console.ResetColor();
                }
            }
        }
 
        //Mehtod for formatting phone number structure variance//
        static string NormalizePhoneNumber(string input)
        {
            //Remove all non-digit characters//
            string digits = Regex.Replace(input, @"\D", "");
            //Ensure it has 10 digits//
            if (digits.Length != 10)
                throw new ArgumentException("Phone number must have 10 digits after removing formatting.");
            //Format consistently: (###) ###-####//
            return $"({digits.Substring(0, 3)}) {digits.Substring(3, 3)}-{digits.Substring(6, 4)}";
        }
    }
}