{
  "openapi": "3.1.0",
  "info": {
    "title": "AgentCache",
    "version": "1.0.0",
    "summary": "Semantic answer cache for AI agents: reuse answers to repeated and reworded questions.",
    "description": "Before calling a model or API, look up the question. A hit (exact, or similar by bge-m3 embedding with matching numbers) returns the saved answer for $0.002. Misses and stores are free. Answers are private to agent + namespace + context. Shares API keys (fv1.*) and the prepaid wallet with Freshness Validator and AgentPay. Human docs: https://myuiaf.com/agentcache/docs",
    "contact": { "name": "myuiaf", "email": "hello@myuiaf.com", "url": "https://myuiaf.com/contact" },
    "termsOfService": "https://myuiaf.com/terms"
  },
  "servers": [{ "url": "https://cache.myuiaf.com" }],
  "externalDocs": { "url": "https://myuiaf.com/agentcache/docs" },
  "security": [{ "agentKey": [] }],
  "components": {
    "securitySchemes": {
      "agentKey": { "type": "apiKey", "in": "header", "name": "X-Agent-API-Key", "description": "fv1.<agent_id>.<key_id>.<secret>. Also accepted as X-Api-Key or Authorization: Bearer. Buy one at https://myuiaf.com/pricing#buy or POST https://api.myuiaf.com/api/v1/credits." }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": ["error", "code"],
        "properties": {
          "error": { "type": "string" },
          "code": { "type": "string" },
          "price_usd": { "type": "number" },
          "topup": { "type": "object", "properties": { "url": { "type": "string" }, "method": { "type": "string" }, "note": { "type": "string" } } }
        }
      },
      "Scope": {
        "type": "object",
        "properties": {
          "namespace": { "type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,47}$", "default": "default" },
          "context": { "type": "string", "maxLength": 4000, "description": "Must match exactly, e.g. model and system prompt version." }
        }
      },
      "LookupRequest": {
        "allOf": [{ "$ref": "#/components/schemas/Scope" }, {
          "type": "object",
          "required": ["prompt"],
          "properties": {
            "prompt": { "type": "string", "maxLength": 8000 },
            "min_similarity": { "type": "number", "minimum": 0.92, "maximum": 1, "default": 0.95 }
          }
        }]
      },
      "LookupResponse": {
        "type": "object",
        "required": ["hit", "charged_usd"],
        "properties": {
          "hit": { "type": "boolean" },
          "match": { "type": "string", "enum": ["exact", "similar"] },
          "similarity": { "type": "number" },
          "entry_id": { "type": "string" },
          "namespace": { "type": "string" },
          "cached_prompt": { "type": "string" },
          "answer": {},
          "cached_at": { "type": "string", "format": "date-time" },
          "expires_at": { "type": "string", "format": "date-time" },
          "charged_usd": { "type": "number" },
          "original_cost_usd": { "type": "number" },
          "saved_usd": { "type": "number" },
          "degraded": { "type": "string", "enum": ["similar_matching_unavailable", "storage_unavailable", "wallet_unavailable"] },
          "next": { "type": "string" }
        }
      },
      "StoreRequest": {
        "allOf": [{ "$ref": "#/components/schemas/Scope" }, {
          "type": "object",
          "required": ["prompt", "answer"],
          "properties": {
            "prompt": { "type": "string", "maxLength": 8000 },
            "answer": { "description": "String or any JSON value, up to 60,000 bytes as JSON." },
            "ttl_seconds": { "type": "integer", "minimum": 60, "maximum": 2592000, "default": 86400 },
            "original_cost_usd": { "type": "number", "minimum": 0, "maximum": 1000 }
          }
        }]
      },
      "StoreResponse": {
        "type": "object",
        "properties": {
          "stored": { "type": "boolean" },
          "entry_id": { "type": "string" },
          "namespace": { "type": "string" },
          "expires_at": { "type": "string", "format": "date-time" },
          "exact_match": { "type": "string", "enum": ["ready"] },
          "similar_match": { "type": "string", "enum": ["indexing", "too_long", "unavailable"] },
          "charged_usd": { "type": "number" }
        }
      }
    },
    "responses": {
      "Error": { "description": "Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
    }
  },
  "paths": {
    "/v1/lookup": {
      "post": {
        "operationId": "lookup",
        "summary": "Check for a saved answer before calling a model. Hit $0.002, miss free.",
        "parameters": [{ "name": "Idempotency-Key", "in": "header", "required": false, "schema": { "type": "string", "maxLength": 250 }, "description": "A retry with the same key and question is never charged twice." }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LookupRequest" } } } },
        "responses": {
          "200": { "description": "Hit or miss", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/LookupResponse" } } } },
          "400": { "$ref": "#/components/responses/Error" },
          "401": { "$ref": "#/components/responses/Error" },
          "402": { "$ref": "#/components/responses/Error" },
          "422": { "$ref": "#/components/responses/Error" },
          "429": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/store": {
      "post": {
        "operationId": "store",
        "summary": "Save a question and its answer. Free.",
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/StoreRequest" } } } },
        "responses": {
          "201": { "description": "Saved", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/StoreResponse" } } } },
          "400": { "$ref": "#/components/responses/Error" },
          "401": { "$ref": "#/components/responses/Error" },
          "413": { "$ref": "#/components/responses/Error" },
          "429": { "$ref": "#/components/responses/Error" },
          "503": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/entries/{entry_id}": {
      "delete": {
        "operationId": "deleteEntry",
        "summary": "Remove one saved answer.",
        "parameters": [{ "name": "entry_id", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": {
          "200": { "description": "Deleted", "content": { "application/json": { "schema": { "type": "object", "properties": { "deleted": { "type": "boolean" }, "entry_id": { "type": "string" } } } } } },
          "404": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/purge": {
      "post": {
        "operationId": "purge",
        "summary": "Remove every saved answer in a namespace (and context). Up to 500 per call.",
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Scope" } } } },
        "responses": {
          "200": { "description": "Purged", "content": { "application/json": { "schema": { "type": "object", "properties": { "deleted": { "type": "integer" }, "namespace": { "type": "string" }, "more": { "type": "boolean" } } } } } }
        }
      }
    },
    "/v1/health": {
      "get": {
        "operationId": "health",
        "security": [],
        "summary": "Service health.",
        "responses": { "200": { "description": "Healthy" }, "503": { "description": "Degraded" } }
      }
    }
  }
}
