SpeedOf.Me SpeedOf.Me

API Documentation

v2.20.423

Getting Started

The SpeedOf.Me API allows you to embed an internet speed test directly into your website or web application. The API uses a JavaScript interface that handles all the complexity of running speed tests.

For AI integration and MCP, see MCP / CLI / SDK.

Quick Start

Follow these three steps to integrate the SpeedOf.Me speed test:

1. Include the API Script

Add the SpeedOf.Me API script to your HTML page:

HTML
<script src="//speedof.me/api/api.js"></script>
Important: Do not download and host the API script yourself. Always load it from speedof.me to ensure you have the latest version.

2. Configure the API

Set your API key and registered domain:

JavaScript
SomApi.account = "YOUR_API_KEY";      // Your API key from the portal
SomApi.domainName = "yourdomain.com"; // Your registered domain

3. Handle Results

Set up callbacks to receive test results:

JavaScript
SomApi.onTestCompleted = function(result) {
    console.log("Download: " + result.download + " Mbps");
    console.log("Upload: " + result.upload + " Mbps");
    console.log("Latency: " + result.latency + " ms");
};

SomApi.onError = function(error) {
    console.error("Error: " + error.message);
};

// Start the test
SomApi.startTest();
Tip: Get your API key from the API Portal. Free trials are available for testing.

Configuration

Configure the API behavior using the SomApi global object.

SomApi.account

SomApi.account string Required

Your unique API key provided when you register. Format: SOMxxxxxxxxxx

SomApi.domainName

SomApi.domainName string Required

The domain where your speed test is hosted. Supports wildcards: *.example.com

Important: The domain in your account Settings, the SomApi.domainName in your JavaScript code, and the actual website domain must all match.

SomApi.config

Fine-tune the speed test behavior with these configuration options:

Property Type Default Description
sustainTime number 6 Controls how long to sustain each download sample (1-8 seconds). Lower values (1-2) = faster but less accurate tests. Higher values (6-8) = slower but more accurate results. The actual download test takes 1-10s at sustainTime=1, or 8-87s at sustainTime=8. Upload time is also affected since its sample size depends on the last download.
uploadTestEnabled boolean true Enable or disable the upload speed test.
latencyTestEnabled boolean true Enable or disable latency (ping) and jitter measurement.
testServerEnabled boolean true Enable or disable detection of the CDN test server location.
userInfoEnabled boolean true Enable or disable fetching user IP address and hostname.
progress.enabled boolean true Enable or disable progress callbacks during the test.
progress.verbose boolean false Enable verbose mode for more frequent progress updates with current speed.
maxTestPass number 0 (auto) Maximum test passes (8-11). Controls data usage. 0 = auto-detect based on speed.

Data Usage

Data consumption depends on connection speed. Use maxTestPass to limit bandwidth consumption per test:

maxTestPass Largest Sample Max Bandwidth per Test
0 (default) No restrictions 256 MB
8 16 MB 32 MB
9 32 MB 64 MB
10 64 MB 128 MB
11 128 MB 256 MB
Tip: To limit data usage, set SomApi.config.maxTestPass = 8 (max 32 MB) or disable upload with SomApi.config.uploadTestEnabled = false.

Localhost Development

Register localhost in your API account, then use it in your JavaScript code:

JavaScript
SomApi.domainName = "localhost";

If you are using a port other than 80, include the port in your JavaScript code:

JavaScript
SomApi.domainName = "localhost:3000";

Example Configuration

JavaScript
// Configure the API
SomApi.account = "SOM_YOUR_API_KEY";
SomApi.domainName = "*.example.com";

// Customize test behavior
SomApi.config.sustainTime = 6;           // Longer test for accuracy
SomApi.config.uploadTestEnabled = true;
SomApi.config.latencyTestEnabled = true;
SomApi.config.progress.enabled = true;
SomApi.config.progress.verbose = true;   // Get real-time speed updates

Callbacks

The API uses callback functions to communicate test progress and results.

onTestCompleted

Called when the speed test completes successfully. Receives a result object with all test metrics.

JavaScript
SomApi.onTestCompleted = function(result) {
    // Speed results
    console.log("Download Speed: " + result.download + " Mbps");
    console.log("Upload Speed: " + result.upload + " Mbps");
    console.log("Max Download: " + result.maxDownload + " Mbps");
    console.log("Max Upload: " + result.maxUpload + " Mbps");

    // Latency results
    console.log("Latency: " + result.latency + " ms");
    console.log("Jitter: " + result.jitter + " ms");

    // Additional info
    console.log("Test Server: " + result.testServer);
    console.log("IP Address: " + result.ip_address);
    console.log("Hostname: " + result.hostname);
    console.log("Test Date: " + result.testDate);
};

