{
  "openapi": "3.1.0",
  "info": {
    "title": "Infrastructure Functions API",
    "version": "1.0.0",
    "description": "Serverless JavaScript functions with versioning, rollback, per-function environment variables, per-function outbound network access, invocation logs, metrics and cron schedules. Every function runs in its own V8 isolate (Cloudflare Dynamic Workers), with no access to the service's bindings or secrets. The owner of every resource is derived from the credential, never from the body or the URL. Errors use the envelope `{ \"error\": { \"code\", \"message\", \"details\"? } }` with a stable `code`; collections use `{ items, page: { limit, offset, total, hasMore } }`. Authenticate data routes with an `fk_` key in `x-api-key` (or as `Authorization: Bearer fk_…`), or with an Infrastructure Auth session JWT. Same login, authorization per product. The MCP server at `/mcp` is a separate transport and is not described here.",
    "contact": {
      "name": "Infrastructure",
      "url": "https://myinfrastructure.click/contact"
    },
    "license": {
      "name": "MIT",
      "identifier": "MIT"
    }
  },
  "servers": [
    {
      "url": "https://functions.manager.myinfrastructure.click"
    }
  ],
  "externalDocs": {
    "description": "Agent-oriented implementation guide",
    "url": "https://myinfrastructure.click/products/functions/llms.txt"
  },
  "tags": [
    {
      "name": "Functions",
      "description": "Publish, inspect and remove functions."
    },
    {
      "name": "Versions",
      "description": "Version history and rollback."
    },
    {
      "name": "Configuration",
      "description": "Environment variables and outbound network access."
    },
    {
      "name": "Observability",
      "description": "Invocation logs and metrics."
    },
    {
      "name": "Execution",
      "description": "Invoking a function over HTTP."
    },
    {
      "name": "Schedules",
      "description": "Cron schedules that invoke functions."
    },
    {
      "name": "Account",
      "description": "Identity, API key, plan and account deletion."
    },
    {
      "name": "Service",
      "description": "Public health and documentation."
    }
  ],
  "paths": {
    "/": {
      "get": {
        "operationId": "getWelcomePage",
        "tags": [
          "Service"
        ],
        "summary": "Documentation page",
        "description": "Human-readable HTML page with the minimal API documentation and the active limits.",
        "responses": {
          "200": {
            "description": "HTML page.",
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": []
      }
    },
    "/status": {
      "get": {
        "operationId": "getStatus",
        "tags": [
          "Service"
        ],
        "summary": "Service health",
        "description": "Public health check. Reports the sandbox level and which isolation limits are actually enforced. Never reports commercial volume.",
        "responses": {
          "200": {
            "description": "Service is up.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServiceStatus"
                }
              }
            }
          }
        },
        "security": []
      }
    },
    "/functions": {
      "get": {
        "operationId": "listFunctions",
        "tags": [
          "Functions"
        ],
        "summary": "List functions",
        "description": "Lists every function of the account, newest first. The list is not paginated: `page.total` and `page.hasMore` are `null`.",
        "responses": {
          "200": {
            "description": "The functions.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items",
                    "page"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/FunctionSummary"
                      }
                    },
                    "page": {
                      "$ref": "#/components/schemas/Page"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "apiKeyBearer": []
          },
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      },
      "post": {
        "operationId": "publishFunction",
        "tags": [
          "Functions"
        ],
        "summary": "Publish a function",
        "description": "Creates the function, or publishes a new version of an existing one and makes it active. The endpoint (`/fn/{name}`) never changes. The plan limit is checked only when a NEW function is created; publishing a new version never hits it.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublishFunctionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A new version of an existing function was published (`created: false`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublishFunctionResult"
                }
              }
            }
          },
          "201": {
            "description": "The function was created (`created: true`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublishFunctionResult"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PlanLimit"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "apiKeyBearer": []
          },
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      }
    },
    "/functions/{name}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/FunctionName"
        }
      ],
      "get": {
        "operationId": "getFunction",
        "tags": [
          "Functions"
        ],
        "summary": "Get a function",
        "description": "Returns the function with the code of its active version.",
        "responses": {
          "200": {
            "description": "The function.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FunctionDetail"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "apiKeyBearer": []
          },
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      },
      "delete": {
        "operationId": "deleteFunction",
        "tags": [
          "Functions"
        ],
        "summary": "Delete a function",
        "description": "Deletes the function together with its versions, environment variables, schedules and invocation history.",
        "responses": {
          "200": {
            "description": "Deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Ok"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "apiKeyBearer": []
          },
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      }
    },
    "/functions/{name}/versions": {
      "parameters": [
        {
          "$ref": "#/components/parameters/FunctionName"
        }
      ],
      "get": {
        "operationId": "listFunctionVersions",
        "tags": [
          "Versions"
        ],
        "summary": "List versions",
        "description": "Version history, newest first, flagging the active one. Not paginated: `page.total` and `page.hasMore` are `null`.",
        "responses": {
          "200": {
            "description": "The versions.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items",
                    "page"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/VersionSummary"
                      }
                    },
                    "page": {
                      "$ref": "#/components/schemas/Page"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "apiKeyBearer": []
          },
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      }
    },
    "/functions/{name}/versions/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/FunctionName"
        },
        {
          "name": "id",
          "in": "path",
          "required": true,
          "description": "Version id (as returned in `versionId`).",
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "operationId": "getFunctionVersion",
        "tags": [
          "Versions"
        ],
        "summary": "Get a version",
        "description": "Returns the code of a specific version.",
        "responses": {
          "200": {
            "description": "The version.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Version"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "apiKeyBearer": []
          },
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      }
    },
    "/functions/{name}/rollback": {
      "parameters": [
        {
          "$ref": "#/components/parameters/FunctionName"
        }
      ],
      "post": {
        "operationId": "rollbackFunction",
        "tags": [
          "Versions"
        ],
        "summary": "Roll back to a version",
        "description": "Makes an earlier version active. No code is re-sent; only the active pointer moves.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RollbackRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The version is now active.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "activeVersionId"
                  ],
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "activeVersionId": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "apiKeyBearer": []
          },
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      }
    },
    "/functions/{name}/network": {
      "parameters": [
        {
          "$ref": "#/components/parameters/FunctionName"
        }
      ],
      "get": {
        "operationId": "getFunctionNetwork",
        "tags": [
          "Configuration"
        ],
        "summary": "Get outbound network access",
        "description": "Whether the function may reach the internet, plus what the manager actually enforces.",
        "responses": {
          "200": {
            "description": "Network state.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "allowNetwork",
                    "enforced"
                  ],
                  "properties": {
                    "allowNetwork": {
                      "type": "boolean"
                    },
                    "enforced": {
                      "$ref": "#/components/schemas/EnforcedLimits"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "apiKeyBearer": []
          },
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      },
      "put": {
        "operationId": "setFunctionNetwork",
        "tags": [
          "Configuration"
        ],
        "summary": "Turn outbound network access on or off",
        "description": "Idempotent. Network is off by default; turning it on takes effect on the next invocation, without republishing. `effective` is always `true` on the isolate runtime.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "enabled"
                ],
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Saved.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "allowNetwork",
                    "effective"
                  ],
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "allowNetwork": {
                      "type": "boolean"
                    },
                    "effective": {
                      "type": "boolean",
                      "description": "Whether the saved setting takes effect. Always `true` on the isolate runtime; kept for clients written against the previous manager."
                    },
                    "warning": {
                      "type": "string",
                      "description": "Present only when network is enabled but egress is unavailable."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "apiKeyBearer": []
          },
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      }
    },
    "/functions/{name}/env": {
      "parameters": [
        {
          "$ref": "#/components/parameters/FunctionName"
        }
      ],
      "get": {
        "operationId": "listFunctionEnv",
        "tags": [
          "Configuration"
        ],
        "summary": "List environment variables",
        "description": "Variables the function receives in `ctx.env`, ordered by name. Secret values are never returned. Not paginated: `page.total` and `page.hasMore` are `null`.",
        "responses": {
          "200": {
            "description": "The variables.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items",
                    "page"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/EnvVar"
                      }
                    },
                    "page": {
                      "$ref": "#/components/schemas/Page"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "apiKeyBearer": []
          },
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      },
      "put": {
        "operationId": "setFunctionEnv",
        "tags": [
          "Configuration"
        ],
        "summary": "Set an environment variable",
        "description": "Creates or replaces one variable. Field names are in Portuguese on the wire: `chave` (name), `valor` (value), `secreto` (secret).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetEnvRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Saved.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Ok"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "apiKeyBearer": []
          },
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      }
    },
    "/functions/{name}/env/{key}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/FunctionName"
        },
        {
          "name": "key",
          "in": "path",
          "required": true,
          "description": "Variable name.",
          "schema": {
            "type": "string"
          }
        }
      ],
      "delete": {
        "operationId": "deleteFunctionEnv",
        "tags": [
          "Configuration"
        ],
        "summary": "Delete an environment variable",
        "description": "Removes one variable from the function.",
        "responses": {
          "200": {
            "description": "Deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Ok"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "apiKeyBearer": []
          },
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      }
    },
    "/functions/{name}/logs": {
      "parameters": [
        {
          "$ref": "#/components/parameters/FunctionName"
        }
      ],
      "get": {
        "operationId": "listFunctionInvocations",
        "tags": [
          "Observability"
        ],
        "summary": "List invocations",
        "description": "Invocation log of the function (HTTP and cron), newest first, with captured console output. Paginated; `page.limit` is the applied limit.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Offset"
          }
        ],
        "responses": {
          "200": {
            "description": "A page of invocations.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items",
                    "page"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Invocation"
                      }
                    },
                    "page": {
                      "$ref": "#/components/schemas/Page"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "apiKeyBearer": []
          },
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      }
    },
    "/functions/{name}/metrics": {
      "parameters": [
        {
          "$ref": "#/components/parameters/FunctionName"
        }
      ],
      "get": {
        "operationId": "getFunctionMetrics",
        "tags": [
          "Observability"
        ],
        "summary": "Get metrics",
        "description": "Aggregated invocation metrics over a window, with an hourly series (empty hours filled with zeros) and the publishes in the window.",
        "parameters": [
          {
            "name": "hours",
            "in": "query",
            "required": false,
            "description": "Window size in hours, clamped to 1–168.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 168,
              "default": 24
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The metrics.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FunctionMetrics"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "apiKeyBearer": []
          },
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      }
    },
    "/fn/{name}": {
      "get": {
        "operationId": "invokeFunctionGet",
        "tags": [
          "Execution"
        ],
        "summary": "Invoke a function (GET)",
        "description": "Runs the active version of the named function, owned by the account behind the credential, inside the sandbox. The function receives the method, the query string (`ctx.query`), the parsed body (`ctx.body`: parsed JSON when `content-type` is `application/json`, raw text otherwise) and its environment variables (`ctx.env`). Forwarded request headers: `content-type`, `accept`, `accept-language`, `user-agent`, `date`, any `x-*` header and known webhook signature headers (`stripe-signature`, `paypal-transmission-sig`, `webhook-signature`, `webhook-id`, `webhook-timestamp`); credentials (`x-api-key`, `authorization`, `cookie`) and infrastructure headers are never forwarded. The response status, headers and body are whatever the function returns (a plain object becomes JSON with status 200); `set-cookie`, `access-control-*` and hop-by-hop headers set by the function are stripped. The same route also answers HEAD. Body limit: 1 MB by default.",
        "parameters": [
          {
            "$ref": "#/components/parameters/FunctionName"
          }
        ],
        "responses": {
          "200": {
            "description": "Response produced by the function. Status (200–599), headers and body are defined by the function code.",
            "content": {
              "*/*": {
                "schema": {}
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "The function has no published version (`error: \"no_active_version\"`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvocationError"
                }
              }
            }
          },
          "500": {
            "description": "The function threw or failed to load (`runtime_error`, `load_error`, `no_default_export`, `network_unavailable`, `spawn_error`, `bad_harness_output`). Carries the message and, for runtime errors, the stack.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvocationError"
                }
              }
            }
          },
          "503": {
            "description": "The service is temporarily unavailable. Retry after the number of seconds in `retry-after`.",
            "headers": {
              "retry-after": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait (always 1)."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "504": {
            "description": "The function exceeded its timeout (`error: \"timeout\"`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvocationError"
                }
              }
            }
          },
          "507": {
            "description": "The function response exceeded the output limit (`error: \"output_too_large\"`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvocationError"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "apiKeyBearer": []
          },
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      },
      "post": {
        "operationId": "invokeFunctionPost",
        "tags": [
          "Execution"
        ],
        "summary": "Invoke a function (POST)",
        "description": "Runs the active version of the named function, owned by the account behind the credential, inside the sandbox. The function receives the method, the query string (`ctx.query`), the parsed body (`ctx.body`: parsed JSON when `content-type` is `application/json`, raw text otherwise) and its environment variables (`ctx.env`). Forwarded request headers: `content-type`, `accept`, `accept-language`, `user-agent`, `date`, any `x-*` header and known webhook signature headers (`stripe-signature`, `paypal-transmission-sig`, `webhook-signature`, `webhook-id`, `webhook-timestamp`); credentials (`x-api-key`, `authorization`, `cookie`) and infrastructure headers are never forwarded. The response status, headers and body are whatever the function returns (a plain object becomes JSON with status 200); `set-cookie`, `access-control-*` and hop-by-hop headers set by the function are stripped. The same route also answers HEAD. Body limit: 1 MB by default.",
        "parameters": [
          {
            "$ref": "#/components/parameters/FunctionName"
          }
        ],
        "requestBody": {
          "required": false,
          "description": "Any payload. JSON is parsed when `content-type` is `application/json`; any other content type reaches the function as a string.",
          "content": {
            "application/json": {
              "schema": {}
            },
            "*/*": {
              "schema": {
                "type": "string"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Response produced by the function. Status (200–599), headers and body are defined by the function code.",
            "content": {
              "*/*": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "The function has no published version (`error: \"no_active_version\"`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvocationError"
                }
              }
            }
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "500": {
            "description": "The function threw or failed to load (`runtime_error`, `load_error`, `no_default_export`, `network_unavailable`, `spawn_error`, `bad_harness_output`). Carries the message and, for runtime errors, the stack.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvocationError"
                }
              }
            }
          },
          "503": {
            "description": "The service is temporarily unavailable. Retry after the number of seconds in `retry-after`.",
            "headers": {
              "retry-after": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait (always 1)."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "504": {
            "description": "The function exceeded its timeout (`error: \"timeout\"`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvocationError"
                }
              }
            }
          },
          "507": {
            "description": "The function response exceeded the output limit (`error: \"output_too_large\"`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvocationError"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "apiKeyBearer": []
          },
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      },
      "put": {
        "operationId": "invokeFunctionPut",
        "tags": [
          "Execution"
        ],
        "summary": "Invoke a function (PUT)",
        "description": "Runs the active version of the named function, owned by the account behind the credential, inside the sandbox. The function receives the method, the query string (`ctx.query`), the parsed body (`ctx.body`: parsed JSON when `content-type` is `application/json`, raw text otherwise) and its environment variables (`ctx.env`). Forwarded request headers: `content-type`, `accept`, `accept-language`, `user-agent`, `date`, any `x-*` header and known webhook signature headers (`stripe-signature`, `paypal-transmission-sig`, `webhook-signature`, `webhook-id`, `webhook-timestamp`); credentials (`x-api-key`, `authorization`, `cookie`) and infrastructure headers are never forwarded. The response status, headers and body are whatever the function returns (a plain object becomes JSON with status 200); `set-cookie`, `access-control-*` and hop-by-hop headers set by the function are stripped. The same route also answers HEAD. Body limit: 1 MB by default.",
        "parameters": [
          {
            "$ref": "#/components/parameters/FunctionName"
          }
        ],
        "requestBody": {
          "required": false,
          "description": "Any payload. JSON is parsed when `content-type` is `application/json`; any other content type reaches the function as a string.",
          "content": {
            "application/json": {
              "schema": {}
            },
            "*/*": {
              "schema": {
                "type": "string"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Response produced by the function. Status (200–599), headers and body are defined by the function code.",
            "content": {
              "*/*": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "The function has no published version (`error: \"no_active_version\"`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvocationError"
                }
              }
            }
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "500": {
            "description": "The function threw or failed to load (`runtime_error`, `load_error`, `no_default_export`, `network_unavailable`, `spawn_error`, `bad_harness_output`). Carries the message and, for runtime errors, the stack.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvocationError"
                }
              }
            }
          },
          "503": {
            "description": "The service is temporarily unavailable. Retry after the number of seconds in `retry-after`.",
            "headers": {
              "retry-after": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait (always 1)."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "504": {
            "description": "The function exceeded its timeout (`error: \"timeout\"`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvocationError"
                }
              }
            }
          },
          "507": {
            "description": "The function response exceeded the output limit (`error: \"output_too_large\"`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvocationError"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "apiKeyBearer": []
          },
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      },
      "patch": {
        "operationId": "invokeFunctionPatch",
        "tags": [
          "Execution"
        ],
        "summary": "Invoke a function (PATCH)",
        "description": "Runs the active version of the named function, owned by the account behind the credential, inside the sandbox. The function receives the method, the query string (`ctx.query`), the parsed body (`ctx.body`: parsed JSON when `content-type` is `application/json`, raw text otherwise) and its environment variables (`ctx.env`). Forwarded request headers: `content-type`, `accept`, `accept-language`, `user-agent`, `date`, any `x-*` header and known webhook signature headers (`stripe-signature`, `paypal-transmission-sig`, `webhook-signature`, `webhook-id`, `webhook-timestamp`); credentials (`x-api-key`, `authorization`, `cookie`) and infrastructure headers are never forwarded. The response status, headers and body are whatever the function returns (a plain object becomes JSON with status 200); `set-cookie`, `access-control-*` and hop-by-hop headers set by the function are stripped. The same route also answers HEAD. Body limit: 1 MB by default.",
        "parameters": [
          {
            "$ref": "#/components/parameters/FunctionName"
          }
        ],
        "requestBody": {
          "required": false,
          "description": "Any payload. JSON is parsed when `content-type` is `application/json`; any other content type reaches the function as a string.",
          "content": {
            "application/json": {
              "schema": {}
            },
            "*/*": {
              "schema": {
                "type": "string"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Response produced by the function. Status (200–599), headers and body are defined by the function code.",
            "content": {
              "*/*": {
                "schema": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "The function has no published version (`error: \"no_active_version\"`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvocationError"
                }
              }
            }
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "500": {
            "description": "The function threw or failed to load (`runtime_error`, `load_error`, `no_default_export`, `network_unavailable`, `spawn_error`, `bad_harness_output`). Carries the message and, for runtime errors, the stack.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvocationError"
                }
              }
            }
          },
          "503": {
            "description": "The service is temporarily unavailable. Retry after the number of seconds in `retry-after`.",
            "headers": {
              "retry-after": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait (always 1)."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "504": {
            "description": "The function exceeded its timeout (`error: \"timeout\"`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvocationError"
                }
              }
            }
          },
          "507": {
            "description": "The function response exceeded the output limit (`error: \"output_too_large\"`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvocationError"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "apiKeyBearer": []
          },
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      },
      "delete": {
        "operationId": "invokeFunctionDelete",
        "tags": [
          "Execution"
        ],
        "summary": "Invoke a function (DELETE)",
        "description": "Runs the active version of the named function, owned by the account behind the credential, inside the sandbox. The function receives the method, the query string (`ctx.query`), the parsed body (`ctx.body`: parsed JSON when `content-type` is `application/json`, raw text otherwise) and its environment variables (`ctx.env`). Forwarded request headers: `content-type`, `accept`, `accept-language`, `user-agent`, `date`, any `x-*` header and known webhook signature headers (`stripe-signature`, `paypal-transmission-sig`, `webhook-signature`, `webhook-id`, `webhook-timestamp`); credentials (`x-api-key`, `authorization`, `cookie`) and infrastructure headers are never forwarded. The response status, headers and body are whatever the function returns (a plain object becomes JSON with status 200); `set-cookie`, `access-control-*` and hop-by-hop headers set by the function are stripped. The same route also answers HEAD. Body limit: 1 MB by default.",
        "parameters": [
          {
            "$ref": "#/components/parameters/FunctionName"
          }
        ],
        "responses": {
          "200": {
            "description": "Response produced by the function. Status (200–599), headers and body are defined by the function code.",
            "content": {
              "*/*": {
                "schema": {}
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "The function has no published version (`error: \"no_active_version\"`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvocationError"
                }
              }
            }
          },
          "500": {
            "description": "The function threw or failed to load (`runtime_error`, `load_error`, `no_default_export`, `network_unavailable`, `spawn_error`, `bad_harness_output`). Carries the message and, for runtime errors, the stack.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvocationError"
                }
              }
            }
          },
          "503": {
            "description": "The service is temporarily unavailable. Retry after the number of seconds in `retry-after`.",
            "headers": {
              "retry-after": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait (always 1)."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "504": {
            "description": "The function exceeded its timeout (`error: \"timeout\"`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvocationError"
                }
              }
            }
          },
          "507": {
            "description": "The function response exceeded the output limit (`error: \"output_too_large\"`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvocationError"
                }
              }
            }
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "apiKeyBearer": []
          },
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      }
    },
    "/schedules": {
      "get": {
        "operationId": "listSchedules",
        "tags": [
          "Schedules"
        ],
        "summary": "List schedules",
        "description": "Every schedule of the account, newest first, with the last cron run and the next run. Not paginated: `page.total` and `page.hasMore` are `null`.",
        "responses": {
          "200": {
            "description": "The schedules.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "items",
                    "page"
                  ],
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Schedule"
                      }
                    },
                    "page": {
                      "$ref": "#/components/schemas/Page"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "apiKeyBearer": []
          },
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      },
      "post": {
        "operationId": "createSchedule",
        "tags": [
          "Schedules"
        ],
        "summary": "Create a schedule",
        "description": "Schedules a function on a cron expression. The schedule fires once per tick (not once per worker).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateScheduleRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "id",
                    "function",
                    "cron"
                  ],
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "id": {
                      "type": "string"
                    },
                    "function": {
                      "type": "string",
                      "description": "Function name."
                    },
                    "cron": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "apiKeyBearer": []
          },
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      }
    },
    "/schedules/{id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ScheduleId"
        }
      ],
      "patch": {
        "operationId": "updateSchedule",
        "tags": [
          "Schedules"
        ],
        "summary": "Update a schedule",
        "description": "Changes the cron expression and/or the params, keeping the id. At least one field is required.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateScheduleRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated schedule.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ScheduleRow"
                    }
                  ],
                  "type": "object",
                  "properties": {
                    "next_run": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time",
                      "description": "Next run (ISO 8601). Note: snake_case here, `nextRun` in the list."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "apiKeyBearer": []
          },
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      },
      "delete": {
        "operationId": "deleteSchedule",
        "tags": [
          "Schedules"
        ],
        "summary": "Delete a schedule",
        "description": "Removes the schedule and disarms its timer.",
        "responses": {
          "200": {
            "description": "Deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Ok"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "apiKeyBearer": []
          },
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      }
    },
    "/schedules/{id}/run": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ScheduleId"
        }
      ],
      "post": {
        "operationId": "runSchedule",
        "tags": [
          "Schedules"
        ],
        "summary": "Run a schedule now",
        "description": "Invokes the scheduled function immediately with the schedule params. Recorded in the log with source `cron`. A failed function run still answers 200 with `ok: false`.",
        "responses": {
          "200": {
            "description": "The run result.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScheduleRunResult"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "apiKeyBearer": []
          },
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      }
    },
    "/plan": {
      "get": {
        "operationId": "getPlan",
        "tags": [
          "Account"
        ],
        "summary": "Get plan notice",
        "description": "The account plan and a billing notice, for display. Never fails: `state: \"unknown\"` when billing cannot be reached. It never decides access.",
        "responses": {
          "200": {
            "description": "The plan notice.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlanNotice"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "security": [
          {
            "apiKey": []
          },
          {
            "apiKeyBearer": []
          },
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      }
    },
    "/me": {
      "get": {
        "operationId": "getMe",
        "tags": [
          "Account"
        ],
        "summary": "Get identity and API key",
        "description": "Exchanges an Infrastructure Auth JWT for the account identity. On the first visit the account `fk_` key is created and returned in cleartext in `apiKey`; afterwards `apiKey` is `null` and only `keyPrefix` identifies it. Use `POST /me/key` to obtain a new one.",
        "responses": {
          "200": {
            "description": "The identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Me"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "security": [
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      },
      "delete": {
        "operationId": "deleteAccount",
        "tags": [
          "Account"
        ],
        "summary": "Delete the account data",
        "description": "Removes the account API keys from Functions. Refused with `HAS_RESOURCES` while any function exists. The account itself lives in Infrastructure Auth. Requires the Auth JWT; an `fk_` key is refused.",
        "responses": {
          "200": {
            "description": "Account data removed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "message",
                    "deleted"
                  ],
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "message": {
                      "type": "string"
                    },
                    "deleted": {
                      "type": "object",
                      "required": [
                        "apiKeys"
                      ],
                      "properties": {
                        "apiKeys": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/JwtRequired"
          },
          "409": {
            "description": "Functions still exist (`HAS_RESOURCES`); `details` carries `functions`, `schedules` and `apiKeys` counts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": [
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      }
    },
    "/me/key": {
      "post": {
        "operationId": "rotateApiKey",
        "tags": [
          "Account"
        ],
        "summary": "Generate a new API key",
        "description": "Creates a new `fk_` key and revokes every previous key of the account. The cleartext value is returned only here. Requires the Auth JWT; an `fk_` key is refused.",
        "responses": {
          "201": {
            "description": "The new key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "apiKey",
                    "keyPrefix"
                  ],
                  "properties": {
                    "apiKey": {
                      "type": "string",
                      "pattern": "^fk_[0-9a-f]{64}$"
                    },
                    "keyPrefix": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/JwtRequired"
          }
        },
        "security": [
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      }
    },
    "/me/deletion-preview": {
      "get": {
        "operationId": "getDeletionPreview",
        "tags": [
          "Account"
        ],
        "summary": "Preview account deletion",
        "description": "What the account holds in Functions, so the caller can decide before `DELETE /me`. Requires the Auth JWT; an `fk_` key is refused.",
        "responses": {
          "200": {
            "description": "The inventory.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountInventory"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/JwtRequired"
          }
        },
        "security": [
          {
            "sessionToken": []
          },
          {
            "oauth2": []
          }
        ]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "Account API key, prefix `fk_`. Accepted on every data route; refused on `/me*`."
      },
      "apiKeyBearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "fk_ API key",
        "description": "The same `fk_` key sent as `Authorization: Bearer fk_…`. Accepted on every data route; refused on `/me*`."
      },
      "sessionToken": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Infrastructure Auth JWT (RS256, `iss: riligar-auth`), e.g. a dashboard session or a device-flow token from https://auth.worker.myinfrastructure.click. Required on `/me*`; also accepted on data routes."
      },
      "oauth2": {
        "type": "oauth2",
        "description": "OAuth 2.1 authorization code with PKCE (S256), issued by Infrastructure Auth. Use it to act on behalf of a person; scopes are listed in the authorization server metadata.",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://auth.worker.myinfrastructure.click/oauth/authorize",
            "tokenUrl": "https://auth.worker.myinfrastructure.click/oauth/token",
            "refreshUrl": "https://auth.worker.myinfrastructure.click/oauth/token",
            "scopes": {
              "auth:read": "Read functions, versions, logs, metrics and schedules.",
              "auth:write": "Publish, configure, roll back and schedule functions."
            }
          }
        }
      }
    },
    "parameters": {
      "FunctionName": {
        "name": "name",
        "in": "path",
        "required": true,
        "description": "Function name.",
        "schema": {
          "type": "string",
          "pattern": "^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$"
        }
      },
      "ScheduleId": {
        "name": "id",
        "in": "path",
        "required": true,
        "description": "Schedule id.",
        "schema": {
          "type": "string"
        }
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "description": "Page size; values above 200 are clamped and the applied value is reported.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 200,
          "default": 50
        }
      },
      "Offset": {
        "name": "offset",
        "in": "query",
        "required": false,
        "description": "Rows to skip.",
        "schema": {
          "type": "integer",
          "minimum": 0,
          "default": 0
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Invalid request (`VALIDATION_ERROR`).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing credential, or invalid/expired token (`UNAUTHORIZED`).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Forbidden": {
        "description": "The API key does not match any account (`FORBIDDEN`).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "JwtRequired": {
        "description": "An `fk_` key (or no Bearer token) was sent where the Infrastructure Auth JWT is required (`FORBIDDEN`).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found (`NOT_FOUND`).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Conflict": {
        "description": "Conflict (`CONFLICT`).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "PlanLimit": {
        "description": "Plan limit reached on function creation: `PLAN_LIMIT` (upgrade) or `SUBSCRIPTION_REQUIRED` (subscribe). `details` carries `resource`, `current`, `limit`, `plan`.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "PayloadTooLarge": {
        "description": "Payload above the limit (`PAYLOAD_TOO_LARGE`): code above 512 KB, env value above 8 KB, or invocation body above 1 MB.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "UNAUTHORIZED",
                  "FORBIDDEN",
                  "NOT_FOUND",
                  "VALIDATION_ERROR",
                  "CONFLICT",
                  "PLAN_LIMIT",
                  "SUBSCRIPTION_REQUIRED",
                  "HAS_RESOURCES",
                  "RATE_LIMITED",
                  "NAME_TAKEN",
                  "EXPIRED",
                  "PAYLOAD_TOO_LARGE",
                  "INTERNAL_ERROR",
                  "SERVICE_UNAVAILABLE"
                ]
              },
              "message": {
                "type": "string",
                "description": "Human-readable (Portuguese); may change."
              },
              "details": {
                "type": "object",
                "additionalProperties": true
              },
              "retriable": {
                "type": "boolean",
                "description": "Present (true) when retrying may succeed."
              }
            }
          }
        }
      },
      "InvocationError": {
        "type": "object",
        "description": "Sandbox failure of a function invocation. Not the standard error envelope: `error` is a string.",
        "required": [
          "error",
          "durationMs"
        ],
        "properties": {
          "error": {
            "type": "string",
            "enum": [
              "no_active_version",
              "timeout",
              "output_too_large",
              "runtime_error",
              "load_error",
              "no_default_export",
              "network_unavailable",
              "spawn_error",
              "bad_harness_output"
            ]
          },
          "message": {
            "type": [
              "string",
              "null"
            ]
          },
          "stack": {
            "type": "string"
          },
          "durationMs": {
            "type": [
              "integer",
              "null"
            ]
          }
        }
      },
      "Page": {
        "type": "object",
        "required": [
          "limit",
          "offset",
          "total",
          "hasMore"
        ],
        "properties": {
          "limit": {
            "type": "integer"
          },
          "offset": {
            "type": "integer"
          },
          "total": {
            "type": [
              "integer",
              "null"
            ],
            "description": "`null` when the route does not count (unpaginated lists)."
          },
          "hasMore": {
            "type": [
              "boolean",
              "null"
            ]
          }
        }
      },
      "Ok": {
        "type": "object",
        "required": [
          "ok"
        ],
        "properties": {
          "ok": {
            "const": true
          }
        }
      },
      "ServiceStatus": {
        "type": "object",
        "required": [
          "service",
          "status",
          "uptime_s",
          "sandbox",
          "enforced",
          "auth",
          "scheduler"
        ],
        "properties": {
          "service": {
            "const": "riligar-functions"
          },
          "status": {
            "const": "ok"
          },
          "uptime_s": {
            "type": "integer"
          },
          "sandbox": {
            "type": "string",
            "enum": [
              "isolate"
            ]
          },
          "enforced": {
            "$ref": "#/components/schemas/EnforcedLimits"
          },
          "auth": {
            "type": "string",
            "enum": [
              "riligar-auth",
              "dev-user"
            ]
          },
          "scheduler": {
            "type": "string",
            "enum": [
              "cron-trigger"
            ]
          },
          "gateDecisionsLastHour": {
            "type": "integer"
          },
          "gateBlindLastHour": {
            "type": "integer"
          },
          "runtime": {
            "const": "cloudflare-worker"
          }
        }
      },
      "EnforcedLimits": {
        "type": "object",
        "properties": {
          "sandbox": {
            "type": "string",
            "enum": [
              "isolate"
            ]
          },
          "timeout": {
            "type": "boolean"
          },
          "outputSize": {
            "type": "boolean"
          },
          "memory": {
            "type": "boolean"
          },
          "network": {
            "type": "boolean",
            "description": "The network policy is enforced by the isolate runtime."
          },
          "egress": {
            "type": "boolean",
            "description": "Functions that enable the network reach the public internet through the egress gateway."
          },
          "filesystem": {
            "type": "boolean"
          },
          "processes": {
            "type": "boolean"
          }
        }
      },
      "PublishFunctionRequest": {
        "type": "object",
        "required": [
          "name",
          "code"
        ],
        "properties": {
          "name": {
            "type": "string",
            "pattern": "^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$",
            "description": "Lowercase letters, digits and hyphens, 1–63 chars. Reserved: functions, schedules, me, admin, status, health, mcp."
          },
          "code": {
            "type": "string",
            "description": "ES module source with a default export `(req, ctx) => Response | object`. Max 512 KB."
          }
        }
      },
      "PublishFunctionResult": {
        "type": "object",
        "required": [
          "ok",
          "name",
          "versionId",
          "created",
          "endpoint"
        ],
        "properties": {
          "ok": {
            "const": true
          },
          "name": {
            "type": "string"
          },
          "versionId": {
            "type": "string"
          },
          "created": {
            "type": "boolean"
          },
          "endpoint": {
            "type": "string",
            "examples": [
              "/fn/hello"
            ]
          }
        }
      },
      "FunctionSummary": {
        "type": "object",
        "required": [
          "id",
          "name",
          "activeVersionId",
          "allowNetwork",
          "createdAt",
          "updatedAt",
          "versions"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "activeVersionId": {
            "type": [
              "string",
              "null"
            ]
          },
          "allowNetwork": {
            "type": "integer",
            "enum": [
              0,
              1
            ],
            "description": "Raw 0/1 in the list (boolean in the detail)."
          },
          "createdAt": {
            "type": "integer",
            "description": "Epoch milliseconds."
          },
          "updatedAt": {
            "type": "integer",
            "description": "Epoch milliseconds."
          },
          "versions": {
            "type": "integer",
            "description": "Number of versions."
          }
        }
      },
      "FunctionDetail": {
        "type": "object",
        "required": [
          "id",
          "name",
          "activeVersionId",
          "allowNetwork",
          "code",
          "endpoint"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "activeVersionId": {
            "type": [
              "string",
              "null"
            ]
          },
          "allowNetwork": {
            "type": "boolean"
          },
          "code": {
            "type": [
              "string",
              "null"
            ],
            "description": "Code of the active version."
          },
          "endpoint": {
            "type": "string",
            "examples": [
              "/fn/hello"
            ]
          }
        }
      },
      "VersionSummary": {
        "type": "object",
        "required": [
          "id",
          "createdAt",
          "active"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "createdAt": {
            "type": "integer",
            "description": "Epoch milliseconds."
          },
          "active": {
            "type": "boolean"
          }
        }
      },
      "Version": {
        "type": "object",
        "required": [
          "id",
          "code",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "created_at": {
            "type": "integer",
            "description": "Epoch milliseconds (snake_case on this route)."
          }
        }
      },
      "RollbackRequest": {
        "type": "object",
        "required": [
          "versionId"
        ],
        "properties": {
          "versionId": {
            "type": "string"
          }
        }
      },
      "EnvVar": {
        "type": "object",
        "required": [
          "chave",
          "valor",
          "secreto",
          "preview",
          "updated_at"
        ],
        "properties": {
          "chave": {
            "type": "string",
            "description": "Variable name."
          },
          "valor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Value; `null` for secrets."
          },
          "secreto": {
            "type": "boolean",
            "description": "Whether the variable is secret."
          },
          "preview": {
            "type": [
              "string",
              "null"
            ],
            "description": "Masked placeholder for secrets; `null` otherwise."
          },
          "updated_at": {
            "type": "integer",
            "description": "Epoch milliseconds."
          }
        }
      },
      "SetEnvRequest": {
        "type": "object",
        "required": [
          "chave",
          "valor"
        ],
        "properties": {
          "chave": {
            "type": "string",
            "pattern": "^[A-Za-z_][A-Za-z0-9_]{0,63}$",
            "description": "Variable name."
          },
          "valor": {
            "type": "string",
            "maxLength": 8192,
            "description": "Value (max 8 KB)."
          },
          "secreto": {
            "type": "boolean",
            "default": false,
            "description": "Secret values are never returned again."
          }
        }
      },
      "LogLine": {
        "type": "object",
        "properties": {
          "nivel": {
            "type": "string",
            "enum": [
              "log",
              "info",
              "warn",
              "error",
              "debug"
            ],
            "description": "Console level."
          },
          "texto": {
            "type": "string",
            "description": "Text."
          },
          "t": {
            "type": "integer",
            "description": "Epoch milliseconds."
          }
        }
      },
      "Invocation": {
        "type": "object",
        "required": [
          "id",
          "source",
          "status",
          "ok",
          "durationMs",
          "error",
          "logs",
          "versionId",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "source": {
            "type": "string",
            "enum": [
              "http",
              "cron"
            ]
          },
          "status": {
            "type": [
              "integer",
              "null"
            ],
            "description": "HTTP status returned by the function; `null` on failure."
          },
          "ok": {
            "type": "integer",
            "enum": [
              0,
              1
            ]
          },
          "durationMs": {
            "type": [
              "integer",
              "null"
            ]
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          },
          "logs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LogLine"
            }
          },
          "versionId": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "integer",
            "description": "Epoch milliseconds."
          }
        }
      },
      "FunctionMetrics": {
        "type": "object",
        "required": [
          "windowHours",
          "total",
          "errors",
          "average",
          "peak",
          "p50",
          "p95",
          "series",
          "publishes"
        ],
        "properties": {
          "windowHours": {
            "type": "integer"
          },
          "total": {
            "type": "integer"
          },
          "errors": {
            "type": "integer"
          },
          "average": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Mean duration (ms)."
          },
          "peak": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Max duration (ms)."
          },
          "p50": {
            "type": [
              "integer",
              "null"
            ]
          },
          "p95": {
            "type": [
              "integer",
              "null"
            ]
          },
          "series": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "hour",
                "invocations",
                "errors"
              ],
              "properties": {
                "hour": {
                  "type": "integer",
                  "description": "Bucket start, epoch ms."
                },
                "invocations": {
                  "type": "integer"
                },
                "errors": {
                  "type": "integer"
                }
              }
            }
          },
          "publishes": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "id",
                "created_at"
              ],
              "properties": {
                "id": {
                  "type": "string"
                },
                "created_at": {
                  "type": "integer"
                }
              }
            }
          }
        }
      },
      "ScheduleParams": {
        "type": "object",
        "description": "What the scheduled invocation receives. With `body` the run is a POST, otherwise a GET.",
        "properties": {
          "query": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "body": {}
        }
      },
      "CreateScheduleRequest": {
        "type": "object",
        "required": [
          "name",
          "cron"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Name of the function to schedule."
          },
          "cron": {
            "type": "string",
            "examples": [
              "*/5 * * * *"
            ]
          },
          "params": {
            "$ref": "#/components/schemas/ScheduleParams"
          }
        }
      },
      "UpdateScheduleRequest": {
        "type": "object",
        "minProperties": 1,
        "properties": {
          "cron": {
            "type": "string"
          },
          "params": {
            "$ref": "#/components/schemas/ScheduleParams"
          }
        }
      },
      "ScheduleRow": {
        "type": "object",
        "required": [
          "id",
          "cron",
          "params",
          "createdAt",
          "functionName",
          "functionId"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "cron": {
            "type": "string"
          },
          "params": {
            "type": [
              "string",
              "null"
            ],
            "description": "JSON-encoded ScheduleParams."
          },
          "createdAt": {
            "type": "integer",
            "description": "Epoch milliseconds."
          },
          "functionName": {
            "type": "string"
          },
          "functionId": {
            "type": "string"
          },
          "lastOk": {
            "type": [
              "integer",
              "null"
            ],
            "enum": [
              0,
              1,
              null
            ]
          },
          "lastStatus": {
            "type": [
              "integer",
              "null"
            ]
          },
          "lastError": {
            "type": [
              "string",
              "null"
            ]
          },
          "lastDurationMs": {
            "type": [
              "integer",
              "null"
            ]
          },
          "lastRun": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Last cron run, epoch ms."
          }
        }
      },
      "Schedule": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ScheduleRow"
          }
        ],
        "type": "object",
        "properties": {
          "nextRun": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "ScheduleRunResult": {
        "type": "object",
        "required": [
          "ok",
          "status",
          "durationMs",
          "error",
          "message",
          "logs"
        ],
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "status": {
            "type": [
              "integer",
              "null"
            ]
          },
          "durationMs": {
            "type": [
              "integer",
              "null"
            ]
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          },
          "message": {
            "type": [
              "string",
              "null"
            ]
          },
          "logs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LogLine"
            }
          }
        }
      },
      "PlanNotice": {
        "type": "object",
        "required": [
          "state",
          "plan",
          "limit",
          "message"
        ],
        "properties": {
          "state": {
            "type": "string",
            "enum": [
              "unknown",
              "active",
              "free",
              "none"
            ]
          },
          "plan": {
            "type": [
              "string",
              "null"
            ]
          },
          "limit": {
            "type": [
              "integer",
              "null"
            ]
          },
          "message": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Me": {
        "type": "object",
        "required": [
          "user",
          "apiKey",
          "keyPrefix",
          "mode"
        ],
        "properties": {
          "user": {
            "type": "object",
            "required": [
              "id"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "email": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "apiKey": {
            "type": [
              "string",
              "null"
            ],
            "description": "Cleartext `fk_` key, only on the visit that creates it."
          },
          "keyPrefix": {
            "type": "string"
          },
          "mode": {
            "type": "string",
            "enum": [
              "auth",
              "dev-user"
            ]
          }
        }
      },
      "AccountInventory": {
        "type": "object",
        "required": [
          "functions",
          "schedules",
          "apiKeys"
        ],
        "properties": {
          "functions": {
            "type": "integer"
          },
          "schedules": {
            "type": "integer"
          },
          "apiKeys": {
            "type": "integer"
          }
        }
      }
    }
  }
}
