Skip to main content

Fiber AI Python SDK

Official Python SDK for the Fiber AI API. Auto-generated from the OpenAPI specification.

PyPI version Python 3.11+ License: MIT

For AI agents (Cursor / Claude / Codex / ChatGPT / Copilot)

Do NOT guess operation names — read the canonical agent-facing docs first:

See also llms.txt in this repo for the SDK-specific quickstart.

Table of contents

Installation

pip install fiberai

Requires Python 3.11 or newer. Runtime dependencies: httpx, attrs, python-dateutil.

Quick start

import os
from fiberai import Client
from fiberai.api.search import company_search
from fiberai.models import CompanySearchBody
from fiberai.models.company_search_response_200 import CompanySearchResponse200

client: Client = Client(base_url="https://api.fiber.ai")

body: CompanySearchBody = CompanySearchBody.from_dict({
    "apiKey": os.environ["FIBER_API_KEY"],
    "searchParams": {
        "industriesV2": {"anyOf": ["Software"]},
        "employeeCountV2": {
            "lowerBoundExclusive": 50,
            "upperBoundInclusive": 500,
        },
    },
    "pageSize": 10,
})

result = company_search.sync(client=client, body=body)

if isinstance(result, CompanySearchResponse200):
    for company in result.output.data:
        print(company.to_dict())
else:
    # 4xx / 5xx — `result` is one of CompanySearchResponse{400,401,402,403,404,429,500}
    print("error:", result.to_dict() if result else "no body")

Field names matter. The body keys are camelCase JSON (apiKey, searchParams, industriesV2, employeeCountV2) — not the snake-case Python attributes. from_dict accepts the same shape the HTTP API accepts. See https://api.fiber.ai/ai-docs/companySearch.md for the full filter list.

Authentication

Every generated operation takes your key as a required apiKey field (in the request body, or as the api_key argument for GET operations), so the plain Client is all you need:

from fiberai import Client

client: Client = Client(base_url="https://api.fiber.ai")

AuthenticatedClient is also exported. It sends the key as an Authorization: Bearer header, which the API accepts too, but the generated models still require apiKey, so it adds nothing over Client.

Get an API key at https://fiber.ai/app/api. Production keys start with sk_live_, sandbox keys with sk_test_. Treat them like passwords — never commit them; load from os.environ or a secrets manager.

Async usage

Every operation ships sync and async variants. The signature, body model, and return type are identical; only the function name changes (sync → asyncio, sync_detailed → asyncio_detailed):

import asyncio
import os
from fiberai import Client
from fiberai.api.search import company_search
from fiberai.models import CompanySearchBody
from fiberai.models.company_search_response_200 import CompanySearchResponse200


async def main() -> None:
    client: Client = Client(base_url="https://api.fiber.ai")

    body: CompanySearchBody = CompanySearchBody.from_dict({
        "apiKey": os.environ["FIBER_API_KEY"],
        "searchParams": {"industriesV2": {"anyOf": ["Software"]}},
        "pageSize": 10,
    })

    result = await company_search.asyncio(client=client, body=body)
    if isinstance(result, CompanySearchResponse200):
        print(f"got {len(result.output.data)} companies")


asyncio.run(main())

For long-running scripts, reuse a single Client (or use it as an async with context manager) so the underlying httpx.AsyncClient connection pool is shared across calls.

Detailed responses

Use sync_detailed / asyncio_detailed when you need the HTTP status code, headers, or raw body alongside the parsed object:

from fiberai.api.search import company_search
from fiberai.types import Response

response: Response = company_search.sync_detailed(client=client, body=body)
print(response.status_code)   # http.HTTPStatus
print(response.headers)       # MutableMapping[str, str]
print(response.content)       # raw bytes
print(response.parsed)        # the same object sync() returns (or None)

response.headers is where you read Retry-After for 429s, X-Request-Id for support tickets, etc.

Error handling

The non-detailed call returns a discriminated union covering every documented status. Type-narrow with isinstance to dispatch:

from fiberai.api.search import company_search
from fiberai.models.company_search_response_200 import CompanySearchResponse200
from fiberai.models.company_search_response_401 import CompanySearchResponse401
from fiberai.models.company_search_response_402 import CompanySearchResponse402
from fiberai.models.company_search_response_429 import CompanySearchResponse429

result = company_search.sync(client=client, body=body)

if isinstance(result, CompanySearchResponse200):
    companies = result.output.data
