Authentication

Authenticate your API requests with an API key.

All API requests are made to https://mlab.sh/api/v1/ and must include your API key in the Authorization header.

header format
Authorization: token mlab_your_api_key_here

Generate an API Key

  1. Log in to mlab.sh
  2. Go to Account > Settings > API Keys
  3. Click Create API Key, give it a descriptive note
  4. Copy the key — it is only shown once
Keep your API key secret. Do not commit it to version control or share it publicly. If compromised, delete it immediately and create a new one.

Quick Start

Make your first API call in seconds.

Test your API key by calling the root endpoint:

terminal
curl -H "Authorization: token YOUR_API_KEY" \
     https://mlab.sh/api/v1/

If your key is valid, you will get a greeting response:

response
{
  "message": "Hello, anonymous user of YourOrganization!"
}

Base URL

EnvironmentBase URL
Productionhttps://mlab.sh/api/v1

All endpoints described in this documentation are relative to this base URL.

Domain Scan

Launch, monitor, and retrieve results from an automated domain security scan.

Launch a scan

MethodPOST
Endpoint/scan/domain
AuthAPI Key required

Request Body

FieldTypeRequiredDescription
domainstringYesThe domain to scan (e.g. example.com)
example request
curl -X POST \
     -H "Authorization: token YOUR_API_KEY" \
     -H "Content-Type: application/json" \
     -d '{"domain": "example.com"}' \
     https://mlab.sh/api/v1/scan/domain

Response

200 OK
{
  "status": "success",
  "message": "Domain scan has been started."
}
400 Bad Request
{
  "status": "error",
  "message": "Provided domain is invalid."
}

// or

{
  "status": "error",
  "message": "Scan limit reached. Please try again later."
}

Check status

MethodGET
Endpoint/scan/domain/status?domain=example.com
AuthAPI Key required

Query Parameters

ParamTypeRequiredDescription
domainstringYesThe domain to check
example request
curl -H "Authorization: token YOUR_API_KEY" \
     "https://mlab.sh/api/v1/scan/domain/status?domain=example.com"

Response

The status field indicates the scan progress:

StatusDescription
pendingScan is queued and has not started yet
scanningScan is actively running
successScan completed successfully
200 OK
{
  "status": "pending",
  "message": "Domain scan is still pending."
}

// or

{
  "status": "scanning",
  "message": "Domain scan is still in progress."
}

// or

{
  "status": "success",
  "message": "Domain scan is in done."
}
Tip: poll this endpoint every few seconds after launching a scan to track its progress. Once the status is success, retrieve the full results with /scan/domain/results.

Get results

MethodGET
Endpoint/scan/domain/results?domain=example.com
AuthAPI Key required

Query Parameters

ParamTypeRequiredDescription
domainstringYesThe domain to get results for
example request
curl -H "Authorization: token YOUR_API_KEY" \
     "https://mlab.sh/api/v1/scan/domain/results?domain=example.com"

Response

200 OK
{
  "status": "completed",
  "domain": "example.com",
  "scan_date": "2026-03-23 10:30:00 UTC",
  "results": {
    "subdomains": ["www.example.com", "mail.example.com"],
    "subdomains_suspicious": [
      { "keyword": "admin", "subdomain": "admin.example.com" }
    ],
    "dns": {
      "resolve": [
        {
          "domain": "example.com",
          "a": ["93.184.216.34"],
          "aaaa": ["2606:2800:220:1:..."],
          "cname": null
        }
      ],
      "txt": {
        "raw": ["v=spf1 include:..."],
        "spf": "v=spf1 include:_spf.google.com ~all",
        "dmarc": "v=DMARC1; p=reject; ...",
        "dkim": []
      }
    },
    "ssl": [
      {
        "domain": "example.com",
        "issuer_name": "C=US, O=DigiCert Inc, ...",
        "common_name": "www.example.org",
        "not_before": "2024-01-30",
        "not_after": "2025-03-01"
      }
    ],
    "files": {
      "security_txt": "Contact: [email protected]\n...",
      "robots_txt": "User-agent: *\nDisallow: /admin"
    }
  }
}

Response Fields

FieldTypeDescription
statusstringcompleted or in_progress
results.subdomainsarrayAll discovered subdomains
results.subdomains_suspiciousarraySubdomains flagged as suspicious (keyword + subdomain)
results.dns.resolvearrayDNS A, AAAA and CNAME records per subdomain
results.dns.txtobjectTXT records: raw, SPF, DMARC, DKIM
results.sslarraySSL certificates found (issuer, dates, names)
results.files.security_txtstringContents of security.txt (empty if not found)
results.files.robots_txtstringContents of robots.txt (empty if not found)
If status is in_progress, some fields may be empty. Poll until completed for full results.

IP Lookup

Retrieve threat intelligence and geolocation data for an IP address.

MethodGET
Endpoint/scan/ip?ip=8.8.8.8
AuthAPI Key or Session

