OnlineHashCrack Private API
Use the private API to submit authorized hash recovery tasks and retrieve your current task list. Requests and responses are JSON, API keys always use the sk_ prefix, and each response includes a server-generated request_id for support and troubleshooting.
https://api.onlinehashcrack.com/v2
api_key in the JSON body.
Content-Type: application/json.
Endpoints
https://api.onlinehashcrack.com/v2https://api.onlinehashcrack.com/v2?schema=1https://api.onlinehashcrack.com/v2?openapi=1agree_terms to yes only when you have read and accepted the Terms & Conditions and you are submitting hashes you are authorized to test.
Request Body
All API actions use a JSON object. If action is omitted, the API defaults to add_tasks.
| Field | Type | Required | Description |
|---|---|---|---|
api_key |
String | Required | Your private API key. Format: sk_ followed by 32 to 64 alphanumeric characters. Generate or manage it from API management. |
agree_terms |
String | Required | Must be exactly yes. Any other value returns terms_not_accepted. |
action |
String | Optional | Allowed values: add_tasks or list_tasks. Defaults to add_tasks. |
algo_mode |
Integer | Required for add_tasks | Non-negative Hashcat algorithm mode. See the accepted hash list. Example: 0 for MD5. |
hashes |
Array<string> | Required for add_tasks | One to 50 hash strings. Each value is trimmed, HTML tags are stripped, values are capped at 512 characters, and duplicates in the same request are ignored. |
Examples
# Add hash recovery tasks
curl -sS -X POST "https://api.onlinehashcrack.com/v2" \
-H "Content-Type: application/json" \
-d '{
"api_key": "sk_REPLACE_WITH_YOUR_KEY",
"agree_terms": "yes",
"action": "add_tasks",
"algo_mode": 0,
"hashes": [
"8124BC0A5335C27F086F24BA2C7A4810"
]
}'
# List current tasks
curl -sS -X POST "https://api.onlinehashcrack.com/v2" \
-H "Content-Type: application/json" \
-d '{
"api_key": "sk_REPLACE_WITH_YOUR_KEY",
"agree_terms": "yes",
"action": "list_tasks"
}'
# Inspect the request schema
curl -sS "https://api.onlinehashcrack.com/v2?schema=1"
# Inspect the OpenAPI 3.0 schema
curl -sS "https://api.onlinehashcrack.com/v2?openapi=1"
import requests
url = "https://api.onlinehashcrack.com/v2"
payload = {
"api_key": "sk_REPLACE_WITH_YOUR_KEY",
"agree_terms": "yes",
"action": "add_tasks",
"algo_mode": 0,
"hashes": ["8124BC0A5335C27F086F24BA2C7A4810"],
}
response = requests.post(url, json=payload, timeout=30)
data = response.json()
if response.status_code == 429:
print("Retry after", response.headers.get("Retry-After"), "seconds")
elif not response.ok:
print(data.get("error_code"), data.get("message"), data.get("request_id"))
else:
print(data)
const response = await fetch('https://api.onlinehashcrack.com/v2', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
api_key: 'sk_REPLACE_WITH_YOUR_KEY',
agree_terms: 'yes',
action: 'add_tasks',
algo_mode: 0,
hashes: ['8124BC0A5335C27F086F24BA2C7A4810'],
}),
});
const data = await response.json();
if (response.status === 429) {
console.log('Retry after', response.headers.get('Retry-After'), 'seconds');
} else if (!response.ok) {
console.error(data.error_code, data.message, data.request_id);
} else {
console.log(data);
}
$uri = 'https://api.onlinehashcrack.com/v2'
$payload = @{
api_key = 'sk_REPLACE_WITH_YOUR_KEY'
agree_terms = 'yes'
action = 'add_tasks'
algo_mode = 0
hashes = @('8124BC0A5335C27F086F24BA2C7A4810')
} | ConvertTo-Json -Depth 4
try {
$response = Invoke-RestMethod `
-Uri $uri `
-Method Post `
-ContentType 'application/json' `
-Body $payload `
-TimeoutSec 30
$response
} catch {
$statusCode = $_.Exception.Response.StatusCode.value__
$retryAfter = $_.Exception.Response.Headers['Retry-After']
Write-Error "OHC API error HTTP $statusCode. Retry-After: $retryAfter"
}
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
)
func main() {
payload := map[string]any{
"api_key": "sk_REPLACE_WITH_YOUR_KEY",
"agree_terms": "yes",
"action": "add_tasks",
"algo_mode": 0,
"hashes": []string{"8124BC0A5335C27F086F24BA2C7A4810"},
}
body, err := json.Marshal(payload)
if err != nil {
panic(err)
}
client := &http.Client{Timeout: 30 * time.Second}
req, err := http.NewRequest(http.MethodPost, "https://api.onlinehashcrack.com/v2", bytes.NewReader(body))
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
responseBody, err := io.ReadAll(resp.Body)
if err != nil {
panic(err)
}
if resp.StatusCode == http.StatusTooManyRequests {
fmt.Println("Retry after", resp.Header.Get("Retry-After"), "seconds")
}
if resp.StatusCode >= 400 {
fmt.Println("API error:", resp.Status, string(responseBody))
return
}
fmt.Println(string(responseBody))
}
$url = 'https://api.onlinehashcrack.com/v2';
$payload = [
'api_key' => 'sk_REPLACE_WITH_YOUR_KEY',
'agree_terms' => 'yes',
'action' => 'add_tasks',
'algo_mode' => 0,
'hashes' => ['8124BC0A5335C27F086F24BA2C7A4810'],
];
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode($payload, JSON_THROW_ON_ERROR),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
$error = curl_error($ch);
curl_close($ch);
if ($body === false) {
throw new RuntimeException('API request failed: ' . $error);
}
$data = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
if ($status >= 400) {
error_log('OHC API error ' . ($data['error_code'] ?? 'unknown') . ' request_id=' . ($data['request_id'] ?? 'none'));
}
print_r($data);
Successful Responses
add_tasks response
The response groups submitted hashes into accepted, skipped, and rejected. Hashes are masked for safe correlation in local logs.
{
"accepted": {
"count": 1,
"hashes": [
"8124...4810"
]
},
"skipped": {
"count": 1,
"reason": "already_sent",
"hashes": [
"5F4D...27E0"
]
},
"rejected": {
"count": 1,
"hashes": [
"BAD...HASH"
],
"reason": "invalid_format"
},
"success": true,
"request_id": "9f8a7b6c5d4e3f21"
}
list_tasks response
{
"success": true,
"tasks": [
{
"created_at": "2026-05-12 14:25:00",
"hash": "8124BC0A5335C27F086F24BA2C7A4810",
"algomode": "0",
"algorithm": "MD5",
"usernote": "",
"status": "In queue",
"lastAttack": ""
}
],
"request_id": "9f8a7b6c5d4e3f21"
}
Error Responses
Request-level errors return a non-2xx HTTP status, success: false, a machine-readable error_code, a human-readable message, and a request_id.
{
"success": false,
"error_code": "invalid_api_key",
"message": "Invalid API key.",
"request_id": "9f8a7b6c5d4e3f21"
}
| Status | Error code | When it happens |
|---|---|---|
| 400 | empty_body |
The request body is empty. |
| 400 | malformed_json |
The body is not a valid JSON object. |
| 400 | missing_field |
api_key or agree_terms is missing. The response includes a missing array. |
| 400 | terms_not_accepted |
agree_terms is not exactly yes. |
| 400 | invalid_action |
action is not add_tasks or list_tasks. |
| 400 | invalid_algo_mode |
algo_mode is missing, negative, or not an integer for add_tasks. |
| 400 | invalid_hashes |
hashes is missing, not an array, empty, above 50 items, or contains non-string values. |
| 401 | invalid_api_key |
The API key format is invalid, the key is unknown, the account is not verified, or API access is unavailable for the account. |
| 405 | method_not_allowed |
The request method is not POST. The response includes Allow: POST. |
| 413 | body_too_large |
The JSON body exceeds 1 MB. |
| 429 | rate_limit_exceeded |
The hourly API limit is exhausted. The response includes Retry-After, retry_after, and limit. Upgrade your Tier from your Profile when your automation needs more headroom. |
| 500 | internal_error |
An internal server error occurred. Provide request_id when contacting support. |
Hash-level rejection reasons
When the request itself is valid but individual hashes cannot be added, they appear in rejected. The reason field contains the last rejection reason returned for that batch.
invalid_format: the hash does not match the selectedalgo_mode.invalid_algorithm: the selected algorithm is unsupported or invalid.quota_exceeded: the account quota is reached. Upgrade your Tier from your Profile to unlock more capacity for larger or recurring audits.internal_error: an unexpected server-side error occurred while saving a task.
Rate Limits
Rate limits are enforced per API key in a fixed one-hour window. Higher tiers are designed for heavier automation, recurring compliance checks, and larger audit workflows. You can upgrade from your Profile.
| Tier | Requests per hour | Upgrade path |
|---|---|---|
| Tier 1 | 50 | Best for light automation and occasional submissions. Need more throughput? Upgrade your Tier. |
| Tier 2 | 500 | Built for regular scripting, scheduled checks, and team workflows. Manage or upgrade it from your Profile. |
| Tier 3 | 2000 | Highest self-service API allowance for intensive audit pipelines. Check your Profile or contact us for specific needs. |
{
"success": false,
"error_code": "rate_limit_exceeded",
"message": "Hourly rate limit of 500 requests exceeded. Retry after 532 seconds, or upgrade your Tier (see Profile).",
"request_id": "9f8a7b6c5d4e3f21",
"retry_after": 532,
"limit": 500
}
Implementation Best Practices
- Keep API keys server-side. Do not expose
sk_keys in browser JavaScript, mobile apps, public repositories, screenshots, or client logs. - Store
request_idwith failed calls. It is the safest value to share with support. - Respect
Retry-Afteron429responses and use backoff instead of retry loops. - Submit up to 50 hashes per request instead of one request per hash when possible.
- Use the schema endpoint in tests to validate your request format before sending production traffic.
- Never submit hashes unless you own the system or have written authorization to test it.
MCP Server
OHC exposes a Model Context Protocol server over Streamable HTTP (spec 2025-03-26). It lets any MCP-compatible AI agent — Claude, ChatGPT, Cursor, and others — call your account directly using natural language. The same sk_ key authenticates both the REST API and the MCP server.
https://mcp.onlinehashcrack.com/sk_YOUR_API_KEYAvailable tools
| Tool | Type | Description |
|---|---|---|
ohc_submit_hashes |
Write | Submit 1–50 hashes for GPU-accelerated cracking. Parameters: algo_mode (Hashcat integer mode), hashes (array of strings), user_confirmed: true. The LLM prompts you for explicit consent before calling this tool. |
ohc_list_tasks |
Read-only | Retrieve all tasks for the account with status, algorithm, last attack, and a structured analysis with prioritized recommendations. |
Client setup
Three ways to connect Claude to your OHC account — all use the same URL.
Option 1 — Claude Code (recommended for developers)
Register the server once. Claude Code persists it across sessions.
claude mcp add onlinehashcrack \
--transport http \
"https://mcp.onlinehashcrack.com/sk_YOUR_API_KEY"
Confirm the server is registered:
claude mcp list
Then just open a session and ask:
claude
# → "List my OHC tasks" or "Submit this hash ..."
Option 2 — Claude Desktop
Open claude_desktop_config.json and add the entry under mcpServers. Create the file if it does not exist.
| OS | Path |
|---|---|
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
{
"mcpServers": {
"onlinehashcrack": {
"url": "https://mcp.onlinehashcrack.com/sk_YOUR_API_KEY"
}
}
}
Restart Claude Desktop. The OHC tools will appear in the tool picker.
Option 3 — Claude.ai (web)
Go to Settings → Integrations, click Add integration, and paste the MCP URL:
https://mcp.onlinehashcrack.com/sk_YOUR_API_KEY
No restart needed — tools are available immediately in the next conversation.
ChatGPT Desktop and the OpenAI Agents SDK both support MCP remote servers.
Option 1 — ChatGPT Desktop
Open Settings → Connections and add the OHC MCP server by pasting the URL directly into the remote server field:
https://mcp.onlinehashcrack.com/sk_YOUR_API_KEY
Option 2 — OpenAI Agents SDK
Use the OHC MCP server inside an agent workflow. Install with pip install openai-agents.
import asyncio
from agents import Agent, Runner
from agents.mcp import MCPServerStreamableHttp
async def main():
params = {"url": "https://mcp.onlinehashcrack.com/sk_YOUR_API_KEY"}
async with MCPServerStreamableHttp(name="OnlineHashCrack", params=params) as ohc:
agent = Agent(
name="hash-auditor",
instructions=(
"You are a security audit assistant with access to OnlineHashCrack. "
"Only submit hashes the user confirms they own or are authorized to test."
),
mcp_servers=[ohc],
)
result = await Runner.run(agent, "List my cracking tasks and summarize the results.")
print(result.final_output)
asyncio.run(main())
See the OpenAI Agents SDK docs for streaming, tool filtering, and multi-server setups.
ohc_submit_hashes. The tool requires user_confirmed: true, enforced server-side. The LLM will ask for your explicit confirmation before dispatching the call — this gate cannot be bypassed programmatically.