FOR DEVELOPERS · API

Fakeshop-Check API

Check online shops and websites for fraud signals programmatically – the same AI-powered analysis that drives our fake-shop check. Free to try, with an API key for production use.

POST/api/check
Quickstart

Your first API call

A single POST request to /api/check is all it takes. Without an API key, the free quota of 50 requests per day and IP address applies – more than enough for initial testing.

curl
curl -X POST "https://fakeshop.ai/api/check?v=2&lang=de" \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: fsk_live_ihr_schluessel" \
  -d '{"url": "https://beispiel-shop.de"}'
JavaScript (fetch)
const res = await fetch('https://fakeshop.ai/api/check?v=2&lang=de', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-Api-Key': 'fsk_live_ihr_schluessel',
  },
  body: JSON.stringify({ url: 'https://beispiel-shop.de' }),
});

const data = await res.json();
console.log(data.verdict, data.score);
Authentication

API key in the header

Authenticated requests send their key in the X-Api-Key header. Without a key, requests run anonymously through the IP-based free quota. You create your own key for free and independently in the developer portal – including free credit for testing. For questions about larger volumes, reach us at [email protected].

Header
X-Api-Key: fsk_live_ihr_schluessel
Limits & quotas

Test for free, fairly limited

Without an API key, 50 checks per day and IP address are available for free. With an API key, your plan's quota (prepaid credits, included in the free plan) applies instead. Once the quota is used up, the API responds with status 429, the error code quota_exceeded and a Retry-After header (seconds until the reset at midnight UTC).

Note

Systematic scraping or abuse of the free quotas is prohibited and may lead to the IP address being blocked. For higher limits or production integrations, please contact us at [email protected].

Endpoint

POST /api/check

Request parameters:

ParameterLocationTypeRequiredDescription
urlBodystringYesThe shop or website URL to check.
checkTypeBodyshop | websiteNoCheck profile. Default is shop. website allows a trustworthiness check when the URL is not an online shop.
forceBodybooleanNoForces a fresh check instead of a cached result (max. 24 h cache).
vQuery2YesResponse version. With v=2 the current, English enum values are returned – without this parameter, an outdated legacy format.
langQueryde | enNoLanguage of the text fields (summary, recommendation, reasons, …). Default is de.
Response

Response schema

Top-level fields of the response:

FieldTypeDescription
domainstringChecked domain without protocol.
scorenumber | nullTrust score 0–100. null for not_a_shop or unreachable.
verdictsafe | suspicious | danger | not_a_shop | unreachableOverall assessment.
checkTypeshop | websiteApplied check profile.
trustLevel{ level, label }level is 1–5 (machine-readable), label is a language-dependent display text.
confidenceBandhigh | medium | lowHow reliable the data basis for this assessment is.
summarystring | nullShort, language-dependent summary of the result.
recommendationstring | nullPlain-text recommendation for action.
factorsFactor[]Individual check signals: { id, label, status, impact, reasons[], display? }.
topSignalsFactor[]The most notable signals, same shape as factors.
cachedbooleantrue if the result comes from the 24 h cache.
checkedAtstring (ISO 8601)Timestamp of the (most recent) check.
faviconUrlstring | nullFavicon of the checked domain, if available.
previewImagestring | nullScreenshot URL of the homepage, if available.

Fields per entry in factors / topSignals:

FieldTypeDescription
idstringStable code of the check signal, e.g. impressum, domainAge, fakeshopLists.
labelstringLanguage-dependent display name.
statusok | warn | fail | unknownResult of this individual signal.
impactpositive | negative | neutralEffect on the overall score.
reasonsstring[]Language-dependent reasoning sentences.
displayobject (optional)Additional, harmless display values (e.g. domain age in months).

Example response:

200 OK
{
  "domain": "beispiel-shop.de",
  "score": 82,
  "verdict": "safe",
  "checkType": "shop",
  "cached": false,
  "checkedAt": "2026-07-02T10:15:32.000Z",
  "trustLevel": {
    "level": 4,
    "label": "sehr sicher"
  },
  "confidenceBand": "high",
  "summary": "Dieser Shop zeigt keine der bekannten Warnsignale für Fake-Shops.",
  "recommendation": "Der Kauf erscheint unbedenklich.",
  "factors": [
    {
      "id": "impressum",
      "label": "Impressum & Rechtstexte",
      "status": "ok",
      "impact": "positive",
      "reasons": [
        "Vollständiges Impressum mit Handelsregisternummer gefunden."
      ]
    },
    {
      "id": "domainAge",
      "label": "Domain-Alter",
      "status": "ok",
      "impact": "positive",
      "reasons": [
        "Domain ist seit 47 Monaten registriert."
      ],
      "display": {
        "ageMonths": 47
      }
    }
  ],
  "topSignals": [
    {
      "id": "impressum",
      "label": "Impressum & Rechtstexte",
      "status": "ok",
      "impact": "positive",
      "reasons": [
        "Vollständiges Impressum mit Handelsregisternummer gefunden."
      ]
    }
  ],
  "faviconUrl": "https://beispiel-shop.de/favicon.ico",
  "previewImage": null,
  "previewCapturedAt": null
}
Error handling

errorCode catalog

In addition to a human-readable error text, error responses always contain a stable errorCode field. Build your error handling against errorCode, not against the text – the text can differ depending on the lang parameter.

errorCodeHTTP statusMeaning
url_required400url is missing from the request body, or the value is not a string.
invalid_check_type400checkType contains an unknown value. Only shop and website are allowed.
quota_exceeded429The daily limit has been reached. The Retry-After header states the seconds until the reset (midnight UTC).
invalid_api_key401The provided X-Api-Key is invalid, unknown or has been blocked.
too_many_requests429Short-term burst limit exceeded, independent of the daily limit.
db_unavailable503The database is temporarily unavailable. Please try again later.
Get started

Ready for production?

Create an API key in the developer portal for free – including free credit for testing. For higher volumes or questions, you can reach us any time at [email protected].