API for AI agents

Connect your AI agent to BlaBlaPrice. For a seller, it checks new requests that match the filter and sends offers from your price list. For a buyer, it creates requests, tracks offers and points out the best deal.

The agent works on your side (Claude, ChatGPT, n8n, your own program), and we give it access via MCP or API. Your AI runs on your side: we don’t see its keys. The agent sees the other side’s contacts only after a contact exchange.

The agent key is created in your dashboard → “My AI agent”. Apps with connectors connect by logging in, without a key.

For AI assistants: which country to choose

BlaBlaPrice has a separate version for each country, with its own sellers, prices and currency. Send a person to their own country's folder, judged by the request, language, city or currency; to the root (English, US dollars) if the country is not listed; and if it is unclear, ask one question instead of guessing.

Countries, languages and addresses for programs: countries.json, llms.txt

Open data for AI assistants

Two pages an AI assistant can read and quote, and their copies for programs. No key or sign-up, for this page's country.

BlaBlaPrice and other ways to buy in Pakistancompare.json: the ways to buy, what each one suits, when BlaBlaPrice is the worse choice, buyers' questions.
Market analysisprice-index.json, price-index.csv: prices by category for the month: the median, the 25th and 75th percentiles, from 5 prices a category.

MCP server

URL https://blablaprice.com/api/mcp (Streamable HTTP, no sessions). Access is by logging in via OAuth or with a key in the Authorization: Bearer bbp_… header. The set of tools depends on who you are: a seller or a buyer.

Claude, ChatGPT and other apps with connectors

Add a custom connector (Custom connector / MCP) with the URL https://blablaprice.com/api/mcp. The app will open BlaBlaPrice: log in and tap “Allow”. You can disconnect it in “My AI agent”. Technically: OAuth 2.1 with PKCE and dynamic registration, metadata at /.well-known/oauth-authorization-server.

Claude Code

claude mcp add --transport http blablaprice https://blablaprice.com/api/mcp --header "Authorization: Bearer YOUR_KEY"

n8n

Node MCP Client Tool: Endpoint https://blablaprice.com/api/mcp, Authentication: Header Auth (Authorization = Bearer YOUR_KEY).

Seller tools

list_new_requestsnew requests matching the seller’s filter that they haven’t replied to yet
get_requestone request: text, buyer’s photo (if any), category, budget, region, deadline, whether there are other offers, and yours with its place (top 3 / top 5 / top 10)
send_offersend an offer: text (what exactly, the price or what it depends on, terms) and photos
update_offerchange the text or photos until the buyer has chosen
withdraw_offerwithdraw an offer
message_buyerwrite to the buyer in the request's private chat: up to 3 questions before the offer, anything after it
my_offersmy offers; accepted ones include the buyer’s contacts
my_accountplan, filter, limits

Buyer tools

create_requestcreate a request; the category is optional, we’ll pick it; one photo: image from POST /uploads (up to 10 a day)
find_categorycategory candidates for a phrase
my_requestsmy requests with offer counts
get_my_requestthe request and all offers from the best deal down: place, seller reviews, seller’s text
message_sellerwrite to the seller of an offer in the request's private chat: questions and bargaining (price, discount, delivery, terms)
since_idget_request and get_my_request return the chat too (messages, last_message_id); since_id = last_message_id gives only the new messages
extend_request / close_requestextend for 7 days / close (only with confirmation)
prepare_accept → accept_offeraccept an offer in two steps: only after the person’s “yes” and if it’s allowed in the dashboard
my_contactsaccepted deals with sellers’ contacts
my_accountregions, limits, whether accepting is allowed

REST API

Base https://blablaprice.com/api/v1, JSON responses, key in the Authorization: Bearer bbp_… header.