onProgress

Called during the test to report progress. Enable with SomApi.config.progress.enabled = true.

JavaScript
SomApi.onProgress = function(progress) {
    console.log("Phase: " + progress.type);        // "download", "upload", or "latency"
    console.log("Pass: " + progress.pass);          // Current pass number
    console.log("Progress: " + progress.percentDone + "%");

    // Available in verbose mode
    if (progress.currentSpeed) {
        console.log("Current Speed: " + progress.currentSpeed + " Mbps");
    }

    // Status message
    console.log("Status: " + progress.message);
};

onError

Called if an error occurs during the test.

JavaScript
SomApi.onError = function(error) {
    console.error("Error Code: " + error.code);
    console.error("Error Message: " + error.message);

    // Handle specific errors
    switch(error.code) {
        case 1001:
            console.log("Invalid API key");
            break;
        case 1002:
            console.log("Domain not registered");
            break;
        default:
            console.log("Test failed");
    }
};

Result Objects

Test Result Object

The onTestCompleted callback receives an object with these properties:

Property Type Description
download number Average download speed in Mbps
upload number Average upload speed in Mbps
maxDownload number Peak download speed in Mbps
maxUpload number Peak upload speed in Mbps
latency number Minimum latency (ping) in milliseconds
jitter number Latency variance in milliseconds
testServer string Test server location (e.g., "Los Angeles 1", "New York 2") or "Unknown"
ip_address string Client's public IP address
hostname string Reverse DNS hostname (if available)
userAgent string Browser user agent string
testDate string ISO 8601 timestamp of test completion

Progress Object

The onProgress callback receives an object with these properties:

Property Type Description
type string Test phase: "download", "upload", or "latency"
pass number Current pass number (1-based). Empty for latency phase.
percentDone number Percentage complete (0-100)
currentSpeed number Current speed in Mbps (verbose mode only)
maxSpeed number Peak speed so far in Mbps (verbose mode only)

Error Codes

API Validation Errors

These errors occur during API key and domain validation:

Code Message Cause
1001 Invalid account API key not found or account is inactive
1002 Domain mismatch The page URL doesn't match any registered domains

Speed Test Errors

These errors occur during the actual speed test:

Code Message Cause
2001 Test error Download or upload test failed
2002 Invalid server response JSON parsing error from CDN server
2003 Request timeout Network timeout during test
Troubleshooting: If you receive error 1002, verify that your SomApi.domainName matches one of the domains registered in your API Portal account.

Advanced Topics

Mobile App Integration

The SpeedOf.Me API is JavaScript-based and requires a web browser environment. To integrate with native mobile apps:

  1. Host your speed test HTML page on a domain registered with your API account (e.g., yourdomain.com/speedtest.html)
  2. Load that page in a WebView (iOS or Android) within your app
  3. Use JavaScript bridges to communicate results back to your native code

iOS (WKWebView)

Use WKWebView with a JavaScript message handler to receive results:

Swift
// In your WKWebView configuration
let config = WKWebViewConfiguration()
config.userContentController.add(self, name: "speedTestHandler")

// JavaScript in the WebView calls:
// window.webkit.messageHandlers.speedTestHandler.postMessage(result);
Important: UIWebView is no longer accepted by the App Store. Always use WKWebView.

Android (WebView)

Use addJavascriptInterface to bridge JavaScript and native code:

Java
// Enable JavaScript
webView.getSettings().setJavaScriptEnabled(true);

// Add interface for JavaScript to call native code
webView.addJavascriptInterface(new SpeedTestInterface(), "Android");

// In JavaScript:
// Android.onTestCompleted(JSON.stringify(result));
Security: Only expose necessary methods via @JavascriptInterface annotation (required for API 17+).

Examples

Basic Sample

basic.html
<!DOCTYPE html>
<html>
<head>
    <script src="//speedof.me/api/api.js"></script>
</head>
<body>
    <button onclick="startTest()">Start Speed Test</button>
    <div id="results"></div>

    <script>
        // Configure the API
        SomApi.account = "SOM_YOUR_API_KEY";  // Replace with your API key
        SomApi.domainName = "yourdomain.com"; // Replace with your domain
        SomApi.config.sustainTime = 6;        // Test duration: 1-8 seconds

        // Handle results
        SomApi.onTestCompleted = function(result) {
            document.getElementById('results').innerHTML =
                '<p>Download: ' + result.download + ' Mbps</p>' +
                '<p>Upload: ' + result.upload + ' Mbps</p>' +
                '<p>Latency: ' + result.latency + ' ms</p>' +
                '<p>Jitter: ' + result.jitter + ' ms</p>';
        };

        // Handle errors
        SomApi.onError = function(error) {
            alert('Error ' + error.code + ': ' + error.message);
        };

        function startTest() {
            document.getElementById('results').innerHTML = 'Testing...';
            SomApi.startTest();
        }
    </script>
