{
  "openapi": "3.1.0",
  "info": {
    "title": "Canli Capital public read API",
    "version": "1.0.0",
    "summary": "A static, cacheable read API over a paper-traded systematic record.",
    "description": "Every response carries the artifacts it was built from with their SHA-256 hashes, the class of claim it represents, and the limits of what it can be used to say. There is no write path and no authentication. Nothing here represents funded performance.",
    "contact": {
      "name": "Arhan Canli",
      "url": "https://canlicapital.com/founder"
    },
    "license": {
      "name": "MIT",
      "identifier": "MIT"
    }
  },
  "servers": [
    {
      "url": "https://canlicapital.com",
      "description": "Production"
    }
  ],
  "externalDocs": {
    "description": "Developer documentation",
    "url": "https://canlicapital.com/developers"
  },
  "paths": {
    "/api/v1/chain/head": {
      "get": {
        "summary": "The head of the signed append-only transparency chain, and the public key needed to verify it.",
        "operationId": "chain_head",
        "responses": {
          "200": {
            "description": "The current snapshot, regenerated on each publish.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "schema",
                    "generated_at",
                    "claim_class",
                    "limits",
                    "sources",
                    "data"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/record": {
      "get": {
        "summary": "The full record as an instance of the canli.paper-evidence.v0 open standard, including what it does not establish.",
        "operationId": "record",
        "responses": {
          "200": {
            "description": "The current snapshot, regenerated on each publish.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "schema",
                    "generated_at",
                    "claim_class",
                    "limits",
                    "sources",
                    "data"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/research": {
      "get": {
        "summary": "Every published research document and topic, including failures and feasibility nulls.",
        "operationId": "research",
        "responses": {
          "200": {
            "description": "The current snapshot, regenerated on each publish.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "schema",
                    "generated_at",
                    "claim_class",
                    "limits",
                    "sources",
                    "data"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/sleeves": {
      "get": {
        "summary": "Per-sleeve state. Note that the research curves are not on a common date grid and cannot be combined.",
        "operationId": "sleeves",
        "responses": {
          "200": {
            "description": "The current snapshot, regenerated on each publish.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "schema",
                    "generated_at",
                    "claim_class",
                    "limits",
                    "sources",
                    "data"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/status": {
      "get": {
        "summary": "Current state of the paper record: capital kind, period, observation count, validation status and broker reconciliation.",
        "operationId": "status",
        "responses": {
          "200": {
            "description": "The current snapshot, regenerated on each publish.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "schema",
                    "generated_at",
                    "claim_class",
                    "limits",
                    "sources",
                    "data"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/trials/summary": {
      "get": {
        "summary": "The trial union used as the multiple-testing denominator, plus the kill counts.",
        "operationId": "trials_summary",
        "responses": {
          "200": {
            "description": "The current snapshot, regenerated on each publish.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "schema",
                    "generated_at",
                    "claim_class",
                    "limits",
                    "sources",
                    "data"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/keys/revoke": {
      "post": {
        "summary": "Permanently revoke the bearer key without consuming validation quota. Already admitted requests may finish; public receipts remain available.",
        "operationId": "keys_revoke",
        "responses": {
          "200": {
            "description": "The envelope with data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "400": {
            "description": "Malformed request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing or unknown bearer key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "405": {
            "description": "Wrong method",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "413": {
            "description": "Body over 1024 bytes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "422": {
            "description": "Input the validator refuses, with the reason",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "503": {
            "description": "Revocation unavailable; key state is not confirmed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {},
                "required": [],
                "additionalProperties": false
              },
              "example": {}
            }
          }
        },
        "security": [
          {
            "bearerKey": []
          }
        ]
      }
    },
    "/api/v1/keys": {
      "post": {
        "summary": "Issue a free key. Returned once; only its hash is stored.",
        "operationId": "keys",
        "responses": {
          "201": {
            "description": "The key, once",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "400": {
            "description": "Malformed request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "405": {
            "description": "Wrong method",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "413": {
            "description": "Body over 1048576 bytes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "422": {
            "description": "Input the validator refuses, with the reason",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "429": {
            "description": "At most 5 keys per client per day",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "label": {
                    "type": "string"
                  }
                },
                "required": []
              },
              "example": {
                "label": "my-backtest-runner"
              }
            }
          }
        }
      }
    },
    "/api/v1/validate/deflated-sharpe": {
      "post": {
        "summary": "Probabilistic and deflated Sharpe from the seven contract inputs, or from a return series plus the trials behind it.",
        "operationId": "validate_deflated_sharpe",
        "responses": {
          "200": {
            "description": "The envelope with data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "400": {
            "description": "Malformed request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "405": {
            "description": "Wrong method",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "413": {
            "description": "Body over 1048576 bytes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "422": {
            "description": "Input the validator refuses, with the reason",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "429": {
            "description": "Daily quota of 1000 validations reached; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "properties": {
                      "observed_sharpe_annualized": {
                        "type": "number"
                      },
                      "observations": {
                        "type": "number"
                      },
                      "periods_per_year": {
                        "type": "number"
                      },
                      "skew": {
                        "type": "number"
                      },
                      "non_excess_kurtosis": {
                        "type": "number"
                      },
                      "effective_independent_trials": {
                        "type": "number"
                      },
                      "cross_trial_sharpe_sd_annualized": {
                        "type": "number"
                      }
                    },
                    "required": [
                      "observed_sharpe_annualized",
                      "observations",
                      "periods_per_year",
                      "skew",
                      "non_excess_kurtosis",
                      "effective_independent_trials",
                      "cross_trial_sharpe_sd_annualized"
                    ],
                    "title": "contract_inputs",
                    "description": "Mode 1: the seven contract inputs"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "returns": {
                        "type": "array",
                        "items": {
                          "type": "number"
                        }
                      },
                      "periods_per_year": {
                        "type": "number"
                      },
                      "effective_independent_trials": {
                        "type": "number"
                      },
                      "cross_trial_sharpe_sd_annualized": {
                        "type": "number"
                      }
                    },
                    "required": [
                      "returns",
                      "periods_per_year",
                      "effective_independent_trials",
                      "cross_trial_sharpe_sd_annualized"
                    ],
                    "title": "return_series",
                    "description": "Mode 2: a return series plus the trials behind it"
                  }
                ]
              },
              "examples": {
                "contract_inputs": {
                  "summary": "Mode 1: the seven contract inputs",
                  "value": {
                    "observed_sharpe_annualized": 1.5,
                    "observations": 730,
                    "periods_per_year": 365,
                    "skew": -0.5,
                    "non_excess_kurtosis": 5,
                    "effective_independent_trials": 229,
                    "cross_trial_sharpe_sd_annualized": 0.57
                  }
                },
                "return_series": {
                  "summary": "Mode 2: a return series plus the trials behind it",
                  "value": {
                    "returns": [
                      0.004,
                      -0.002,
                      0.007,
                      0.001,
                      -0.003,
                      0.005,
                      0.002,
                      -0.001
                    ],
                    "periods_per_year": 252,
                    "effective_independent_trials": 30,
                    "cross_trial_sharpe_sd_annualized": 0.5
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerKey": []
          }
        ]
      }
    },
    "/api/v1/validate/overfitting": {
      "post": {
        "summary": "Probability of backtest overfitting by CSCV over the returns of every variant tried.",
        "operationId": "validate_overfitting",
        "responses": {
          "200": {
            "description": "The envelope with data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "400": {
            "description": "Malformed request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "405": {
            "description": "Wrong method",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "413": {
            "description": "Body over 1048576 bytes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "422": {
            "description": "Input the validator refuses, with the reason",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "429": {
            "description": "Daily quota of 1000 validations reached; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "matrix": {
                    "type": "array",
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "number"
                      }
                    }
                  },
                  "n_splits": {
                    "type": "number"
                  },
                  "max_combinations": {
                    "type": "number",
                    "description": "Defaults to the service ceiling; may not exceed it."
                  },
                  "seed": {
                    "type": "number",
                    "description": "Defaults to 42. Seeds the service's own sampler for the non-exhaustive case."
                  }
                },
                "required": [
                  "matrix"
                ]
              },
              "example": {
                "matrix": [
                  [
                    0.01,
                    0.002,
                    -0.004
                  ],
                  [
                    -0.003,
                    0.001,
                    0.006
                  ],
                  [
                    0.004,
                    -0.002,
                    0.001
                  ],
                  [
                    0.002,
                    0.003,
                    -0.001
                  ]
                ],
                "n_splits": 4
              }
            }
          }
        },
        "security": [
          {
            "bearerKey": []
          }
        ]
      }
    },
    "/api/v1/validate/paper-evidence": {
      "post": {
        "summary": "Conformance of a performance record against the canli.paper-evidence.v0 standard.",
        "operationId": "validate_paper_evidence",
        "responses": {
          "200": {
            "description": "The envelope with data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "400": {
            "description": "Malformed request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "405": {
            "description": "Wrong method",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "413": {
            "description": "Body over 1048576 bytes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "422": {
            "description": "Input the validator refuses, with the reason",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "429": {
            "description": "Daily quota of 1000 validations reached; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "record": {
                    "type": "object",
                    "properties": {
                      "schema": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "schema"
                    ]
                  }
                },
                "required": [
                  "record"
                ]
              },
              "example": {
                "record": {
                  "schema": "canli.paper-evidence.v0"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerKey": []
          }
        ]
      }
    },
    "/api/v1/validate/breadth": {
      "post": {
        "summary": "Book Sharpe ceiling from per-sleeve quality and average pairwise correlation, and the sleeves a target needs.",
        "operationId": "validate_breadth",
        "responses": {
          "200": {
            "description": "The envelope with data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "400": {
            "description": "Malformed request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "405": {
            "description": "Wrong method",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "413": {
            "description": "Body over 1048576 bytes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "422": {
            "description": "Input the validator refuses, with the reason",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "429": {
            "description": "Daily quota of 1000 validations reached; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "sleeve_sharpe": {
                    "type": "number"
                  },
                  "average_pairwise_correlation": {
                    "type": "number"
                  },
                  "sleeves": {
                    "type": "number"
                  },
                  "target": {
                    "type": "number"
                  }
                },
                "required": [
                  "sleeve_sharpe",
                  "average_pairwise_correlation"
                ]
              },
              "example": {
                "sleeve_sharpe": 0.5,
                "average_pairwise_correlation": 0.05,
                "sleeves": 4,
                "target": 1.5
              }
            }
          }
        },
        "security": [
          {
            "bearerKey": []
          }
        ]
      }
    },
    "/api/v1/validate/track-record": {
      "post": {
        "summary": "Minimum track record length for a Sharpe to clear a benchmark at a confidence level, and the probabilistic Sharpe of a record of a given length.",
        "operationId": "validate_track_record",
        "responses": {
          "200": {
            "description": "The envelope with data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "400": {
            "description": "Malformed request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "405": {
            "description": "Wrong method",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "413": {
            "description": "Body over 1048576 bytes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "422": {
            "description": "Input the validator refuses, with the reason",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "429": {
            "description": "Daily quota of 1000 validations reached; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "observed_sharpe_annualized": {
                    "type": "number"
                  },
                  "benchmark_sharpe_annualized": {
                    "type": "number"
                  },
                  "periods_per_year": {
                    "type": "number"
                  },
                  "skew": {
                    "type": "number"
                  },
                  "non_excess_kurtosis": {
                    "type": "number"
                  },
                  "observations": {
                    "type": "number"
                  },
                  "confidence": {
                    "type": "number",
                    "description": "Defaults to 0.95. Strictly between 0 and 1."
                  }
                },
                "required": [
                  "observed_sharpe_annualized",
                  "periods_per_year",
                  "skew",
                  "non_excess_kurtosis"
                ]
              },
              "example": {
                "observed_sharpe_annualized": 2,
                "benchmark_sharpe_annualized": 1,
                "periods_per_year": 252,
                "skew": 0,
                "non_excess_kurtosis": 3,
                "observations": 504
              }
            }
          }
        },
        "security": [
          {
            "bearerKey": []
          }
        ]
      }
    },
    "/api/v1/validate/backtest-length": {
      "post": {
        "summary": "Minimum backtest length for the best of N independent trials not to reach a target Sharpe by luck, and the trials a backtest's years allow.",
        "operationId": "validate_backtest_length",
        "responses": {
          "200": {
            "description": "The envelope with data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "400": {
            "description": "Malformed request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "405": {
            "description": "Wrong method",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "413": {
            "description": "Body over 1048576 bytes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "422": {
            "description": "Input the validator refuses, with the reason",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "429": {
            "description": "Daily quota of 1000 validations reached; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "effective_independent_trials": {
                    "type": "number"
                  },
                  "backtest_years": {
                    "type": "number"
                  },
                  "target_sharpe_annualized": {
                    "type": "number"
                  }
                },
                "required": []
              },
              "example": {
                "effective_independent_trials": 45,
                "backtest_years": 5,
                "target_sharpe_annualized": 1
              }
            }
          }
        },
        "security": [
          {
            "bearerKey": []
          }
        ]
      }
    },
    "/api/v1/validate/haircut-sharpe": {
      "post": {
        "summary": "Haircut Sharpe ratio for multiple testing: the p-value of a Sharpe found among several tests, adjusted by Bonferroni, for independent tests, and with the other tests' Sharpe ratios by Holm and BHY.",
        "operationId": "validate_haircut_sharpe",
        "responses": {
          "200": {
            "description": "The envelope with data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "400": {
            "description": "Malformed request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "405": {
            "description": "Wrong method",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "413": {
            "description": "Body over 1048576 bytes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "422": {
            "description": "Input the validator refuses, with the reason",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "429": {
            "description": "Daily quota of 1000 validations reached; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "observed_sharpe_annualized": {
                    "type": "number"
                  },
                  "periods_per_year": {
                    "type": "number"
                  },
                  "observations": {
                    "type": "number"
                  },
                  "tests": {
                    "type": "number"
                  },
                  "autocorrelation": {
                    "type": "number"
                  },
                  "other_sharpe_ratios_annualized": {
                    "type": "array",
                    "items": {
                      "type": "number"
                    },
                    "description": "Annualized Sharpe ratios of the other tests, over the same observations; adds Holm and BHY."
                  }
                },
                "required": [
                  "observed_sharpe_annualized",
                  "periods_per_year",
                  "observations"
                ]
              },
              "example": {
                "observed_sharpe_annualized": 1,
                "periods_per_year": 12,
                "observations": 120,
                "tests": 100,
                "autocorrelation": 0.1
              }
            }
          }
        },
        "security": [
          {
            "bearerKey": []
          }
        ]
      }
    },
    "/api/v1/validate/luck-trials": {
      "post": {
        "summary": "Luck-equivalent trials: how many skill-less strategies a search would have had to try for its best to reach the observed Sharpe by luck, and, with a trial count, the chance that it did.",
        "operationId": "validate_luck_trials",
        "responses": {
          "200": {
            "description": "The envelope with data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "400": {
            "description": "Malformed request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "405": {
            "description": "Wrong method",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "413": {
            "description": "Body over 1048576 bytes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "422": {
            "description": "Input the validator refuses, with the reason",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "429": {
            "description": "Daily quota of 1000 validations reached; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "observed_sharpe_annualized": {
                    "type": "number"
                  },
                  "periods_per_year": {
                    "type": "number"
                  },
                  "observations": {
                    "type": "number"
                  },
                  "effective_independent_trials": {
                    "type": "number"
                  },
                  "skew": {
                    "type": "number"
                  },
                  "autocorrelation": {
                    "type": "number"
                  }
                },
                "required": [
                  "observed_sharpe_annualized",
                  "periods_per_year",
                  "observations"
                ]
              },
              "example": {
                "observed_sharpe_annualized": 1.5,
                "periods_per_year": 252,
                "observations": 756,
                "effective_independent_trials": 200,
                "skew": -0.4,
                "autocorrelation": 0.05
              }
            }
          }
        },
        "security": [
          {
            "bearerKey": []
          }
        ]
      }
    },
    "/api/v1/validate/reality-check": {
      "post": {
        "summary": "Data-snooping tests on every variant a search tried: Hansen's SPA, White's Reality Check and Romano and Wolf's StepM on one seeded stationary bootstrap. Did the best variant beat the benchmark by more than the best of K would by luck, and which variants did?",
        "operationId": "validate_reality_check",
        "responses": {
          "200": {
            "description": "The envelope with data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "400": {
            "description": "Malformed request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "405": {
            "description": "Wrong method",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "413": {
            "description": "Body over 1048576 bytes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "422": {
            "description": "Input the validator refuses, with the reason",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "429": {
            "description": "Daily quota of 1000 validations reached; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "matrix": {
                    "type": "array",
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "number"
                      }
                    }
                  },
                  "benchmark": {
                    "type": "array",
                    "items": {
                      "type": "number"
                    },
                    "description": "The benchmark's return in each period, one per row of matrix. Defaults to zero: the test is then whether the best variant's mean return beats zero."
                  },
                  "block_length": {
                    "type": "integer",
                    "description": "Mean block length of the stationary bootstrap, in periods. Defaults to round(n^(1/3))."
                  },
                  "reps": {
                    "type": "integer",
                    "description": "Bootstrap draws. Defaults to 2000, fewer when the matrix is large; periods x variants x draws may not exceed 200,000,000."
                  },
                  "seed": {
                    "type": "integer",
                    "description": "Defaults to 42. Seeds the service's own generator, so a result reproduces exactly."
                  },
                  "alpha": {
                    "type": "number",
                    "description": "Familywise error for StepM and the verdict. Defaults to 0.05."
                  }
                },
                "required": [
                  "matrix"
                ]
              },
              "example": {
                "matrix": [
                  [
                    0.0045,
                    0.0065,
                    -0.0005
                  ],
                  [
                    0.0073,
                    -0.0031,
                    -0.0042
                  ],
                  [
                    -0.0002,
                    -0.0055,
                    0.0058
                  ],
                  [
                    -0.0049,
                    0.0051,
                    -0.0002
                  ],
                  [
                    0.0008,
                    0.0038,
                    -0.0046
                  ],
                  [
                    0.0041,
                    -0.0064,
                    0.0023
                  ],
                  [
                    0.0006,
                    -0.0016,
                    0.0012
                  ],
                  [
                    0.002,
                    0.007,
                    0.0015
                  ],
                  [
                    0.0068,
                    -0.0007,
                    -0.0062
                  ],
                  [
                    0.0024,
                    -0.0066,
                    0.0044
                  ],
                  [
                    -0.0051,
                    0.003,
                    0.002
                  ],
                  [
                    -0.0018,
                    0.0055,
                    -0.0036
                  ],
                  [
                    0.0049,
                    -0.0047,
                    -0.0004
                  ],
                  [
                    0.003,
                    -0.0037,
                    0.0011
                  ],
                  [
                    0.0006,
                    0.0058,
                    0.0041
                  ],
                  [
                    0.0047,
                    0.0016,
                    -0.0068
                  ],
                  [
                    0.0042,
                    -0.006,
                    0.0021
                  ],
                  [
                    -0.0036,
                    0.0004,
                    0.003
                  ],
                  [
                    -0.0041,
                    0.0055,
                    -0.0012
                  ],
                  [
                    0.0041,
                    -0.0022,
                    -0.0022
                  ],
                  [
                    0.0056,
                    -0.0044,
                    -0.0006
                  ],
                  [
                    0.0009,
                    0.0034,
                    0.0062
                  ],
                  [
                    0.0021,
                    0.0029,
                    -0.0056
                  ],
                  [
                    0.0046,
                    -0.0039,
                    -0.0003
                  ],
                  [
                    -0.0011,
                    -0.0014,
                    0.0022
                  ],
                  [
                    -0.0051,
                    0.0039,
                    0.0015
                  ],
                  [
                    0.0019,
                    0.0001,
                    -0.0024
                  ],
                  [
                    0.0073,
                    -0.0034,
                    -0.0031
                  ],
                  [
                    0.0027,
                    0.0008,
                    0.0069
                  ],
                  [
                    -0.0001,
                    0.0026,
                    -0.0033
                  ]
                ]
              }
            }
          }
        },
        "security": [
          {
            "bearerKey": []
          }
        ]
      }
    },
    "/api/v1/validate/status": {
      "get": {
        "summary": "Service and store status with the quota constants in force.",
        "operationId": "validate_status",
        "responses": {
          "200": {
            "description": "Service, store and usage status.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/Envelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "object",
                          "properties": {
                            "service": {
                              "type": "string"
                            },
                            "store_reachable": {
                              "type": "boolean"
                            },
                            "quotas": {
                              "type": "object"
                            },
                            "usage": {
                              "$ref": "#/components/schemas/UsageSummary"
                            },
                            "usage_available": {
                              "type": "boolean"
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Malformed request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "405": {
            "description": "Wrong method",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "503": {
            "description": "The store is unreachable; usage is still reported, as null",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/receipts/{id}": {
      "get": {
        "summary": "A stored verdict by content-hash id. Immutable.",
        "operationId": "receipts_id_",
        "responses": {
          "200": {
            "description": "The envelope with data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "400": {
            "description": "Malformed request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "404": {
            "description": "No such receipt",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          },
          "405": {
            "description": "Wrong method",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-f]{24}$"
            }
          }
        ]
      }
    },
    "/api/v1/receipts/{id}/badge.svg": {
      "get": {
        "summary": "An embeddable SVG badge for a receipt: the formula version and the receipt id prefix only, never a pass or fail mark.",
        "operationId": "receipts_id_badge_svg",
        "responses": {
          "200": {
            "description": "An SVG badge: the formula version and the receipt id prefix only, rendered from the stored receipt's own fields. Never the words verified, approved, passed, certified or profitable, and never a pass/fail mark. The <title> element carries the receipt's own sample-size or trial-count fact as alt text.",
            "content": {
              "image/svg+xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Unknown receipt id: a plain grey \"receipt not found\" badge.",
            "content": {
              "image/svg+xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "405": {
            "description": "Wrong method",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Envelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-f]{24}$"
            }
          }
        ]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "A key from POST /api/v1/keys, sent as Authorization: Bearer ck_live_..."
      }
    },
    "schemas": {
      "Envelope": {
        "type": "object",
        "required": [
          "schema",
          "endpoint",
          "generated_at",
          "claim_class",
          "capital_kind",
          "canonical_human_page",
          "limits",
          "sources",
          "data"
        ],
        "properties": {
          "schema": {
            "const": "canli.api.v1"
          },
          "endpoint": {
            "type": "string"
          },
          "generated_at": {
            "type": "string",
            "format": "date-time"
          },
          "claim_class": {
            "type": "string"
          },
          "capital_kind": {
            "type": "string"
          },
          "canonical_human_page": {
            "type": "string"
          },
          "limits": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "minItems": 1
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "data": {
            "type": "object"
          },
          "receipt": {
            "type": "object"
          },
          "error": {
            "type": "object"
          }
        }
      },
      "UsageSummary": {
        "type": "object",
        "nullable": true,
        "oneOf": [
          {
            "type": "null"
          },
          {
            "type": "object",
            "required": [
              "validations_today",
              "validations_total",
              "keys_issued_today",
              "as_of_utc_day"
            ],
            "properties": {
              "validations_today": {
                "type": "integer",
                "minimum": 0
              },
              "validations_total": {
                "type": "integer",
                "minimum": 0
              },
              "keys_issued_today": {
                "type": "integer",
                "minimum": 0
              },
              "as_of_utc_day": {
                "type": "string",
                "format": "date"
              },
              "keys_by_source_host_today": {
                "type": "object",
                "nullable": true,
                "description": "Top ten Referer hosts (lowercase, no path or query) among keys issued today, by count. Absent until 20260906_usage_summary_v2.sql is applied.",
                "additionalProperties": {
                  "type": "integer",
                  "minimum": 0
                }
              },
              "keys_by_label_today": {
                "type": "object",
                "nullable": true,
                "description": "Top ten POST /api/v1/keys label values among keys issued today, by count. Absent until 20260906_usage_summary_v2.sql is applied.",
                "additionalProperties": {
                  "type": "integer",
                  "minimum": 0
                }
              }
            }
          }
        ]
      }
    }
  }
}