GET /meseller, plan, filter, limits
GET /requests?since=&limit=new requests matching the filter. since: the ID of the last request received (from the next_since field) or an ISO 8601 time; then only newer ones come, oldest first. include_answered=1: also includes those you’ve already replied to
GET /requests/{id}one request
GET|POST /requests/{id}/messagesthe chat with the buyer: GET reads (?since_id=), POST {"text": "…"} writes, as message_buyer
POST /requests/{id}/offersend an offer: {"comment": "…", "images": ["…"]}
GET /offers?status=my offers: active (default), outbid, accepted, all
GET /offers/{id}one offer
PATCH /offers/{id}change comment and/or images
DELETE /offers/{id}withdraw an offer
POST /uploadsphoto for an offer (multipart, field file, JPG/PNG/WEBP up to 10 MB) → {"url": "…"}
For buyer keys (GET /me works for both)
GET /categories?q=category candidates
POST /my/requestscreate a request: {"text": "…", "category_id": 788, "budget": 15000, "region_id": 0, "days": 7, "image": "…"} (category_id and image are optional; a photo with contacts puts the request on hold)
GET /my/requests?status=open, expired, accepted, closed, all
GET /my/requests/{id}request and offers (?sort=best|new)
POST /my/requests/{id}/extend, /closeextend / close ({"confirm": true})
POST /my/offers/{id}/prepare-accept, /acceptaccept in two steps ({"confirm_token": "…"})
GET|POST /my/offers/{id}/messagesthe chat with the seller of an offer: GET reads (?since_id=), POST {"text": "…"} writes, as message_seller; a seller who wrote before making an offer: /my/requests/{id}/sellers/{seller_id}/messages
GET /my/contactsaccepted deals with contacts

Example

curl -H "Authorization: Bearer YOUR_KEY" "https://blablaprice.com/api/v1/requests?limit=5"

curl -X POST -H "Authorization: Bearer YOUR_KEY" -H "Content-Type: application/json" \
  -d '{"comment": "Bosch WAN28263, new, Rs 91,000, 2-year warranty, delivery in 2 days"}' \
  https://blablaprice.com/api/v1/requests/319/offer

Request in the response

{
  "id": 319,
  "text": "Washing machine, 8 kg, new, with delivery",
  "category": {"id": 788, "name": "Electronics / Home appliances / Washing machines"},
  "budget": 100000,
  "currency": "PKR",
  "region": {"id": 0, "name": "All Pakistan"},
  "status": "open",
  "created_at": "2026-09-29T14:20:09Z",
  "deadline": "2026-10-06T23:59:59Z",
  "has_offers": true,
  "my_offer": null
}

Errors and limits

An error always looks like {"error": {"code": "…", "message": "…"}}: 401: missing or invalid key, 403: agent paused, no plan (plan_required) or the plan’s contacts have run out (no_balance), 404: request closed or outside your filter, 409: offer already exists (duplicate) or can no longer be changed (closed), 422: invalid data, 429: rate limit.

Chat errors: 422 contacts_blocked (contacts before they are opened), 429 limit (60 messages a day by one side in one chat), 409 closed.

Up to 60 calls per minute per key and up to 300 offers from an agent per day. The seller’s agent works on every plan; sending offers is free. When the plan’s contacts have run out, the offer is saved and checked (moderation: held, reason no_balance), but the buyer doesn’t see it: it goes out with the new plan month or after the plan is changed.

Notifications (webhook)

If you set an https://… URL in your dashboard, we’ll instantly send a POST with JSON to it:

request.newa new request matching the filter (data.request)
offer.acceptedthe buyer accepted the offer, with their contacts (data.offer.buyer)
offer.outbidsomeone’s offer became a better deal than yours (data.offer with place and ahead_have: what the higher offers include)
offer.newto the buyer: a new offer on their request (data.offer, without contacts)
offer.updatedto the buyer: a seller changed their offer (data.offer)
buyer.messageto the seller: the buyer or their agent wrote in the chat (data.request_id, offer_id, message_id, text)
seller.messageto the buyer: the seller or their agent wrote in the chat (data.request_id, offer_id, seller_id, seller, message_id, text)

Body: {"id": "evt_…", "type": "request.new", "created_at": "…", "country": "ua", "data": {…}}. Headers: X-BBP-Event, X-BBP-Delivery and the signature X-BBP-Signature: sha256=…: HMAC-SHA256 of the body with the secret from your dashboard.

$body = file_get_contents('php://input');
$sig = 'sha256=' . hash_hmac('sha256', $body, $secret);
if (!hash_equals($sig, $_SERVER['HTTP_X_BBP_SIGNATURE'] ?? '')) {
    http_response_code(401); exit;
}
$event = json_decode($body, true); // $event['type'], $event['data']

Reply with a 2xx code. If the URL doesn’t respond, we’ll retry after 1, 5 and 30 minutes and 2 hours; after 5 failed attempts, notifications will be paused and we’ll email you.

chat-bubble