</body>
</html>
More Examples

Ready-to-use integrations for React, Vue, Angular, iOS, Android, Flutter, and more.

Browse All Examples

Quick Links

MCP / CLI / SDK

Beyond web embedding, you can use our npm package for AI agents, command-line tools, or Node.js applications.

Bash
npm i @speedofme/mcp

Requirements

  • Node.js 18+
  • API Secret - Different from API Key (see below)

Getting Your API Secret

The API Secret is different from your API Key. To get your API Secret:

  1. Log in to the API Portal
  2. Go to Settings
  3. Click Generate to create your API Secret (first time only)
  4. Copy your API Secret from the modal (you won't be able to see it again)
Keep your API Secret secure. Never expose it in client-side code or public repositories.

MCP & Agent Integrations

Use SpeedOf.Me with AI coding assistants and agent frameworks. Choose your client below:

MCP Clients

Claude Code

Run this command in your terminal:

Bash
claude mcp add-json speedofme '{"type":"stdio","command":"npx","args":["-y","@speedofme/mcp"],"env":{"SOM_API_SECRET":"your-api-secret"}}'
Claude Desktop

Add to your config file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
claude_desktop_config.json
{
  "mcpServers": {
    "speedofme": {
      "command": "npx",
      "args": ["-y", "@speedofme/mcp"],
      "env": {
        "SOM_API_SECRET": "your-api-secret"
      }
    }
  }
}
Cursor

Add to .cursor/mcp.json (project) or ~/.cursor/mcp.json (global):

mcp.json
{
  "mcpServers": {
    "speedofme": {
      "command": "npx",
      "args": ["-y", "@speedofme/mcp"],
      "env": {
        "SOM_API_SECRET": "your-api-secret"
      }
    }
  }
}
Windsurf

Add to ~/.codeium/windsurf/mcp_config.json:

mcp_config.json
{
  "mcpServers": {
    "speedofme": {
      "command": "npx",
      "args": ["-y", "@speedofme/mcp"],
      "env": {
        "SOM_API_SECRET": "your-api-secret"
      }
    }
  }
}
Zed

Add to ~/.config/zed/settings.json:

settings.json
{
  "context_servers": {
    "speedofme": {
      "command": {
        "path": "npx",
        "args": ["-y", "@speedofme/mcp"]
      },
      "env": {
        "SOM_API_SECRET": "your-api-secret"
      }
    }
  }
}
VS Code (Copilot)

Add to .vscode/mcp.json (workspace) or via "MCP: Open User Configuration" command:

mcp.json
{
  "servers": {
    "speedofme": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@speedofme/mcp"],
      "env": {
        "SOM_API_SECRET": "your-api-secret"
      }
    }
  }
}
Cline

Add via the MCP Servers icon in the Cline pane (cline_mcp_settings.json):

cline_mcp_settings.json
{
  "mcpServers": {
    "speedofme": {
      "command": "npx",
      "args": ["-y", "@speedofme/mcp"],
      "env": {
        "SOM_API_SECRET": "your-api-secret"
      }
    }
  }
}
Continue

Add to your config.yaml:

config.yaml
mcpServers:
  - name: speedofme
    command: npx
    args:
      - "-y"
      - "@speedofme/mcp"
    env:
      SOM_API_SECRET: "your-api-secret"
JetBrains

Go to Settings → Tools → MCP Server → Add Server, or copy this config:

MCP Server Settings
{
  "mcpServers": {
    "speedofme": {
      "command": "npx",
      "args": ["-y", "@speedofme/mcp"],
      "env": {
        "SOM_API_SECRET": "your-api-secret"
      }
    }
  }
}
Goose

Add to ~/.config/goose/config.yaml:

config.yaml
extensions:
  speedofme:
    name: SpeedOf.Me
    cmd: npx
    args: [-y, "@speedofme/mcp"]
    enabled: true
    envs:
      SOM_API_SECRET: "your-api-secret"
    type: stdio
    timeout: 300

Available Tools

Tool Description
run_speed_test Run a speed test with optional parameters
get_test_history Get historical test results

Tool Parameters

Parameter Type Default Description
tests string[] all Tests to run: download, upload, latency
sustainTime number 6 Seconds per sample (1-8). Lower = faster, higher = more accurate

