K
Zansify
API

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.