🔌 Developer API

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 auth No tracking CORS * GET or POST JSON 120 req/min CC 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.

StatusMeaningExample
200OKthe documented object
400Your input could not be processed: missing parameter, bad CIDR, malformed token, unknown algo, invalid UTF-8…{"error":"Prefix must be 0–32."}
404Unknown endpoint path{"error":"Unknown endpoint. See …/ for the endpoint list."}
405Method other than GET / POST / HEAD / OPTIONS{"error":"method_not_allowed"}
429Rate limit hit — back off for the number of seconds in the Retry-After header{"error":"Rate limit exceeded. …"}
500Our 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.
ParamValueRequired
inputText containing indicators (up to 8 KB). e.g. http://evil.example.com/xyes
modeDirection. One of: defang, refang. e.g. defangno
curl 'https://cyberramen.com/api/tools/defang?input=http://evil.example.com/login'
Example response (live) "hxxp[://]evil[.]example[.]com/login"
GET /api/tools/refang
Reverse a defanged indicator. Understands [.] (.) {.} [dot] (dot) [at] [://] hxxp h**p.
ParamValueRequired
inputDefanged text (up to 8 KB). e.g. hxxp://evil[.]example[.]com/xyes
curl 'https://cyberramen.com/api/tools/refang?input=hxxp://evil[.]example[.]com/login'
Example response (live) "http://evil.example.com/login"
GET /api/tools/hash-id
Guess a hash type from its length and charset (hex digests) or its prefix (bcrypt, argon2, crypt(3)). A hint, not a proof.
ParamValueRequired
inputThe hash (up to 256 chars). e.g. 5d41402abc4b2a76b9719d911017c592yes
curl 'https://cyberramen.com/api/tools/hash-id?input=5d41402abc4b2a76b9719d911017c592'
Example response (live) { "input": "5d41402abc4b2a76b9719d911017c592", "length": 32, "candidates": [ "MD5", "NTLM", "MD4", "LM" ], "note": "Length/charset-based guess; not definitive." }
GET /api/tools/cidr
Subnet math for IPv4 and IPv6: network, mask, first/last address, counts. IPv6 counts are strings (they exceed 64-bit integers).
ParamValueRequired
inputCIDR notation (up to 64 chars). e.g. 10.0.0.0/24yes
curl 'https://cyberramen.com/api/tools/cidr?input=192.168.1.77/27'
Example response (live) { "input": "192.168.1.77/27", "network": "192.168.1.64", "prefix": 27, "netmask": "255.255.255.224", "wildcard": "0.0.0.31", "broadcast": "192.168.1.95", "first_host": "192.168.1.65", "last_host": "192.168.1.94", "num_addresses": 32, "num_usable": 30, "family": "IPv4" }
GET /api/tools/timestamp
Normalise a timestamp. Epoch seconds, milliseconds or microseconds are detected by magnitude; anything else is parsed as a date string (ISO 8601 recommended).
ParamValueRequired
inputEpoch or date string (up to 64 chars). e.g. 1700000000yes
curl 'https://cyberramen.com/api/tools/timestamp?input=1700000000'
Example response (live) { "input": "1700000000", "detected_unit": "seconds", "epoch_seconds": 1700000000, "iso8601_utc": "2023-11-14T22:13:20Z", "rfc2822": "Tue, 14 Nov 2023 22:13:20 +0000", "date_utc": "2023-11-14 22:13:20 UTC", "weekday": "Tuesday" }
GET / POST /api/tools/ioc-extract
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.
ParamValueRequired
inputFree text (up to 200 KB). e.g. see 8.8.8.8 and evil[.]comyes
curl -X POST 'https://cyberramen.com/api/tools/ioc-extract' -H 'Content-Type: application/json' \ -d '{"input": "Beacon to hxxp://cdn.evil[.]com/a.php then 203.0.113.9 and c2.badhost[.]org; dropper setup.exe, contact ops[at]evil[.]com, sha256 2cf24d…"}'
Example response (live) { "counts": { "urls": 1, "ipv4": 1, "domains": 1, "emails": 1, "md5": 0, "sha1": 0, "sha256": 1 }, "iocs": { "urls": [ "http://cdn.evil.com/a.php" ], "ipv4": [ "203.0.113.9" ], "domains": [ "c2.badhost.org" ], "emails": [ "ops@evil.com" ], "md5": [], "sha1": [], "sha256": [ "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824" ] }, "warnings": [], "note": "Input is refanged before extraction. Heuristic regex; verify before use." }
GET /api/tools/cvss
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.
ParamValueRequired
vectorFull 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:Hyes
curl 'https://cyberramen.com/api/tools/cvss?vector=CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:P'
Example response (live) { "vector": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:P", "version": "4.0", "score": 8.9, "severity": "High", "score_type": "CVSS-BT", "macro_vector": "000210", "metrics": { "AV": "N", "AC": "L", "AT": "N", "PR": "N", "UI": "N", "VC": "H", "VI": "H", "VA": "H", "SC": "N", "SI": "N", "SA": "N", "E": "P" }, "note": "FIRST CVSS v4.0 reference algorithm; same tables and rounding as the CVSS v4.0 Calculator tool." }
GET / POST /api/tools/hash
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.
ParamValueRequired
inputText to hash (up to 200 KB). e.g. helloyes
algoOne algorithm; omit for all. One of: md5, sha1, sha256, sha384, sha512, sha3-256, sha3-512, crc32b. e.g. sha256no
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.
ParamValueRequired
inputText or base64 (up to 200 KB). e.g. aGVsbG8gd29ybGQyes
modeDirection. One of: encode, decode. e.g. decodeno
urlsafeEmit the URL-safe alphabet without padding (encode only). e.g. 1no
curl 'https://cyberramen.com/api/tools/base64?input=Sm9zw6kg5pel5pysIPCfjZw&mode=decode'
Example response (live) { "mode": "decode", "variant": "standard", "output_bytes": 17, "is_text": true, "result": "José 日本 🍜" }
GET /api/tools/url-parse
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).
ParamValueRequired
inputURL (defanged accepted; bare host assumed http) (up to 4 KB). e.g. hxxps://login.example[.]com:8443/a.php?u=1yes
curl 'https://cyberramen.com/api/tools/url-parse?input=hxxps://login.paypal.com.evil-site[.]com:8443/a/update.exe?u=1%26t=2'
Example response (live) { "input": "hxxps://login.paypal.com.evil-site[.]com:8443/a/update.exe?u=1&t=2", "normalized": "https://login.paypal.com.evil-site.com:8443/a/update.exe?u=1&t=2", "scheme": "https", "host": "login.paypal.com.evil-site.com", "host_type": "domain", "tld": "com", "registrable_domain": "evil-site.com", "subdomain": "login.paypal.com", "port": 8443, "port_is_default": false, "user": null, "has_password": false, "path": "/a/update.exe", "path_segments": [ "a", "update.exe" ], "file_extension": "exe", "query": "u=1&t=2", "query_params": [ { "name": "u", "value": "1" }, { "name": "t", "value": "2" } ], "fragment": null, "defanged": "hxxps[://]login[.]paypal[.]com[.]evil-site[.]com:8443/a/update[.]exe?u=1&t=2", "flags": [ "non_standard_port", "deep_subdomain", "executable_or_archive_path" ] }
GET / POST /api/tools/jwt-decode
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.
ParamValueRequired
inputCompact JWS token (Bearer prefix tolerated) (up to 16 KB). e.g. eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ4In0.sigyes
curl 'https://cyberramen.com/api/tools/jwt-decode?input=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'
Example response (live) { "header": { "alg": "HS256", "typ": "JWT" }, "payload": { "sub": "1234567890", "name": "John Doe", "iat": 1516239022 }, "signature_b64url": "SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c", "alg": "HS256", "typ": "JWT", "kid": null, "times": { "iat": { "epoch": 1516239022, "iso8601_utc": "2018-01-18T01:30:22Z" } }, "status": "no_expiry", "checked_at": "2027-01-15T08:00:00Z", "warnings": [ "No \"exp\" claim — token never expires." ], "note": "Decoded only — the signature was NOT verified." }
POST /api/tools/cert-decode
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.
ParamValueRequired
inputPEM or base64 DER (up to 64 KB). e.g. -----BEGIN CERTIFICATE-----…yes
curl -X POST 'https://cyberramen.com/api/tools/cert-decode' -H 'Content-Type: application/json' \ -d "$(jq -Rs '{input: .}' < cert.pem)"
Example response (live) { "subject": { "CN": "fixture.cyberramen.test", "O": "CyberRamen Tests", "C": "LU" }, "issuer": { "CN": "fixture.cyberramen.test", "O": "CyberRamen Tests", "C": "LU" }, "common_name": "fixture.cyberramen.test", "serial_hex": "210E4B9E93C9FE704ACF2BF6127BE9D85ED36C3F", "version": 3, "signature_algorithm": "ecdsa-with-SHA256", "not_before": "2026-09-16T06:37:32Z", "not_after": "2036-09-13T06:37:32Z", "status": "valid", "days_remaining": 3528, "lifetime_days": 3650, "self_signed": true, "validation": "OV", "is_ca": true, "san": [ { "type": "dns", "value": "fixture.cyberramen.test" }, { "type": "dns", "value": "www.fixture.cyberramen.test" }, { "type": "ip address", "value": "203.0.113.7" } ], "key": { "type": "EC", "bits": 256, "curve": "prime256v1" }, "key_usage": [ "Digital Signature" ], … }
GET / POST /api/tools/stix
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.
ParamValueRequired
inputIOCs separated by newlines, commas or spaces (up to 200 KB). e.g. evil[.]com,8.8.8.8,CVE-2021-44228yes
tlpTLP 2.0 marking. One of: clear, green, amber, amber+strict, red. e.g. amberno
labelsComma list of indicator_types (JSON array accepted on POST). e.g. malicious-activityno
confidence0–100 (default 50). e.g. 80no
valid_daysSets valid_until. e.g. 30no
producerAdds an identity object and created_by_ref. e.g. Blue Teamno
curl 'https://cyberramen.com/api/tools/stix?input=evil[.]com,203.0.113.9,CVE-2021-44228&tlp=amber&valid_days=30'
Example response (live) { "bundle": { "type": "bundle", "id": "bundle--2f7c8c1e-5b7a-4a1e-9f3d-0c1b2a3d4e5f", "objects": [ { "type": "marking-definition", "spec_version": "2.1", "id": "marking-definition--55d920b0-5e8b-4f79-9ee9-91f868d9b421", "created": "2022-10-01T00:00:00.000Z", "definition_type": "TLP", "name": "TLP:AMBER", "extensions": { "extension-definition--60a3c5c5-0d10-413e-aab3-9e08dde9e88d": { "extension_type": "property-extension", "tlp_2_0": "amber" } } }, { "type": "indicator", "id": "indicator--631b163b-0aeb-53a9-b7a2-630ba3d5dee7", "spec_version": "2.1", "created": "2027-01-15T08:00:00.000Z", "modified": "2027-01-15T08:00:00.000Z", "object_marking_refs": [ "marking-definition--55d920b0-5e8b-4f79-9ee9-91f868d9b421" ], "name": "evil.com", "pattern": "[domain-name:value = 'evil.com']", "pattern_type": "stix", "pattern_version": "2.1", "valid_from": "2027-01-15T08:00:00.000Z", "indicator_types": [ "malicious-activity" ], "confidence": 50, "valid_until": "2027-02-14T08:00:00.000Z" }, { "type": "indicator", "id": "indicator--4c4f8b1a-1ccd-56fe-93d5-ef62134b1bca", "spec_version": "2.1", "created": "2027-01-15T08:00:00.000Z", "modified": "2027-01-15T08:00:00.000Z", "object_marking_refs": [ "marking-definition--55d920b0-5e8b-4f79-9ee9-91f868d9b421" ], "name": "203.0.113.9", "pattern": "[ipv4-addr:value = '203.0.113.9']", "pattern_type": "stix", "pattern_version": "2.1", "valid_from": "2027-01-15T08:00:00.000Z", "indicator_types": [ "malicious-activity" ], "confidence": 50, "valid_until": "2027-02-14T08:00:00.000Z" }, { … }
GET / POST /api/tools/spf
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.
ParamValueRequired
inputOne or more TXT strings, newline-separated (up to 8 KB). e.g. v=spf1 include:_spf.google.com ~allyes
curl 'https://cyberramen.com/api/tools/spf?input=v%3Dspf1%20include%3A_spf.google.com%20~all'
Example response (live) { "found": true, "record": "v=spf1 include:_spf.google.com ~all", "valid": true, "issues": [], "recommendations": [], "lookups": 1, "all_qualifier": "~", "records_count": 1 }
GET / POST /api/tools/dmarc
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).
ParamValueRequired
inputOne or more TXT strings, newline-separated (up to 8 KB). e.g. v=DMARC1; p=reject; rua=mailto:d@example.comyes
curl 'https://cyberramen.com/api/tools/dmarc?input=v%3DDMARC1%3B%20p%3Dreject%3B%20rua%3Dmailto%3Admarc%40example.com'
Example response (live) { "found": true, "record": "v=DMARC1; p=reject; rua=mailto:dmarc@example.com", "policy": "reject", "subdomain_policy": "reject", "pct": 100, "valid": true, "issues": [], "recommendations": [ "Consider an explicit sp= for subdomains" ], "tags": { "v": "DMARC1", "p": "reject", "rua": "mailto:dmarc@example.com" }, "records_count": 1 }

5. Code examples

The same call — extract IOCs from a text blob via POST — in four environments. No SDK, no dependencies beyond the standard library.

bash + curl + jq

extract_iocs() { curl -sS -X POST 'https://cyberramen.com/api/tools/ioc-extract' \ -H 'Content-Type: application/json' \ -d "$(jq -Rn --arg t "$1" '{input: $t}')" } extract_iocs "$(cat report.txt)" | jq -r '.iocs.domains[], .iocs.ipv4[]'

Python 3 (standard library only)

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

  1. POST the raw report to /ioc-extract.
  2. Join .iocs.urls, .iocs.domains, .iocs.ipv4, .iocs.sha256 with newlines.
  3. POST that list to /stix with tlp, labels, valid_days and your producer name.
  4. Import .bundle into MISP / OpenCTI / your TAXII server. Because indicator ids are stable, re-running the pipeline updates rather than duplicates.
curl -sS -X POST https://cyberramen.com/api/tools/ioc-extract -H 'Content-Type: application/json' \ -d "$(jq -Rs '{input: .}' < report.txt)" \ | jq -r '[.iocs.urls[], .iocs.domains[], .iocs.ipv4[], .iocs.sha256[]] | join("\n")' \ | jq -Rs '{input: ., tlp: "amber", labels: "malicious-activity", valid_days: 30, producer: "Blue Team"}' \ | curl -sS -X POST https://cyberramen.com/api/tools/stix -H 'Content-Type: application/json' -d @- \ | jq .bundle > indicators.stix.json

Safe-to-share ticket text

Before pasting an analyst note into Slack, Jira or an email, defang it wholesale so nobody clicks a live link by accident:

pbpaste | jq -Rs '{input: .}' | curl -sS -X POST https://cyberramen.com/api/tools/defang \ -H 'Content-Type: application/json' -d @- | jq -r .result | pbcopy # macOS; use xclip / Get-Clipboard elsewhere

Certificate expiry gate in CI

Fail a pipeline when a certificate your service ships has fewer than 30 days left:

days=$(curl -sS -X POST https://cyberramen.com/api/tools/cert-decode -H 'Content-Type: application/json' \ -d "$(jq -Rs '{input: .}' < deploy/tls/server.pem)" | jq .days_remaining) [ "$days" -ge 30 ] || { echo "certificate expires in $days days"; exit 1; }

Batch CVSS scoring from a CSV

# 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.

Same logic as the tools. Each endpoint mirrors a browser tool (IOC Defanger, CVSS Calculator, CIDR Calculator, JWT Decoder, Certificate Decoder, STIX Formatter…). Both implementations are checked against one shared set of test vectors, so a result you get here matches what the tool shows.

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.