Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/PloutusLab/krafta-web/llms.txt

Use this file to discover all available pages before exploring further.

The catalog API is the central registry for all printable products on the Krafta platform. Each product has one or more ProductVariant records that carry the SKU, base price, and a PrintTemplate defining where the customer’s artwork is placed on the mockup. GET requests are public and unauthenticated; POST, PUT, and DELETE require an ADMIN session cookie.

GET /api/catalog

Retrieves the product catalog. The response shape varies depending on which query parameters are supplied. Without any parameters, the full list of active products — including their variants and print templates — is returned.

Query parameters

id
string
Return a single product record by its ID. Includes the full category, variants, and nested printTemplate for each variant. Returns 404 if the product does not exist or is inactive (unless admin=1 is also set).
summary
string
Pass "1" to receive a lightweight payload optimised for catalog listing cards. Each product includes a computed thumbnailUrl derived from the first variant’s mockupImageUrl. Any data: URI mockups are replaced with a static fallback path so the payload stays small.
admin
string
Pass "1" to include inactive products in the response. Intended for the admin product management panel. Does not enforce an auth check at the query-parameter level; callers are responsible for protecting the UI that passes this flag.
editor
string
Pass "1" when fetching a single product for the design editor. Strips data: URI mockup images and replaces them with the computed static thumbnailUrl, keeping the editor payload lean.

Response (summary mode)

{
  "success": true,
  "products": [
    {
      "id": "prod-1",
      "name": "Camiseta Básica Unisex",
      "description": "Franela de algodón fresca y cómoda para uso diario.",
      "active": true,
      "categoryId": "cat-1",
      "category": { "name": "Camisetas" },
      "thumbnailUrl": "/mockups/franela.png",
      "images": "[\"/mockups/franela.png\"]",
      "variants": [
        {
          "id": "var-1",
          "sku": "CAM-BASE-M-BLANCO",
          "basePrice": 12,
          "attributes": { "color": "Blanco", "talla": "M" },
          "printTemplate": {
            "mockupImageUrl": "/mockups/franela.png",
            "printAreaX": 20,
            "printAreaY": 20,
            "printAreaWidth": 60,
            "printAreaHeight": 60,
            "rotation": 0,
            "shape": "RECTANGLE",
            "minDpi": 150
          }
        }
      ]
    }
  ]
}

Response (single product via ?id=)

{
  "success": true,
  "product": {
    "id": "prod-1",
    "name": "Camiseta Básica Unisex",
    "description": "Franela de algodón fresca y cómoda para uso diario.",
    "active": true,
    "categoryId": "cat-1",
    "category": { "id": "cat-1", "name": "Camisetas", "slug": "camisetas" },
    "images": "[\"/mockups/franela.png\"]",
    "variants": [
      {
        "id": "var-1",
        "sku": "CAM-BASE-M-BLANCO",
        "basePrice": 12,
        "attributes": { "color": "Blanco", "talla": "M" },
        "active": true,
        "printTemplate": {
          "id": "tmpl-1",
          "mockupImageUrl": "/mockups/franela.png",
          "printAreaX": 20,
          "printAreaY": 20,
          "printAreaWidth": 60,
          "printAreaHeight": 60,
          "rotation": 0,
          "shape": "RECTANGLE",
          "minDpi": 150
        }
      }
    ]
  }
}

Error responses

StatusCondition
404A product id was supplied but no matching active product was found

POST /api/catalog

Creates a new product with a single default variant. Requires the ADMIN role — requests without a valid krafta-token cookie carrying the ADMIN claim are rejected with 403. The category is resolved by name: if a Category record with the given categoryName already exists it is reused; otherwise a new one is created automatically with a slugified identifier. A product is marked active: true only when a non-placeholder images array is provided together with a valid mockupImageUrl. Products saved without images are stored as inactive and will not appear in the public catalog until updated.

Request body

