API Overview
How the Kasify tRPC API works, authentication, and how to call it.
Overview
The Kasify API is built with tRPC v11 on top of Hono, running on Node.js. Every operation — creating products, placing orders, managing customers — is a tRPC procedure.
The API is fully type-safe. When you call a procedure from the dashboard or storefront, TypeScript guarantees the input and output types match. There are no runtime surprises.
Base URL:
http://localhost:3001 # development
https://api.yourdomain.com # production
Authentication
Most procedures require a valid JWT access token passed as a Bearer token:
Authorization: Bearer <access_token>
Getting a token
curl -X POST https://api.yourdomain.com/trpc/auth.login \
-H "Content-Type: application/json" \
-d '{"json": {"email": "you@example.com", "password": "yourpassword"}}'
Response:
{
"result": {
"data": {
"json": {
"accessToken": "eyJhbGciOiJIUzI1NiJ9...",
"refreshToken": "eyJhbGciOiJIUzI1NiJ9...",
"user": { "id": "...", "email": "you@example.com" }
}
}
}
}
Access tokens expire after 15 minutes. Use the refresh token to get a new one:
curl -X POST https://api.yourdomain.com/trpc/auth.refresh \
-H "Content-Type: application/json" \
-d '{"json": {"refreshToken": "eyJ..."}}'
Calling procedures
tRPC procedures map to HTTP endpoints at /trpc/<router>.<procedure>.
Queries (GET)
curl "https://api.yourdomain.com/trpc/catalog.list?input=%7B%22json%22%3A%7B%7D%7D" \
-H "Authorization: Bearer <token>" \
-H "x-tenant-id: your-store-slug"
Mutations (POST)
curl -X POST "https://api.yourdomain.com/trpc/catalog.create" \
-H "Authorization: Bearer <token>" \
-H "x-tenant-id: your-store-slug" \
-H "Content-Type: application/json" \
-d '{
"json": {
"name": "My Product",
"price": 9999,
"description": "A great product"
}
}'
Prices are in cents.
9999= R 99.99. This avoids floating-point issues.
Tenant context
Most procedures require a x-tenant-id header identifying which store the request belongs to:
x-tenant-id: my-store-slug
Procedures in the auth router (login, register) do not require this header.
Router map
| Router | Prefix | Description |
|---|---|---|
| Authentication | auth.* | Admin login, register, refresh |
| Customer auth | customerAuth.* | Storefront customer auth |
| Catalog | catalog.* | Products and variants |
| Orders | orders.* | Order management |
| Customers | customers.* | Customer profiles |
| Collections | collections.* | Product collections |
| Coupons | coupons.* | Discount codes |
| Shipping | shipping.* | Rates and methods |
| Reviews | reviews.* | Product reviews |
| Analytics | analytics.* | Store reporting |
| Storefront | storefront.* | Pages and settings |
| Email | email.* | Templates and logs |
| AI Assistant | aiAssistant.* | AI settings and chat |
| Integrations | integrations.* | Third-party connectors |
Error handling
tRPC errors use standard HTTP status codes and return a consistent shape:
{
"error": {
"json": {
"message": "Product not found",
"code": -32004,
"data": {
"code": "NOT_FOUND",
"httpStatus": 404,
"path": "catalog.getById"
}
}
}
}
Common error codes:
| tRPC code | HTTP status | Meaning |
|---|---|---|
| UNAUTHORIZED | 401 | Missing or invalid token |
| FORBIDDEN | 403 | Valid token but insufficient permissions |
| NOT_FOUND | 404 | Resource doesn't exist |
| BAD_REQUEST | 400 | Invalid input (Zod validation failed) |
| CONFLICT | 409 | Duplicate resource (e.g. email already registered) |
| TOO_MANY_REQUESTS | 429 | Rate limit exceeded |
| INTERNAL_SERVER_ERROR | 500 | Something went wrong on our end |
Rate limiting
The API applies sliding-window rate limits per IP address:
| Endpoint group | Limit | Window | |---|---|---| | Login / register | 10 requests | 15 minutes | | Customer register | 5 requests | 1 hour | | Order lookup | 20 requests | 15 minutes |
Exceeding the limit returns a TOO_MANY_REQUESTS error. Limits reset automatically after the window expires.