TombaTomba
Start free
  • Documentation
  • API reference
  • SDKs & CLI
  • AI & MCP
  • Integrations
  • Enterprise
  • Migration guides

Find, verify and enrich B2B contacts from public sources, in the app, your spreadsheet or through the API.

GDPR & CCPA

// docs

  • API changelog
  • Support options
  • Security

// platform

  • Dashboard
  • Pricing
  • API status

// resources

  • Help center
  • Product updates
  • TombaBot crawler

// company

  • Website
  • Contact us
  • Edit or remove your data

© 2021–2026 Tomba.io

  • Terms of service
  • Privacy policy
  • Cookie policy
  • Security policy
  • GDPR
  • CCPA
Get started
Platform
    Credits and usageRate limitsErrorsWebhooksVersioningAll limits
API guides
Response reference
Policies
Resources
Platform

Errors

When a request fails, the response body contains an errors object. Branch on errors.type: one HTTP status can cover several causes.

Error format

Code
{ "errors": { "type": "params_invalid", "message": "Either domain or company parameter must be provided.", "code": 422 } }
FieldDescription
typeMachine-readable cause. The values are listed under Error types.
messageHuman-readable explanation. The wording can change; don't match on it.
codeThe HTTP status code of the response.

errors is always a single object, never an array. Responses from the API carry an X-Request-ID header, and you can send your own (Request IDs); include it when you contact support about a failed request.

A few failures don't use this format:

  • A request body larger than 4 MB returns 413 with {"error": "Request Entity Too Large"}.
  • A request that runs longer than 180 seconds returns 504 from the gateway, with a non-JSON body.
  • GET /people/find, GET /companies/find, and GET /combined/find return status 200 with an errors body, code 404 or 422, when nothing is found or the input is a disposable or webmail address. Check the body for errors on these endpoints.

Status codes

StatusMeaningRetry?
200Success—
201Resource created. GET /email-sources also returns 201, with no data, when it finds no sources.—
400Credentials are missing, malformed, or expired, or a parameter or plan rule rejected the requestNo. Fix the request.
401Credentials don't match an account, the account can't use the API, or the OAuth token is invalidNo
402Not enough credits for the requestNo. Wait for your usage window to renew or add credits.
403The OAuth token lacks a scope, or the plan doesn't include the featureNo
404The route or record doesn't existNo
408The email verifier couldn't complete the mailbox checkYes, later
409A duplicate record, or a bulk job whose status doesn't allow the actionNo
413The request body is larger than 4 MBNo
422A parameter failed validation, or an account cap was reachedNo. Fix the request.
429A rate limit was hit, or the email count or sources balance is used upYes, after Retry-After, for rate limits
451The address, profile, or phone number is withheld at its owner's requestNo
500Server errorYes, with backoff
504The request took longer than 180 secondsYes, or use bulk jobs

None of the error responses consume credits.

Error types

errors.typeStatusCauseWhat to do
params_invalid422, 400A parameter failed validation (422), or a plan rule rejected it (400), such as the Free plan's result limit.Correct the parameter named in the message.
unknown_record404, 400The record doesn't exist (404), or the email finder received a disposable or webmail domain (400).Check the ID or the input.
unknown_route404The URL doesn't match an endpoint.Check the method and path in the API reference.
not_found404The requested log entry doesn't exist. The find endpoints also return it inside a 200 response.—
authentication_failed400, 401, 403The credentials are missing, malformed, or wrong, or the account can't use the API.See Authentication.
api_key_expired400The API key is past its expiry date. The X-Tomba-Key-Expired header gives the date.Rotate the key.
invalid_token401The OAuth access token is invalid, expired, or revoked.Refresh the token or re-authorize.
insufficient_scope403The OAuth access token lacks the scope the endpoint needs.Request the scope; see OAuth 2.0.
forbidden403A workspace member without admin rights requested team or member usage.Use scope=user, or ask a workspace admin.
quota_exceeded402The search or verification balance, or the member's individual limit, is lower than the request's cost.See Credits and usage.
rate_limit429, 422429: a rate limit was hit, or the email count or sources balance is used up. 422: the account reached its cap on API keys, leads, lead lists, or lead attributes.For 429, see Handle 429 responses. For 422, remove items or change plan.
proxy_error408The email verifier's mailbox check failed.Retry later.
duplicate_record409A flag for the same item is already pending review.Wait for the review.
invalid_state409The bulk job's status doesn't allow the action, such as launching a job that is already running, or the job has expired. The message says which.Check the job's status; see Lifecycle.
claimed_email, claimed_linkedin, claimed_phone451The person asked Tomba to stop processing their data, so the address, LinkedIn profile, or phone number is withheld permanently.Remove the record from your data.
ip_blocked400Tomba's firewall blocks the request's IP address.Contact support.
openai_error, search_failed422Company search couldn't process the query.Retry, or simplify the query.
internal_error500A live technology lookup failed.Retry with backoff.
api_error500, 400, 404, 422An unexpected error, or a bulk job without the requested result file (404).Retry a 500 with backoff. If it persists, contact support with the X-Request-ID.

Handle errors

Last modified on October 1, 2026
Rate limitsWebhooks
On this page
  • Error format
  • Status codes
  • Error types
  • Handle errors
JSON
const res = await fetch( "https://api.tomba.io/v1/email-finder?domain=stripe.com&full_name=Jane%20Doe", { headers: { "X-Tomba-Key": process.env.TOMBA_API_KEY, "X-Tomba-Secret": process.env.TOMBA_SECRET_KEY, }, }, ); const body = await res.json(); if (body.errors) { const { type, message } = body.errors; const requestId = res.headers.get("X-Request-ID"); if (type === "rate_limit" && res.status === 429) { // Wait for Retry-After, then retry. See /rate-limits. } else if (res.status === 408 || res.status >= 500) { // Transient: retry later with backoff. } else { throw new Error( `${res.status} ${type}: ${message} (request ${requestId})`, ); } } else { console.log(body.data); }