name
string
required
The product’s display name (e.g. "Camiseta Básica Unisex").
description
string
A longer description of the product. Defaults to an empty string if omitted.
categoryName
string
The category name to assign. If the category does not exist it is created. Defaults to "Otros" when omitted.
sku
string
required
The stock-keeping unit for the default variant (e.g. "CAM-BASE-M-BLANCO"). Must be unique across all variants.
basePrice
number
required
The platform minimum price in USD for the default variant (e.g. 12.00).
mockupImageUrl
string
URL or path to the primary mockup image used in the print template (e.g. "/mockups/franela.png").
images
array
Array of image URLs forming the product’s commercial photo carousel. Used to determine whether the product is published as active.
printTemplate
object
Print area configuration for the default variant.
{
  "name": "Camiseta Básica Unisex",
  "description": "Franela de algodón fresca y cómoda.",
  "categoryName": "Camisetas",
  "sku": "CAM-BASE-M-BLANCO",
  "basePrice": 12.00,
  "mockupImageUrl": "/mockups/franela.png",
  "images": ["/mockups/franela.png"],
  "printTemplate": {
    "printAreaX": 20,
    "printAreaY": 20,
    "printAreaWidth": 60,
    "printAreaHeight": 60
  }
}

Response

success
boolean
true when the product is created successfully.
product
object
The persisted product record as returned by Prisma, including the auto-generated id.
{
  "success": true,
  "product": {
    "id": "prod-a1b2c3d",
    "name": "Camiseta Básica Unisex",
    "description": "Franela de algodón fresca y cómoda.",
    "active": true,
    "categoryId": "cat-uuid",
    "images": "[\"/mockups/franela.png\"]"
  }
}

Error responses

StatusCondition
400name, sku, or basePrice is missing from the request body
403The request does not carry a valid ADMIN session

PUT /api/catalog

Updates an existing product’s name, description, category, pricing, and print template. Requires the ADMIN role. The endpoint performs an upsert on the PrintTemplate record: if a print template already exists for the first variant it is updated in place; if not, a new one is created. The product’s active flag is recomputed on every update based on whether a valid non-placeholder mockupImageUrl and a non-empty images array are present.

Request body

id
string
required
The ID of the product to update.
name
string
required
Updated display name for the product.
description
string
Updated product description.
categoryName
string
Category name to assign. Created automatically if it does not exist.
images
array
Updated array of commercial photo URLs.
variants
array
required
Array of variant update objects. At least one element is required. Only the first element is applied in the current implementation.
{
  "id": "prod-a1b2c3d",
  "name": "Camiseta Básica Unisex — Edición Verano",
  "description": "Franela de algodón fresca y cómoda.",
  "categoryName": "Camisetas",
  "images": ["/mockups/franela-verano.png"],
  "variants": [
    {
      "sku": "CAM-BASE-M-BLANCO",
      "basePrice": 13.00,
      "printTemplate": {
        "mockupImageUrl": "/mockups/franela-verano.png",
        "printAreaX": 22,
        "printAreaY": 18,
        "printAreaWidth": 58,
        "printAreaHeight": 62
      }
    }
  ]
}

Response

success
boolean
true when the update is applied.
productId
string
The ID of the updated product.
{
  "success": true,
  "productId": "prod-a1b2c3d"
}

Error responses

StatusCondition
400id, name, or variants is missing, or variants is an empty array
400A variant with the given SKU already exists on a different product (Prisma P2002 unique constraint)
403The request does not carry a valid ADMIN session

DELETE /api/catalog?id=<productId>

Permanently deletes a product and all its associated variants and print templates from the database. Requires the ADMIN role.
id
string
required
The ID of the product to delete.

Response

success
boolean
true when the product is deleted.
{
  "success": true
}

Error responses

StatusCondition
400The id query parameter is missing
403The request does not carry a valid ADMIN session
500Database delete operation failed

Build docs developers (and LLMs) love