WebmeticDocs
Get startedDetectEnrichPersonalizeIntegrateManagePartnersDevelopers

Errors

These are the status codes and error codes the Webmetic API returns, and how your code should react.

The API reports every error as JSON with a status code, a fixed error code, and a readable text.

Error response format

All public endpoints answer an error in the same format. One example is a request without an API key:

curl "https://hub.webmetic.de/company-sessions?domain=your-website.com"

The API answers with status 403:

{
  "detail": {
    "error": "API_KEY_MISSING",
    "message": "Send your API key in the Authorization header."
  }
}
  • detail.error: the error code in capitals. Check this field in your code.
  • detail.message: an English text for people, for example for your log. Don't check this text in code, because it can change.

This format doesn't apply to the Data Layer, which answers with a shorter body.

Some errors contain more fields in detail:

FieldComes withMeaning
errorsVALIDATION_ERRORList of the missing or invalid parameters and fields. Each entry gives the place in loc, the problem in msg, and the kind of error in type
featurePLAN_REQUIRED, FEATURE_DISABLEDThe feature your plan doesn't include or that is turned off
required_tierPLAN_REQUIREDThe plan the feature needs
current_tierPLAN_REQUIREDYour current plan
requiredINSUFFICIENT_CREDITSHow many credits the action needs
availableINSUFFICIENT_CREDITSHow many credits your account has
websiteWEBSITE_NOT_AUTHORIZED, SEGMENT_WEBSITEThe website in question
limitWEBHOOK_LIMIT_REACHEDThe maximum number of webhooks for your account

The API always reports problems with the key as 403, never as 401. For RATE_LIMITED, CONCURRENT_UPDATE, PROVIDER_UNAVAILABLE, PROVIDER_ERROR, and INTERNAL_ERROR, a new attempt can work because the error is temporary. For all other errors, change the request, the account, or the plan first.

This format applies to the API endpoints. For a mistyped path outside them, the API answers {"detail": "Not Found"}. So check in your code whether detail is an object.

Common errors

