API Overview
The Caty.AI API enables programmatic access to all platform features.
Base URL
https://api.catyai.ioAPI Types
Public Commerce & Catalog Endpoints
Unauthenticated (or lightly gated) endpoints powering catalog visibility — Google Shopping distribution, AI-agent discovery and lead intake:
| Endpoint | Method | Purpose | Auth | Rate limit (real, per IP) |
|---|---|---|---|---|
/api/public/catalog-stats | GET | Public catalog counters (active merchants, total products) — same figures as shop.catyai.io/aff-llms.txt | — | — |
/geo/v2/lookup | GET | Product search over the public affiliate catalog. Params: q, gtin, sku, pid, max_price, category, merchant, limit | — | 30 req/min |
/geo/v2/lookup?widget_id=… | GET | Single-product B2B lookup for a widget catalog. Params: widget_id + sku or pid | widget UUID | 120 req/h |
/geo/v2/catalog | GET | Full product catalog for a widget. Params: limit, page, offset | X-API-Key | 60 req/h |
/geo/v2/catalog/agentic-index.txt | GET | Complete agentic index for AI agents | — | 10 req/h |
/geo/v2/llms.txt?domain=X | GET | NAP v3 protocol document for AI assistants | — | — |
/geo/v2/answer | POST | Signed (EdDSA) answer to a product query — AKL v2 envelope | see GEO guide | 60 req/h |
/api/leads/catalog-audit | POST | Feed-audit request intake (the form on catyai.io). Fields: name, email, site/feed URL, caty_source | — | server-side rate limit |
/api/public/ai-visibility | POST | AI visibility check for a business/domain | — | — |
Rate limits are enforced in Redis, per IP, fail-open. Source of truth: src/config/geo-rate-limits.js — the discovery documents (llms.txt, /.well-known/ai-context) read the same object, so documented limits cannot drift from enforcement.
Widget API
Public endpoints for the chat widget:
/api/widget/config- Get widget configuration/api/widget/session- Create/get session/api/widget/message- Send/receive messages/api/widget/track- Behavioral tracking
Authentication: Widget API Key (X-API-Key header)
Admin API
Protected endpoints for dashboard operations:
/api/admin/widgets- Manage widgets/api/admin/conversations- View conversations/api/admin/leads- Manage leads/api/admin/knowledge- Manage knowledge base/api/admin/analytics- Get analytics data
Authentication: Supabase JWT (Authorization: Bearer header)
Response Format
All responses follow this structure:
{
"success": true,
"data": { ... },
"message": "Optional message"
}Error responses:
{
"success": false,
"error": "Error description",
"code": "ERROR_CODE"
}Rate Limits
| Endpoint | Limit |
|---|---|
| Widget API | 100 req/min |
| Admin API | 60 req/min |
| Message | 20 req/min |
For the public commerce endpoints (/geo/v2/*), see the table above — those limits are the enforced ones.
Error Codes
| Code | Description |
|---|---|
MISSING_API_KEY | API key not provided |
INVALID_API_KEY | API key is invalid or inactive |
RATE_LIMITED | Too many requests |
VALIDATION_ERROR | Invalid request data |
NOT_FOUND | Resource not found |
UNAUTHORIZED | Authentication required |
SDKs
Coming soon:
- JavaScript/TypeScript
- Python
- PHP
Quick Example
// Public catalog counters
const stats = await fetch('https://api.catyai.io/api/public/catalog-stats').then(r => r.json());
console.log(stats.data.totalProducts, stats.data.totalMerchants);// Send a message
const response = await fetch('https://api.catyai.io/api/widget/message', {
method: 'POST',
headers: {
'X-API-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
session_id: 'sess_xxx',
message: 'Hello!'
})
});
const data = await response.json();
console.log(data.response); // AI's response