{
  "openapi": "3.1.0",
  "info": {
    "title": "SaferICO API",
    "version": "1.0.0",
    "summary": "On-chain security reads for contracts, tokens and wallets.",
    "description": "Lightweight read tools over 25 EVM networks: token facts, honeypot simulation,\nexplorer verification status, deployed-bytecode analysis of unverified contracts,\nnative balances, and market/gas data.\n\n**The full 201-detector Solidity audit is not in this API.** It needs far more CPU than an\nedge request may use, so it runs where the CPU is free and the source never has to move:\nin the browser on saferico.com, in your CI runner via the GitHub Action, or locally with\n`npx saferico scan`. Engine version at the time of writing: 2026.09.01.\n\nEvery response carries `ok`. On failure, switch on `error` — the wording of `detail` may change.\n\nGENERATED FILE — built from the tool registry by scripts/openapi.mjs. Do not edit by hand.",
    "contact": {
      "name": "SaferICO",
      "url": "https://saferico.com/docs"
    },
    "license": {
      "name": "Proprietary"
    }
  },
  "servers": [
    {
      "url": "https://saferico.com",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "Tools",
      "description": "The read tools. One path per tool."
    },
    {
      "name": "Discovery",
      "description": "What this key may call."
    },
    {
      "name": "CI",
      "description": "Used by the GitHub Action and `npx saferico scan`. Your source never leaves your machine."
    },
    {
      "name": "MCP",
      "description": "The Model Context Protocol endpoint, for AI agents."
    }
  ],
  "paths": {
    "/api/v1/tools": {
      "get": {
        "operationId": "listTools",
        "summary": "List the tools this key may call",
        "tags": [
          "Discovery"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "The catalogue, filtered to the key's plan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "credits": {
                      "type": "object",
                      "description": "This key's credit position for the current month.",
                      "properties": {
                        "used": {
                          "type": "integer",
                          "description": "Credits spent since the last reset."
                        },
                        "max": {
                          "type": "integer",
                          "description": "The plan's monthly allowance."
                        },
                        "left": {
                          "type": "integer",
                          "description": "Remaining credits, never below zero."
                        },
                        "resetAt": {
                          "type": "integer",
                          "description": "Unix seconds at which `used` returns to zero."
                        }
                      },
                      "required": [
                        "used",
                        "max",
                        "left",
                        "resetAt"
                      ]
                    },
                    "tools": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          },
                          "params": {
                            "type": "object",
                            "additionalProperties": {
                              "type": "string"
                            }
                          },
                          "required": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No key, or a key that is unknown or revoked. `error` is `no-key` or `bad-key`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan behind this key no longer includes API access (`plan-required`). API access starts at Business.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Either the month's credits are spent (`credits-exhausted`) or a request ceiling was reached (`rate-limited`): 240 requests per minute per address, 10000 per day per key. The two are different: the ceilings bound REQUESTS and leave credits untouched, and both send `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "The database binding is not configured (`db-unconfigured`). A deployment problem, not a client one.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/market_info": {
      "post": {
        "operationId": "market_info",
        "summary": "Live native-coin prices and gas across the supported chains, and which chain is cheapest t",
        "description": "Live native-coin prices and gas across the supported chains, and which chain is cheapest to deploy on right now.\n\nPlan: **Business** or higher. Costs 2 credits per call.",
        "tags": [
          "Tools"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {},
                "required": [],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tool ran. Check `ok`: a tool that refuses (bad address, unsupported chain) also answers 200 with `ok:false`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "description": "true when the tool answered; false when it refused."
                    },
                    "error": {
                      "type": "string",
                      "description": "Stable machine-readable reason, present only when ok is false."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation, present only when ok is false."
                    }
                  },
                  "additionalProperties": true,
                  "description": "Live native-coin prices and gas across the supported chains, and which chain is cheapest to deploy on right now."
                }
              }
            }
          },
          "400": {
            "description": "The tool refused the arguments.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No key, or a key that is unknown or revoked. `error` is `no-key` or `bad-key`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan behind this key no longer includes API access (`plan-required`). API access starts at Business.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "This tool is not exposed over the API (`not-available-over-api`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Use POST with a JSON body of arguments.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Either the month's credits are spent (`credits-exhausted`) or a request ceiling was reached (`rate-limited`): 240 requests per minute per address, 10000 per day per key. The two are different: the ceilings bound REQUESTS and leave credits untouched, and both send `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "The database binding is not configured (`db-unconfigured`). A deployment problem, not a client one.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/token_info": {
      "post": {
        "operationId": "token_info",
        "summary": "Read a token's on-chain facts: name, symbol, decimals, total supply and owner",
        "description": "Read a token's on-chain facts: name, symbol, decimals, total supply and owner.\n\nPlan: **Business** or higher. Costs 2 credits per call.",
        "tags": [
          "Tools"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "token": {
                    "type": "string",
                    "description": "Token contract address",
                    "maxLength": 4096
                  },
                  "network": {
                    "type": "string",
                    "description": "Chain name or id",
                    "maxLength": 4096
                  }
                },
                "required": [
                  "token"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tool ran. Check `ok`: a tool that refuses (bad address, unsupported chain) also answers 200 with `ok:false`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "description": "true when the tool answered; false when it refused."
                    },
                    "error": {
                      "type": "string",
                      "description": "Stable machine-readable reason, present only when ok is false."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation, present only when ok is false."
                    }
                  },
                  "additionalProperties": true,
                  "description": "Read a token's on-chain facts: name, symbol, decimals, total supply and owner."
                }
              }
            }
          },
          "400": {
            "description": "The tool refused the arguments.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No key, or a key that is unknown or revoked. `error` is `no-key` or `bad-key`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan behind this key no longer includes API access (`plan-required`). API access starts at Business.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "This tool is not exposed over the API (`not-available-over-api`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Use POST with a JSON body of arguments.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Either the month's credits are spent (`credits-exhausted`) or a request ceiling was reached (`rate-limited`): 240 requests per minute per address, 10000 per day per key. The two are different: the ceilings bound REQUESTS and leave credits untouched, and both send `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "The database binding is not configured (`db-unconfigured`). A deployment problem, not a client one.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/check_honeypot": {
      "post": {
        "operationId": "check_honeypot",
        "summary": "Simulate a buy and a sell against a token to detect honeypots and hidden transfer taxes",
        "description": "Simulate a buy and a sell against a token to detect honeypots and hidden transfer taxes.\n\nPlan: **Business** or higher. Costs 2 credits per call.",
        "tags": [
          "Tools"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "token": {
                    "type": "string",
                    "description": "Token address",
                    "maxLength": 4096
                  },
                  "network": {
                    "type": "string",
                    "description": "Chain name or id",
                    "maxLength": 4096
                  }
                },
                "required": [
                  "token"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tool ran. Check `ok`: a tool that refuses (bad address, unsupported chain) also answers 200 with `ok:false`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "description": "true when the tool answered; false when it refused."
                    },
                    "error": {
                      "type": "string",
                      "description": "Stable machine-readable reason, present only when ok is false."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation, present only when ok is false."
                    }
                  },
                  "additionalProperties": true,
                  "description": "Simulate a buy and a sell against a token to detect honeypots and hidden transfer taxes."
                }
              }
            }
          },
          "400": {
            "description": "The tool refused the arguments.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No key, or a key that is unknown or revoked. `error` is `no-key` or `bad-key`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan behind this key no longer includes API access (`plan-required`). API access starts at Business.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "This tool is not exposed over the API (`not-available-over-api`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Use POST with a JSON body of arguments.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Either the month's credits are spent (`credits-exhausted`) or a request ceiling was reached (`rate-limited`): 240 requests per minute per address, 10000 per day per key. The two are different: the ceilings bound REQUESTS and leave credits untouched, and both send `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "The database binding is not configured (`db-unconfigured`). A deployment problem, not a client one.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/portfolio_scan": {
      "post": {
        "operationId": "portfolio_scan",
        "summary": "Read the wallet's native-coin balance and its USD value across the supported chains",
        "description": "Read the wallet's native-coin balance and its USD value across the supported chains.\n\nPlan: **Business** or higher. Costs 2 credits per call.",
        "tags": [
          "Tools"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "address": {
                    "type": "string",
                    "description": "Wallet address (defaults to the connected wallet)",
                    "maxLength": 4096
                  }
                },
                "required": [],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tool ran. Check `ok`: a tool that refuses (bad address, unsupported chain) also answers 200 with `ok:false`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "description": "true when the tool answered; false when it refused."
                    },
                    "error": {
                      "type": "string",
                      "description": "Stable machine-readable reason, present only when ok is false."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation, present only when ok is false."
                    }
                  },
                  "additionalProperties": true,
                  "description": "Read the wallet's native-coin balance and its USD value across the supported chains."
                }
              }
            }
          },
          "400": {
            "description": "The tool refused the arguments.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No key, or a key that is unknown or revoked. `error` is `no-key` or `bad-key`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan behind this key no longer includes API access (`plan-required`). API access starts at Business.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "This tool is not exposed over the API (`not-available-over-api`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Use POST with a JSON body of arguments.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Either the month's credits are spent (`credits-exhausted`) or a request ceiling was reached (`rate-limited`): 240 requests per minute per address, 10000 per day per key. The two are different: the ceilings bound REQUESTS and leave credits untouched, and both send `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "The database binding is not configured (`db-unconfigured`). A deployment problem, not a client one.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/contract_source": {
      "post": {
        "operationId": "contract_source",
        "summary": "Fetch a contract's verification status, compiler, proxy status and source metadata from th",
        "description": "Fetch a contract's verification status, compiler, proxy status and source metadata from the explorer.\n\nPlan: **Business** or higher. Costs 2 credits per call.",
        "tags": [
          "Tools"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "address": {
                    "type": "string",
                    "description": "Contract address",
                    "maxLength": 4096
                  },
                  "network": {
                    "type": "string",
                    "description": "Chain name or id",
                    "maxLength": 4096
                  }
                },
                "required": [
                  "address"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tool ran. Check `ok`: a tool that refuses (bad address, unsupported chain) also answers 200 with `ok:false`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "description": "true when the tool answered; false when it refused."
                    },
                    "error": {
                      "type": "string",
                      "description": "Stable machine-readable reason, present only when ok is false."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation, present only when ok is false."
                    }
                  },
                  "additionalProperties": true,
                  "description": "Fetch a contract's verification status, compiler, proxy status and source metadata from the explorer."
                }
              }
            }
          },
          "400": {
            "description": "The tool refused the arguments.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No key, or a key that is unknown or revoked. `error` is `no-key` or `bad-key`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan behind this key no longer includes API access (`plan-required`). API access starts at Business.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "This tool is not exposed over the API (`not-available-over-api`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Use POST with a JSON body of arguments.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Either the month's credits are spent (`credits-exhausted`) or a request ceiling was reached (`rate-limited`): 240 requests per minute per address, 10000 per day per key. The two are different: the ceilings bound REQUESTS and leave credits untouched, and both send `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "The database binding is not configured (`db-unconfigured`). A deployment problem, not a client one.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/bytecode_scan": {
      "post": {
        "operationId": "bytecode_scan",
        "summary": "Analyse an UNVERIFIED contract straight from its deployed bytecode: which functions it exp",
        "description": "Analyse an UNVERIFIED contract straight from its deployed bytecode: which functions it exposes (mint, blacklist, pause, fee and withdrawal entry points), which opcodes it contains (SELFDESTRUCT, DELEGATECALL, tx.origin), whether it is an upgradeable proxy, and which compiler built it. Use this whenever contract_source reports the source is not verified.\n\nPlan: **AI Agents** or higher. Costs 2 credits per call.",
        "tags": [
          "Tools"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "address": {
                    "type": "string",
                    "description": "Contract address",
                    "maxLength": 4096
                  },
                  "network": {
                    "type": "string",
                    "description": "Chain name or id",
                    "maxLength": 4096
                  }
                },
                "required": [
                  "address"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tool ran. Check `ok`: a tool that refuses (bad address, unsupported chain) also answers 200 with `ok:false`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "description": "true when the tool answered; false when it refused."
                    },
                    "error": {
                      "type": "string",
                      "description": "Stable machine-readable reason, present only when ok is false."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation, present only when ok is false."
                    }
                  },
                  "additionalProperties": true,
                  "description": "Analyse an UNVERIFIED contract straight from its deployed bytecode: which functions it exposes (mint, blacklist, pause, fee and withdrawal entry points), which opcodes it contains (SELFDESTRUCT, DELEGATECALL, tx.origin), whether it is an upgradeable proxy, and which compiler built it. Use this whenever contract_source reports the source is not verified."
                }
              }
            }
          },
          "400": {
            "description": "The tool refused the arguments.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No key, or a key that is unknown or revoked. `error` is `no-key` or `bad-key`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan behind this key no longer includes API access (`plan-required`). API access starts at Business.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "This tool is not exposed over the API (`not-available-over-api`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Use POST with a JSON body of arguments.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Either the month's credits are spent (`credits-exhausted`) or a request ceiling was reached (`rate-limited`): 240 requests per minute per address, 10000 per day per key. The two are different: the ceilings bound REQUESTS and leave credits untouched, and both send `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "The database binding is not configured (`db-unconfigured`). A deployment problem, not a client one.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/explain_transaction": {
      "post": {
        "operationId": "explain_transaction",
        "summary": "Explain what one transaction actually did: status, decoded function call, ERC-20 and NFT m",
        "description": "Explain what one transaction actually did: status, decoded function call, ERC-20 and NFT movements, approvals granted (flagging unlimited ones), every contract touched, and security-relevant signals such as proxy upgrades, ownership transfers and role grants. Reads the receipt and its logs — it does NOT trace internal calls, because public RPC endpoints do not expose tracing.\n\nPlan: **Business** or higher. Costs 2 credits per call.",
        "tags": [
          "Tools"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "hash": {
                    "type": "string",
                    "description": "Transaction hash (0x + 64 hex)",
                    "maxLength": 4096
                  },
                  "network": {
                    "type": "string",
                    "description": "Chain name or id",
                    "maxLength": 4096
                  }
                },
                "required": [
                  "hash"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tool ran. Check `ok`: a tool that refuses (bad address, unsupported chain) also answers 200 with `ok:false`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "description": "true when the tool answered; false when it refused."
                    },
                    "error": {
                      "type": "string",
                      "description": "Stable machine-readable reason, present only when ok is false."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation, present only when ok is false."
                    }
                  },
                  "additionalProperties": true,
                  "description": "Explain what one transaction actually did: status, decoded function call, ERC-20 and NFT movements, approvals granted (flagging unlimited ones), every contract touched, and security-relevant signals such as proxy upgrades, ownership transfers and role grants. Reads the receipt and its logs — it does NOT trace internal calls, because public RPC endpoints do not expose tracing."
                }
              }
            }
          },
          "400": {
            "description": "The tool refused the arguments.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No key, or a key that is unknown or revoked. `error` is `no-key` or `bad-key`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan behind this key no longer includes API access (`plan-required`). API access starts at Business.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "This tool is not exposed over the API (`not-available-over-api`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Use POST with a JSON body of arguments.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Either the month's credits are spent (`credits-exhausted`) or a request ceiling was reached (`rate-limited`): 240 requests per minute per address, 10000 per day per key. The two are different: the ceilings bound REQUESTS and leave credits untouched, and both send `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "The database binding is not configured (`db-unconfigured`). A deployment problem, not a client one.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/scan_agent_config": {
      "post": {
        "operationId": "scan_agent_config",
        "summary": "Security-review the text of an AI agent skill, instruction file or MCP server configuratio",
        "description": "Security-review the text of an AI agent skill, instruction file or MCP server configuration for patterns that are dangerous by construction: shell commands in server definitions, disabled sandboxes, wildcard command permissions, hardcoded credentials and private keys, instructions to read credential stores, outbound calls to data-collection endpoints, prompt-injection and instruction-override text, hidden HTML-comment instructions, invisible or bidirectional-override characters, and unpinned packages. This is pattern matching over text, NOT smart-contract analysis, and a clean result means no known pattern matched — not that the file is safe to run. Reads up to 4 KB here; use `npx saferico skill <path>` for a whole directory, locally, with nothing uploaded.\n\nPlan: **Business** or higher. Costs 1 credits per call.",
        "tags": [
          "Tools"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "content": {
                    "type": "string",
                    "description": "The file's text",
                    "maxLength": 4096
                  },
                  "filename": {
                    "type": "string",
                    "description": "Its name, e.g. mcp.json or SKILL.md — decides which rules apply",
                    "maxLength": 4096
                  }
                },
                "required": [
                  "content"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tool ran. Check `ok`: a tool that refuses (bad address, unsupported chain) also answers 200 with `ok:false`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "description": "true when the tool answered; false when it refused."
                    },
                    "error": {
                      "type": "string",
                      "description": "Stable machine-readable reason, present only when ok is false."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Human-readable explanation, present only when ok is false."
                    }
                  },
                  "additionalProperties": true,
                  "description": "Security-review the text of an AI agent skill, instruction file or MCP server configuration for patterns that are dangerous by construction: shell commands in server definitions, disabled sandboxes, wildcard command permissions, hardcoded credentials and private keys, instructions to read credential stores, outbound calls to data-collection endpoints, prompt-injection and instruction-override text, hidden HTML-comment instructions, invisible or bidirectional-override characters, and unpinned packages. This is pattern matching over text, NOT smart-contract analysis, and a clean result means no known pattern matched — not that the file is safe to run. Reads up to 4 KB here; use `npx saferico skill <path>` for a whole directory, locally, with nothing uploaded."
                }
              }
            }
          },
          "400": {
            "description": "The tool refused the arguments.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No key, or a key that is unknown or revoked. `error` is `no-key` or `bad-key`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan behind this key no longer includes API access (`plan-required`). API access starts at Business.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "This tool is not exposed over the API (`not-available-over-api`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Use POST with a JSON body of arguments.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Either the month's credits are spent (`credits-exhausted`) or a request ceiling was reached (`rate-limited`): 240 requests per minute per address, 10000 per day per key. The two are different: the ceilings bound REQUESTS and leave credits untouched, and both send `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "The database binding is not configured (`db-unconfigured`). A deployment problem, not a client one.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/ci/session": {
      "post": {
        "operationId": "ciSession",
        "summary": "Open a CI run and get the engine to download",
        "description": "Called before any scanning. Returns the licence, the gate policy and the URLs of the detector engine to run locally. Pass `engineVersion` to pin a specific engine for a reproducible scan; omit it to always get the newest detectors.",
        "tags": [
          "CI"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "version": {
                    "type": "string",
                    "description": "Runner version, for support."
                  },
                  "repo": {
                    "type": "string",
                    "description": "Repository slug, stored on the run record."
                  },
                  "engineVersion": {
                    "type": "string",
                    "description": "Pin an engine version from /engine/manifest.json. Omit for the newest."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Licence, engine urls (with sha-256 when pinned), and the fail-on policy."
          },
          "400": {
            "description": "`unknown-engine-version` — the response lists the versions that exist.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No key, or a key that is unknown or revoked. `error` is `no-key` or `bad-key`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan behind this key no longer includes API access (`plan-required`). API access starts at Business.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Either the month's credits are spent (`credits-exhausted`) or a request ceiling was reached (`rate-limited`): 240 requests per minute per address, 10000 per day per key. The two are different: the ceilings bound REQUESTS and leave credits untouched, and both send `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "The database binding is not configured (`db-unconfigured`). A deployment problem, not a client one.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/ci/report": {
      "post": {
        "operationId": "ciReport",
        "summary": "Close a CI run with the counts it found",
        "description": "Posts back counts per severity and rule ids only — never source, never the evidence strings that quote it.",
        "tags": [
          "CI"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "counts": {
                    "type": "object",
                    "description": "critical/high/medium/low integers."
                  },
                  "failOn": {
                    "type": "string",
                    "enum": [
                      "critical",
                      "high",
                      "medium",
                      "low",
                      "none"
                    ]
                  },
                  "repo": {
                    "type": "string"
                  },
                  "ref": {
                    "type": "string"
                  },
                  "commit": {
                    "type": "string"
                  },
                  "actor": {
                    "type": "string"
                  },
                  "files": {
                    "type": "integer"
                  },
                  "score": {
                    "type": "integer"
                  },
                  "top": {
                    "type": "array",
                    "items": {
                      "type": "object"
                    },
                    "description": "Rule ids and severities. No source."
                  },
                  "durationMs": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The stored run: verdict, reason, counts and a dashboard link."
          },
          "401": {
            "description": "No key, or a key that is unknown or revoked. `error` is `no-key` or `bad-key`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The plan behind this key no longer includes API access (`plan-required`). API access starts at Business.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "POST only.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Either the month's credits are spent (`credits-exhausted`) or a request ceiling was reached (`rate-limited`): 240 requests per minute per address, 10000 per day per key. The two are different: the ceilings bound REQUESTS and leave credits untouched, and both send `Retry-After`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "The database binding is not configured (`db-unconfigured`). A deployment problem, not a client one.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/mcp": {
      "post": {
        "operationId": "mcp",
        "summary": "Model Context Protocol endpoint (JSON-RPC 2.0)",
        "description": "For MCP clients, not for hand-written HTTP. Speaks protocol revisions 2026-07-28, 2025-11-25, 2025-06-18, 2025-03-26\nover a single POST, with no sessions and no GET stream. It exposes the same read tools as\n/api/v1 under the same key and the same meter. Add it to a client as:\n\n    { \"url\": \"https://saferico.com/mcp\", \"headers\": { \"Authorization\": \"Bearer sfi_live_…\" } }",
        "tags": [
          "MCP"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jsonrpc",
                  "method"
                ],
                "properties": {
                  "jsonrpc": {
                    "type": "string",
                    "enum": [
                      "2.0"
                    ]
                  },
                  "id": {
                    "description": "Omit for a notification; the server answers 202 with no body."
                  },
                  "method": {
                    "type": "string",
                    "examples": [
                      "initialize",
                      "tools/list",
                      "tools/call",
                      "ping"
                    ]
                  },
                  "params": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A JSON-RPC result. A tool that refuses answers here too, with `isError: true`."
          },
          "202": {
            "description": "A notification was accepted."
          },
          "400": {
            "description": "Malformed JSON-RPC, unsupported protocol version, or a header that disagrees with the body (-32020)."
          },
          "401": {
            "description": "No `Authorization` header, or a key that is unknown or revoked (-32600). `ping` is the only method that answers without one."
          },
          "403": {
            "description": "Foreign `Origin`, or a plan without API access."
          },
          "404": {
            "description": "Unknown JSON-RPC method (-32601)."
          },
          "405": {
            "description": "GET or DELETE — this revision of the transport has neither."
          },
          "413": {
            "description": "Request body over 64 KB."
          },
          "503": {
            "description": "The database binding is not configured (`db-unconfigured`). A deployment problem, not a client one."
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "ok",
          "error"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "error": {
            "type": "string",
            "description": "Stable machine-readable code. Switch on this, never on `detail`."
          },
          "detail": {
            "type": "string",
            "description": "Human-readable explanation. Wording may change; the code will not."
          }
        },
        "additionalProperties": true
      }
    },
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "An API key from the API keys tab of your account. Requires the Business plan or higher."
      }
    }
  }
}