Any endpoint can return these errors. The key codes apply to the Visitor Intelligence key, which you also use for /contacts/* and /webhooks. Enrichment has its own codes.

StatusCodeMeaningWhat you do
403API_KEY_MISSINGThe request has no Authorization headerSend the key in the Authorization header
403API_KEY_INVALIDThe key has the wrong format, for example with Bearer in frontSend the key unchanged, without Bearer, spaces, or quotes
403API_KEY_NOT_FOUNDNo account has this key, for example after generating a new one or with the Enrichment keyCopy the current key under Menu > Integrations > API
404NOT_FOUNDThe path doesn't existCheck the address in the reference
405METHOD_NOT_ALLOWEDThe path doesn't accept this method, for example POST instead of GETUse the method from the reference
422VALIDATION_ERRORA parameter or field is missing or invalid, for example page below 1 or page_size above 10,000Fix the places listed in errors. For details, see Pagination
500INTERNAL_ERRORAn error at Webmetic, with no details in the answerTry again later. If the error stays, write to support

Visitor Intelligence

The eight visit endpoints, for example /company-sessions and /company, also return these errors.

StatusCodeMeaningWhat you do
400INVALID_DATEThe API can't read from_date or to_date, for example -3 weeks or 31.02.2026Use, for example, 2026-10-01 or -7 days. For details, see Date ranges and time zones
403API_KEY_NOT_AUTHORIZEDThe domain doesn't belong to your account or is spelled differentlyEnter the domain exactly as it appears under Menu > Websites
429RATE_LIMITEDMore than one request per second to the same endpointWait the number of seconds in Retry-After, then send the request again. For details, see Rate limits

On the Free plan, the API reports no error for hidden companies but returns the row with blurred: true and only a few fields. For details, see Plans.

Enrichment

The endpoints under /enrichment/* use the Enrichment key.

StatusCodeMeaningWhat you do
400INVALID_DOMAINNo domain can be read from the input to GET /enrichment/companyEnter a domain such as your-website.com
403ENRICHMENT_KEY_MISSINGThe request has no Authorization headerSend the Enrichment key in the Authorization header
403ENRICHMENT_KEY_INVALIDThe key has the wrong formatSend the key unchanged, without Bearer
403ENRICHMENT_KEY_NOT_FOUNDNo account has this Enrichment key, for example with the Visitor Intelligence keyCopy the current Enrichment key under Menu > Integrations > API
403PLAN_REQUIREDNew lists, new domains, and single lookups need the Growth plan. Reading and exporting still work, except with ACCOUNT_NOT_ELIGIBLESwitch to the plan in required_tier, see Plans
403ACCOUNT_NOT_ELIGIBLEYour account can't use Enrichment right now, for example after a cancellationWrite to support. A new attempt changes nothing
404LIST_NOT_FOUNDThe list doesn't exist or belongs to another accountUse the ID of a list from GET /enrichment/lists
422VALIDATION_ERRORFor example domain under 3 characters, more than 5,000 domains per call, or an unknown value in statusFix the parameter. Spread many domains over several calls

GET /enrichment/company also answers with 202 and 404, which are not errors. 202 means the result isn't ready yet, and 404 with "status": "not_found" means there is no company data for this domain. For details, see Asynchronous results.

Contacts

The endpoints under /contacts/* use the Visitor Intelligence key. If a call ends with an error, Webmetic deducts no credits. For details, see Credits in the API.

StatusCodeMeaningWhat you do
402INSUFFICIENT_CREDITSYour credits aren't enough. Webmetic deducts nothing and unlocks nothingBuy more credits in the dashboard and repeat the call
403CONTACTS_SETUP_REQUIREDYour account hasn't set up contacts yet. This affects search, reveal, and findSet up contacts once, see Set up contacts
403COMPANY_NOT_IDENTIFIEDThe company_id doesn't belong to a company that visited your websitesUse a company_id from /company-sessions or /company
403PLAN_REQUIREDThe company is hidden on the Free planPick a company you can see, or switch plans
403FEATURE_DISABLEDYour partner turned off the Data profiles feature for your accountAsk your partner to enable the feature, see Choose features for customers
404COMPANY_WITHOUT_WEBSITEThis company has no website on fileThe API returns no contacts for this company
404CONTACT_NOT_FOUNDThe contact isn't from your search, can no longer be found, or may not be deliveredSearch again and use the new result
409CONCURRENT_UPDATEThe same unlock is already running, or another deduction ran at the same momentRepeat the call after a short wait. Webmetic never deducts twice
502PROVIDER_UNAVAILABLEThe data source is temporarily unreachableTry again in a few minutes
502PROVIDER_ERRORThe request to the data source failedTry again later. If the error stays, write to support

Webhooks

The endpoints under /webhooks use the Visitor Intelligence key. For details, see Webhooks.

StatusCodeMeaningWhat you do
400INVALID_URLThe URL is empty, longer than 2,048 characters, not https, contains credentials, or has no valid host or portUse a public https URL without credentials
400PRIVATE_ADDRESSThe host points to a private or reserved addressUse a server that is reachable from the internet
400UNRESOLVABLE_HOSTThe host can't be resolvedCheck the host name and its DNS record
400SEGMENT_REQUIREDThe segment.entered event needs a segment_idSend the segment_id
400SEGMENT_WEBSITEThe segment belongs to a website the webhook doesn't coverAdd the website to websites
400NO_WEBSITEYour account has no website yetAdd a website first
400UNKNOWN_EVENTGET /webhooks/sample doesn't know the eventUse an event name from the reference
403WEBSITE_NOT_AUTHORIZEDA website in websites or website doesn't belong to your accountEnter the website as it appears in your account
404WEBHOOK_NOT_FOUNDThe webhook doesn't exist or belongs to another accountUse the ID of a webhook from GET /webhooks
404SEGMENT_NOT_FOUNDThe segment doesn't existCheck the segment_id
409WEBHOOK_LIMIT_REACHEDYour account already has the maximum number of webhooks. limit gives the numberDelete webhooks you no longer need

Error handling in code

The example reads the code from detail.error when an error comes back, and it also handles a text in detail. For RATE_LIMITED and CONCURRENT_UPDATE, it waits the seconds in Retry-After and tries up to three times. If the header is missing, it waits only briefly. It reports all other errors with status, code, and text.

const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const RETRY = ['RATE_LIMITED', 'CONCURRENT_UPDATE'];

async function callWebmetic(url, attempts = 3) {
  for (let i = 1; i <= attempts; i++) {
    const res = await fetch(url, {
      headers: { Authorization: 'wmtc_YOUR_API_KEY' },
    });
    if (res.ok) return res.json();

    const { detail } = await res.json();
    // Paths outside the API answer {"detail": "Not Found"}
    const known = detail !== null && typeof detail === 'object';
    const error = known ? detail.error : `HTTP_${res.status}`;
    const message = known ? detail.message : String(detail);
    // Temporary errors: wait and try again
    if (RETRY.includes(error) && i < attempts) {
      const retryAfter = Number(res.headers.get('Retry-After'));
      await sleep(retryAfter > 0 ? retryAfter * 1000 : 1000 * i); // Retry-After first, else the backoff
      continue;
    }
    throw new Error(`${res.status} ${error}: ${message}`);
  }
}

const data = await callWebmetic(
  'https://hub.webmetic.de/company-sessions?domain=your-website.com',
);

If your code doesn't know an error code, treat it as an error that a new attempt won't fix.

Next steps

On this page