Fiber AI
Build with Fiber

SDKs

Official TypeScript and Python SDKs for the Fiber AI API — typed requests, typed responses, and credit costs on every call.

SDKs

Official SDKs exist for TypeScript/JavaScript (@fiberai/sdk) and Python (fiberai). Every call returns fully typed results plus a chargeInfo field that is authoritative for what a request cost — you never have to guess your spend. See Billing & credits for credit pricing.

Building with an AI agent? Don't paste from memory — point your agent at the canonical docs: llms.txt for routing rules, ai-docs/index.md for every operation, and Developing with AI agents for plugin and MCP setup. Add Context7 so the agent can pull current SDK signatures while it writes code.

Authentication

Create a key at fiber.ai/app/api and export FIBER_API_KEY. Pass apiKey in the request body for POST calls and as a query parameter for GET calls. Headers (x-api-key, Bearer), sandbox keys, and revoke are on API keys.

export FIBER_API_KEY=sk_live_...

TypeScript SDK

Install (Node.js 18+):

npm install @fiberai/sdk

Call functions from @fiberai/sdk. The SDK already ships Zod — import schemas from @fiberai/sdk/zod (you do not need a separate copy of the request types). Every request type FooData has zFooData. Parse env, HTTP bodies, and agent output with those schemas before you call; keep the function import from @fiberai/sdk so you only load /zod when you validate.

Search companies:

import { companySearch } from "@fiberai/sdk";
import type { CompanySearchData } from "@fiberai/sdk";
import { zCompanySearchData } from "@fiberai/sdk/zod";

const searchRequest: CompanySearchData = zCompanySearchData.parse({
  body: {
    apiKey: process.env.FIBER_API_KEY!,
    searchParams: {
      industriesV2: { anyOf: ["Software"] },
      // employeeCountV2 bounds are bucketed.
      // Allowed values: 0 | 1 | 10 | 50 | 200 | 500 | 1000 | 5000 | 10000 | null
      employeeCountV2: {
        lowerBoundExclusive: 50,
        upperBoundInclusive: 500,
      },
      headquartersCountryCode: { anyOf: ["USA"] },
    },
    pageSize: 10,
  },
});

const result: Awaited<ReturnType<typeof companySearch>> =
  await companySearch(searchRequest);

console.log(`Found ${result.data?.output.data.length} companies`);
console.log("Cost:", result.data?.chargeInfo);

Search people by title and country:

import { peopleSearch } from "@fiberai/sdk";
import type { PeopleSearchData } from "@fiberai/sdk";
import { zPeopleSearchData } from "@fiberai/sdk/zod";

const peopleRequest: PeopleSearchData = zPeopleSearchData.parse({
  body: {
    apiKey: process.env.FIBER_API_KEY!,
    searchParams: {
      jobTitleV2: {
        anyOf: [
          { type: "term", term: "CEO" },
          { type: "term", term: "CTO" },
          { type: "static-groups", groups: ["c-suite"] },
        ],
      },
      country3LetterCode: { anyOf: ["USA"] },
    },
    pageSize: 25,
  },
});

const people: Awaited<ReturnType<typeof peopleSearch>> =
  await peopleSearch(peopleRequest);

Reveal contacts (sync, fast — see Contact Reveal for all tiers):

import { syncQuickContactReveal } from "@fiberai/sdk";
import type { SyncQuickContactRevealData } from "@fiberai/sdk";
import { zSyncQuickContactRevealData } from "@fiberai/sdk/zod";

const revealRequest: SyncQuickContactRevealData =
  zSyncQuickContactRevealData.parse({
    body: {
      apiKey: process.env.FIBER_API_KEY!,
      linkedinUrl: "https://www.linkedin.com/in/example",
      enrichmentType: {
        getWorkEmails: true,
        getPersonalEmails: false,
        getPhoneNumbers: true,
      },
    },
  });

