Bowlly Agent API
Clean, affiliate-free product data for AI agents and applications. Access comprehensive cat food information without tracking links.
Quick Start
Make your first request with your API key:
curl -H "X-API-Key: your_api_key_here" "https://api.bowlly.net/agent/products?limit=5"Example response:
{
"items": [
{
"id": "product-123",
"name": "Premium Cat Food",
"brand": "Acme",
"detailUrl": "https://bowlly.net/products/product-123?src=agent",
"imageUrl": "https://bowlly.net/api/images/product-123-thumb.jpg",
"form": "dry",
"lifeStageTags": ["adult"],
"conditionTags": ["sensitive"],
"nutrition": {
"protein": 40,
"fat": 20,
"fiber": 3,
"moisture": 10
},
"derivedMetrics": {
"meatScore": 85,
"carbEstimated": 15
}
}
],
"meta": {
"total": 1500,
"offset": 0,
"limit": 20,
"hasMore": true,
"query": { "search": "", "filters": {} },
"executionTimeMs": 45,
"apiVersion": "1.0.0",
"timestamp": "2026-02-19T12:00:00Z"
}
}Authentication
API Key Required
All Agent API endpoints require an API key passed in the X-API-Key header. Public self-serve key issuance is not available yet.
curl -H "X-API-Key: your_api_key_here" "https://api.bowlly.net/agent/products?limit=5"Authentication Errors
| Status | Description | Response |
|---|---|---|
| 401 | Unauthorized - Missing or invalid API key | { error: "Authentication required" } |
| 403 | Forbidden - API key revoked | { error: "API key revoked" } |
Rate Limiting
100 Requests per Minute per API Key
Each API key is limited to 100 requests per minute. If you exceed this limit, you will receive a 429 Too Many Requests response with a Retry-After header indicating when you can retry.
HTTP/1.1 429 Too Many Requests
Retry-After: 45
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
{
"error": "Rate limit exceeded. Please try again later.",
"code": "RATE_LIMITED"
}Need higher limits? Contact us at contact@bowlly.net
Base URL
Production
https://api.bowlly.netDevelopment
http://localhost:3001Endpoints
/agent/productsList products with optional filtering and pagination.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| offset | integer | 0 | Number of results to skip |
| limit | integer | 20 | Number of results to return (max 50) |
| search | string | - | Search term for product name/brand |
| form | string | - | Filter by form: "dry" or "wet" |
| grainFree | boolean | - | Filter for grain-free products only |
| primaryProtein | string | - | Filter by primary protein (e.g., "chicken", "salmon") |
| minProtein | number | - | Minimum protein percentage |
| maxProtein | number | - | Maximum protein percentage |
| minMeatScore | number | - | Minimum meat score (0-100) |
| maxMeatScore | number | - | Maximum meat score (0-100) |
| conditions | string | - | Comma-separated condition tags |
| agent | string | - | Identifies calling agent (e.g., "chatgpt", "claude") |
Scalability Notes
Current `/agent/products` uses active-catalog query + in-memory filtering for MVP speed. For stable latency, keep active catalog around ~500 products. Above that, we recommend filter-specific indexes or a dedicated search service.
Response Format
Product Object
{
"id": "string", // Unique product identifier
"name": "string", // Product name
"brand": "string", // Brand name
"detailUrl": "string", // Bowlly product page URL (with src=agent)
"imageUrl": "string", // Thumbnail image URL (optional)
"form": "dry" | "wet", // Product form (optional)
"lifeStageTags": [], // Array of life stage tags (optional)
"conditionTags": [], // Array of condition tags (optional)
"nutrition": { // Nutritional data (optional)
"protein": number, // Protein percentage
"fat": number, // Fat percentage
"fiber": number, // Fiber percentage
"moisture": number // Moisture percentage
},
"derivedMetrics": { // Computed metrics (optional)
"meatScore": number, // 0-100 meat content score
"carbEstimated": number // Estimated carbohydrate percentage
}
}Meta Object
{
"total": number, // Total matching products
"offset": number, // Current offset
"limit": number, // Results per page
"hasMore": boolean, // Whether more results exist
"query": { // Applied query parameters
"search": "string",
"filters": {}
},
"executionTimeMs": number,// Query execution time
"apiVersion": "string", // API version
"timestamp": "string" // ISO 8601 response timestamp
}Error Handling
| Status | Description | Response |
|---|---|---|
| 200 | Success | { items: [], meta: {} } |
| 400 | Bad Request | { error: "Invalid parameter" } |
| 429 | Rate Limited | { error: "Rate limit exceeded" } |
| 500 | Server Error | { error: "Internal server error" } |
Example Requests
Basic Request
GET /agent/products?limit=10With Search Filter
GET /agent/products?search=grain-free&form=dry&limit=20With Pagination
GET /agent/products?offset=20&limit=20With Agent Identification
GET /agent/products?agent=chatgpt&limit=5The agent parameter helps us understand API usage patterns and optimize for different AI platforms.
Complex Filter
GET /agent/products?form=dry&minProtein=35&grainFree=true&conditions=sensitive,urinaryGPT Actions Integration
Use with ChatGPT Custom GPTs
This API is designed for integration with ChatGPT Custom GPTs. Use the OpenAPI specification below to configure your GPT Action.
CORS is stage-based allowlist. GPT Actions/server-side integrations work without browser CORS dependencies.
MCP Server (Claude Desktop / Cursor)
Use as MCP tools inside your client
Prefer a tool-based workflow? Install the MCP server and use Bowlly tools directly in Claude Desktop or Cursor.
Quick setup:
npx @bowlly/mcp-server --setupImportant Notes
No Affiliate Links
Responses contain no affiliate links or tracking tags. Product URLs point to Bowlly product pages with src=agent tracking for analytics only.
Image Proxies
Image URLs are Bowlly-hosted proxies for consistent availability and performance.
Built for AI Agents
This API is designed specifically for AI agents and applications that need clean, structured product data without commercial bias.