{
  "openapi": "3.1.0",
  "info": {
    "title": "easy-predict API",
    "version": "1.1.0",
    "description": "Agent-first prediction and anomaly detection API. All paid endpoints use x402 v2 micropayments on Base (USDC). Calling a paid endpoint without payment returns HTTP 402 with the full PaymentRequired body and PAYMENT-REQUIRED header.",
    "contact": { "email": "support@easy-predict.com", "url": "https://easy-predict.com" },
    "license": { "name": "MIT", "url": "https://opensource.org/licenses/MIT" },
    "x-guidance": "POST to a paid endpoint with PAYMENT-SIGNATURE containing a signed x402 v2 payment payload. Omit PAYMENT-SIGNATURE to receive the 402 payment challenge with exact terms. See /.well-known/x402 for the machine-readable resource list."
  },
  "servers": [{ "url": "https://easy-predict.com" }],
  "x-x402": {
    "version": 2,
    "network": "eip155:8453",
    "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    "payTo": "0xc99b83818c8865340AC55C45554f377f41c68DBC",
    "facilitator": "https://x402.org/facilitator"
  },
  "paths": {
    "/timeseries": {
      "get": {
        "summary": "Splash page",
        "description": "Human-readable landing page for easy-predict.",
        "security": [],
        "responses": {
          "200": { "description": "HTML splash page" }
        }
      },
      "post": {
        "summary": "Predict the next value in a numeric time series",
        "description": "Accepts a JSON array or an object with a `series` key (3–1000 numbers) and returns the next predicted value. Uses model selection: holds out the last point, evaluates linear, log1p-linear, last-delta (naive drift), and mean models against it, then retrains the winner on the full series. The endpoint is gated by an x402 v2 micropayment; calling without a valid `PAYMENT-SIGNATURE` header returns HTTP 402 with the full payment terms.",
        "security": [{ "x402": [] }],
        "parameters": [
          {
            "name": "PAYMENT-SIGNATURE",
            "in": "header",
            "required": true,
            "schema": { "type": "string" },
            "description": "Base64-encoded signed x402 v2 PaymentPayload (JSON)."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "array",
                    "items": { "type": "number" },
                    "minItems": 3,
                    "maxItems": 1000,
                    "example": [1.0, 2.3, 4.1, 6.8, 9.2]
                  },
                  {
                    "type": "object",
                    "required": ["series"],
                    "properties": {
                      "series": {
                        "type": "array",
                        "items": { "type": "number" },
                        "minItems": 3,
                        "maxItems": 1000,
                        "example": [1.0, 2.3, 4.1, 6.8, 9.2]
                      },
                      "context": {
                        "type": "string",
                        "maxLength": 200,
                        "description": "Optional description of what this series represents (e.g. 'monthly revenue', 'daily active users'). Providing context helps easy-predict choose the best model for your data and is echoed back in the response.",
                        "example": "monthly revenue in USD"
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Prediction result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["prediction", "method", "holdout_errors"],
                  "properties": {
                    "prediction":     { "type": "number", "description": "Predicted next value." },
                    "method":         { "type": "string", "enum": ["linear", "log1p-linear", "last-delta", "mean"], "description": "Model selected by holdout evaluation." },
                    "holdout_errors": { "type": "object", "description": "Absolute error of each candidate model on the held-out last point.", "additionalProperties": { "type": "number" } },
                    "confidence_interval": {
                      "type": "object",
                      "description": "95% prediction interval for the next value.",
                      "required": ["lower", "upper", "level"],
                      "properties": {
                        "lower": { "type": "number", "description": "Lower bound of the 95% prediction interval." },
                        "upper": { "type": "number", "description": "Upper bound of the 95% prediction interval." },
                        "level": { "type": "number", "description": "Confidence level (always 0.95).", "example": 0.95 }
                      }
                    },
                    "slope":          { "type": "number", "description": "Regression slope (present when method is linear or log1p-linear)." },
                    "intercept":      { "type": "number", "description": "Regression intercept (present when method is linear or log1p-linear)." },
                    "context":        { "type": "string", "description": "Echoed back from the request if provided." }
                  }
                },
                "example": {
                  "prediction": 12.1,
                  "method": "linear",
                  "holdout_errors": { "linear": 0.05, "log1p-linear": 0.31, "last-delta": 0.05, "mean": 3.5 },
                  "confidence_interval": { "lower": 10.2, "upper": 14.0, "level": 0.95 },
                  "slope": 1.94,
                  "intercept": 0.12,
                  "context": "monthly revenue in USD"
                }
              }
            }
          },
          "400": { "description": "Invalid request — bad JSON, wrong type, or series outside 3–1000 elements." },
          "402": {
            "description": "Payment Required — missing or invalid x402 v2 payment. Body and PAYMENT-REQUIRED header contain the payment terms.",
            "headers": {
              "PAYMENT-REQUIRED": {
                "schema": { "type": "string" },
                "description": "Base64-encoded JSON of the full PaymentRequired object (x402Version, resource, accepts)."
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PaymentRequired" }
              }
            }
          }
        },
        "x-payment-info": {
          "price": {
            "fixed":   { "mode": "fixed",   "currency": "USD", "amount": "0.01" },
            "dynamic": { "mode": "dynamic", "currency": "USD", "min": "0.01", "max": "0.01" }
          },
          "protocols": [{ "x402": {} }],
          "x402": {
            "version": 2,
            "resource": {
              "url": "https://easy-predict.com/timeseries",
              "description": "Predict the next value in a numeric series using automatic model selection (linear, log1p-linear, last-delta, mean).",
              "mimeType": "application/json"
            },
            "accepts": [{
              "scheme": "exact",
              "network": "eip155:8453",
              "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
              "amount": "10000",
              "payTo": "0xc99b83818c8865340AC55C45554f377f41c68DBC",
              "maxTimeoutSeconds": 60,
              "extra": { "name": "USD Coin", "version": "2" }
            }],
            "facilitator": "https://x402.org/facilitator"
          }
        }
      }
    },
    "/anomaly-detection": {
      "get": {
        "summary": "Splash page",
        "description": "Human-readable landing page for easy-predict.",
        "security": [],
        "responses": {
          "200": { "description": "HTML splash page" }
        }
      },
      "post": {
        "summary": "Detect anomalies in a numeric series",
        "description": "Accepts a JSON array or an object with a `series` key (3–1000 numbers) and returns a list of anomalous points using z-score detection. An optional `threshold` (default 2.0) controls sensitivity. The endpoint is gated by an x402 v2 micropayment; calling without a valid `PAYMENT-SIGNATURE` header returns HTTP 402 with the full payment terms.",
        "security": [{ "x402": [] }],
        "parameters": [
          {
            "name": "PAYMENT-SIGNATURE",
            "in": "header",
            "required": true,
            "schema": { "type": "string" },
            "description": "Base64-encoded signed x402 v2 PaymentPayload (JSON)."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "array",
                    "items": { "type": "number" },
                    "minItems": 3,
                    "maxItems": 1000,
                    "example": [1.0, 2.3, 4.1, 6.8, 99.0]
                  },
                  {
                    "type": "object",
                    "required": ["series"],
                    "properties": {
                      "series": {
                        "type": "array",
                        "items": { "type": "number" },
                        "minItems": 3,
                        "maxItems": 1000,
                        "example": [1.0, 2.3, 4.1, 6.8, 99.0]
                      },
                      "threshold": {
                        "type": "number",
                        "exclusiveMinimum": 0,
                        "maximum": 10,
                        "default": 2.0,
                        "description": "Z-score cutoff above which a point is flagged as an anomaly. Default 2.0. Lower values flag more points; higher values flag fewer.",
                        "example": 2.0
                      },
                      "context": {
                        "type": "string",
                        "maxLength": 200,
                        "description": "Optional description of what this series represents (e.g. 'cpu usage %'). Echoed back in the response.",
                        "example": "cpu usage %"
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Anomaly detection result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["anomalies", "method", "mean", "std", "threshold"],
                  "properties": {
                    "anomalies": {
                      "type": "array",
                      "description": "Points whose absolute z-score exceeds the threshold. Empty array means no anomalies detected.",
                      "items": {
                        "type": "object",
                        "required": ["index", "value", "z_score"],
                        "properties": {
                          "index":   { "type": "integer", "description": "0-based position in the input series." },
                          "value":   { "type": "number",  "description": "Original value at this index." },
                          "z_score": { "type": "number",  "description": "Signed z-score (sample std, ddof=1)." }
                        }
                      }
                    },
                    "method":    { "type": "string", "enum": ["z-score"] },
                    "mean":      { "type": "number", "description": "Sample mean of the series." },
                    "std":       { "type": "number", "description": "Sample standard deviation (ddof=1)." },
                    "threshold": { "type": "number", "description": "The z-score cutoff used." },
                    "normal_range": {
                      "type": "object",
                      "description": "Range of values considered non-anomalous: [mean − threshold×std, mean + threshold×std].",
                      "required": ["lower", "upper"],
                      "properties": {
                        "lower": { "type": "number", "description": "Lower bound of the normal range." },
                        "upper": { "type": "number", "description": "Upper bound of the normal range." }
                      }
                    },
                    "context":   { "type": "string", "description": "Echoed back from the request if provided." }
                  }
                },
                "example": {
                  "anomalies": [{ "index": 4, "value": 99.0, "z_score": 2.14 }],
                  "method": "z-score",
                  "mean": 15.12,
                  "std": 39.18,
                  "threshold": 2.0,
                  "normal_range": { "lower": -63.24, "upper": 93.48 },
                  "context": "cpu usage %"
                }
              }
            }
          },
          "400": { "description": "Invalid request — bad JSON, wrong type, series outside 3–1000 elements, or invalid threshold." },
          "402": {
            "description": "Payment Required — missing or invalid x402 v2 payment.",
            "headers": {
              "PAYMENT-REQUIRED": {
                "schema": { "type": "string" },
                "description": "Base64-encoded JSON of the full PaymentRequired object."
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PaymentRequired" }
              }
            }
          }
        },
        "x-payment-info": {
          "price": {
            "fixed":   { "mode": "fixed",   "currency": "USD", "amount": "0.01" },
            "dynamic": { "mode": "dynamic", "currency": "USD", "min": "0.01", "max": "0.01" }
          },
          "protocols": [{ "x402": {} }],
          "x402": {
            "version": 2,
            "resource": {
              "url": "https://easy-predict.com/anomaly-detection",
              "description": "Detect anomalies in a numeric series using z-score method.",
              "mimeType": "application/json"
            },
            "accepts": [{
              "scheme": "exact",
              "network": "eip155:8453",
              "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
              "amount": "10000",
              "payTo": "0xc99b83818c8865340AC55C45554f377f41c68DBC",
              "maxTimeoutSeconds": 60,
              "extra": { "name": "USD Coin", "version": "2" }
            }],
            "facilitator": "https://x402.org/facilitator"
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "summary": "OpenAPI discovery document",
        "description": "This OpenAPI 3.1 document. Free to fetch — no payment required.",
        "security": [],
        "responses": {
          "200": { "description": "OpenAPI 3.1 document" }
        }
      }
    },
    "/.well-known/x402": {
      "get": {
        "summary": "x402 v2 resource discovery",
        "description": "Machine-readable list of paid x402 v2 resources and their PaymentRequirements, plus a pointer to /openapi.json. Free to fetch.",
        "security": [],
        "responses": {
          "200": {
            "description": "x402 v2 discovery payload",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["x402Version", "openapi", "resources"],
                  "properties": {
                    "x402Version": { "type": "integer", "example": 2 },
                    "openapi":     { "type": "string", "format": "uri" },
                    "resources": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "resource": { "$ref": "#/components/schemas/ResourceInfo" },
                          "method":   { "type": "string" },
                          "accepts":  { "type": "array", "items": { "$ref": "#/components/schemas/PaymentRequirements" } }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "x402Version": 2,
                  "openapi": "https://easy-predict.com/openapi.json",
                  "resources": [{
                    "resource": {
                      "url": "https://easy-predict.com/timeseries",
                      "description": "Predict the next value in a numeric series using automatic model selection (linear, log1p-linear, last-delta, mean).",
                      "mimeType": "application/json"
                    },
                    "method": "POST",
                    "accepts": [{
                      "scheme": "exact",
                      "network": "eip155:8453",
                      "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
                      "amount": "10000",
                      "payTo": "0xc99b83818c8865340AC55C45554f377f41c68DBC",
                      "maxTimeoutSeconds": 60,
                      "extra": { "name": "USD Coin", "version": "2" }
                    }]
                  }]
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "x402": {
        "type": "apiKey",
        "in": "header",
        "name": "PAYMENT-SIGNATURE",
        "description": "x402 v2 micropayment. Send a base64-encoded signed PaymentPayload JSON. Omitting it returns HTTP 402 with exact payment terms in the `accepts` array."
      }
    },
    "schemas": {
      "ResourceInfo": {
        "type": "object",
        "required": ["url"],
        "properties": {
          "url":         { "type": "string", "format": "uri" },
          "description": { "type": "string" },
          "mimeType":    { "type": "string" }
        }
      },
      "PaymentRequirements": {
        "type": "object",
        "required": ["scheme", "network", "asset", "amount", "payTo", "maxTimeoutSeconds"],
        "properties": {
          "scheme":            { "type": "string", "example": "exact" },
          "network":           { "type": "string", "example": "eip155:8453" },
          "asset":             { "type": "string", "description": "ERC-20 contract address." },
          "amount":            { "type": "string", "example": "10000", "description": "Payment amount in atomic units (USDC has 6 decimals, so 10000 = $0.01)." },
          "payTo":             { "type": "string", "description": "EVM wallet address that receives payment." },
          "maxTimeoutSeconds": { "type": "integer", "example": 60 },
          "extra": {
            "type": "object",
            "properties": {
              "name":    { "type": "string" },
              "version": { "type": "string" }
            }
          }
        }
      },
      "PaymentRequired": {
        "type": "object",
        "required": ["x402Version", "resource", "accepts"],
        "properties": {
          "x402Version": { "type": "integer", "example": 2 },
          "error":       { "type": "string" },
          "resource":    { "$ref": "#/components/schemas/ResourceInfo" },
          "accepts":     { "type": "array", "items": { "$ref": "#/components/schemas/PaymentRequirements" } },
          "extensions":  { "type": "object" }
        }
      }
    }
  }
}