const reveal: Awaited<ReturnType<typeof syncQuickContactReveal>> =
  await syncQuickContactReveal(revealRequest);

console.log("Emails:", reveal.data?.output.profile.emails);
console.log("Cost:", reveal.data?.chargeInfo);

For bulk rows use startBatchContactDetailspollBatchContactDetails, and pick up the finished job with a webhook.

Check credits (free). output is an array of usage periods (one per subscription), not a single object:

import { getOrgCredits } from "@fiberai/sdk";
import type { GetOrgCreditsData } from "@fiberai/sdk";
import { zGetOrgCreditsData } from "@fiberai/sdk/zod";

const creditsRequest: GetOrgCreditsData = zGetOrgCreditsData.parse({
  query: { apiKey: process.env.FIBER_API_KEY! },
});
const credits: Awaited<ReturnType<typeof getOrgCredits>> =
  await getOrgCredits(creditsRequest);
const available: number | undefined = credits.data?.output[0]?.available;
console.log(`Available: ${available}`);

Error handling. SDK functions return { data, error, response } — check error before reading data, or pass throwOnError: true to throw on non-2xx instead:

if (result.error) {
  console.error(`HTTP ${result.response.status}:`, result.error);
} else {
  console.log(`${result.data.output.data.length} companies`);
}
CodeMeaningWhat to do
400Malformed request (missing apiKey on a JSON body, bad fields)Fix the payload
401No API key sentAdd apiKey / x-api-key
403Key invalid, expired, revoked, or over its per-key ceilingCheck the key; raise the limit if you capped it
402Org out of credits (or billing period expired)Top up (see billing)
429Too many requestsSlow down — you hit our rate limit
500Server errorRetry, then contact support
501Sandbox not available for this operationUse a live key, or skip that call in CI

Python SDK

Install (Python 3.9+):

pip install fiberai

Every operation has .sync() and .asyncio() variants:

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

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,
        },
        "headquartersCountryCode": {"anyOf": ["USA"]},
    },
    "pageSize": 10,
})

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

Reveal contacts:

from fiberai.api.contact_details import sync_quick_contact_reveal

result = sync_quick_contact_reveal.sync(client=client, body={
    "apiKey": os.environ["FIBER_API_KEY"],
    "linkedinUrl": "https://www.linkedin.com/in/example",
    "enrichmentType": {
        "getWorkEmails": True,
        "getPersonalEmails": False,
        "getPhoneNumbers": True,
    },
})

Error handling — the non-detailed call returns a discriminated union; narrow with isinstance:

if isinstance(result, CompanySearchResponse200):
    companies = result.output.data
elif isinstance(result, CompanySearchResponse402):
    raise RuntimeError("out of credits")
elif isinstance(result, CompanySearchResponse429):
    raise RuntimeError("rate limited; back off and retry")

Set raise_on_unexpected_status=True on the client to also raise on transient 5xx.

Module map:

ModuleWhat's in it
fiberai.api.searchCompany, people, investor, investment, and job-posting search
fiberai.api.live_fetchReal-time LinkedIn fetches for profiles and companies
fiberai.api.contact_detailsEmail + phone reveal (all tiers and batch)
fiberai.api.agentic_searchText-to-search: job descriptions and free text → profiles
fiberai.api.kitchen_sinkBulk identifier-based lookup (see Kitchen Sink)
fiberai.api.google_mapsGoogle Maps business search (async)
fiberai.api.email_lookupReverse email lookup (see Reverse Email Lookup)
fiberai.api.exclusionsCompany & prospect exclusion lists (see Exclusion lists)
fiberai.api.accountCredits, auto-top-up settings, credit purchase
fiberai.api.enumsIndustries, NAICS, regions, languages, accelerators
fiberai.api.typeaheadsCompany, location, and skills autocomplete + job-title expansion (see Typeaheads)
fiberai.api.validationEmail bounce detection
fiberai.api.utilityHealth check and OpenAPI download (no key needed)

Resources

On this page