API overview
Authentication, base URL, and getting started.
Overview
Katura provides a comprehensive REST API for managing your store programmatically. The API powers both the admin panel and the customer-facing storefront.
API architecture
Katura's API is built with Next.js Route Handlers:
- Admin API β routes under
/api/admin/*(requires authentication + role check) - Storefront API β routes under
/api/*(public or customer-auth required) - Webhook API β routes for receiving webhooks from Stripe, Shopify, etc.
Admin API endpoints
The admin API has 60+ route groups covering:
| Group | Endpoints |
|---|---|
| Products | CRUD operations, variants, images, bulk operations |
| Orders | List, create, update status, assign sales rep |
| Customers | List, create, update, import/export |
| Collections | CRUD, product management, sort order |
| CRM | Deals, pipeline stages, contacts, notes |
| Marketing | Email campaigns, promotions, segments |
| Payroll | Runs, periods, employees, reports |
| Wholesale | Accounts, leads, settings |
| Analytics | Revenue, products, customers, team performance |
| Settings | Store config, payment, shipping, notifications |
Authentication
Admin API routes require a valid session token from Supabase Auth. The middleware checks authentication on every request and verifies the user's role meets the minimum requirement for the endpoint.
Note
The API uses the same Prisma models as the admin UI, so data is always consistent. There's no separate API database or sync process.
Base URL & versioning
Production base URL is https://{your-domain}/api. The API is currently unversioned β breaking changes are announced 90 days in advance via the changelog and emailed to every account with a registered API key. Additive changes (new fields, new endpoints) ship without notice and are safe by design.
API keys
For server-to-server integrations, generate an API key at Settings β Developer β API Keys. Pass it as a Bearer token:
curl https://yourdomain.com/api/admin/orders \
-H "Authorization: Bearer kat_live_..." \
-H "Content-Type: application/json"Keys are scoped to a role β pick the most restrictive role that lets the integration do its job. Keys can be rotated and revoked at any time without affecting other keys. Lost or leaked keys should be revoked immediately; the audit log shows every call made with each key.
Response format
All responses are JSON. Successful responses use HTTP 2xx and include the resource directly (or { data, pagination } for list endpoints). Errors use 4xx/5xx and follow this shape:
{
"error": {
"code": "validation_failed",
"message": "name is required",
"field": "name",
"request_id": "req_01HX..."
}
}Error codes
| HTTP | Code | Meaning |
|---|---|---|
| 400 | validation_failed | Request body or query is malformed |
| 401 | unauthenticated | Missing or invalid API key / session |
| 403 | forbidden | Authenticated but role lacks permission |
| 404 | not_found | Resource doesn't exist or isn't visible to you |
| 409 | conflict | Idempotency key reused with different body, or stale write |
| 422 | unprocessable | Valid request, but business rule rejected it |
| 429 | rate_limited | See rate limits |
| 500 | internal_error | Our problem β request_id helps support trace it |
Idempotency
Send Idempotency-Key: <uuid> on any POST, PUT, or PATCH. Replays within 24 hours return the cached response without re-running the handler. Keys are scoped per API key + endpoint. Reusing a key with a different body returns 409.
Pagination
List endpoints accept page (1-indexed) and limit (1β100, default 20). Response includes:
{
"data": [ ... ],
"pagination": {
"page": 1,
"limit": 20,
"total": 487,
"totalPages": 25
}
}