# List all enrichmentsenrichments = client.list_enrichments()# Search by keywordenrichments = client.list_enrichments(q="phone number")for e in enrichments: print(f"[{e.id}] {e.name} — {e.price} credits/call")
Get enrichment details
enrichment = client.get_enrichment(123)print(enrichment.name)print(enrichment.description)for param in enrichment.params: required = "required" if param.is_required else "optional" print(f" {param.name} ({param.type_field}, {required}): {param.description}")for field in enrichment.response_fields: print(f" → {field.name} ({field.type_field})")
Run a single enrichment
# Async — returns immediately with a task IDtask = client.run_enrichment(123, {"email": "alice@example.com"})print(task.task_id) # poll this later# Sync — submits and waits for completion in one callresult = client.run_enrichment_sync(123, {"email": "alice@example.com"})print(result)
Bulk run
inputs = [ {"email": "alice@example.com"}, {"email": "bob@example.com"}, {"email": "carol@example.com"},]# Sync — submits and waits for all resultsresults = client.run_enrichment_bulk_sync(123, inputs)# Results are aligned to inputs: one element per input, in input order,# with None for inputs that returned no data (len(results) == len(inputs)).for lead, result in zip(inputs, results): if result is None: print(f"{lead['email']}: no data") else: print(f"{lead['email']}: {result}")
Get choices for a select parameter
# For enrichments with select/multiselect parameterschoices = client.get_param_choices(123, "country", q="united")for choice in choices.items: print(f" {choice.id}: {choice.name}")if choices.has_next_page: next_page = client.get_param_choices(123, "country", page=2)
Waterfalls chain multiple enrichment providers together with automatic fallback — if provider A doesn’t return a result, provider B is tried automatically.
List waterfalls
waterfalls = client.list_waterfalls()for w in waterfalls: providers = len(w.available_enrichments) print(f"{w.identifier}: {w.name} ({providers} providers)")
Run a waterfall
# Uses the providers enabled by default (enabled_by_default=True)result = client.run_waterfall_sync( "email_getter", {"linkedin_url": "https://linkedin.com/in/alice"})print(result)# Or specify providers explicitlyresult = client.run_waterfall_sync( "email_getter", {"linkedin_url": "https://linkedin.com/in/alice"}, enrichments=[10, 11, 12] # provider IDs from get_waterfall())
# Create a table with predefined columnstable = client.create_table( name="My Leads", columns=["email", "name", "company", "linkedin_url"])print(f"Created: {table.identifier}")# List all tablestables = client.list_tables()for t in tables: print(f"{t.identifier}: {t.name}")
Read rows
# Get rows with paginationdata = client.get_rows(table.identifier, page=1, per_page=500)
Insert rows
from databar import InsertRow, InsertOptions, DedupeOptionsrows = [ InsertRow(fields={"email": "alice@example.com", "name": "Alice"}), InsertRow(fields={"email": "bob@example.com", "name": "Bob"}),]# With deduplication on email columnresponse = client.create_rows( table.identifier, rows, options=InsertOptions( allow_new_columns=True, dedupe=DedupeOptions(enabled=True, keys=["email"]) ))created = [r for r in response.results if r.action == "created"]skipped = [r for r in response.results if r.action == "skipped_duplicate"]print(f"Inserted {len(created)}, skipped {len(skipped)} duplicates")
Large inserts are auto-batched in chunks of 50 — no manual chunking needed.
from databar import UpsertRowrows = [ UpsertRow(key={"email": "alice@example.com"}, fields={"name": "Alice", "company": "Acme"}), UpsertRow(key={"email": "new@example.com"}, fields={"name": "New User"}),]response = client.upsert_rows(table.identifier, rows)for r in response.results: print(f"{r.id}: {r.action}") # "created" or "updated"
Duplicate, clear, export, dedupe
copy = client.duplicate_table(table.identifier)client.clear_table(table.identifier)export = client.export_table(table.identifier, format="csv")status = client.get_table_export(table.identifier)print(status.file)# Omit columns to compare every main column. Oldest row in each group is kept.result = client.dedupe_table_rows(table.identifier)print(result.count_rows_delete)
A workbook is the document that owns one or more tables (sheets). Table.workbook is the parent workbook id.
workbooks = client.list_workbooks()wb = client.get_workbook(workbooks[0].identifier)client.rename_workbook(wb.identifier, "Q4 leads")client.add_workbook_table(wb.identifier, name="Sheet 2")# Set the sheet (tab) order: table_ids lists every live sheet exactly oncesheets = client.get_workbook(wb.identifier).tablesclient.reorder_workbook_tables(wb.identifier, [s.identifier for s in reversed(sheets)])copy = client.duplicate_workbook(wb.identifier)# Fold other workbooks' sheets into this oneclient.merge_workbooks(wb.identifier, [copy.identifier])# Move one sheet into another workbook, or split it into a new documentclient.move_table(table.identifier, workbook=wb.identifier)client.move_table(table.identifier, new_workbook=True, name="Split out")# Trash for 30 daysclient.delete_workbook(wb.identifier)
for item in client.list_trash(): print(item.kind, item.identifier, item.name)client.restore_trash(workbooks=["wb_id"], tables=["table-uuid"])client.purge_trash(workbooks=["wb_id"])
For async operations, you can check task status manually or poll until complete:
# Submit without waitingtask = client.run_enrichment(123, {"email": "alice@example.com"})print(f"Task submitted: {task.task_id}")# Check status oncestatus = client.get_task(task.task_id)print(status.status) # "processing", "completed", "failed", "cancelled", or "gone"print(status.progress) # bulk runs: {"total", "completed", "failed", "processing"}# Poll until complete (blocks until done or times out)result = client.poll_task(task.task_id)print(result)# Rows a running bulk task has already finished, without waiting for the restclient.get_task(task.task_id, include_partial=True).data# Stop a task that is going nowhere; unfinished requests are refundedclient.cancel_task(task.task_id)
from databar import ( DatabarClient, DatabarAuthError, DatabarNotFoundError, DatabarInsufficientCreditsError, DatabarTaskFailedError, DatabarTimeoutError,)try: result = client.run_enrichment_sync(123, {"email": "alice@example.com"})except DatabarAuthError: print("Invalid API key — check your DATABAR_API_KEY")except DatabarInsufficientCreditsError: print("Out of credits — top up at databar.ai")except DatabarNotFoundError: print("Enrichment not found")except DatabarTaskFailedError as e: print(f"Enrichment failed: {e.message}")except DatabarTimeoutError as e: print(f"Timed out after {e.max_attempts} polls — task may still be running")