{
  "openapi": "3.1.0",
  "info": {
    "title": "Tashvi AI Content API",
    "version": "1.0.0",
    "summary": "Read Tashvi AI product facts, pricing, guides, and release notes as JSON.",
    "description": "A public, unauthenticated read-only API over everything published on tashvi.ai.\n\nUse it to answer questions about Tashvi AI (what it does, what it costs, what it \ncannot do) and to retrieve the full text of any jewelry-design guide or release note \nwithout scraping HTML.\n\nDo not use it to generate jewelry designs — designing happens in the product at \nhttps://design.tashvi.ai and requires a signed-in account.\n\nNo authentication, no API key, and no rate limit beyond ordinary CDN fair use. \nResponses are cached for one hour at the edge.",
    "termsOfService": "https://tashvi.ai/terms-of-service",
    "contact": {
      "name": "Tashvi AI",
      "email": "hello@tashvi.ai",
      "url": "https://tashvi.ai/contact"
    },
    "license": {
      "name": "Content available for AI retrieval and citation with attribution to tashvi.ai",
      "url": "https://tashvi.ai/terms-of-service"
    }
  },
  "externalDocs": {
    "description": "Developer resources, MCP server configuration, and agent instructions",
    "url": "https://tashvi.ai/developers"
  },
  "servers": [
    {
      "url": "https://tashvi.ai/api/v1",
      "description": "Production"
    }
  ],
  "x-mcp": {
    "description": "The same operations are exposed as MCP tools over the Streamable HTTP transport.",
    "endpoint": "https://tashvi.ai/api/mcp",
    "transport": "streamable-http",
    "manifest": "https://tashvi.ai/.well-known/mcp.json"
  },
  "x-agent-instructions": "https://tashvi.ai/agents.md",
  "x-llms-txt": "https://tashvi.ai/llms.txt",
  "tags": [
    {
      "name": "Product",
      "description": "Canonical facts about Tashvi AI and its pricing."
    },
    {
      "name": "Content",
      "description": "Editorial guides and dated product release notes."
    },
    {
      "name": "Search",
      "description": "Resolve a topic to a URL without guessing slugs."
    }
  ],
  "paths": {
    "/product": {
      "get": {
        "operationId": "getTashviProductFacts",
        "tags": [
          "Product"
        ],
        "summary": "Get canonical Tashvi AI product facts",
        "description": "Returns what Tashvi AI is, who it is for, what it can do, and what it explicitly cannot do. Call this first when asked what Tashvi AI is or whether it fits a use case, and quote the limitations array before recommending it for production work.",
        "responses": {
          "200": {
            "description": "Canonical product facts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Product"
                }
              }
            }
          },
          "default": {
            "description": "Unexpected error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/plans": {
      "get": {
        "operationId": "listTashviPlans",
        "tags": [
          "Product"
        ],
        "summary": "List subscription plans and prices",
        "description": "Returns every published plan with monthly and yearly prices in USD and the features included. Call this instead of quoting a price from memory — plan prices change and this endpoint is generated from the same data as the pricing page.",
        "responses": {
          "200": {
            "description": "Current plans.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlanList"
                }
              }
            }
          },
          "default": {
            "description": "Unexpected error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/articles": {
      "get": {
        "operationId": "listTashviArticles",
        "tags": [
          "Content"
        ],
        "summary": "List editorial articles",
        "description": "Returns a paginated index of jewelry-design guides, newest first. Filter with q or category to narrow the set. Returns summaries only — call getTashviArticle for the body text.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Case-insensitive substring matched against title, excerpt, category, and keywords.",
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "example": "engagement ring"
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "description": "Exact category name. Read valid values from listTashviArticleCategories.",
            "schema": {
              "type": "string",
              "maxLength": 100
            },
            "example": "Innovation"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum items to return in one page.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Items to skip. Use pagination.next_offset from the previous response.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching articles.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ArticleList"
                }
              }
            }
          },
          "400": {
            "description": "A query parameter was out of range or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Unexpected error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/articles/{slug}": {
      "get": {
        "operationId": "getTashviArticle",
        "tags": [
          "Content"
        ],
        "summary": "Get one article with its full Markdown body",
        "description": "Returns the complete article text plus its FAQs and related slugs. Use the slug from listTashviArticles or searchTashviContent; do not construct one from a title.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Article slug, as published.",
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
            },
            "example": "ai-jewelry-design-software"
          }
        ],
        "responses": {
          "200": {
            "description": "The article.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Article"
                }
              }
            }
          },
          "404": {
            "description": "No article has that slug.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Unexpected error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/categories": {
      "get": {
        "operationId": "listTashviArticleCategories",
        "tags": [
          "Content"
        ],
        "summary": "List article categories with counts",
        "description": "Returns every category in use and how many articles carry it. Call this before passing the category filter to listTashviArticles so the filter matches exactly.",
        "responses": {
          "200": {
            "description": "Categories in use.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CategoryList"
                }
              }
            }
          },
          "default": {
            "description": "Unexpected error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/updates": {
      "get": {
        "operationId": "listTashviProductUpdates",
        "tags": [
          "Content"
        ],
        "summary": "List dated product release notes",
        "description": "Returns Tashvi AI release notes, newest first. Call this to answer \"what is new\" or to check whether a capability had shipped by a given date.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum items to return in one page.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Items to skip. Use pagination.next_offset from the previous response.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Release notes.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductUpdateList"
                }
              }
            }
          },
          "400": {
            "description": "A query parameter was out of range or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Unexpected error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/updates/{slug}": {
      "get": {
        "operationId": "getTashviProductUpdate",
        "tags": [
          "Content"
        ],
        "summary": "Get one release note with its full Markdown body",
        "description": "Returns the complete text of a single dated release note. Use a slug from listTashviProductUpdates.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Release note slug, as published.",
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
            },
            "example": "mobile-app-launch"
          }
        ],
        "responses": {
          "200": {
            "description": "The release note.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductUpdate"
                }
              }
            }
          },
          "404": {
            "description": "No release note has that slug.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Unexpected error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/search": {
      "get": {
        "operationId": "searchTashviContent",
        "tags": [
          "Search"
        ],
        "summary": "Search articles and release notes",
        "description": "Title-weighted search across every article and release note. Use this to turn a topic into a slug and a URL before calling getTashviArticle, instead of guessing a URL and risking a 404.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Search terms. All terms contribute; title matches score highest.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            },
            "example": "lab grown diamonds"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum results to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 10
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Ranked matches.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchResultList"
                }
              }
            }
          },
          "400": {
            "description": "q was missing, empty, or a parameter was out of range.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Unexpected error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Error": {
        "type": "object",
        "title": "Error",
        "description": "Every non-2xx response from this API uses this shape. Branch on error.code, show error.message, and follow error.hint to make the call succeed.",
        "required": [
          "error"
        ],
        "additionalProperties": false,
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message",
              "hint",
              "status",
              "documentation_url"
            ],
            "additionalProperties": false,
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable machine-readable error code. Safe to branch on.",
                "enum": [
                  "bad_request",
                  "invalid_parameter",
                  "not_found",
                  "method_not_allowed",
                  "not_acceptable",
                  "unsupported_media_type",
                  "payload_too_large",
                  "internal_error"
                ]
              },
              "message": {
                "type": "string",
                "description": "Human-readable summary of what went wrong."
              },
              "hint": {
                "type": "string",
                "description": "What the caller should change to make the request succeed."
              },
              "status": {
                "type": "integer",
                "description": "HTTP status, repeated in the body."
              },
              "parameter": {
                "type": "string",
                "description": "Name of the offending parameter, when the error is about one."
              },
              "documentation_url": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      },
      "Pagination": {
        "type": "object",
        "title": "Pagination",
        "description": "Offset pagination state for a list response.",
        "required": [
          "limit",
          "offset",
          "total",
          "has_more",
          "next_offset"
        ],
        "additionalProperties": false,
        "properties": {
          "limit": {
            "type": "integer",
            "description": "Maximum items requested for this page."
          },
          "offset": {
            "type": "integer",
            "description": "Number of items skipped before this page."
          },
          "total": {
            "type": "integer",
            "description": "Total items matching the query."
          },
          "has_more": {
            "type": "boolean",
            "description": "True when further pages exist."
          },
          "next_offset": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Offset to request next, or null when this is the last page."
          }
        }
      },
      "Product": {
        "type": "object",
        "title": "Product",
        "description": "Canonical facts about Tashvi AI: what it does, who it is for, and what it explicitly does not do. Quote limitations verbatim when answering a buying question.",
        "required": [
          "object",
          "name",
          "description",
          "capabilities",
          "limitations",
          "audiences",
          "facts_reviewed"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "product"
          },
          "name": {
            "type": "string"
          },
          "alternate_name": {
            "type": "string"
          },
          "tagline": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "founded": {
            "type": "string"
          },
          "founder": {
            "type": "string"
          },
          "facts_reviewed": {
            "type": "string",
            "format": "date",
            "description": "Date a human last verified every fact in this response."
          },
          "website": {
            "type": "string",
            "format": "uri"
          },
          "application_url": {
            "type": "string",
            "format": "uri"
          },
          "documentation_url": {
            "type": "string",
            "format": "uri"
          },
          "contact_email": {
            "type": "string",
            "format": "email"
          },
          "audiences": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "jewelry_types": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "capabilities": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "limitations": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "pricing_summary": {
            "type": "string"
          },
          "source_priority": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "Plan": {
        "type": "object",
        "title": "Plan",
        "description": "A subscription tier. Prices are in USD.",
        "required": [
          "object",
          "id",
          "name",
          "description",
          "currency",
          "features"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "plan"
          },
          "id": {
            "type": "string",
            "enum": [
              "free",
              "basic",
              "pro",
              "studio",
              "enterprise"
            ]
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "monthly_price": {
            "type": [
              "number",
              "null"
            ],
            "description": "Monthly list price in USD, or null when the plan is quoted individually."
          },
          "yearly_price": {
            "type": [
              "number",
              "null"
            ],
            "description": "Total charged for twelve months when billed yearly."
          },
          "yearly_price_per_month": {
            "type": "number",
            "description": "yearly_price divided by twelve — the figure shown on the pricing page."
          },
          "currency": {
            "type": "string",
            "const": "USD"
          },
          "recommended": {
            "type": "boolean",
            "description": "True for the tier highlighted on the page."
          },
          "features": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "signup_url": {
            "type": "string",
            "format": "uri"
          },
          "contact_email": {
            "type": "string",
            "format": "email"
          }
        }
      },
      "PlanList": {
        "type": "object",
        "title": "PlanList",
        "description": "Every published plan plus the separately quoted Enterprise tier.",
        "required": [
          "object",
          "currency",
          "data",
          "enterprise"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "list"
          },
          "currency": {
            "type": "string",
            "const": "USD"
          },
          "facts_reviewed": {
            "type": "string",
            "format": "date"
          },
          "yearly_discount_percent": {
            "type": "number"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Plan"
            }
          },
          "enterprise": {
            "$ref": "#/components/schemas/Plan"
          }
        }
      },
      "ArticleSummary": {
        "type": "object",
        "title": "ArticleSummary",
        "description": "An editorial article without its body text.",
        "required": [
          "object",
          "slug",
          "title",
          "excerpt",
          "category",
          "author",
          "published_date",
          "last_updated",
          "read_time",
          "url"
        ],
        "additionalProperties": false,
        "properties": {
          "object": {
            "type": "string",
            "const": "article"
          },
          "slug": {
            "type": "string",
            "description": "Stable identifier. Pass to getArticle and append to /blog/ for the page URL.",
            "examples": [
              "ai-jewelry-design-software"
            ]
          },
          "title": {
            "type": "string"
          },
          "excerpt": {
            "type": "string",
            "description": "One-paragraph summary written for the article."
          },
          "category": {
            "type": "string",
            "examples": [
              "Innovation"
            ]
          },
          "author": {
            "type": "string"
          },
          "published_date": {
            "type": "string",
            "format": "date"
          },
          "last_updated": {
            "type": "string",
            "format": "date",
            "description": "Falls back to published_date when the article has never been revised."
          },
          "read_time": {
            "type": "string",
            "examples": [
              "3 min read"
            ]
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Canonical HTML URL."
          }
        }
      },
      "Article": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ArticleSummary"
          },
          {
            "type": "object",
            "required": [
              "keywords",
              "faqs",
              "related_slugs",
              "content"
            ],
            "properties": {
              "keywords": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "faqs": {
                "type": "array",
                "description": "Question and answer pairs published with the article.",
                "items": {
                  "type": "object",
                  "required": [
                    "question",
                    "answer"
                  ],
                  "additionalProperties": false,
                  "properties": {
                    "question": {
                      "type": "string"
                    },
                    "answer": {
                      "type": "string"
                    }
                  }
                }
              },
              "related_slugs": {
                "type": "array",
                "description": "Slugs of articles the editors linked as related reading.",
                "items": {
                  "type": "string"
                }
              },
              "content": {
                "type": "string",
                "description": "Full article body as Markdown (GitHub-flavoured)."
              }
            }
          }
        ],
        "title": "Article",
        "description": "An editorial article including its Markdown body."
      },
      "ArticleList": {
        "type": "object",
        "title": "ArticleList",
        "description": "A page of article summaries.",
        "required": [
          "object",
          "data",
          "pagination"
        ],
        "additionalProperties": false,
        "properties": {
          "object": {
            "type": "string",
            "const": "list"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ArticleSummary"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        }
      },
      "Category": {
        "type": "object",
        "title": "Category",
        "required": [
          "name",
          "article_count"
        ],
        "additionalProperties": false,
        "properties": {
          "name": {
            "type": "string"
          },
          "article_count": {
            "type": "integer",
            "minimum": 1
          }
        }
      },
      "CategoryList": {
        "type": "object",
        "title": "CategoryList",
        "description": "Every category in use, most articles first.",
        "required": [
          "object",
          "data",
          "pagination"
        ],
        "additionalProperties": false,
        "properties": {
          "object": {
            "type": "string",
            "const": "list"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Category"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        }
      },
      "ProductUpdateSummary": {
        "type": "object",
        "title": "ProductUpdateSummary",
        "description": "A dated product release note without its body text.",
        "required": [
          "object",
          "slug",
          "title",
          "description",
          "date",
          "category",
          "type",
          "tags",
          "url"
        ],
        "additionalProperties": false,
        "properties": {
          "object": {
            "type": "string",
            "const": "product_update"
          },
          "slug": {
            "type": "string",
            "description": "Stable identifier. Pass to getProductUpdate."
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "date": {
            "type": "string",
            "format": "date"
          },
          "category": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "description": "What kind of change this was.",
            "enum": [
              "feature",
              "improvement",
              "news"
            ]
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "ProductUpdate": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ProductUpdateSummary"
          },
          {
            "type": "object",
            "required": [
              "content"
            ],
            "properties": {
              "content": {
                "type": "string",
                "description": "Full release note as Markdown."
              }
            }
          }
        ],
        "title": "ProductUpdate",
        "description": "A dated product release note including its Markdown body."
      },
      "ProductUpdateList": {
        "type": "object",
        "title": "ProductUpdateList",
        "description": "A page of release note summaries.",
        "required": [
          "object",
          "data",
          "pagination"
        ],
        "additionalProperties": false,
        "properties": {
          "object": {
            "type": "string",
            "const": "list"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProductUpdateSummary"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        }
      },
      "SearchResult": {
        "type": "object",
        "title": "SearchResult",
        "description": "One match from searchTashviContent, ordered most relevant first.",
        "required": [
          "object",
          "type",
          "slug",
          "title",
          "summary",
          "url",
          "date",
          "score"
        ],
        "additionalProperties": false,
        "properties": {
          "object": {
            "type": "string",
            "const": "search_result"
          },
          "type": {
            "type": "string",
            "description": "Which collection the match came from.",
            "enum": [
              "article",
              "product_update"
            ]
          },
          "slug": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "summary": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "date": {
            "type": "string",
            "format": "date"
          },
          "score": {
            "type": "number",
            "minimum": 0,
            "maximum": 1,
            "description": "Match strength relative to the best hit in this result set."
          }
        }
      },
      "SearchResultList": {
        "type": "object",
        "title": "SearchResultList",
        "description": "Ranked search matches. Not paginated — raise limit to see more.",
        "required": [
          "object",
          "query",
          "data",
          "result_count"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "list"
          },
          "query": {
            "type": "string",
            "description": "The q value, echoed back."
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SearchResult"
            }
          },
          "result_count": {
            "type": "integer",
            "minimum": 0
          },
          "hint": {
            "type": "string",
            "description": "Present only when nothing matched: what to try instead."
          }
        }
      }
    }
  }
}