Merka2a as LlamaIndex Function Tools
Wrap the Merka2a REST API as LlamaIndex FunctionTools and hand them to a FunctionAgent so your LlamaIndex app can search, negotiate, and order autonomously.
LlamaIndex agents take a set of FunctionTools and reason about when to call them. There is no dedicated Merka2a LlamaIndex package — and you don't need one. The Merka2a REST API is a handful of endpoints, so three small Python functions wrapped as FunctionTools give a LlamaIndex FunctionAgent full purchasing power.
What We're Building
Three FunctionTools (search_products, negotiate, place_order) backed by the REST API, driven by a LlamaIndex FunctionAgent.
Prerequisites
- Python 3.10+
- A Merka2a API key (register here)
- An OpenAI API key
Installation
pip install llama-index llama-index-llms-openai requests
Step 1: REST Helpers
The API uses Bearer auth and JSON. These thin wrappers are the only integration code you need.
import os
import requests
BASE_URL = "https://merka2a.com"
HEADERS = {
"Authorization": f"Bearer {os.environ['MERKA2A_API_KEY']}",
"Content-Type": "application/json",
}
def search_products(
query: str = "",
category: str = "",
max_budget: int = 0,
currency: str = "GBP",
limit: int = 10,
) -> list:
"""Search the Merka2a marketplace. max_budget is in minor units (e.g. 5000 = £50.00)."""
intent = {"query": query or None, "category": category or None}
if max_budget:
intent["budget"] = {"max": {"amount": max_budget, "currency": currency}}
resp = requests.post(
f"{BASE_URL}/v1/search-intent",
headers=HEADERS,
json={"intent": intent, "pagination": {"limit": limit}},
timeout=30,
)
resp.raise_for_status()
return resp.json().get("results", [])
def negotiate(offer_id: str, target_price: int, currency: str = "GBP", volume: int = 1) -> dict:
"""Negotiate a price. target_price is in minor units. Returns session id and status."""
resp = requests.post(
f"{BASE_URL}/v1/negotiate",
headers=HEADERS,
json={
"offerIds": [offer_id],
"targetPrice": {"amount": target_price, "currency": currency},
"volume": volume,
},
timeout=30,
)
resp.raise_for_status()
return resp.json()
def place_order(
offer_id: str,
quantity: int = 1,
negotiation_session_id: str = "",
shipping_country: str = "GB",
shipping_city: str = "",
shipping_postal_code: str = "",
shipping_method: str = "standard",
) -> dict:
"""Place an order. Pass negotiation_session_id to lock a negotiated price."""
body = {
"offerId": offer_id,
"quantity": quantity,
"shippingAddress": {
"country": shipping_country,
"city": shipping_city or None,
"postalCode": shipping_postal_code or None,
},
"shippingMethod": shipping_method,
}
if negotiation_session_id:
body["negotiationSessionId"] = negotiation_session_id
resp = requests.post(f"{BASE_URL}/v1/create-order", headers=HEADERS, json=body, timeout=30)
resp.raise_for_status()
return resp.json()
Step 2: Wrap as FunctionTools
LlamaIndex reads the docstring and type hints to build the tool schema automatically.
from llama_index.core.tools import FunctionTool
tools = [
FunctionTool.from_defaults(fn=search_products),
FunctionTool.from_defaults(fn=negotiate),
FunctionTool.from_defaults(fn=place_order),
]
Step 3: Build the Agent
from llama_index.core.agent.workflow import FunctionAgent
from llama_index.llms.openai import OpenAI
agent = FunctionAgent(
tools=tools,
llm=OpenAI(model="gpt-4-turbo"),
system_prompt=(
"You are a procurement agent for the Merka2a marketplace. "
"Search, evaluate by price and specs, negotiate when worthwhile, then place the order. "
"Prices are in minor units (pence). Each search result has an 'offerId'."
),
)
Step 4: Run It
import asyncio
async def main():
response = await agent.run(
"Find a wireless mouse under £50, negotiate about 10% off, "
"and ship to London UK (EC1A 1BB)."
)
print(response)
asyncio.run(main())
The agent calls search_products, picks an offer, calls negotiate, and finishes with place_order — passing the returned sessionId as negotiation_session_id to lock the negotiated price.
A Note on Fulfilment
Merka2a aggregates live inventory from electronics distributors (Mouser, Digi-Key, Octopart). place_order records an order with status created; aggregated orders are fulfilled manually by an operator (typically 1–5 business days). Poll the order endpoint to track status.
Next Steps
- Pydantic AI Integration Guide — typed Python agents
- CrewAI Integration Guide — role-based crews with a ready-made package
- API Reference — full endpoint documentation
Ready to give your LlamaIndex agent a marketplace? Get your API key →