Query Parameters

ParamTypeRequiredDescription
ipstringYesIPv4 or IPv6 address to look up
example request
curl -H "Authorization: token YOUR_API_KEY" \
     "https://mlab.sh/api/v1/scan/ip?ip=8.8.8.8"

Response

200 OK
{
  "ip": "8.8.8.8",
  "reserved": false,
  "isp": "Google LLC",
  "org": "Google Public DNS",
  "as": "AS15169 Google LLC",
  "city": "Mountain View",
  "region": "California",
  "country": "United States",
  "country_code": "US",
  "continent": "North America",
  "continent_code": "NA",
  "timezone": "America/Los_Angeles",
  "zip": "94035",
  "lat": 37.386,
  "lon": -122.0838,
  "currency": "USD",
  "status": "success"
}

Response Fields

FieldTypeDescription
ipstringThe queried IP address
reservedbooleantrue if the IP is a private/reserved range
ispstringInternet Service Provider
orgstringOrganization owning the IP
asstringAutonomous System number and name
citystringCity geolocation
regionstringRegion / state
countrystringCountry name
country_codestringISO 3166 country code
continentstringContinent name
timezonestringIANA timezone identifier
lat / lonnumberLatitude and longitude
currencystringLocal currency code

Reserved IP Response

If the IP belongs to a private or reserved range, the response format differs:

reserved IP
{
  "ip": "192.168.1.1",
  "reserved": true,
  "type": "IPv4",
  "range": "Private network (Class C)",
  "rfc": "RFC 1918"
}

Check IP Lookup Quota

check remaining quota
curl -H "Authorization: token YOUR_API_KEY" \
     https://mlab.sh/api/v1/limit/ip
200 OK
{
  "scan_type": "ip",
  "remaining": 48,
  "total": 50
}
Results are cached for 30 days. Subsequent lookups for the same IP within that period return cached data without consuming quota.

File Scan

Upload and analyze files for threats and metadata.

Upload a file

MethodPOST
Endpoint/upload/file
AuthSession cookie or API Key
Content-Typemultipart/form-data
FieldTypeRequiredDescription
filebinaryYesThe file to analyze (max 10 MB)

Supported file types: PNG, JPG, PDF, DOCX, XLSX, PPTX, EXE, DLL, SYS

upload a file
curl -X POST \
     -H "Authorization: token YOUR_API_KEY" \
     -F "[email protected]" \
     https://mlab.sh/upload/file

Upload Response

200 OK
{
  "success": true,
  "filename": "uuid.ext",
  "sha256": "a1b2c3d4e5f6...",
  "job_launched": true
}

Upload Errors

error response
{
  "success": false,
  "error": { "code": 429, "message": "rate_limited" }
}
StatusMessageDescription
400invalid_content_typeNot multipart/form-data
400no_fileNo file in form
400Unsupported or forbidden...MIME type not supported
413file_too_largeFile exceeds 10 MB
429rate_limitedQuota exceeded
500storage_errorInternal storage error

Get scan results

After uploading, use the sha256 from the upload response to retrieve the analysis results.

MethodGET
Endpoint/scan/file/results?sha256=...
AuthAPI Key or Session
get file scan results
curl -H "Authorization: token YOUR_API_KEY" \
     "https://mlab.sh/api/v1/scan/file/results?sha256=a1b2c3d4e5f6..."

Results Response

200 OK — completed
{
  "status": "completed",
  "file": {
    "sha256": "a1b2c3d4e5f6...",
    "md5": "d4e5f6a1b2c3...",
    "ssdeep": "384:H8a9fJ2k...",
    "filename": "malware.exe",
    "size": 1234567,
    "mime_type": "application/x-dosexec",
    "created_at": "2026-03-30T12:00:00Z"
  },
  "jobs_total": 3,
  "jobs_completed": 3,
  "analysis": [
    {
      "job_name": "file",
      "end_date": "2026-03-30T12:01:00Z",
      "data": "decoded analysis content"
    },
    {
      "job_name": "strings",
      "end_date": "2026-03-30T12:01:05Z",
      "data": "extracted strings content"
    }
  ]
}

Response Fields

FieldTypeDescription
statusstringpending, in_progress, or completed
fileobjectFile metadata (hashes, filename, size, mime type)
jobs_totalnumberTotal analysis jobs launched
jobs_completednumberJobs that have finished
analysis[]arrayResults per job (decoded from base64)
analysis[].job_namestringName of the analysis tool (e.g. file, strings)
analysis[].datastring/objectDecoded analysis output (JSON object or plain text)
If status is in_progress, poll this endpoint every few seconds until completed. The analysis array will grow as jobs finish.

Check file scan quota

check remaining quota
curl -H "Authorization: token YOUR_API_KEY" \
     https://mlab.sh/api/v1/limit/file
200 OK
{
  "scan_type": "file",
  "remaining": 19,
  "total": 20
}

