Grok · xAI Function Calling6 min read · Developer guide

UK Parcel Quotes with Grok — Using xAI's Function Calling

Grok's function calling API lets you give the model access to real-world data mid-conversation. This guide shows you how to wire up the AI Parcels API as a Grok tool so it can fetch live UK parcel prices from Evri, DPD, Royal Mail, and more — in real time.

⏱ Time savings estimate

Normally every shipping price check requires a separate HTTP request, parsing a new carrier API, and normalising incompatible formats. With AI Parcels + Grok, a single function call returns a ranked list from every UK carrier. Dev teams report cutting logistics feature time from days to hours.

What you'll be able to do

  • Fetch live UK parcel prices during any Grok conversation
  • Compare rates from 6+ carriers in a single response
  • Find nearby drop-off lockers by UK postcode
  • Walk users through the full booking flow

Prerequisites

  • An xAI API key from console.x.ai
  • Node.js 18+ or Python 3.9+ installed
  • No AI Parcels API key needed — the quote endpoint is open

TypeScript Example

The xAI API is compatible with the OpenAI SDK. Install it with npm i openai, then:

shipping-tool.ts
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.XAI_API_KEY,
  baseURL: "https://api.x.ai/v1",
});

const tools: OpenAI.Chat.ChatCompletionTool[] = [
  {
    type: "function",
    function: {
      name: "get_uk_parcel_quotes",
      description: "Get real-time UK parcel quotes from Evri, DPD, Royal Mail and more.",
      parameters: {
        type: "object",
        properties: {
          originPostcode: { type: "string", description: "UK origin postcode (e.g. SW1A 2AA)" },
          destinationPostcode: { type: "string", description: "Destination postcode" },
          destination: { type: "string", description: "ISO 2-digit country code (e.g. GB, US)" },
          weight: { type: "number", description: "Parcel weight in kilograms" },
          length: { type: "integer", description: "Length in cm" },
          width: { type: "integer", description: "Width in cm" },
          height: { type: "integer", description: "Height in cm" },
        },
        required: ["originPostcode", "weight"],
      },
    },
  },
];

async function fetchQuotes(args: Record<string, string | number>) {
  const dest = (args.destination as string) || "GB";
  const params = new URLSearchParams(
    Object.fromEntries(
      Object.entries(args)
        .filter(([k]) => k !== "destination")
        .map(([k, v]) => [k, String(v)])
    )
  );
  const res = await fetch(
    `https://api.ai.parcels.dotnethelp.co.uk/.api/quote/shipments/GB/${dest}?${params}`
  );
  return res.json();
}

const messages: OpenAI.Chat.ChatCompletionMessageParam[] = [
  { role: "user", content: "Cheapest way to send 3kg parcel SW1A 2AA → EH2 2EQ?" },
];

const response = await client.chat.completions.create({
  model: "grok-3",
  messages,
  tools,
  tool_choice: "auto",
});

const choice = response.choices[0];
if (choice.finish_reason === "tool_calls") {
  const toolCall = choice.message.tool_calls![0];
  const quotes = await fetchQuotes(JSON.parse(toolCall.function.arguments));

  messages.push(choice.message);
  messages.push({ role: "tool", tool_call_id: toolCall.id, content: JSON.stringify(quotes) });

  const final = await client.chat.completions.create({ model: "grok-3", messages, tools });
  console.log(final.choices[0].message.content);
}
Python

Python Example

Install dependencies: pip install openai requests

shipping_tool.py
import os, json, requests
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["XAI_API_KEY"],
    base_url="https://api.x.ai/v1",
)

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_uk_parcel_quotes",
            "description": "Fetch real-time UK parcel prices from Evri, DPD, Royal Mail and more.",
            "parameters": {
                "type": "object",
                "properties": {
                    "originPostcode": {"type": "string"},
                    "destinationPostcode": {"type": "string"},
                    "weight": {"type": "number"},
                    "length": {"type": "integer"},
                    "width": {"type": "integer"},
                    "height": {"type": "integer"},
                },
                "required": ["originPostcode", "weight"],
            },
        },
    }
]

def fetch_quotes(args: dict) -> dict:
    r = requests.get(
        "https://api.ai.parcels.dotnethelp.co.uk/.api/quote/shipments/GB/GB",
        params=args,
    )
    return r.json()

messages = [{"role": "user", "content": "Cheapest parcel SW1A 2AA to EH2 2EQ, 3kg?"}]
resp = client.chat.completions.create(model="grok-3", messages=messages, tools=tools, tool_choice="auto")

choice = resp.choices[0]
if choice.finish_reason == "tool_calls":
    tool_call = choice.message.tool_calls[0]
    result = fetch_quotes(json.loads(tool_call.function.arguments))

    messages.append(choice.message)
    messages.append({"role": "tool", "tool_call_id": tool_call.id, "content": json.dumps(result)})

    final = client.chat.completions.create(model="grok-3", messages=messages)
    print(final.choices[0].message.content)

Example output

Grok's response

Grok

Here are the available options for your 3kg parcel from London to Edinburgh:

  • 💰 Evri Parcel Shop — £3.99 · Delivery: 2–3 days (cheapest)
  • 📮 Royal Mail Tracked 48 — £5.29 · Delivery: 2 days
  • 🚚 DPD Next Day — £7.49 · Delivery: next working day

Evri is the cheapest at £3.99. Shall I look up the nearest Evri drop-off to SW1A 2AA?

When to use Grok for shipping queries

  • xAI API users — if you're building on Grok already, AI Parcels keeps your stack unified
  • X.com workflows — Grok's tight integration with X makes it ideal for social commerce shipping automation
  • Real-time reasoning — Grok excels at fast, factual responses — a natural fit for live price lookups

Explore the full API

Dropshops, requirements, validate, and checkout endpoints.