elif isinstance(result, CompanySearchResponse401):
    raise RuntimeError("invalid API key")
elif isinstance(result, CompanySearchResponse402):
    raise RuntimeError("out of credits — top up at https://fiber.ai/app/billing")
elif isinstance(result, CompanySearchResponse429):
    # Rate limited — sync_detailed exposes the Retry-After header
    raise RuntimeError("rate limited; back off and retry")
else:
    raise RuntimeError(f"unexpected error: {result}")

For undocumented status codes (e.g. transient 502/503 from upstream), the SDK returns None by default. Set raise_on_unexpected_status=True to surface them as exceptions instead:

from fiberai import Client
from fiberai import errors

client: Client = Client(
    base_url="https://api.fiber.ai",
    raise_on_unexpected_status=True,
)

try:
    result = company_search.sync(client=client, body=body)
except errors.UnexpectedStatus as exc:
    print(exc.status_code, exc.content[:200])

httpx.TimeoutException (request exceeded timeout) and httpx.ConnectError (network) propagate untouched.

Pagination

Search responses include output.next_cursor. Pass it back as the next request's cursor to walk the full result set:

import os
from typing import Optional
from fiberai.api.search import company_search
from fiberai.models import CompanySearchBody
from fiberai.models.company_search_response_200 import CompanySearchResponse200

cursor: Optional[str] = None
all_companies: list[dict] = []

while True:
    body: CompanySearchBody = CompanySearchBody.from_dict({
        "apiKey": os.environ["FIBER_API_KEY"],
        "searchParams": {"industriesV2": {"anyOf": ["Software"]}},
        "pageSize": 100,
        **({"cursor": cursor} if cursor else {}),
    })

    result = company_search.sync(client=client, body=body)
    if not isinstance(result, CompanySearchResponse200):
        raise RuntimeError(f"search failed: {result}")

    all_companies.extend(c.to_dict() for c in result.output.data)

    cursor = result.output.next_cursor or None
    if not cursor:
        break

The same pattern applies to people_search, investor_search, investment_search, and job_posting_search.

Credit tracking

Every successful response carries a charge_info object documenting exactly how many credits were consumed and why. Persist it for billing reconciliation rather than deriving cost from result counts:

result = company_search.sync(client=client, body=body)
if isinstance(result, CompanySearchResponse200):
    print(result.charge_info.to_dict())
    # { "method": "...", "creditsCharged": 7.0 }

To check your balance before kicking off a large batch:

import os
from fiberai.api.account import get_org_credits
from fiberai.models.get_org_credits_response_200 import GetOrgCreditsResponse200

credits = get_org_credits.sync(client=client, api_key=os.environ["FIBER_API_KEY"])
if isinstance(credits, GetOrgCreditsResponse200):
    print(credits.to_dict())

get_org_credits is a GET request that takes the API key as a query-string kwarg rather than a body. A handful of read-only utility operations follow this convention; the per-operation docs at https://api.fiber.ai/ai-docs/index.md note which.

Available API modules

The SDK is organized by API domain. The endpoint path corresponding to each operation lives in the module's _get_kwargs helper if you need to grep for it.

Module What's in it
fiberai.api.search company_search, people_search, investor_search, investment_search, job_posting_search (+ _count variants), and the combined-search trio (combined_search, sync_combined_search, poll_combined_search)
fiberai.api.live_fetch Real-time LinkedIn fetches: profile_live_enrich, company_live_enrich, plus posts/comments/reactions for both profiles and companies
fiberai.api.contact_details Email + phone reveal: sync_contact_enrichment (sync), trigger_contact_enrichment + poll_contact_enrichment_result (async waterfall), start_batch_contact_enrichment + poll_batch_contact_enrichment (batch)
fiberai.api.kitchen_sink Bulk company/profile lookup by identifier: kitchen_sink_company, kitchen_sink_profile, kitchen_sink_bulk_company, kitchen_sink_bulk_profile
fiberai.api.google_maps Google Maps business search: google_maps_search, poll_google_maps_results, check_google_maps_results
fiberai.api.ai_research AI-powered domain lookup: domain_lookup_trigger, domain_lookup_polling
fiberai.api.agentic_search LLM-powered text-to-search: text_to_company_search, text_to_profile_search, text_to_combined_search
fiberai.api.exclusions Manage company and prospect exclusion lists (create / add / remove / list / delete)
fiberai.api.saved_search Saved search lifecycle: create, list, run, fetch run results
fiberai.api.email_lookup reverse_email_lookup (email → LinkedIn profile)
fiberai.api.validation email_bounce_detection
fiberai.api.account get_org_credits
fiberai.api.enums Enum value lookups: industries, accelerators, NAICS codes, regions, languages, tags, time zones
fiberai.api.typeaheads company_typeahead, location_typeahead
fiberai.api.company_info bulk_company_logos
fiberai.api.coming_soon Beta endpoints: start_local_business_search, poll_local_business_search
fiberai.api.utility health_check, get_open_api (no API key required)