SSL Info

Retrieve SSL certificate information for a domain.

MethodGET
Endpoint/domain/ssl?domain=example.com
AuthAPI Key required

Query Parameters

ParamTypeRequiredDescription
domainstringYesThe domain to check SSL for
example request
curl -H "Authorization: token YOUR_API_KEY" \
     "https://mlab.sh/api/v1/domain/ssl?domain=example.com"

Returns SSL certificate details including issuer, validity dates, and certificate chain information.

Rate Limits

Understand and monitor your API usage limits.

API rate limits depend on your organization's subscription plan. You can check your remaining quota at any time.

MethodGET
Endpoint/limit/domain  |  /limit/ip  |  /limit/file  |  /limit/crypto
AuthAPI Key or Session
check domain scan limit
curl -H "Authorization: token YOUR_API_KEY" \
     https://mlab.sh/api/v1/limit/domain

Response

200 OK
{
  "scan_type": "domain",
  "remaining": 98,
  "total": 100
}

Response Fields

FieldTypeDescription
scan_typestringThe scan type checked (domain, ip, file, or crypto)
remainingnumberScans remaining for the current day
totalnumberTotal daily limit for your plan

Scan Limits by Plan

PlanDomain scans/dayFile scans/dayIP lookups/dayCrypto lookups/day
anonymous2153
free531010
pro25205030
team10080200100
enterpriseUnlimitedUnlimitedUnlimitedUnlimited

Limits are per organization, shared across all members. Resets daily.

When a scan limit is reached, the API returns a 400 error. Upgrade your plan on the pricing page for higher limits.

Errors

HTTP status codes and error handling.

The API uses standard HTTP status codes to indicate success or failure.

CodeMeaningDescription
200OKRequest succeeded
400Bad RequestMissing or invalid parameters
401UnauthorizedInvalid or missing API key
404Not FoundEndpoint does not exist

Error Response Format

Error responses are returned as JSON with a descriptive message:

error response
{
  "status": "error",
  "message": "Description of what went wrong."
}

Common Errors

ErrorCauseFix
Provided domain is invalid. Domain format is wrong Use a valid domain like example.com
Scan limit reached. Rate limit exceeded Wait or upgrade your plan
Please provide all required information. Missing required fields in request body Check the endpoint documentation for required fields
Need help?

[email protected]

Help Center

mlab.sh/helpcenter

Crypto Address Lookup

Retrieve threat intelligence for a blockchain address.

MethodGET
Endpoint/scan/crypto?address=0x...&chain=eth
AuthAPI Key or Session

Query Parameters

ParamTypeRequiredDescription
addressstringYesThe blockchain address to look up
chainstringNoChain ID (auto-detected for EVM/BTC/TRX addresses). See supported chains below.
example request
curl -H "Authorization: token YOUR_API_KEY" \
     "https://mlab.sh/api/v1/scan/crypto?address=0x722122df12d4e14e13ac3b6895a86e84145b6967&chain=eth"

Response

200 OK
{
  "address": "0x722122df12d4e14e13ac3b6895a86e84145b6967",
  "chain": "ETH",
  "type": "contract",
  "categories": ["contract", "mixer"],
  "labels": [
    { "name": "Tornado Cash: Proxy", "source": "community" }
  ],
  "sanctions": { "is_sanctioned": false },
  "risk_score": 80,
  "risk_level": "critical",
  "checked_at": "2026-04-16T09:22:49.482Z"
}

Response Fields

FieldTypeDescription
addressstringThe queried address
chainstringChain ID
typestringeoa, contract, or unknown
categoriesarrayAddress categories (e.g. exchange, defi, mixer, scam, sanctioned)
labelsarrayLabels with name and source
sanctionsobjectSanctions status (is_sanctioned, optional authority and list_date)
risk_scorenumber0–100 risk score
risk_levelstringlow, medium, high, or critical
checked_atstringISO 8601 timestamp

Supported Chains

ChainIDAuto-detected
EthereumETHYes (0x...)
BNB ChainBSCUse chain=BSC
PolygonPOLYGONUse chain=POLYGON
ArbitrumARBITRUMUse chain=ARBITRUM
OptimismOPTIMISMUse chain=OPTIMISM
BaseBASEUse chain=BASE
AvalancheAVAXUse chain=AVAX
BitcoinBTCYes (1.../3.../bc1...)
TronTRXYes (T...)
SolanaSOLUse chain=SOL
TONTONUse chain=TON
DogecoinDOGEUse chain=DOGE
EVM addresses (0x...) default to Ethereum. To query the same address on BSC, Polygon, etc., pass the chain parameter explicitly.

Check Crypto Lookup Quota

check remaining quota
curl -H "Authorization: token YOUR_API_KEY" \
     https://mlab.sh/api/v1/limit/crypto
200 OK
{
  "scan_type": "crypto",
  "remaining": 28,
  "total": 30
}