{
  "components": {
    "schemas": {
      "AiAssistRequest": {
        "properties": {
          "lang": {
            "anyOf": [
              {
                "maxLength": 5,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": "en",
            "title": "Lang"
          },
          "query": {
            "maxLength": 500,
            "minLength": 1,
            "title": "Query",
            "type": "string"
          }
        },
        "required": [
          "query"
        ],
        "title": "AiAssistRequest",
        "type": "object"
      },
      "AnalyticsEvent": {
        "properties": {
          "data": {
            "additionalProperties": true,
            "default": {},
            "title": "Data",
            "type": "object"
          },
          "event": {
            "title": "Event",
            "type": "string"
          },
          "slug": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Slug"
          }
        },
        "required": [
          "event"
        ],
        "title": "AnalyticsEvent",
        "type": "object"
      },
      "BatchItem": {
        "properties": {
          "inputs": {
            "additionalProperties": true,
            "title": "Inputs",
            "type": "object"
          },
          "slug": {
            "title": "Slug",
            "type": "string"
          }
        },
        "required": [
          "slug",
          "inputs"
        ],
        "title": "BatchItem",
        "type": "object"
      },
      "BatchRequest": {
        "properties": {
          "calculations": {
            "items": {
              "$ref": "#/components/schemas/BatchItem"
            },
            "title": "Calculations",
            "type": "array"
          }
        },
        "required": [
          "calculations"
        ],
        "title": "BatchRequest",
        "type": "object"
      },
      "BatchResponse": {
        "properties": {
          "results": {
            "items": {
              "$ref": "#/components/schemas/BatchResultItem"
            },
            "title": "Results",
            "type": "array"
          }
        },
        "required": [
          "results"
        ],
        "title": "BatchResponse",
        "type": "object"
      },
      "BatchResultItem": {
        "description": "One calculation of a batch: its values and provenance, or its error.",
        "properties": {
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why this item was not computed; absent on success.",
            "title": "Error"
          },
          "errorKind": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Errorkind"
          },
          "errors": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Errors"
          },
          "provenance": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ResultProvenance"
              },
              {
                "type": "null"
              }
            ]
          },
          "slug": {
            "title": "Slug",
            "type": "string"
          },
          "values": {
            "anyOf": [
              {
                "additionalProperties": {
                  "anyOf": [
                    {
                      "type": "number"
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Values"
          },
          "warnings": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Warnings"
          }
        },
        "required": [
          "slug"
        ],
        "title": "BatchResultItem",
        "type": "object"
      },
      "CalculateRequest": {
        "properties": {
          "inputs": {
            "additionalProperties": {
              "type": "number"
            },
            "description": "Input values keyed by input key",
            "title": "Inputs",
            "type": "object"
          },
          "slug": {
            "description": "Calculator slug, e.g. 'microstrip-impedance'",
            "title": "Slug",
            "type": "string"
          }
        },
        "required": [
          "slug",
          "inputs"
        ],
        "title": "CalculateRequest",
        "type": "object"
      },
      "CalculateResponse": {
        "properties": {
          "errors": {
            "default": [],
            "items": {
              "type": "string"
            },
            "title": "Errors",
            "type": "array"
          },
          "provenance": {
            "$ref": "#/components/schemas/ResultProvenance"
          },
          "slug": {
            "title": "Slug",
            "type": "string"
          },
          "values": {
            "additionalProperties": {
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "null"
                }
              ]
            },
            "title": "Values",
            "type": "object"
          },
          "warnings": {
            "default": [],
            "items": {
              "type": "string"
            },
            "title": "Warnings",
            "type": "array"
          }
        },
        "required": [
          "slug",
          "values",
          "provenance"
        ],
        "title": "CalculateResponse",
        "type": "object"
      },
      "CheckRequest": {
        "properties": {
          "params": {
            "additionalProperties": true,
            "default": {},
            "title": "Params",
            "type": "object"
          }
        },
        "title": "CheckRequest",
        "type": "object"
      },
      "CheckResponse": {
        "properties": {
          "frequencies": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Frequencies"
          },
          "unknowns": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unknowns"
          },
          "valid": {
            "title": "Valid",
            "type": "boolean"
          },
          "violations": {
            "items": {
              "$ref": "#/components/schemas/Violation"
            },
            "title": "Violations",
            "type": "array"
          }
        },
        "required": [
          "valid",
          "violations",
          "unknowns",
          "frequencies"
        ],
        "title": "CheckResponse",
        "type": "object"
      },
      "CreateKeyRequest": {
        "properties": {
          "client": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Client"
          },
          "label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Label"
          }
        },
        "title": "CreateKeyRequest",
        "type": "object"
      },
      "CreditBalance": {
        "properties": {
          "available": {
            "description": "included + purchased - held.",
            "title": "Available",
            "type": "integer"
          },
          "held": {
            "description": "Held by running paid-lane jobs.",
            "title": "Held",
            "type": "integer"
          },
          "included": {
            "description": "This period's tier grant, unspent.",
            "title": "Included",
            "type": "integer"
          },
          "purchased": {
            "description": "Bought credits, unspent; negative after a refund.",
            "title": "Purchased",
            "type": "integer"
          }
        },
        "required": [
          "included",
          "purchased",
          "held",
          "available"
        ],
        "title": "CreditBalance",
        "type": "object"
      },
      "CreditGrant": {
        "properties": {
          "credits": {
            "description": "Included credits the tier grants each calendar month (UTC).",
            "title": "Credits",
            "type": "integer"
          },
          "monthly": {
            "description": "The same figure as `credits`.",
            "title": "Monthly",
            "type": "integer"
          },
          "period": {
            "title": "Period",
            "type": "string"
          },
          "renewsAt": {
            "title": "Renewsat",
            "type": "string"
          },
          "rollOver": {
            "title": "Rollover",
            "type": "boolean"
          },
          "tier": {
            "title": "Tier",
            "type": "string"
          }
        },
        "required": [
          "tier",
          "credits",
          "monthly",
          "rollOver",
          "period",
          "renewsAt"
        ],
        "title": "CreditGrant",
        "type": "object"
      },
      "CreditPack": {
        "properties": {
          "checkoutAvailable": {
            "description": "Whether an order for this pack would be credited: its variant is configured in either store.",
            "title": "Checkoutavailable",
            "type": "boolean"
          },
          "credits": {
            "title": "Credits",
            "type": "integer"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "priceUsd": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "The pack's price in US dollars, as its Lemon Squeezy variant charges it.",
            "title": "Priceusd"
          },
          "testCheckoutAvailable": {
            "description": "Whether the test store's variant is configured.",
            "title": "Testcheckoutavailable",
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "credits",
          "checkoutAvailable",
          "testCheckoutAvailable"
        ],
        "title": "CreditPack",
        "type": "object"
      },
      "CreditUsageJob": {
        "properties": {
          "at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the job was submitted.",
            "title": "At"
          },
          "credits": {
            "description": "Settled, or still held while the job is open; 0 once released.",
            "title": "Credits",
            "type": "integer"
          },
          "jobId": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Jobid"
          },
          "jobType": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Jobtype"
          },
          "outcome": {
            "enum": [
              "settled",
              "released",
              "open"
            ],
            "title": "Outcome",
            "type": "string"
          }
        },
        "required": [
          "credits",
          "outcome"
        ],
        "title": "CreditUsageJob",
        "type": "object"
      },
      "CreditUsageSummary": {
        "description": "What the account's paid-lane jobs would have used while credits are not enforced.",
        "properties": {
          "complete": {
            "description": "False when the listing was cut short and the sums are a lower bound.",
            "title": "Complete",
            "type": "boolean"
          },
          "credits": {
            "description": "settled + held: what those jobs used, and at most what the open ones will.",
            "title": "Credits",
            "type": "integer"
          },
          "days": {
            "title": "Days",
            "type": "integer"
          },
          "held": {
            "description": "Credits held by those still running or not yet settled.",
            "title": "Held",
            "type": "integer"
          },
          "jobCount": {
            "description": "Paid-lane jobs submitted since `since` that carry a credit hold.",
            "title": "Jobcount",
            "type": "integer"
          },
          "jobs": {
            "description": "The most recent of those jobs, newest first.",
            "items": {
              "$ref": "#/components/schemas/CreditUsageJob"
            },
            "title": "Jobs",
            "type": "array"
          },
          "period": {
            "description": "The window, in words: `the last 30 days`.",
            "title": "Period",
            "type": "string"
          },
          "released": {
            "description": "Credits released by those that failed.",
            "title": "Released",
            "type": "integer"
          },
          "settled": {
            "description": "Credits those that completed would have been debited.",
            "title": "Settled",
            "type": "integer"
          },
          "since": {
            "title": "Since",
            "type": "string"
          }
        },
        "required": [
          "credits",
          "period",
          "since",
          "days",
          "jobCount",
          "settled",
          "held",
          "released",
          "complete",
          "jobs"
        ],
        "title": "CreditUsageSummary",
        "type": "object"
      },
      "CreditsResponse": {
        "properties": {
          "balance": {
            "$ref": "#/components/schemas/CreditBalance"
          },
          "creditVcpuSeconds": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "number"
              }
            ],
            "title": "Creditvcpuseconds"
          },
          "enforced": {
            "description": "Whether a shortfall refuses a paid-lane submission.",
            "title": "Enforced",
            "type": "boolean"
          },
          "grants": {
            "$ref": "#/components/schemas/CreditGrant"
          },
          "holdFactor": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "number"
              }
            ],
            "title": "Holdfactor"
          },
          "ledger": {
            "description": "Recent ledger entries, newest first.",
            "items": {
              "additionalProperties": true,
              "type": "object"
            },
            "title": "Ledger",
            "type": "array"
          },
          "packs": {
            "items": {
              "$ref": "#/components/schemas/CreditPack"
            },
            "title": "Packs",
            "type": "array"
          },
          "purchaseUrl": {
            "title": "Purchaseurl",
            "type": "string"
          },
          "wouldHaveUsed": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/CreditUsageSummary"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shadow mode only: jobs hold nothing from the balance, so this is what they would have used."
          }
        },
        "required": [
          "enforced",
          "creditVcpuSeconds",
          "holdFactor",
          "balance",
          "grants",
          "ledger",
          "packs",
          "purchaseUrl"
        ],
        "title": "CreditsResponse",
        "type": "object"
      },
      "ErrorBody": {
        "additionalProperties": true,
        "description": "Every refusal: `errorKind` beside `detail`, from the closed set the jobs API uses.",
        "properties": {
          "detail": {
            "title": "Detail",
            "type": "string"
          },
          "errorKind": {
            "title": "Errorkind",
            "type": "string"
          }
        },
        "required": [
          "detail",
          "errorKind"
        ],
        "title": "ErrorBody",
        "type": "object"
      },
      "EstimateBudget": {
        "additionalProperties": true,
        "description": "The lane limit the worker enforces for this job, and this job against it.",
        "properties": {
          "estimated": {
            "anyOf": [
              {},
              {
                "type": "null"
              }
            ],
            "description": "This job's figure in the same terms; null where it is not predicted.",
            "title": "Estimated"
          },
          "kind": {
            "enum": [
              "cells",
              "nec2"
            ],
            "title": "Kind",
            "type": "string"
          },
          "limit": {
            "anyOf": [
              {},
              {
                "type": "null"
              }
            ],
            "description": "`cells`: the mesh-cell budget. `nec2`: `{solveSeconds, peakRssBytes}`.",
            "title": "Limit"
          }
        },
        "required": [
          "kind",
          "limit",
          "estimated"
        ],
        "title": "EstimateBudget",
        "type": "object"
      },
      "EstimateRange": {
        "properties": {
          "estimate": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "number"
              }
            ],
            "title": "Estimate"
          },
          "high": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "number"
              }
            ],
            "title": "High"
          },
          "low": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "number"
              }
            ],
            "title": "Low"
          }
        },
        "required": [
          "estimate",
          "low",
          "high"
        ],
        "title": "EstimateRange",
        "type": "object"
      },
      "ExportComponent": {
        "properties": {
          "placement": {
            "enum": [
              "series",
              "shunt"
            ],
            "title": "Placement",
            "type": "string"
          },
          "ref": {
            "title": "Ref",
            "type": "string"
          },
          "type": {
            "enum": [
              "R",
              "L",
              "C"
            ],
            "title": "Type",
            "type": "string"
          },
          "value": {
            "title": "Value",
            "type": "string"
          }
        },
        "required": [
          "ref",
          "type",
          "value",
          "placement"
        ],
        "title": "ExportComponent",
        "type": "object"
      },
      "HTTPValidationError": {
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            },
            "title": "Detail",
            "type": "array"
          }
        },
        "title": "HTTPValidationError",
        "type": "object"
      },
      "JobEstimateResponse": {
        "additionalProperties": true,
        "description": "What a submission would cost (design Decision 2). Nothing is charged.",
        "properties": {
          "basis": {
            "description": "`cells_surrogate`, `nec2`, `trials`, `constant`, `reference` (an uncalibrated pair's committed runtime), `not_available` or `none`.",
            "title": "Basis",
            "type": "string"
          },
          "billedVcpuSeconds": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Paid lane: vcpus x max(60 s, wall + task start), what Fargate bills. Null on the free lane.",
            "title": "Billedvcpuseconds"
          },
          "budget": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/EstimateBudget"
              },
              {
                "type": "null"
              }
            ]
          },
          "calibratedOn": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Calibratedon"
          },
          "credits": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Paid lane: billed vCPU-seconds in credits, rounded up. Null on the free lane.",
            "title": "Credits"
          },
          "creditsEnforced": {
            "description": "False while credits are shown and recorded but never charged.",
            "title": "Creditsenforced",
            "type": "boolean"
          },
          "creditsHold": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Paid lane: what a submission would hold, credits x holdFactor rounded up.",
            "title": "Creditshold"
          },
          "jobType": {
            "title": "Jobtype",
            "type": "string"
          },
          "lane": {
            "description": "Where the job would run: the paid lane for Pro and API accounts.",
            "enum": [
              "free",
              "paid"
            ],
            "title": "Lane",
            "type": "string"
          },
          "message": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What the figures rest on, and what to change when over budget.",
            "title": "Message"
          },
          "mode": {
            "description": "The normalised solve mode; `default` for a job type without modes.",
            "title": "Mode",
            "type": "string"
          },
          "turnaroundSeconds": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/EstimateRange"
              },
              {
                "type": "null"
              }
            ],
            "description": "Wall time plus the paid lane's task start; queue wait excluded."
          },
          "vcpuSeconds": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Allocated vCPU-seconds: vcpus x wall time.",
            "title": "Vcpuseconds"
          },
          "vcpus": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "vCPUs the lane allocates to one job.",
            "title": "Vcpus"
          },
          "wallSeconds": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/EstimateRange"
              },
              {
                "type": "null"
              }
            ],
            "description": "The worker's run time. Null when nothing is measured."
          },
          "withinBudget": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Whether the lane would run it; null where only the worker can tell.",
            "title": "Withinbudget"
          },
          "work": {
            "additionalProperties": true,
            "description": "The size driver: cells, unknowns/frequencies/evaluations, trials, ...",
            "title": "Work",
            "type": "object"
          }
        },
        "required": [
          "jobType",
          "lane",
          "mode",
          "wallSeconds",
          "turnaroundSeconds",
          "vcpus",
          "vcpuSeconds",
          "billedVcpuSeconds",
          "credits",
          "creditsHold",
          "creditsEnforced",
          "withinBudget",
          "work",
          "basis",
          "message"
        ],
        "title": "JobEstimateResponse",
        "type": "object"
      },
      "JobStatusResponse": {
        "properties": {
          "computeCost": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Computecost"
          },
          "createdAt": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Createdat"
          },
          "elapsedSeconds": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Elapsedseconds"
          },
          "errorDetails": {
            "anyOf": [
              {
                "items": {},
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Errordetails"
          },
          "errorKind": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Errorkind"
          },
          "errorMessage": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Errormessage"
          },
          "expiresAt": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expiresat"
          },
          "finishedAt": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Finishedat"
          },
          "jobId": {
            "title": "Jobid",
            "type": "string"
          },
          "jobType": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Jobtype"
          },
          "progress": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Progress"
          },
          "queuePosition": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Queueposition"
          },
          "queueTotal": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Queuetotal"
          },
          "resultExpiresAt": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Resultexpiresat"
          },
          "resultUrl": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Resulturl"
          },
          "resultUrlExpiresIn": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Resulturlexpiresin"
          },
          "stage": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Stage"
          },
          "startedAt": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Startedat"
          },
          "status": {
            "title": "Status",
            "type": "string"
          }
        },
        "required": [
          "jobId",
          "status"
        ],
        "title": "JobStatusResponse",
        "type": "object"
      },
      "JobSubmitRequest": {
        "properties": {
          "inputFileKeys": {
            "default": [],
            "items": {
              "type": "string"
            },
            "title": "Inputfilekeys",
            "type": "array"
          },
          "jobType": {
            "title": "Jobtype",
            "type": "string"
          },
          "params": {
            "additionalProperties": true,
            "default": {},
            "title": "Params",
            "type": "object"
          }
        },
        "required": [
          "jobType"
        ],
        "title": "JobSubmitRequest",
        "type": "object"
      },
      "JobSubmitResponse": {
        "properties": {
          "deduplicated": {
            "default": false,
            "title": "Deduplicated",
            "type": "boolean"
          },
          "errorKind": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Errorkind"
          },
          "errorMessage": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Errormessage"
          },
          "jobId": {
            "title": "Jobid",
            "type": "string"
          },
          "queuePosition": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Queueposition"
          },
          "queueTotal": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Queuetotal"
          },
          "status": {
            "title": "Status",
            "type": "string"
          }
        },
        "required": [
          "jobId",
          "status"
        ],
        "title": "JobSubmitResponse",
        "type": "object"
      },
      "JobTypeCatalogue": {
        "description": "Every job type this API accepts, with the limits that apply to each.",
        "properties": {
          "checks": {
            "default": [],
            "items": {
              "type": "string"
            },
            "title": "Checks",
            "type": "array"
          },
          "concurrentJobLimit": {
            "default": 0,
            "title": "Concurrentjoblimit",
            "type": "integer"
          },
          "dedupWindowSeconds": {
            "default": 0,
            "title": "Dedupwindowseconds",
            "type": "integer"
          },
          "errorKinds": {
            "default": [],
            "items": {
              "type": "string"
            },
            "title": "Errorkinds",
            "type": "array"
          },
          "jobTypes": {
            "additionalProperties": true,
            "title": "Jobtypes",
            "type": "object"
          }
        },
        "required": [
          "jobTypes"
        ],
        "title": "JobTypeCatalogue",
        "type": "object"
      },
      "KicadExportRequest": {
        "properties": {
          "components": {
            "items": {
              "$ref": "#/components/schemas/ExportComponent"
            },
            "title": "Components",
            "type": "array"
          },
          "load_z": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Load Z"
          },
          "source_z": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Z"
          },
          "title": {
            "title": "Title",
            "type": "string"
          },
          "topology": {
            "title": "Topology",
            "type": "string"
          }
        },
        "required": [
          "topology",
          "title",
          "components"
        ],
        "title": "KicadExportRequest",
        "type": "object"
      },
      "ProvenanceAssumption": {
        "additionalProperties": true,
        "properties": {
          "code": {
            "description": "Stable kebab-case code, e.g. `quasi-static`.",
            "title": "Code",
            "type": "string"
          },
          "text": {
            "description": "The sentence a person reads.",
            "title": "Text",
            "type": "string"
          }
        },
        "required": [
          "code",
          "text"
        ],
        "title": "ProvenanceAssumption",
        "type": "object"
      },
      "ProvenanceBound": {
        "additionalProperties": true,
        "properties": {
          "max": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Upper end; null states no bound.",
            "title": "Max"
          },
          "min": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Lower end; null states no bound.",
            "title": "Min"
          },
          "unit": {
            "description": "The input's unit; empty when dimensionless.",
            "title": "Unit",
            "type": "string"
          }
        },
        "required": [
          "min",
          "max",
          "unit"
        ],
        "title": "ProvenanceBound",
        "type": "object"
      },
      "ProvenanceFittedModel": {
        "additionalProperties": true,
        "properties": {
          "description": {
            "description": "The geometry the fit was measured over.",
            "title": "Description",
            "type": "string"
          },
          "inside": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Whether the inputs lay inside it; null when unknown.",
            "title": "Inside"
          },
          "worstCaseError": {
            "description": "Worst-case error inside that range, as a fraction.",
            "title": "Worstcaseerror",
            "type": "number"
          }
        },
        "required": [
          "description",
          "worstCaseError",
          "inside"
        ],
        "title": "ProvenanceFittedModel",
        "type": "object"
      },
      "ProvenanceValidRange": {
        "additionalProperties": true,
        "properties": {
          "bounds": {
            "additionalProperties": {
              "$ref": "#/components/schemas/ProvenanceBound"
            },
            "description": "Input key to its stated range.",
            "title": "Bounds",
            "type": "object"
          },
          "model": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ProvenanceFittedModel"
              },
              {
                "type": "null"
              }
            ],
            "description": "The fitted model's validated range, or null where none applies."
          },
          "outside": {
            "description": "Input keys whose values lay outside their bounds.",
            "items": {
              "type": "string"
            },
            "title": "Outside",
            "type": "array"
          },
          "status": {
            "enum": [
              "inside",
              "outside",
              "unknown"
            ],
            "title": "Status",
            "type": "string"
          }
        },
        "required": [
          "status",
          "bounds",
          "outside",
          "model"
        ],
        "title": "ProvenanceValidRange",
        "type": "object"
      },
      "QuotaRefusalBody": {
        "additionalProperties": true,
        "description": "402: the account's allowance (or overage cap) is spent, or — enforced\nsimulation credits — a paid-lane job's credit hold is more than the\navailable balance. Sent with Retry-After.",
        "properties": {
          "available": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "`credits`: included + purchased - held; negative after a refund.",
            "title": "Available"
          },
          "detail": {
            "title": "Detail",
            "type": "string"
          },
          "errorKind": {
            "title": "Errorkind",
            "type": "string"
          },
          "limit": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Limit"
          },
          "overageUrl": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Overageurl"
          },
          "purchaseUrl": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "`credits`: where to buy a credit pack.",
            "title": "Purchaseurl"
          },
          "reason": {
            "enum": [
              "allowance",
              "overage_cap",
              "solve_mode",
              "credits"
            ],
            "title": "Reason",
            "type": "string"
          },
          "renewsAt": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "`credits`: when the tier's included credits are next granted.",
            "title": "Renewsat"
          },
          "required": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "`credits`: the credits this job would hold.",
            "title": "Required"
          },
          "resetAt": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Resetat"
          },
          "upgradeUrl": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Upgradeurl"
          },
          "used": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Used"
          }
        },
        "required": [
          "detail",
          "errorKind",
          "reason"
        ],
        "title": "QuotaRefusalBody",
        "type": "object"
      },
      "RateLimitBody": {
        "additionalProperties": true,
        "description": "429: more requests in the window than the credential allows. Sent with Retry-After.",
        "properties": {
          "detail": {
            "title": "Detail",
            "type": "string"
          },
          "errorKind": {
            "title": "Errorkind",
            "type": "string"
          },
          "limit": {
            "title": "Limit",
            "type": "integer"
          },
          "upgradeUrl": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Upgradeurl"
          },
          "windowSeconds": {
            "title": "Windowseconds",
            "type": "integer"
          }
        },
        "required": [
          "detail",
          "errorKind",
          "limit",
          "windowSeconds"
        ],
        "title": "RateLimitBody",
        "type": "object"
      },
      "ReportRequest": {
        "properties": {
          "inputs": {
            "additionalProperties": {
              "type": "number"
            },
            "title": "Inputs",
            "type": "object"
          },
          "note": {
            "anyOf": [
              {
                "maxLength": 500,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Note"
          },
          "outputs": {
            "additionalProperties": {
              "type": "number"
            },
            "title": "Outputs",
            "type": "object"
          },
          "slug": {
            "title": "Slug",
            "type": "string"
          }
        },
        "required": [
          "slug",
          "inputs",
          "outputs"
        ],
        "title": "ReportRequest",
        "type": "object"
      },
      "RequestCreate": {
        "properties": {
          "category": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Category"
          },
          "description": {
            "maxLength": 500,
            "minLength": 10,
            "title": "Description",
            "type": "string"
          },
          "title": {
            "maxLength": 120,
            "minLength": 5,
            "title": "Title",
            "type": "string"
          }
        },
        "required": [
          "title",
          "description"
        ],
        "title": "RequestCreate",
        "type": "object"
      },
      "ResultProvenance": {
        "additionalProperties": true,
        "description": "What computed a result, from which source, under which assumptions, when.",
        "properties": {
          "assumptions": {
            "items": {
              "$ref": "#/components/schemas/ProvenanceAssumption"
            },
            "title": "Assumptions",
            "type": "array"
          },
          "computedAt": {
            "description": "ISO-8601 UTC, millisecond precision, `Z` suffix.",
            "title": "Computedat",
            "type": "string"
          },
          "elapsedSeconds": {
            "title": "Elapsedseconds",
            "type": "number"
          },
          "formulaRef": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The published source of the formula, or null.",
            "title": "Formularef"
          },
          "inputs": {
            "additionalProperties": true,
            "description": "The inputs after defaults were applied.",
            "title": "Inputs",
            "type": "object"
          },
          "method": {
            "description": "`calculator:<slug>`, or a job's method.",
            "title": "Method",
            "type": "string"
          },
          "seed": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Null for every calculator.",
            "title": "Seed"
          },
          "validRange": {
            "$ref": "#/components/schemas/ProvenanceValidRange"
          },
          "version": {
            "description": "Engine version, `<component>@<revision>`, e.g. `api@3f2c1a9b04de`.",
            "title": "Version",
            "type": "string"
          }
        },
        "required": [
          "method",
          "version",
          "formulaRef",
          "assumptions",
          "validRange",
          "computedAt",
          "inputs",
          "seed",
          "elapsedSeconds"
        ],
        "title": "ResultProvenance",
        "type": "object"
      },
      "SatPassRequest": {
        "properties": {
          "freq_mhz": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Freq Mhz"
          },
          "lat": {
            "title": "Lat",
            "type": "number"
          },
          "lon": {
            "title": "Lon",
            "type": "number"
          },
          "norad_id": {
            "title": "Norad Id",
            "type": "integer"
          }
        },
        "required": [
          "norad_id",
          "lat",
          "lon"
        ],
        "title": "SatPassRequest",
        "type": "object"
      },
      "SaveRequest": {
        "properties": {
          "inputs": {
            "additionalProperties": true,
            "title": "Inputs",
            "type": "object"
          },
          "label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Label"
          },
          "slug": {
            "title": "Slug",
            "type": "string"
          }
        },
        "required": [
          "slug",
          "inputs"
        ],
        "title": "SaveRequest",
        "type": "object"
      },
      "SaveResponse": {
        "properties": {
          "created_at": {
            "title": "Created At",
            "type": "integer"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "inputs": {
            "additionalProperties": true,
            "title": "Inputs",
            "type": "object"
          },
          "label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Label"
          },
          "slug": {
            "title": "Slug",
            "type": "string"
          }
        },
        "required": [
          "id",
          "slug",
          "label",
          "inputs",
          "created_at"
        ],
        "title": "SaveResponse",
        "type": "object"
      },
      "SolveRequest": {
        "properties": {
          "grid": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "A positive manufacturing grid. The solution is rounded to the nearest multiple inside the search range, half away from zero.",
            "title": "Grid"
          },
          "inputs": {
            "additionalProperties": {
              "type": "number"
            },
            "description": "The calculator's other inputs. A value for `solveFor` here is the start value (else the input's default); the solve replaces it.",
            "title": "Inputs",
            "type": "object"
          },
          "range": {
            "anyOf": [
              {
                "maxItems": 2,
                "minItems": 2,
                "prefixItems": [
                  {
                    "type": "number"
                  },
                  {
                    "type": "number"
                  }
                ],
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "`[low, high]` inside the input's stated range, narrowing the search. Required when the input states no bound on either side.",
            "title": "Range"
          },
          "slug": {
            "description": "Calculator slug, e.g. 'microstrip-impedance'",
            "title": "Slug",
            "type": "string"
          },
          "solveFor": {
            "description": "The input to solve for; one of the calculator's declared inputs.",
            "title": "Solvefor",
            "type": "string"
          },
          "target": {
            "$ref": "#/components/schemas/SolveTarget"
          }
        },
        "required": [
          "slug",
          "inputs",
          "solveFor",
          "target"
        ],
        "title": "SolveRequest",
        "type": "object"
      },
      "SolveResponse": {
        "properties": {
          "evaluations": {
            "description": "Forward evaluations the search used (at most 400).",
            "title": "Evaluations",
            "type": "integer"
          },
          "grid": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "The grid as given; null when none was.",
            "title": "Grid"
          },
          "reached": {
            "description": "Whether the unrounded solution meets the target to 1e-9 relative. False: no value in the range reaches it, and `value` is the one that came nearest.",
            "title": "Reached",
            "type": "boolean"
          },
          "result": {
            "$ref": "#/components/schemas/CalculateResponse",
            "description": "The forward call at exactly `value`: what POST /v1/calculate returns for those inputs."
          },
          "slug": {
            "title": "Slug",
            "type": "string"
          },
          "solveFor": {
            "title": "Solvefor",
            "type": "string"
          },
          "target": {
            "$ref": "#/components/schemas/SolveTarget"
          },
          "unrounded": {
            "description": "The search's own solution, before any grid rounding.",
            "title": "Unrounded",
            "type": "number"
          },
          "value": {
            "description": "The returned value: the solution on the grid, or unrounded without one.",
            "title": "Value",
            "type": "number"
          },
          "warnings": {
            "description": "The solve's own: other solutions in the range, an unreachable target.",
            "items": {
              "type": "string"
            },
            "title": "Warnings",
            "type": "array"
          }
        },
        "required": [
          "slug",
          "solveFor",
          "target",
          "grid",
          "value",
          "unrounded",
          "reached",
          "evaluations",
          "warnings",
          "result"
        ],
        "title": "SolveResponse",
        "type": "object"
      },
      "SolveTarget": {
        "properties": {
          "output": {
            "description": "The output key to bring to the value, e.g. `impedance`.",
            "title": "Output",
            "type": "string"
          },
          "value": {
            "description": "The value that output should take.",
            "title": "Value",
            "type": "number"
          }
        },
        "required": [
          "output",
          "value"
        ],
        "title": "SolveTarget",
        "type": "object"
      },
      "SubscribeRequest": {
        "properties": {
          "email": {
            "format": "email",
            "title": "Email",
            "type": "string"
          }
        },
        "required": [
          "email"
        ],
        "title": "SubscribeRequest",
        "type": "object"
      },
      "UnauthorizedBody": {
        "additionalProperties": true,
        "description": "401: no key, or not one of ours. Never about the allowance.",
        "properties": {
          "detail": {
            "title": "Detail",
            "type": "string"
          },
          "errorKind": {
            "title": "Errorkind",
            "type": "string"
          },
          "keyUrl": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Where to get a free key; sent when no key was given.",
            "title": "Keyurl"
          }
        },
        "required": [
          "detail",
          "errorKind"
        ],
        "title": "UnauthorizedBody",
        "type": "object"
      },
      "UploadRequest": {
        "properties": {
          "contentType": {
            "default": "application/octet-stream",
            "title": "Contenttype",
            "type": "string"
          },
          "filename": {
            "title": "Filename",
            "type": "string"
          }
        },
        "required": [
          "filename"
        ],
        "title": "UploadRequest",
        "type": "object"
      },
      "UploadResponse": {
        "properties": {
          "fields": {
            "additionalProperties": true,
            "default": {},
            "title": "Fields",
            "type": "object"
          },
          "key": {
            "title": "Key",
            "type": "string"
          },
          "uploadUrl": {
            "title": "Uploadurl",
            "type": "string"
          }
        },
        "required": [
          "uploadUrl",
          "key"
        ],
        "title": "UploadResponse",
        "type": "object"
      },
      "UsageKey": {
        "properties": {
          "active": {
            "title": "Active",
            "type": "boolean"
          },
          "client": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Client"
          },
          "keyId": {
            "title": "Keyid",
            "type": "string"
          },
          "label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Label"
          },
          "lastUsedAt": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lastusedat"
          },
          "used": {
            "title": "Used",
            "type": "integer"
          }
        },
        "required": [
          "keyId",
          "active",
          "used"
        ],
        "title": "UsageKey",
        "type": "object"
      },
      "UsageOverage": {
        "properties": {
          "active": {
            "title": "Active",
            "type": "boolean"
          },
          "cap": {
            "title": "Cap",
            "type": "integer"
          },
          "eligible": {
            "title": "Eligible",
            "type": "boolean"
          },
          "manageUrl": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Manageurl"
          },
          "reportedThisPeriod": {
            "anyOf": [
              {},
              {
                "type": "null"
              }
            ],
            "title": "Reportedthisperiod"
          },
          "used": {
            "description": "Calls past the allowance this period, net of releases.",
            "title": "Used",
            "type": "integer"
          }
        },
        "required": [
          "eligible",
          "active",
          "used",
          "cap"
        ],
        "title": "UsageOverage",
        "type": "object"
      },
      "UsageResponse": {
        "properties": {
          "allowance": {
            "title": "Allowance",
            "type": "integer"
          },
          "keys": {
            "items": {
              "$ref": "#/components/schemas/UsageKey"
            },
            "title": "Keys",
            "type": "array"
          },
          "overage": {
            "$ref": "#/components/schemas/UsageOverage"
          },
          "period": {
            "description": "The calendar month (UTC), `YYYY-MM`.",
            "title": "Period",
            "type": "string"
          },
          "rateLimitPerMinute": {
            "title": "Ratelimitperminute",
            "type": "integer"
          },
          "remaining": {
            "title": "Remaining",
            "type": "integer"
          },
          "resetAt": {
            "title": "Resetat",
            "type": "string"
          },
          "tier": {
            "title": "Tier",
            "type": "string"
          },
          "used": {
            "description": "Calls counted against the account this period, net of releases.",
            "title": "Used",
            "type": "integer"
          }
        },
        "required": [
          "tier",
          "period",
          "resetAt",
          "allowance",
          "used",
          "remaining",
          "overage",
          "keys",
          "rateLimitPerMinute"
        ],
        "title": "UsageResponse",
        "type": "object"
      },
      "ValidationError": {
        "properties": {
          "ctx": {
            "title": "Context",
            "type": "object"
          },
          "input": {
            "title": "Input"
          },
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "title": "Location",
            "type": "array"
          },
          "msg": {
            "title": "Message",
            "type": "string"
          },
          "type": {
            "title": "Error Type",
            "type": "string"
          }
        },
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError",
        "type": "object"
      },
      "Violation": {
        "properties": {
          "code": {
            "title": "Code",
            "type": "string"
          },
          "message": {
            "title": "Message",
            "type": "string"
          },
          "wire": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Wire"
          }
        },
        "required": [
          "code",
          "message"
        ],
        "title": "Violation",
        "type": "object"
      }
    }
  },
  "info": {
    "description": "Backend API for rftools.io — RF & Electronics Calculator Hub",
    "title": "RFTools API",
    "version": "1.0.0"
  },
  "openapi": "3.1.0",
  "paths": {
    "/api/py/health": {
      "get": {
        "operationId": "health_api_py_health_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Health"
      }
    },
    "/api/py/v1/ai-assist": {
      "post": {
        "operationId": "ai_assist_api_py_v1_ai_assist_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AiAssistRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Ai Assist",
        "tags": [
          "ai"
        ]
      }
    },
    "/api/py/v1/analytics": {
      "post": {
        "description": "Accept analytics events from the frontend.",
        "operationId": "record_analytics_api_py_v1_analytics_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AnalyticsEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Record Analytics",
        "tags": [
          "analytics",
          "internal"
        ],
        "x-internal": true
      }
    },
    "/api/py/v1/antenna/check": {
      "post": {
        "operationId": "check_antenna_geometry_api_py_v1_antenna_check_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CheckRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CheckResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Check Antenna Geometry"
      }
    },
    "/api/py/v1/apikeys": {
      "get": {
        "operationId": "list_api_keys_api_py_v1_apikeys_get",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Api Keys"
      },
      "post": {
        "operationId": "create_api_key_api_py_v1_apikeys_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/CreateKeyRequest"
                  },
                  {
                    "type": "null"
                  }
                ],
                "title": "Body"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Create Api Key"
      }
    },
    "/api/py/v1/apikeys/usage": {
      "get": {
        "description": "The dashboard's usage figures, over the account counters.\n\nKept in its old shape — ``usage[]`` per key and ``monthly_quota`` — until\nthe dashboard reads ``GET /v1/usage``. ``monthly_quota`` is now the\naccount's allowance, which is what the dashboard already summed the keys\nagainst.",
        "operationId": "get_usage_api_py_v1_apikeys_usage_get",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Usage"
      }
    },
    "/api/py/v1/apikeys/{key_id}": {
      "delete": {
        "operationId": "revoke_api_key_api_py_v1_apikeys__key_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "key_id",
            "required": true,
            "schema": {
              "title": "Key Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Revoke Api Key"
      }
    },
    "/api/py/v1/billing/webhook": {
      "post": {
        "operationId": "lemon_squeezy_webhook_api_py_v1_billing_webhook_post",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Lemon Squeezy Webhook",
        "tags": [
          "internal"
        ],
        "x-internal": true
      }
    },
    "/api/py/v1/calculate": {
      "post": {
        "operationId": "calculate_api_py_v1_calculate_post",
        "parameters": [
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CalculateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CalculateResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            },
            "description": "An input is not a finite number, or is out of the range the calculator accepts."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnauthorizedBody"
                }
              }
            },
            "description": "No API key, or one that is unknown or revoked."
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaRefusalBody"
                }
              }
            },
            "description": "The account's monthly allowance is spent."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            },
            "description": "No calculator by that slug."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitBody"
                }
              }
            },
            "description": "Too many requests in the window."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            },
            "description": "A store did not answer. Nothing was charged."
          }
        },
        "summary": "Compute one calculator (metered: one call)",
        "tags": [
          "calculate"
        ]
      }
    },
    "/api/py/v1/calculate/batch": {
      "post": {
        "operationId": "calculate_batch_api_py_v1_calculate_batch_post",
        "parameters": [
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            },
            "description": "An input is not a finite number, or is out of the range the calculator accepts."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnauthorizedBody"
                }
              }
            },
            "description": "No API key, or one that is unknown or revoked."
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaRefusalBody"
                }
              }
            },
            "description": "The account's monthly allowance is spent."
          },
          "403": {
            "description": "The account's plan has no batch access."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            },
            "description": "No calculator by that slug."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitBody"
                }
              }
            },
            "description": "Too many requests in the window."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            },
            "description": "A store did not answer. Nothing was charged."
          }
        },
        "summary": "Compute up to 50 calculators (metered: one call per computed item)",
        "tags": [
          "calculate"
        ]
      }
    },
    "/api/py/v1/calculate/solve": {
      "post": {
        "operationId": "calculate_solve_api_py_v1_calculate_solve_post",
        "parameters": [
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SolveRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SolveResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            },
            "description": "The request cannot be solved: `param` names the field — `solveFor` (not a declared input), `target.output` (not an output), `target.value`, `grid` (not positive, or no multiple in the range), `range` (needed, reversed, empty or outside the stated bounds) or `inputs`. Nothing was charged."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnauthorizedBody"
                }
              }
            },
            "description": "No API key, or one that is unknown or revoked."
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaRefusalBody"
                }
              }
            },
            "description": "The account's monthly allowance is spent."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            },
            "description": "No calculator by that slug."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitBody"
                }
              }
            },
            "description": "Too many requests in the window."
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            },
            "description": "The solve failed. Nothing was charged."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            },
            "description": "A store did not answer. Nothing was charged."
          }
        },
        "summary": "Solve one calculator input for a target output (metered: one call)",
        "tags": [
          "calculate"
        ]
      }
    },
    "/api/py/v1/calculate/{slug}": {
      "get": {
        "description": "Stub for GET-based calculation (query params → inputs): always the 400.\n\nIt took ``**kwargs`` until the solve route was added, which FastAPI read\nas a required query parameter named ``kwargs``, so every GET was a 422\nabout a parameter nobody could know to send.",
        "operationId": "calculate_get_api_py_v1_calculate__slug__get",
        "parameters": [
          {
            "in": "path",
            "name": "slug",
            "required": true,
            "schema": {
              "title": "Slug",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Calculate Get",
        "tags": [
          "calculate",
          "internal"
        ],
        "x-internal": true
      }
    },
    "/api/py/v1/credits": {
      "get": {
        "operationId": "get_credits_api_py_v1_credits_get",
        "parameters": [
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditsResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnauthorizedBody"
                }
              }
            },
            "description": "No key or session, or a key that is unknown or revoked."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitBody"
                }
              }
            },
            "description": "Too many requests in the window."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            },
            "description": "The credit store did not answer."
          }
        },
        "summary": "This account's simulation credits (never metered)",
        "tags": [
          "credits"
        ]
      }
    },
    "/api/py/v1/digest/send": {
      "post": {
        "description": "Send weekly digest to all active subscribers. Called by EventBridge or manually.",
        "operationId": "send_digest_api_py_v1_digest_send_post",
        "parameters": [
          {
            "in": "query",
            "name": "secret",
            "required": false,
            "schema": {
              "default": "",
              "title": "Secret",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "X-Digest-Secret",
            "required": false,
            "schema": {
              "default": "",
              "title": "X-Digest-Secret",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Send Digest",
        "tags": [
          "internal"
        ],
        "x-internal": true
      }
    },
    "/api/py/v1/export/kicad": {
      "post": {
        "operationId": "export_kicad_api_py_v1_export_kicad_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/KicadExportRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Export Kicad",
        "tags": [
          "export"
        ]
      }
    },
    "/api/py/v1/jobs": {
      "get": {
        "description": "Recent jobs belonging to the caller.\n\nFor a Cognito user that is everything they submitted from the browser plus\neverything submitted with any key they hold — a job run through the API is\nstill their job, and a dashboard that hides it is lying about what the\naccount has done. For an API key it is what that key submitted.\n\nThe owner's key-submitted jobs are found by querying the existing\n``userId-createdAt`` index once per key the account holds, rather than by\nadding an ``ownerSub`` index: a tier holds at most five keys, so this is at\nmost six queries against an index that already exists, and it needs no\nchange to the table.",
        "operationId": "list_jobs_api_py_v1_jobs_get",
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 20,
              "title": "Limit",
              "type": "integer"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Jobs",
        "tags": [
          "jobs"
        ]
      },
      "post": {
        "description": "Submit an async computation job.",
        "operationId": "submit_job_api_py_v1_jobs_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          },
          {
            "description": "Send `true` to run an identical request again inside the dedup window instead of being given the existing job. For a randomised tool whose seed is drawn per run, or for a retry after a result was discarded.",
            "in": "header",
            "name": "Idempotency-Bypass",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Send `true` to run an identical request again inside the dedup window instead of being given the existing job. For a randomised tool whose seed is drawn per run, or for a retry after a result was discarded.",
              "title": "Idempotency-Bypass"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JobSubmitRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobSubmitResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnauthorizedBody"
                }
              }
            },
            "description": "An API key that is unknown or revoked."
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaRefusalBody"
                }
              }
            },
            "description": "The account's allowance, or a solve mode's monthly quota, is spent; or, with credits enforced, the paid-lane credit hold exceeds the available credits (`reason: credits`)."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitBody"
                }
              }
            },
            "description": "Too many requests in the window, or too many jobs pending."
          }
        },
        "summary": "Submit Job",
        "tags": [
          "jobs"
        ]
      }
    },
    "/api/py/v1/jobs/estimate": {
      "post": {
        "description": "Estimate a prospective job from the body a submission would carry: the\nlane it would run on, its wall time and range, the vCPU-seconds, the\ncredits where the paid lane applies them, and whether it fits the lane's\nbudget (openspec simulation-metering, design Decision 2).\n\nValidated by the functions submission uses — the job type, the caller's\ntier, the parameter contract, the antenna mode and the antenna geometry —\nso an estimate is refused exactly where a submission would be, with the\nsame status and the same parameter details. It reads no uploaded file, so\nthe files' existence and ownership are left to the submission.\n\nNever charged, never written, never queued: it spends no API call (a key\nis verified, not metered), creates no record and sends nothing. The\nconcurrency limit and the dedup window are about submissions, and do not\napply. Anonymous callers get the free lane's estimate. Rate-limited by the\nmiddleware like every other route.",
        "operationId": "estimate_job_api_py_v1_jobs_estimate_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JobSubmitRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobEstimateResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            },
            "description": "The body is outside its job type's contract — the same refusal a submission gets."
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnauthorizedBody"
                }
              }
            },
            "description": "An API key that is unknown or revoked."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            },
            "description": "A solve mode the caller's tier does not include."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitBody"
                }
              }
            },
            "description": "Too many requests in the window."
          }
        },
        "summary": "What a job would cost, without submitting it (never charged)",
        "tags": [
          "jobs"
        ]
      }
    },
    "/api/py/v1/jobs/feed": {
      "get": {
        "description": "Public activity feed — recent non-failed jobs (anonymized).",
        "operationId": "jobs_feed_api_py_v1_jobs_feed_get",
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 10,
              "title": "Limit",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Jobs Feed",
        "tags": [
          "jobs"
        ]
      }
    },
    "/api/py/v1/jobs/types": {
      "get": {
        "description": "The job type catalogue: every type, its parameter contract's tier limits,\nits time ceiling and whether it takes uploaded files.\n\nUnauthenticated on purpose — a caller has to be able to read the contract\nbefore they have an account, and nothing here is specific to one caller.\nPer-parameter detail is one request away at /jobs/types/{jobType}.",
        "operationId": "list_job_types_api_py_v1_jobs_types_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobTypeCatalogue"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "List Job Types",
        "tags": [
          "jobs"
        ]
      }
    },
    "/api/py/v1/jobs/types/{job_type}": {
      "get": {
        "description": "One job type's parameter contract, as the JSON Schema every surface reads.\n\nThe same bytes the worker validates against and the browser form is built\nfrom, so a caller that satisfies this document is a caller the whole system\naccepts.",
        "operationId": "get_job_type_api_py_v1_jobs_types__job_type__get",
        "parameters": [
          {
            "in": "path",
            "name": "job_type",
            "required": true,
            "schema": {
              "title": "Job Type",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Job Type",
        "tags": [
          "jobs"
        ]
      }
    },
    "/api/py/v1/jobs/{job_id}": {
      "get": {
        "description": "Poll job status. Returns a presigned result URL when completed.",
        "operationId": "get_job_status_api_py_v1_jobs__job_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobStatusResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Job Status",
        "tags": [
          "jobs"
        ]
      }
    },
    "/api/py/v1/live/ism-coexistence": {
      "get": {
        "operationId": "live_ism_coexistence_api_py_v1_live_ism_coexistence_get",
        "parameters": [
          {
            "in": "query",
            "name": "band",
            "required": true,
            "schema": {
              "title": "Band",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "region",
            "required": false,
            "schema": {
              "default": "us",
              "title": "Region",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Live Ism Coexistence",
        "tags": [
          "live"
        ]
      }
    },
    "/api/py/v1/live/satellite-catalog": {
      "get": {
        "description": "Public API for satellite catalog. Frontend hardcodes this for static export,\nbut the endpoint is available for API consumers and browser extensions.",
        "operationId": "live_satellite_catalog_api_py_v1_live_satellite_catalog_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Live Satellite Catalog",
        "tags": [
          "live"
        ]
      }
    },
    "/api/py/v1/live/satellite-passes": {
      "post": {
        "operationId": "live_satellite_passes_api_py_v1_live_satellite_passes_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SatPassRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Live Satellite Passes",
        "tags": [
          "live"
        ]
      }
    },
    "/api/py/v1/live/space-weather": {
      "get": {
        "operationId": "live_space_weather_api_py_v1_live_space_weather_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Live Space Weather",
        "tags": [
          "live"
        ]
      }
    },
    "/api/py/v1/me": {
      "get": {
        "operationId": "get_me_api_py_v1_me_get",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Me"
      }
    },
    "/api/py/v1/oauth/device/approve": {
      "post": {
        "description": "Approve, deny or look up a code, for the signed-in account.\n\n``decision`` is ``approve``, ``deny`` or ``inspect``. ``inspect`` returns\nthe client name the program gave, for the page to show before the person\ndecides (RFC 8628 section 5.4: the name and a warning are the mitigation\nfor a code someone else started). All three count a wrong code the same\nway, so a lookup is no oracle for guessing codes.",
        "operationId": "device_approve_api_py_v1_oauth_device_approve_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          },
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Device Approve",
        "tags": [
          "device"
        ]
      }
    },
    "/api/py/v1/oauth/device/code": {
      "post": {
        "operationId": "device_code_api_py_v1_oauth_device_code_post",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Device Code",
        "tags": [
          "device"
        ]
      }
    },
    "/api/py/v1/oauth/device/token": {
      "post": {
        "operationId": "device_token_api_py_v1_oauth_device_token_post",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Device Token",
        "tags": [
          "device"
        ]
      }
    },
    "/api/py/v1/og/{slug}": {
      "get": {
        "description": "Generate or return cached OG image for a calculator.",
        "operationId": "og_image_api_py_v1_og__slug__get",
        "parameters": [
          {
            "in": "path",
            "name": "slug",
            "required": true,
            "schema": {
              "title": "Slug",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "result",
            "required": false,
            "schema": {
              "default": "",
              "title": "Result",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Og Image",
        "tags": [
          "og"
        ]
      }
    },
    "/api/py/v1/report": {
      "post": {
        "operationId": "submit_report_api_py_v1_report_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReportRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Submit Report",
        "tags": [
          "report"
        ]
      }
    },
    "/api/py/v1/requests": {
      "get": {
        "description": "List all calculator requests sorted by votes desc.",
        "operationId": "list_requests_api_py_v1_requests_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "List Requests"
      },
      "post": {
        "description": "Submit a new calculator request.",
        "operationId": "create_request_api_py_v1_requests_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RequestCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Create Request"
      }
    },
    "/api/py/v1/requests/{request_id}/vote": {
      "post": {
        "description": "Upvote a calculator request (atomic increment).",
        "operationId": "vote_request_api_py_v1_requests__request_id__vote_post",
        "parameters": [
          {
            "in": "path",
            "name": "request_id",
            "required": true,
            "schema": {
              "title": "Request Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Vote Request"
      }
    },
    "/api/py/v1/saves": {
      "get": {
        "operationId": "list_saves_api_py_v1_saves_get",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Saves"
      },
      "post": {
        "operationId": "create_save_api_py_v1_saves_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SaveRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SaveResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Create Save"
      }
    },
    "/api/py/v1/saves/{save_id}": {
      "delete": {
        "operationId": "delete_save_api_py_v1_saves__save_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "save_id",
            "required": true,
            "schema": {
              "title": "Save Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Save"
      }
    },
    "/api/py/v1/subscribe": {
      "post": {
        "description": "Subscribe to the weekly digest.",
        "operationId": "subscribe_api_py_v1_subscribe_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubscribeRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Subscribe"
      }
    },
    "/api/py/v1/subscribe/{email}": {
      "delete": {
        "description": "Unsubscribe from digest. Requires a valid HMAC token.",
        "operationId": "unsubscribe_api_py_v1_subscribe__email__delete",
        "parameters": [
          {
            "in": "path",
            "name": "email",
            "required": true,
            "schema": {
              "title": "Email",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "token",
            "required": false,
            "schema": {
              "default": "",
              "title": "Token",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Unsubscribe"
      }
    },
    "/api/py/v1/subscribers/count": {
      "get": {
        "description": "Get active subscriber count (admin).",
        "operationId": "subscriber_count_api_py_v1_subscribers_count_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Subscriber Count",
        "tags": [
          "internal"
        ],
        "x-internal": true
      }
    },
    "/api/py/v1/upload": {
      "post": {
        "description": "Return a presigned S3 POST for direct upload, to an identified caller.\n\nAnonymous uploads are refused. An upload is the one route that hands out\nwrite access to our bucket, and rate alone is not an identity: twenty\nobjects a minute from every address that cares to ask is an open door with\na queue at it. A session or a key names who wrote each object, which is\nalso what lets ``_validate_input_keys`` refuse a key submitted by someone\nother than whoever uploaded it.\n\nThe per-address limit stays, as a second bound on an authenticated caller.",
        "operationId": "get_upload_url_api_py_v1_upload_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UploadRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Upload Url",
        "tags": [
          "jobs"
        ]
      }
    },
    "/api/py/v1/usage": {
      "get": {
        "operationId": "get_usage_api_py_v1_usage_get",
        "parameters": [
          {
            "in": "header",
            "name": "x-api-key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Api-Key"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsageResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnauthorizedBody"
                }
              }
            },
            "description": "No key or session, or a key that is unknown or revoked."
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitBody"
                }
              }
            },
            "description": "Too many requests in the window."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            },
            "description": "The usage store did not answer."
          }
        },
        "summary": "This account's usage this month (never metered)",
        "tags": [
          "usage"
        ]
      }
    }
  }
}
