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
SDKs
    SDK overviewC# SDKDart SDKDeno SDKElixir SDKGo SDKLua SDKNode.js SDKPerl SDKPHP SDKPython SDKR SDKRuby SDKRust SDK
CLI
SDKs

Python SDK

tomba-io is the official Python client for the Tomba API. Each API area is a service class, and each method sends one request.

Requirements

  • Python 3.8 or later. The package declares no minimum version; its CI tests Python 3.8 to 3.12.
  • requests, installed as a dependency.

Install

TerminalCode
pip install tomba-io

The import name is tomba.

Authenticate

Create an API key and copy your secret on the API keys page, then export both:

TerminalCode
export TOMBA_API_KEY="ta_xxxx" export TOMBA_SECRET_KEY="ts_xxxx"

The SDK doesn't read environment variables. Pass the values to set_key() and set_secret(), and the client sends them as the X-Tomba-Key and X-Tomba-Secret headers. Key expiry and rotation are covered in Authentication.

First request

Find the email address of a person at a company:

Code
import os from tomba import Client, Finder client = Client() client.set_key(os.environ["TOMBA_API_KEY"]).set_secret(os.environ["TOMBA_SECRET_KEY"]) result = Finder(client).email_finder("stripe.com", "Jane", "Doe") print(result["data"]["data"]["email"])

Every method returns a dict with two keys: data, the decoded JSON body, and rate_limit. The API wraps its payload in its own data object (Response format), so the address is at result["data"]["data"]["email"].

Errors

The SDK raises TombaException when the API responds with status 400 or higher, when the request fails, and before sending a request when a required argument is None.

AttributeValue
codeThe HTTP status. 0 when no response was received, for example a missing argument or a network error.
messageThe API's errors.message, or the underlying error.
responseThe decoded error body, {"errors": {"type": …, "message": …, "code": …}}, or None.
Code
import os from tomba import Client, Finder, TombaException client = Client() client.set_key(os.environ["TOMBA_API_KEY"]).set_secret(os.environ["TOMBA_SECRET_KEY"]) try: result = Finder(client).email_finder("stripe.com", "Jane", "Doe") except TombaException as error: print(error.code, error.message) if error.response: print(error.response["errors"]["type"]) else: print(result["data"]["data"]["email"])

Enrichment.person(), company(), and combined() don't raise when nothing is found: those endpoints answer with status 200 and an errors body, so check result["data"].get("errors"). Each errors.type is described in Errors.

Rate limits and retries

The SDK doesn't retry. result["rate_limit"] holds the response's rate limit headers as second_limit, minute_limit, daily_limit, minute_remaining, daily_remaining, minute_reset, daily_reset, retry_after, policy, and rate_limit. Numbers are integers, and a header that is absent or 0 becomes None.

A 429 raises TombaException with code 429, without the Retry-After header. Wait before retrying as described in Handle 429 responses.

Requests time out after 120 seconds. Change the timeout with client.set_timeout(seconds).

Method reference

Create each service with the client, for example Finder(client). Every class is importable from tomba. IDs are strings.

MethodEndpoint
Account.get_account()GET /me
Usage.get_usage()GET /usage
Logs.get_logs(page=None, limit=None)GET /logs
Domain.domain_search(domain, page=None, limit=None, department=None, country=None, enrich_mobile=None, webhook_url=None)GET /domain-search
Finder.email_finder(domain, first_name, last_name, webhook_url=None)GET /email-finder
Finder.author_finder(url, webhook_url=None)GET /author-finder
Finder.linkedin_finder(url)GET /linkedin
Finder.enrichment(email, webhook_url=None)GET /enrich
Finder.format(domain), Format.email_format(domain)GET /email-format
Finder.location(domain), Location.get_location(domain)GET /location
Count.email_count(domain)GET /email-count
Verifier.email_verifier(email, enrich_mobile=None, webhook_url=None)GET /email-verifier
Sources.email_sources(email)GET /email-sources
Enrichment.person(email, webhook_url=None)GET /people/find
Enrichment.company(domain)GET /companies/find
Enrichment.combined(email)GET /combined/find
Phone.finder(email=None, domain=None, linkedin=None, full=None, webhook_url=None)GET /phone-finder
Phone.validator(phone)GET /phone-validator
Status.domain_status(domain)GET /domain-status
Status.auto_complete(query)GET /domain-suggestions
Similar.websites(domain)GET /similar
Technology.list(domain)GET /technology
Reveal.search_companies(**params)POST /reveal/search
Flag.list_flags(page=None, limit=None)GET /flag
Keys.get_keys()GET /keys
Keys.get_key(id)GET /keys/{id}
Keys.create_key(**params)POST /keys
Keys.reset_key(id)PUT /keys/{id}
Keys.delete_key(id)DELETE /keys/{id}
Leads.list_leads(page=None, limit=None, domain=None)GET /leads
Leads.get_lead(lead_id)GET /leads/{id}
Leads.create_lead(**params)POST /leads
Leads.update_lead(lead_id, **params)PUT /leads/{id}
Leads.delete_lead(lead_id)DELETE /leads/{id}
LeadsLists.get_lists()GET /leads_lists
LeadsLists.create_list(**params)POST /leads_lists
LeadsLists.update_list_id(id, **params)PUT /leads_lists/{id}
LeadsLists.delete_list_id(id)DELETE /leads_lists/{id}
LeadsAttributes.get_lead_attributes()GET /attributes
LeadsAttributes.create_lead_attribute(**params)POST /attributes
LeadsAttributes.update_lead_attribute(id, **params)PUT /attributes/{id}
LeadsAttributes.delete_lead_attribute(id)DELETE /attributes/{id}
Bulk.list_bulks(bulk_type, page=None, limit=None)GET /bulk/{type}
Bulk.create_bulk(bulk_type, **params)POST /bulk/{type}
Bulk.get_bulk(bulk_type, bulk_id)GET /bulk/{type}/{id}
Bulk.launch_bulk(bulk_type, bulk_id)PUT /bulk/{type}/{id}
Bulk.bulk_progress(bulk_type, bulk_id)GET /bulk/{type}/{id}/progress
Bulk.download_bulk(bulk_type, bulk_id)GET /bulk/{type}/{id}/download
Bulk.rename_bulk(bulk_type, bulk_id, name)PUT /bulk/{type}/{id}/rename
Bulk.archive_bulk(bulk_type, bulk_id)DELETE /bulk/{type}/{id}/archive
Bulk.delete_bulk(bulk_type, bulk_id)DELETE /bulk/{type}/{id}/delete

bulk_type is the {type} segment listed in Bulk types; the order of calls is described in Lifecycle. create_bulk sends a JSON body, so it can't create jobs that need a CSV upload, such as email finder jobs. download_bulk returns the results file, a CSV, as bytes in result["data"].

Source

github.com/tomba-io/python (Apache-2.0). Release notes are in CHANGELOG.md.

Last modified on September 30, 2026
PHP SDKR SDK
On this page
  • Requirements
  • Install
  • Authenticate
  • First request
  • Errors
  • Rate limits and retries
  • Method reference
  • Source