Free, no-signup, curl-able JSON endpoints for the everyday pure-logic transforms — so you can wire CyberRamen into playbooks, Slack bots, SOAR actions and CI pipelines without opening a browser. This page is the complete guide: how to call it, what comes back, and a live example for every endpoint.
No authNo trackingCORS *GET or POST JSON120 req/minCC BY 4.0
1. Quick start
Three calls from any terminal. Nothing to install beyond curl; jq is optional but handy.
# Defang a URL before pasting it into a ticket
curl 'https://cyberramen.com/api/tools/defang?input=http://evil.example.com/login'
# → {"mode":"defang","input":"http://evil.example.com/login","result":"hxxp[://]evil[.]example[.]com/login"}# Score a CVSS vector
curl 'https://cyberramen.com/api/tools/cvss?vector=CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H' | jq .base_score
# → 9.8# Extract every IOC from a report (POST: no URL-encoding worries)
curl -X POST 'https://cyberramen.com/api/tools/ioc-extract' -H 'Content-Type: application/json' \
-d "$(jq -Rs '{input: .}' < incident-report.txt)" | jq .iocs
Machine-readable: discovery of every endpoint at GET https://cyberramen.com/api/tools/, and an OpenAPI 3.0 document at https://cyberramen.com/api/tools/openapi.json for client generators, Postman/Insomnia imports and API monitors. Both carry an ETag and answer 304 to If-None-Match.
2. Making requests
Base URLhttps://cyberramen.com/api/tools/<endpoint>. HTTPS only; HTTP is upgraded.
GETParameters in the query string, URL-encoded. Fine for one indicator, one vector, one token. Remember to encode & (%26) and # (%23) inside values.
POSTSame parameter names as keys of a JSON object: {"input": "…", "mode": "decode"} with Content-Type: application/json. Use it for anything long (reports, certificates) or containing characters you do not want to escape. A JSON list is accepted where a comma list is documented ("labels": ["a","b"]).
Defanged input is fineEvery endpoint that takes an indicator refangs it first, so you can feed it straight from a ticket: hxxp://evil[.]com works everywhere http://evil.com does.
EncodingUTF-8 in, UTF-8 out. Hashes and byte counts are computed on the UTF-8 bytes. Invalid UTF-8 in a parameter is rejected with a 400 rather than silently mangled.
From a browserCORS is open (Access-Control-Allow-Origin: *, no credentials), so a plain fetch() works from any web page or extension. OPTIONS and HEAD are supported.
3. Responses & errors
Always JSON (application/json; charset=utf-8), always a body. Success is 200 with the endpoint’s object. Anything else is an object with a single human-readable error string — test for the status code, then show .error.
Status
Meaning
Example
200
OK
the documented object
400
Your input could not be processed: missing parameter, bad CIDR, malformed token, unknown algo, invalid UTF-8…
{"error":"Prefix must be 0–32."}
404
Unknown endpoint path
{"error":"Unknown endpoint. See …/ for the endpoint list."}
405
Method other than GET / POST / HEAD / OPTIONS
{"error":"method_not_allowed"}
429
Rate limit hit — back off for the number of seconds in the Retry-After header
{"error":"Rate limit exceeded. …"}
500
Our fault. Please tell us.
{"error":"…"}
Determinism. The same input always produces the same output, except for fields that are explicitly about the current time: checked_at, certificate and JWT status/days_remaining, and STIX created/modified/valid_from. Responses carry Cache-Control: public, max-age=600; cache them freely.
Heuristics are labelled. Where an answer is a guess (hash-id candidates, ioc-extract, url-parse flags) the response says so in a note. Treat those as leads, not verdicts.
4. Endpoint reference
Each card shows the parameters, a ready-to-run curl line and the actual response — generated live by the same code that serves the API (clock pinned to 2027-01-15 for the time-dependent fields), so what you see is what you get. Long responses scroll inside their box; click the pill to collapse one.
GET /api/tools/defang
Defang URLs, domains, IPs and emails so they cannot be clicked. Idempotent — already-defanged input is left alone.
Param
Value
Required
input
Text containing indicators (up to 8 KB). e.g. http://evil.example.com/x
Normalise a timestamp. Epoch seconds, milliseconds or microseconds are detected by magnitude; anything else is parsed as a date string (ISO 8601 recommended).
Param
Value
Required
input
Epoch or date string (up to 64 chars). e.g. 1700000000
Pull URLs, IPv4s, domains, emails and MD5/SHA-1/SHA-256 hashes out of free text (a ticket, a report, an email body). Input is refanged first; hosts already inside a URL or email are not repeated as domains; file names such as setup.exe are ignored. Use POST for anything longer than a URL can carry.
Param
Value
Required
input
Free text (up to 200 KB). e.g. see 8.8.8.8 and evil[.]com
CVSS scoring for both current versions. v3.1 (or v3.0): base score, severity band and impact/exploitability subscores with the specification’s integer Roundup. v4.0: the FIRST reference algorithm (MacroVector lookup + severity-distance interpolation) for Base, Base+Threat, Base+Environmental or full BTE vectors; the tables are the same file the CVSS v4.0 Calculator uses and both engines are checked against each other on every test run.
Param
Value
Required
vector
Full vector starting with CVSS:3.1/, CVSS:3.0/ or CVSS:4.0/ (up to 256 chars). e.g. CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H
Digests of a text (its UTF-8 bytes). Omit algo to get them all. Do not send secrets or passwords to a remote API — use the browser Hash Generator, which never leaves your machine.
Param
Value
Required
input
Text to hash (up to 200 KB). e.g. hello
yes
algo
One algorithm; omit for all. One of: md5, sha1, sha256, sha384, sha512, sha3-256, sha3-512, crc32b. e.g. sha256
no
curl 'https://cyberramen.com/api/tools/hash?input=hello&algo=sha256'Example response (live){
"input_bytes": 5,
"encoding": "UTF-8 bytes of the input as received",
"hashes": {
"sha256": "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
}
}
GET / POST /api/tools/base64
Encode or decode Base64, UTF-8 safe. Decoding accepts standard and URL-safe alphabets, missing padding and embedded whitespace. If the decoded bytes are not text, you get result_hex instead of result.
Param
Value
Required
input
Text or base64 (up to 200 KB). e.g. aGVsbG8gd29ybGQ
yes
mode
Direction. One of: encode, decode. e.g. decode
no
urlsafe
Emit the URL-safe alphabet without padding (encode only). e.g. 1
Break a URL into parts (defanged input welcome): host type, registrable domain, port, path segments, query parameters with duplicates preserved, plus a defanged copy and triage flags (credentials in URL, IP host, punycode, non-standard port, deep subdomain, executable path).
Param
Value
Required
input
URL (defanged accepted; bare host assumed http) (up to 4 KB). e.g. hxxps://login.example[.]com:8443/a.php?u=1
Decode a JWT’s header and payload, render iat/nbf/exp as dates and tell you whether it is active, expired or not yet valid. The signature is not verified — this is for reading tokens, not trusting them. A leading Bearer is stripped.
Param
Value
Required
input
Compact JWS token (Bearer prefix tolerated) (up to 16 KB). e.g. eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ4In0.sig
Summarise an X.509 certificate: subject, issuer, SANs, validity window and days remaining, key type/size, usages, SHA-1/SHA-256 fingerprints. Accepts PEM or bare base64 DER; in a chain, the first certificate is decoded. Use POST — PEM does not fit a query string.
Param
Value
Required
input
PEM or base64 DER (up to 64 KB). e.g. -----BEGIN CERTIFICATE-----…
Turn a list of IOCs (newline, comma or space separated; defanged is fine) into a STIX 2.1 bundle of indicator objects (URL, IPv4/6, domain, email, MD5/SHA-1/SHA-256/SHA-512) and vulnerability objects (CVE ids). Indicator ids are UUIDv5 of the pattern, so the same IOC always yields the same id — re-running a playbook is idempotent for your TIP. Unrecognised tokens are listed, never silently dropped.
Param
Value
Required
input
IOCs separated by newlines, commas or spaces (up to 200 KB). e.g. evil[.]com,8.8.8.8,CVE-2021-44228
yes
tlp
TLP 2.0 marking. One of: clear, green, amber, amber+strict, red. e.g. amber
no
labels
Comma list of indicator_types (JSON array accepted on POST). e.g. malicious-activity
no
confidence
0–100 (default 50). e.g. 80
no
valid_days
Sets valid_until. e.g. 30
no
producer
Adds an identity object and created_by_ref. e.g. Blue Team
Analyse an SPF record from its text: qualifier of all, DNS-querying mechanism count (top level), deprecated ptr, unknown terms, and the classic misconfigurations — two records (RFC 7208 permanent error), bare all, terms after all. No DNS is performed; pass several records as separate lines to test the duplicate case.
Param
Value
Required
input
One or more TXT strings, newline-separated (up to 8 KB). e.g. v=spf1 include:_spf.google.com ~all
Analyse a DMARC record from its text: policy and subdomain policy, pct, reporting addresses, alignment tags, tag order, and duplicates (RFC 7489: several records are all discarded).
Param
Value
Required
input
One or more TXT strings, newline-separated (up to 8 KB). e.g. v=DMARC1; p=reject; rua=mailto:d@example.com
import json, urllib.request
def cyberramen(endpoint, **params):
req = urllib.request.Request(
f"https://cyberramen.com/api/tools/{endpoint}",
data=json.dumps(params).encode("utf-8"),
headers={"Content-Type": "application/json", "Accept": "application/json"},
method="POST",
)
try:
with urllib.request.urlopen(req, timeout=15) as r:
return json.load(r)
except urllib.error.HTTPError as e: # 4xx/5xx still carry a JSON body
raise RuntimeError(json.load(e).get("error", str(e))) from None
iocs = cyberramen("ioc-extract", input=open("report.txt", encoding="utf-8").read())
print(iocs["counts"])
bundle = cyberramen("stix", input="\n".join(iocs["iocs"]["domains"]), tlp="amber")
open("indicators.stix.json", "w").write(json.dumps(bundle["bundle"], indent=2))
JavaScript (browser or Node 18+)
async function cyberramen(endpoint, params) {
const r = await fetch(`https://cyberramen.com/api/tools/${endpoint}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(params)
});
const data = await r.json(); // errors are JSON too
if (!r.ok) throw new Error(data.error);
return data;
}
const { result } = await cyberramen('defang', { input: 'http://evil.example.com/x' });
const cvss = await cyberramen('cvss', { vector: 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H' });
console.log(result, cvss.base_score, cvss.severity);
PowerShell 7
$body = @{ input = (Get-Content .\report.txt -Raw) } | ConvertTo-Json
$r = Invoke-RestMethod -Method Post -Uri 'https://cyberramen.com/api/tools/ioc-extract' `
-ContentType 'application/json' -Body $body
$r.iocs.urls
# GET works the same way for short inputs:
(Invoke-RestMethod 'https://cyberramen.com/api/tools/hash-id?input=5d41402abc4b2a76b9719d911017c592').candidates
6. SOC recipes
Triage pipeline: report → IOCs → STIX bundle for your TIP
POST the raw report to /ioc-extract.
Join .iocs.urls, .iocs.domains, .iocs.ipv4, .iocs.sha256 with newlines.
POST that list to /stix with tlp, labels, valid_days and your producer name.
Import .bundle into MISP / OpenCTI / your TAXII server. Because indicator ids are stable, re-running the pipeline updates rather than duplicates.
# findings.csv: id,vector
tail -n +2 findings.csv | while IFS=, read -r id vector; do
printf '%s,%s\n' "$id" "$(curl -sS "https://cyberramen.com/api/tools/cvss?vector=$vector" | jq -r '"\(.base_score),\(.severity)"')"
sleep 0.5 # stay well under 120 req/min
done
Slack / Teams slash command
A /defang or /cvss command is a one-line proxy: forward the command text as input (or vector), return .result or .base_score. No key to store, no vendor account, and the endpoint never sees who asked.
7. Limits & fair use
Rate120 requests per minute per client. Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (epoch seconds); over the limit you get 429 with Retry-After. For bulk work, batch on your side (POST 200 KB of text to /ioc-extract once rather than one line per call).
SizeText blobs (ioc-extract, hash, base64, stix): 200 KB. Certificates: 64 KB. JWTs: 16 KB. URLs: 4 KB. Others: 8 KB. Oversize input is truncated at the cap, never rejected.
StabilityThis is v1 (see version in the discovery document). Fields are only ever added, never renamed or removed, within a version. New endpoints appear in the discovery list and on this page.
UptimeBest effort, no SLA. Build a timeout (10–15 s is plenty; most calls answer in milliseconds) and a graceful fallback into anything that matters.
8. Privacy & terms
Pure logic, no memory. Every endpoint is a deterministic function of its input: no external call is made on your behalf, nothing is stored, forwarded or logged beyond a short-lived, salted hash of the client address used for the rate limit. There are no accounts and no API keys, so there is nothing to leak. Still, the honest advice: do not send secrets, passwords or private keys to any remote API — the equivalent browser tools run entirely on your machine.
Licence. Provided as-is under CC BY 4.0 — attribution “CyberRamen.com”. No warranty; heuristic outputs should be verified before action. Questions, a bug, or a need for a higher limit? hello@cyberramen.com. Changes are announced in the changelog and its feed.
GRC datasets API — /api/v1/
Separate from the Tools API: read-only access to the governance/risk datasets (frameworks, control crosswalk, regulatory calendar, evidence lists). See /api/v1/ for its discovery document.