{"record":{"id":"3246f6862367820a","repo":"wpscanteam/wpscan","slug":"your-api-limit-has-been-reached","errorCode":null,"errorMessage":"Your API limit has been reached","messagePattern":"Your API limit has been reached","errorType":"exception","errorClass":"WPScan::Error::ApiLimitReached","httpStatus":null,"severity":"error","filePath":"app/controllers/vuln_api.rb","lineNumber":67,"sourceCode":"          )\n        ]\n      end\n\n      def before_scan\n        # Already done by Core#before_scan (before the DB update, to fail as early as possible),\n        # kept as a safety net in case this controller is used in a chain without Core.\n        self.class.validate_api_tokens!\n\n        return setup_enterprise_db if enterprise_db_token\n\n        return unless api_token\n\n        DB::VulnApi.token = api_token\n\n        api_status = DB::VulnApi.status\n\n        raise Error::InvalidApiToken if api_status['status'] == 'forbidden'\n        raise Error::ApiLimitReached if api_status['requests_remaining'] == 0\n        raise Error::ApiConnectionError, api_status['http_error'] if api_status['http_error']\n      end\n\n      def after_scan\n        output('status', status: DB::VulnApi.status, api_requests: WPScan.api_requests)\n      end\n\n      private\n\n      # @return [ String, nil ] The enterprise DB token (CLI or ENV)\n      def enterprise_db_token\n        self.class.enterprise_db_token\n      end\n\n      # @return [ String, nil ] The API token (CLI or ENV var)\n      def api_token\n        self.class.api_token\n      end","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/wpscanteam/wpscan/blob/62c9cef471de90095f6b42245a11d0f8172d19c9/app/controllers/vuln_api.rb#L49-L85","documentation":"Raised by VulnApi#before_scan (app/controllers/vuln_api.rb:67) when the API status payload reports requests_remaining == 0 — the token's daily quota is exhausted. The free tier allows 25 requests per day and each detected WordPress version, plugin and theme consumes one request, so enumeration-heavy scans drain it quickly.","triggerScenarios":"`wpscan --url http://t --api-token TOKEN` where a previous scan the same day already consumed the quota, or the status check itself reports zero remaining before the scan body starts; api_status['requests_remaining'] == 0 at line 67.","commonSituations":"Multiple scans per day on the free tier; scheduled jobs sharing one token across projects; large enumerations (>25 plugins/themes/version lookups) exhausting the quota within a single run.","solutions":["Wait for the daily quota reset and re-run the scan","Upgrade the API plan at wpscan.com for a higher daily limit","Run without a token (drop --api-token / unset WPSCAN_API_TOKEN) if vulnerability data is not required"],"exampleFix":"# before\nwpscan --url http://t --api-token TOKEN   # quota already spent today\n# => Your API limit has been reached\n\n# after (scan without vulnerability data)\nunset WPSCAN_API_TOKEN && wpscan --url http://t","handlingStrategy":"retry","validationCode":"# Check remaining quota before launching\nWPScan::DB::VulnApi.token = token\nremaining = WPScan::DB::VulnApi.status['requests_remaining']\nabort 'quota exhausted — wait for the daily reset' if remaining.to_i.zero?","typeGuard":null,"tryCatchPattern":"begin\n  scan.run\nrescue WPScan::Error::ApiLimitReached\n  sleep_until_daily_reset; retry # or rerun without the token\nend","preventionTips":["Budget one API request per version/plugin/theme you expect to enumerate","Use one token per project to avoid cross-team quota exhaustion","Strip the token when vulnerability data is not needed","Watch requests_remaining in the scan footer to anticipate exhaustion"],"tags":["api-token","rate-limit","quota","free-tier"],"backgroundTag":"api-rate-limit-exceeded","analyzedSha":"62c9cef471de90095f6b42245a11d0f8172d19c9","analyzedAt":"2026-08-21T17:10:47.902Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}