Available Resources

Resource Description
speedofme://history Recent test results (JSON)
speedofme://config SDK configuration and status

Agent Frameworks

Integrate SpeedOf.Me into your AI agent applications:

LangChain / LangGraph

Install: pip install langchain-mcp-adapters

Python
from langchain_mcp_adapters.client import MultiServerMCPClient
from langgraph.prebuilt import create_react_agent

client = MultiServerMCPClient({
    "speedofme": {
        "command": "npx",
        "args": ["-y", "@speedofme/mcp"],
        "transport": "stdio",
        "env": {"SOM_API_SECRET": "your-api-secret"}
    }
})

tools = await client.get_tools()
agent = create_react_agent(model, tools)
result = await agent.ainvoke({
    "messages": [("user", "Run a speed test")]
})
LlamaIndex

Install: pip install llama-index-tools-mcp

Python
from llama_index.tools.mcp import BasicMCPClient
from llama_index.agent.openai import OpenAIAgent

client = BasicMCPClient("npx", args=["-y", "@speedofme/mcp"])
tools = await client.list_tools()

agent = OpenAIAgent.from_tools(tools, llm=llm)
response = agent.chat("Run a speed test")
AutoGen

Install: pip install autogen-ext[mcp]

Python
from autogen_ext.tools.mcp import StdioServerParams, mcp_server_tools
from autogen_agentchat.agents import AssistantAgent

server_params = StdioServerParams(
    command="npx",
    args=["-y", "@speedofme/mcp"],
    env={"SOM_API_SECRET": "your-api-secret"}
)

tools = await mcp_server_tools(server_params)
agent = AssistantAgent(
    name="assistant",
    model_client=model_client,
    tools=tools
)
CrewAI

Install: pip install crewai-tools[mcp]

Python
from crewai import Agent
from crewai.mcp import MCPServerStdio

agent = Agent(
    role="Network Analyst",
    goal="Assess connection quality",
    mcps=[
        MCPServerStdio(
            command="npx",
            args=["-y", "@speedofme/mcp"],
            env={"SOM_API_SECRET": "your-api-secret"}
        )
    ]
)
Semantic Kernel (.NET)

NuGet: Microsoft.SemanticKernel.Core (1.44.0+)

C#
using Microsoft.SemanticKernel;
using ModelContextProtocol.Client;

await using var mcpClient = await McpClientFactory.CreateAsync(
    new StdioClientTransport(new() {
        Name = "speedofme",
        Command = "npx",
        Arguments = ["-y", "@speedofme/mcp"],
    }));

var tools = await mcpClient.ListToolsAsync();
kernel.Plugins.AddFromFunctions("SpeedOfMe",
    tools.Select(t => t.AsKernelFunction()));

var result = await kernel.InvokePromptAsync(
    "Run a speed test and summarize the results");
Semantic Kernel (Python)

Install: pip install semantic-kernel>=1.28.1

Python
from semantic_kernel import Kernel
from semantic_kernel.connectors.mcp import MCPStdioPlugin

kernel = Kernel()
plugin = MCPStdioPlugin(
    command="npx",
    args=["-y", "@speedofme/mcp"],
    env={"SOM_API_SECRET": "your-api-secret"}
)
kernel.add_plugin(plugin, "speedofme")

result = await kernel.invoke_prompt(
    "Run a speed test and tell me the results")

CLI

Run speed tests directly from the command line.

Quick Start

Bash
# Set your API secret
export SOM_API_SECRET=your-api-secret

# Run a speed test with progress output
npx -y @speedofme/mcp --progress

Common Commands

Command Description
npx @speedofme/mcp --progress Run test with progress output
npx @speedofme/mcp --json Output results as JSON
npx @speedofme/mcp --tests download,latency Run specific tests only
npx @speedofme/mcp history View test history

Node.js SDK

Integrate speed testing into your Node.js applications.

Example

JavaScript
const { SpeedTest } = require('@speedofme/mcp');

const test = new SpeedTest({
  apiSecret: process.env.SOM_API_SECRET
});

const result = await test.run();
console.log("Download: " + result.download + " Mbps");
console.log("Upload: " + result.upload + " Mbps");
console.log("Latency: " + result.latency + " ms");

Configuration Options

Option Type Default Description
apiSecret string - Your API Secret (required)
sustainTime number 6 Seconds per sample (1-8)
saveHistory boolean true Save results to local history
tests string[] all Tests to run: download, upload, latency

See the npm package for complete documentation.

Need help? Visit the API Portal or contact support.

© 2026 SpeedOf.Me