If you want LinkedIn-URL → company details, use live_fetch.company_live_enrich (not company_info). The company_info module currently only exposes bulk logo fetching.

The Python SDK lags slightly behind the API in a few places — notably the new syncQuickContactReveal / syncTurboContactEnrichment / triggerExhaustiveContactEnrichment operation names, which still ship under their older sync_contact_enrichment / trigger_contact_enrichment module names here. See llms.txt for the workaround (direct httpx call) until the next regeneration.

Configuration

Client accepts the same kwargs as httpx.Client plus a few of its own:

import httpx
import ssl
from fiberai import Client

client: Client = Client(
    base_url="https://api.fiber.ai",
    timeout=httpx.Timeout(60.0, connect=10.0),
    headers={"X-Custom-Header": "value"},
    cookies={"session": "..."},
    verify_ssl=True,                       # bool | str | ssl.SSLContext
    follow_redirects=False,
    raise_on_unexpected_status=False,      # see "Error handling"
    httpx_args={"http2": True},            # forwarded to httpx.Client(...)
)

Useful helpers (each returns a new Client rather than mutating in place):

client_with_auth: Client = client.with_headers({"X-Trace-Id": "abc123"})
client_with_timeout: Client = client.with_timeout(httpx.Timeout(120.0))

For long-running services, use the client as a context manager so connection pools are torn down cleanly:

with Client(base_url="https://api.fiber.ai") as client:
    result = company_search.sync(client=client, body=body)

# or, async:
async with Client(base_url="https://api.fiber.ai") as client:
    result = await company_search.asyncio(client=client, body=body)

Choosing the right operation

Several Fiber operations cover overlapping use cases (e.g. three different ways to reveal contact info, two ways to search). The trade-offs (cost, latency, coverage, quality) live in the per-operation docs, not in this README:

Use case Read this
Sync vs turbo vs exhaustive contact reveal https://api.fiber.ai/llms.txt and the relevant ai-docs/<operationId>.md
When to use audiences vs ad-hoc search https://api.fiber.ai/ai-docs/index.md
Rate limits and credit cost per operation Stamped at the top of each ai-docs/<operationId>.md page

When in doubt, prefer reading these over guessing — the routing rules change faster than this SDK regenerates.

License

MIT — see LICENSE for details.

Metadata

Release files for fiberai 0.0.74

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fiberai 0.0.74
File Size Uploaded Provenance Actions
fiberai-0.0.74.tar.gz 6.8 MB With provenance Details for fiberai-0.0.74.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for fiberai 0.0.74
File Interpreter ABI Platform Actions
fiberai-0.0.74-py3-none-any.whl Python 3 none any Details for fiberai-0.0.74-py3-none-any.whl

Total release size: 33.1 MB

Release files / fiberai-0.0.74.tar.gz

Download URL fiberai-0.0.74.tar.gz
Size 6.8 MB
Tags Source
SHA-256 checksum
How to use checksums
d23463f0933374946da05d1fb3d4253a8c762af14fe899bccbd24f3235ef0a04
BLAKE2b-256 checksum
How to use checksums
9c95b951fce717a8bc7323a05936295d38e9979ae79fbbe50dd76b1e1cb19d53
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 30, 2026.

Transparency log

Release files / fiberai-0.0.74-py3-none-any.whl

Download URL fiberai-0.0.74-py3-none-any.whl
Size 26.3 MB
Tags Python 3
SHA-256 checksum
How to use checksums
66cc38b780f7623f1ddf05a5ce40215d1ebccdaa62257192273c168e4b97aa1c
BLAKE2b-256 checksum
How to use checksums
5c51d7e77956b18e6d712065146846b938dd4c59836ba0b526e28612e0437709
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 30, 2026.

Transparency log

Security for fiberai 0.0.74

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for fiberai-0.0.74.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 30, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.0.74 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page