{
  "openapi": "3.1.0",
  "info": {
    "title": "Agent-Tees Agent API",
    "version": "0.1.0-phase0",
    "description": "Agent-first merch store. AI agents design a graphic tee from a prompt, preview a mockup, get a quote, and place an order that the human owner confirms. PHASE 0: payments and print-on-demand are MOCKED; nothing is charged or shipped.",
    "contact": {
      "name": "Agent-Tees (Ur Needs LLC)"
    }
  },
  "servers": [
    {
      "url": "https://agent-tees.com"
    }
  ],
  "tags": [
    {
      "name": "design"
    },
    {
      "name": "mockup"
    },
    {
      "name": "commerce"
    },
    {
      "name": "catalog"
    }
  ],
  "paths": {
    "/api/v1/products": {
      "get": {
        "tags": [
          "catalog"
        ],
        "operationId": "listProducts",
        "summary": "List rail tees",
        "responses": {
          "200": {
            "description": "Products"
          }
        }
      }
    },
    "/api/v1/products/{slug}": {
      "get": {
        "tags": [
          "catalog"
        ],
        "operationId": "getProduct",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Product"
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/safety/check": {
      "post": {
        "tags": [
          "design"
        ],
        "operationId": "checkPrompt",
        "summary": "Pre-check a prompt against safety rules",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "prompt"
                ],
                "properties": {
                  "prompt": {
                    "type": "string"
                  },
                  "text": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "allowed": {
                      "type": "boolean"
                    },
                    "violations": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Violation"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/designs": {
      "post": {
        "tags": [
          "design"
        ],
        "operationId": "createDesign",
        "summary": "Generate an original tee graphic from a prompt",
        "parameters": [
          {
            "name": "X-Agent-Name",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Optional: identify your agent"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DesignRequest"
              },
              "example": {
                "prompt": "retro sunset over a desert highway, warm colors",
                "text": "OPEN ROAD",
                "color": "black"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Design created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Design"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Prompt blocked by safety rules (error.violations lists why)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/designs/{design_id}": {
      "get": {
        "tags": [
          "design"
        ],
        "operationId": "getDesign",
        "parameters": [
          {
            "$ref": "#/components/parameters/DesignId"
          }
        ],
        "responses": {
          "200": {
            "description": "Design",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Design"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/designs/{design_id}/svg": {
      "get": {
        "tags": [
          "design"
        ],
        "operationId": "getDesignSvg",
        "parameters": [
          {
            "$ref": "#/components/parameters/DesignId"
          }
        ],
        "responses": {
          "200": {
            "description": "SVG",
            "content": {
              "image/svg+xml": {}
            }
          }
        }
      }
    },
    "/api/v1/designs/{design_id}/png": {
      "get": {
        "tags": [
          "design"
        ],
        "operationId": "getDesignPng",
        "parameters": [
          {
            "$ref": "#/components/parameters/DesignId"
          },
          {
            "name": "width",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 100,
              "maximum": 3000
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Transparent PNG",
            "content": {
              "image/png": {}
            }
          }
        }
      }
    },
    "/api/v1/mockups": {
      "post": {
        "tags": [
          "mockup"
        ],
        "operationId": "createMockup",
        "summary": "Composite the design onto a boxy oversized tee",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "design_id"
                ],
                "properties": {
                  "design_id": {
                    "type": "string"
                  },
                  "color": {
                    "$ref": "#/components/schemas/Color"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Mockup",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Mockup"
                }
              }
            }
          },
          "404": {
            "description": "Design not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/mockups/{mockup_id}/png": {
      "get": {
        "tags": [
          "mockup"
        ],
        "operationId": "getMockupPng",
        "parameters": [
          {
            "name": "mockup_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "PNG 1200x1400",
            "content": {
              "image/png": {}
            }
          }
        }
      }
    },
    "/api/v1/quotes": {
      "post": {
        "tags": [
          "commerce"
        ],
        "operationId": "createQuote",
        "summary": "Price a tee. $45 core / $65 drop / $99 rail exclusive, free fast US shipping (lower 48 + DC)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QuoteRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Quote (valid 30 min)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Quote"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orders": {
      "post": {
        "tags": [
          "commerce"
        ],
        "operationId": "createOrder",
        "summary": "Place an order from a quote. Returns an owner_confirm_url; nothing is charged until the owner confirms.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Agent-Name",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OrderRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Order awaiting owner confirmation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Order"
                }
              }
            }
          },
          "404": {
            "description": "Quote not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Quote already used",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "Quote expired",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Invalid shipping address (error.errors)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orders/{order_id}": {
      "get": {
        "tags": [
          "commerce"
        ],
        "operationId": "trackOrder",
        "summary": "Track an order",
        "parameters": [
          {
            "$ref": "#/components/parameters/OrderId"
          },
          {
            "name": "as_of",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Phase 0 only: simulate tracking at a future time"
          }
        ],
        "responses": {
          "200": {
            "description": "Order",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Order"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orders/{order_id}/confirm": {
      "post": {
        "tags": [
          "commerce"
        ],
        "operationId": "confirmOrder",
        "summary": "OWNER ONLY: confirm with the token from owner_confirm_url",
        "description": "Agents must not call this on their own. The owner reaches it through the confirm page.",
        "parameters": [
          {
            "$ref": "#/components/parameters/OrderId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "confirm_token"
                ],
                "properties": {
                  "confirm_token": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Confirmed (mock payment + mock POD)"
          },
          "403": {
            "description": "Bad token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/orders/{order_id}/cancel": {
      "post": {
        "tags": [
          "commerce"
        ],
        "operationId": "cancelOrder",
        "summary": "OWNER ONLY: decline an unconfirmed order",
        "parameters": [
          {
            "$ref": "#/components/parameters/OrderId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "confirm_token": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Cancelled"
          }
        }
      }
    }
  },
  "components": {
    "parameters": {
      "DesignId": {
        "name": "design_id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "OrderId": {
        "name": "order_id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        }
      }
    },
    "schemas": {
      "Color": {
        "type": "string",
        "enum": [
          "bone",
          "black",
          "heather",
          "navy",
          "brown",
          "sage"
        ]
      },
      "Size": {
        "type": "string",
        "enum": [
          "S",
          "M",
          "L",
          "XL",
          "2XL",
          "3XL"
        ]
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            },
            "additionalProperties": true
          }
        }
      },
      "Violation": {
        "type": "object",
        "properties": {
          "category": {
            "type": "string",
            "enum": [
              "trademark",
              "logo",
              "copyright",
              "real_person",
              "hate",
              "nsfw"
            ]
          },
          "term": {
            "type": "string"
          },
          "reason": {
            "type": "string"
          }
        }
      },
      "DesignRequest": {
        "type": "object",
        "required": [
          "prompt"
        ],
        "properties": {
          "prompt": {
            "type": "string",
            "minLength": 3,
            "maxLength": 500,
            "description": "What the owner wants. Original ideas only."
          },
          "text": {
            "type": "string",
            "maxLength": 28,
            "description": "Optional exact words for the shirt"
          },
          "style": {
            "type": "string",
            "enum": [
              "sunset",
              "space",
              "robot",
              "circuit",
              "waves",
              "flames",
              "mountains",
              "bloom",
              "type"
            ]
          },
          "palette": {
            "type": "string",
            "enum": [
              "sunset",
              "neon",
              "ocean",
              "earth",
              "mono",
              "pastel",
              "royal",
              "forest",
              "fire",
              "ice"
            ]
          },
          "color": {
            "$ref": "#/components/schemas/Color"
          },
          "seed": {
            "type": "integer",
            "description": "Re-roll by changing the seed"
          }
        }
      },
      "Design": {
        "type": "object",
        "properties": {
          "design_id": {
            "type": "string"
          },
          "headline": {
            "type": "string"
          },
          "style": {
            "type": "string"
          },
          "palette": {
            "type": "string"
          },
          "svg_url": {
            "type": "string"
          },
          "png_url": {
            "type": "string"
          },
          "tier": {
            "type": "string"
          },
          "provenance": {
            "type": "object"
          }
        }
      },
      "Mockup": {
        "type": "object",
        "properties": {
          "mockup_id": {
            "type": "string"
          },
          "design_id": {
            "type": "string"
          },
          "color": {
            "type": "string"
          },
          "image_url": {
            "type": "string"
          }
        }
      },
      "QuoteRequest": {
        "type": "object",
        "required": [
          "design_id",
          "size"
        ],
        "properties": {
          "design_id": {
            "type": "string"
          },
          "color": {
            "$ref": "#/components/schemas/Color"
          },
          "size": {
            "$ref": "#/components/schemas/Size"
          },
          "quantity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 5,
            "default": 1
          },
          "tier": {
            "type": "string",
            "enum": [
              "core",
              "drop",
              "rail_exclusive"
            ]
          }
        }
      },
      "Quote": {
        "type": "object",
        "properties": {
          "quote_id": {
            "type": "string"
          },
          "unit_price_cents": {
            "type": "integer"
          },
          "shipping_cents": {
            "type": "integer"
          },
          "total_cents": {
            "type": "integer"
          },
          "total_usd": {
            "type": "number"
          },
          "delivery_window": {
            "type": "object"
          },
          "expires_at": {
            "type": "string"
          }
        }
      },
      "Address": {
        "type": "object",
        "required": [
          "name",
          "line1",
          "city",
          "state",
          "postal_code"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "line1": {
            "type": "string"
          },
          "line2": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "state": {
            "type": "string",
            "description": "2-letter US code"
          },
          "postal_code": {
            "type": "string"
          },
          "country": {
            "type": "string",
            "enum": [
              "US"
            ],
            "default": "US"
          }
        }
      },
      "OrderRequest": {
        "type": "object",
        "required": [
          "quote_id",
          "shipping"
        ],
        "properties": {
          "quote_id": {
            "type": "string"
          },
          "shipping": {
            "$ref": "#/components/schemas/Address"
          },
          "owner_name": {
            "type": "string"
          }
        }
      },
      "Order": {
        "type": "object",
        "properties": {
          "order_id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "awaiting_owner_confirmation",
              "confirmed",
              "in_production",
              "shipped",
              "out_for_delivery",
              "delivered",
              "cancelled"
            ]
          },
          "total_usd": {
            "type": "number"
          },
          "owner_confirmation": {
            "type": "object",
            "properties": {
              "owner_confirm_url": {
                "type": "string"
              },
              "expires_at": {
                "type": "string"
              }
            }
          },
          "fulfillment": {
            "type": "object"
          },
          "timeline": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "estimated_delivery": {
            "type": "string"
          }
        }
      }
    }
  }
}