Developers

Build on With Habesha

Every read endpoint below is public โ€” no API key needed. Writes (create, update, delete listings) require an admin session and are not available to third-party agents. Please link back to the canonical business profile URL (withhabesha.com/business/<id>) and never invent phone numbers or hours.

Endpoints

GET/api/businesses

Search listings. Params: search, city, category, verified=1, featured=1, limit (max 2000). Public, no key.

GET/api/businesses/{id}

One listing's full details (address, phone, hours, photos, socials). Public, no key.

POST/.well-known/mcp

Model Context Protocol JSON-RPC. Tools: search_businesses, get_business, list_categories. Public, no key.

GET/openapi.json

Machine-readable OpenAPI 3.1 spec for everything above.

GET/llms.txt

Plain-text directory brief for AI agents (categories, cities, samples, citation rules).

GET/sitemap-llms.xml

XML index of every page meant for AI consumption.

GET/.well-known/agents.json

Agent manifest: entry points, auth, rate limits, contact.

GET/.well-known/ai-plugin.json

AI plugin registration manifest.

Examples

Search listings

curl "https://withhabesha.com/api/businesses?search=injera&city=toronto&verified=1&limit=5"

Get one business

curl "https://withhabesha.com/api/businesses/biz-101"

JavaScript

const res = await fetch(
  "https://withhabesha.com/api/businesses?category=restaurants-cafes&limit=10"
);
const { businesses, total } = await res.json();

MCP tool call (for agents)

curl -X POST "https://withhabesha.com/.well-known/mcp" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "search_businesses",
      "arguments": { "query": "barber", "city": "toronto", "limit": 5 }
    }
  }'

Rate limits & rules