{
  "openapi": "3.0.1",
  "info": {
    "title": "AI API Spend Kill-Switch – OpenAI & Anthropic Budget Guard",
    "description": "Hard spending limit for OpenAI and Anthropic (Claude) APIs. Checks spend via the official Admin APIs on a schedule, alerts Slack/Discord/webhooks, and can automatically disable leaked or runaway API keys.",
    "version": "0.1",
    "x-build-id": "105SSJHiqzeT08suH"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/jet_mythology~ai-api-spend-kill-switch/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-jet_mythology-ai-api-spend-kill-switch",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/jet_mythology~ai-api-spend-kill-switch/runs": {
      "post": {
        "operationId": "runs-sync-jet_mythology-ai-api-spend-kill-switch",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/jet_mythology~ai-api-spend-kill-switch/run-sync": {
      "post": {
        "operationId": "run-sync-jet_mythology-ai-api-spend-kill-switch",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "openaiAdminKey": {
            "title": "OpenAI Admin API key",
            "type": "string",
            "description": "An OpenAI **Admin** key (sk-admin-...), created by an Organization Owner at platform.openai.com > Settings > Organization > Admin keys. A normal project key will not work. Stored encrypted by Apify, never logged. Leave both keys empty to run a demo with simulated data."
          },
          "anthropicAdminKey": {
            "title": "Anthropic Admin API key",
            "type": "string",
            "description": "An Anthropic **Admin** key (sk-ant-admin...), created by an organization admin in the Claude Console > Settings > Admin keys. Stored encrypted by Apify, never logged."
          },
          "dailyLimitUsd": {
            "title": "Daily limit (USD, whole organization)",
            "minimum": 0,
            "type": "integer",
            "description": "Trigger when today's (UTC) spend for the whole organization exceeds this amount. Applied per provider."
          },
          "monthlyLimitUsd": {
            "title": "Monthly limit (USD, whole organization)",
            "minimum": 0,
            "type": "integer",
            "description": "Trigger when month-to-date (UTC) spend exceeds this amount. Applied per provider."
          },
          "perKeyOrWorkspaceDailyLimitUsd": {
            "title": "Daily limit per key (OpenAI) / per workspace (Anthropic), USD",
            "minimum": 0,
            "type": "integer",
            "description": "Optional. Catches one leaked key burning money even when the org total is still below the limit. OpenAI reports cost per API key; Anthropic's cost report is per workspace, so on Anthropic this applies per workspace."
          },
          "mode": {
            "title": "Action when a limit is exceeded",
            "enum": [
              "alert",
              "disable"
            ],
            "type": "string",
            "description": "Start with Alert only. In Disable mode, Anthropic keys are set to status \"inactive\" (reversible in the Console). OpenAI has no documented way to pause a project key, so OpenAI keys are DELETED (irreversible: you will need to create new keys) or, if you choose it below, their project is archived.",
            "default": "alert"
          },
          "disableScope": {
            "title": "Which keys to disable",
            "enum": [
              "offending",
              "all"
            ],
            "type": "string",
            "description": "Offending: OpenAI keys / Anthropic workspaces that spent money in the breached period (or, with a per-key/workspace limit set, only those over that limit). All: every active key in scope.",
            "default": "offending"
          },
          "openaiDisableAction": {
            "title": "OpenAI kill-switch action",
            "enum": [
              "delete_keys",
              "archive_projects"
            ],
            "type": "string",
            "description": "OpenAI cannot pause a project key through the API. Deleting keys is irreversible; archiving a project is irreversible and blocks all its keys.",
            "default": "delete_keys"
          },
          "dryRun": {
            "title": "Dry run (show what would be disabled, change nothing)",
            "type": "boolean",
            "description": "Recommended for your first runs in Disable mode.",
            "default": false
          },
          "protectedKeyIds": {
            "title": "Allowlist: key IDs never touched",
            "type": "array",
            "description": "OpenAI key IDs (key_...) or Anthropic key IDs (apikey_...) that must never be disabled.",
            "items": {
              "type": "string"
            }
          },
          "protectedProjectOrWorkspaceIds": {
            "title": "Allowlist: projects / workspaces never touched",
            "type": "array",
            "description": "OpenAI project IDs (proj_...) or Anthropic workspace IDs (wrkspc_...; use \"default\" for the default workspace).",
            "items": {
              "type": "string"
            }
          },
          "onlyProjectOrWorkspaceIds": {
            "title": "Only act inside these projects / workspaces",
            "type": "array",
            "description": "Optional. If set, keys outside these projects/workspaces are never disabled.",
            "items": {
              "type": "string"
            }
          },
          "blocklistKeyIds": {
            "title": "Blocklist: keys always disabled when any limit is hit",
            "type": "array",
            "description": "Key IDs to kill first whenever any limit is exceeded (e.g. keys you know were exposed on a host).",
            "items": {
              "type": "string"
            }
          },
          "webhookUrl": {
            "title": "Alert webhook URL (Slack, Discord or any HTTPS endpoint)",
            "type": "string",
            "description": "Slack incoming webhook and Discord webhook URLs get a readable message; any other URL receives a JSON POST with the full result."
          },
          "alertEveryRun": {
            "title": "Alert on every run while over the limit",
            "type": "boolean",
            "description": "Off: one alert per breach per UTC day (plus every time keys are disabled).",
            "default": false
          },
          "failOnError": {
            "title": "Mark the run as failed if a provider check fails",
            "type": "boolean",
            "description": "Lets Apify's own run-failure notifications warn you when a key is wrong or a provider API is down.",
            "default": true
          },
          "demoMode": {
            "title": "Demo mode (simulated data)",
            "type": "boolean",
            "description": "Runs against simulated Admin API responses so you can see the output and test your webhook. Automatically on when no key is given. Demo runs are not charged per check.",
            "default": false
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}