Fiber AI
Audiences & lists

Audiences

Turn company and people filters into a saved list of accounts and contacts, add verified emails and phones, and export it as CSV or ad-platform files.

Audiences

We built audiences for the bulk job: define who you want to reach once, and we fill a saved list with the matching companies and the people who work there. From that list you can add work emails, personal emails, and phone numbers in one run, then export it as a CSV or a file ready for LinkedIn, Meta, or Google Ads. It's the same audience you see in the dashboard, driven from code.

You see the price before you pay for contacts. The enrichment estimate is free and returns a credit total plus a time estimate, so you can confirm the spend before anything is charged.

What it does

The workflow runs in this order. Two steps charge credits; everything else is free.

  1. Create an empty audience. It starts in DRAFT.
  2. Set filters for companies and prospects while the audience is still in DRAFT.
  3. Build the audience. This runs in the background and charges per company and per person found once it completes.
  4. Poll the build until the status reads NORMAL (done) or FAILED.
  5. Estimate enrichment for the channels you want. The estimate is free.
  6. Trigger enrichment. Credits are charged up front, based on the estimate.
  7. Poll enrichment progress until it reaches 100%.
  8. Export companies or prospects as CSV or ad-platform files, free.

You can also list every audience in your organization, page through an audience's companies and prospects directly, and archive audiences you no longer need.

Inputs and outputs

StepYou sendYou get back
Createname (1–200 characters)audienceId, status: "DRAFT"
Set filterscompanySearchParams, prospectSearchParamsThe filters as saved
BuildNothing beyond your keystatus: "BUILDING"
Build statusaudienceIdstatus, timestamps, and counts
Estimate / enrichmaxProspectsToEnrich, enrichmentType (getWorkEmails, getPersonalEmails, getPhoneNumbers, each default true)Estimate: totalCredits, a per-operation breakdown, timeEstimate. Enrich: enrichmentId, estimatedCredits
Enrichment statusaudienceIdcurrentStage, progressPercent (0–100), steps completed and remaining
Exportformat, optional maxRowsToExport, excludeFields, userEmail; prospects also take onlyWithContactsestimatedRows, maxRowsAllowed; CSV links by email or in the response

Company filters cover industry, headcount, headquarters country and location, keywords, funding stage and amounts, founding and last-funded dates, accelerators, and exact companies by domain or LinkedIn URL. Most use include/exclude lists, for example industriesV2: { anyOf: [...] } or employeeCountV2: { lowerBoundExclusive, upperBoundInclusive }. Prospect filters cover job title and location. The full filter schema lives in the filter reference.

Filters lock once you build. Setting filters and building both require DRAFT. If a build is already running, poll its status instead of retrying; if the audience is already built, create a new audience for a different set of filters.

End-to-end example

The happy path in TypeScript. POST and PATCH calls take apiKey in the body; GET and DELETE calls take it as a query parameter.

const BASE = "https://api.fiber.ai/v1/audiences";
const apiKey = process.env.FIBER_API_KEY!;
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));

async function call(method: string, path: string, body?: object) {
  const url =
    method === "GET" || method === "DELETE"
      ? `${BASE}${path}?apiKey=${apiKey}`
      : `${BASE}${path}`;
  const res = await fetch(url, {
    method,
    headers: { "Content-Type": "application/json" },
    body: body ? JSON.stringify({ apiKey, ...body }) : undefined,
  });
  if (!res.ok) throw new Error(`${method} ${path}: ${res.status}`);
  return res.json();
}

// 1. Create (free): createAudience
const { output: created } = await call("POST", "/create", {
  name: "AI startups, US, 50-1,000 employees",
});
const id = created.audienceId;

// 2. Set filters (free, DRAFT only): updateAudienceSearchParams
await call("PATCH", `/${id}/search-params`, {
  companySearchParams: {
    industriesV2: { anyOf: ["Artificial Intelligence"] },
    headquartersCountryCode: { anyOf: ["USA"] },
    employeeCountV2: { lowerBoundExclusive: 50, upperBoundInclusive: 1000 },
    stage: { anyOf: ["seed", "series_a", "series_b"] },
  },
  // prospectSearchParams: job title, location — see the filter reference
});

// 3. Build (charges per company and person found): buildAudience
await call("POST", `/${id}/build`);

// 4. Poll the build (free): getAudienceStatus
let status = "BUILDING";
while (status !== "NORMAL" && status !== "FAILED") {
  await sleep(30_000);
  status = (await call("GET", `/${id}/status`)).output.status;
}
if (status === "FAILED") throw new Error("Build failed");

// 5. Estimate enrichment (free): estimateEnrichmentCost
const enrichment = {
  maxProspectsToEnrich: 5000,
  enrichmentType: {
    getWorkEmails: true,
    getPersonalEmails: false,
    getPhoneNumbers: true,
  },
};
const { output: estimate } = await call(
  "POST", `/${id}/enrichment/estimate`, enrichment,
);
console.log(estimate.totalCredits, estimate.timeEstimate.formatted);
// Confirm the spend here before continuing.

// 6. Enrich (charged up front): triggerEnrichment
await call("POST", `/${id}/enrich`, enrichment);

// 7. Poll enrichment (free): getEnrichmentStatus
let progress;
do {
  await sleep(30_000);
  progress = (await call("GET", `/${id}/enrichment/status`)).output;
} while (progress.currentStage !== "DONE" && progress.currentStage !== "FAILED");

// 8. Export (free, counts against export quota): exportProspects
const { output: exp } = await call("POST", `/${id}/export/prospects`, {
  format: "PROSPECT_GENERIC_CSV",
  onlyWithContacts: true,
  userEmail: "you@example.com",
});
console.log(exp.estimatedRows, exp.maxRowsAllowed);

Statuses

An audience reports DRAFT from creation until you build, BUILDING while the build runs, and NORMAL when it's ready to enrich and export. FAILED means the build didn't complete. You may see other in-progress values between BUILDING and NORMAL; treat anything that isn't NORMAL or FAILED as still working and keep polling.

Enrichment tracks progress separately. Its status starts at NOT_STARTED, reports a progressPercent from 0 to 100 as it runs, and finishes at DONE or FAILED.

Exports

Both exports run in the background and are free, but they draw on your export quota: maxRowsToExport defaults to whatever quota you have left, and each response tells you estimatedRows and maxRowsAllowed. Pass userEmail to get the CSV links by email; leave it out and the links come back in the API response.

ExportFormats
CompaniesCOMPANY_GENERIC_CSV, COMPANY_LI_ADS_CSV (LinkedIn Ads)
ProspectsPROSPECT_GENERIC_CSV, PROSPECT_LI_ADS_CSV, PROSPECT_META_ADS_CSV, PROSPECT_GOOGLE_ADS_CSV

Set onlyWithContacts: true on a prospect export to keep only people with verified emails or phones. Use excludeFields to drop columns you don't need.

Reading members without exporting

The company and prospect reads return an audience's members page by page, up to 500 per page. Pass the nextCursor from each response as cursor on the next call; hasMore turns false on the last page. Companies come back with name, domain, LinkedIn URL, industry, and headcount; prospects with name, LinkedIn URL, job title, company, and location. Both are free.

Webhooks

Instead of polling, you can subscribe to audience.build_completed, audience.enrichment_completed, audience.company_export_completed, and audience.prospect_export_completed. Setup and payloads: Webhooks.

What you can call

OperationWhat it doesReference
Create an audiencePOST /v1/audiences/create. Starts an empty audience in DRAFTcreateAudience
Set filtersPATCH /v1/audiences/{audienceId}/search-params. Company and prospect filters; DRAFT onlyupdateAudienceSearchParams
BuildPOST /v1/audiences/{audienceId}/build. Fills the audience in the backgroundbuildAudience
Build statusGET /v1/audiences/{audienceId}/status. Status, timestamps, and countsgetAudienceStatus
Enrichment cost estimatePOST /v1/audiences/{audienceId}/enrichment/estimate. Credit total, breakdown, and time estimateestimateEnrichmentCost
EnrichmentPOST /v1/audiences/{audienceId}/enrich. Adds emails and phones to the audience's prospectstriggerEnrichment
Enrichment statusGET /v1/audiences/{audienceId}/enrichment/status. Stage and percent completegetEnrichmentStatus
Company exportPOST /v1/audiences/{audienceId}/export/companies. CSV or LinkedIn Ads fileexportCompanies
Prospect exportPOST /v1/audiences/{audienceId}/export/prospects. CSV or ad-platform fileexportProspects
List audiencesGET /v1/audiences. Every visible audience with status and countslistAudiences
Read companiesGET /v1/audiences/{audienceId}/companies. Paged company membersgetAudienceCompanies
Read prospectsGET /v1/audiences/{audienceId}/prospects. Paged prospect membersgetAudienceProspects
Archive an audienceDELETE /v1/audiences/{audienceId}. Hides it from view; data and enrichment history are keptdeleteAudience
Exclusion list from an audienceTurns an audience's companies or prospects into an exclusion listcreateCompanyExclusionListFromAudience / createProspectExclusionListFromAudience

Create, build, and enrichment are rate-limited at 30 requests per minute. The other audience operations above allow 120 per minute.

A building audience can't be archived. Wait for the build to reach NORMAL or FAILED first.

Using it effectively

  • Confirm before each charge. Build and enrichment are the only steps that cost credits. If an agent or script drives the workflow, have it stop and confirm before each of those two calls.
  • Run the free estimate with the exact settings you plan to enrich with, then send the same body to enrichment. Turn off channels you won't use: at 2 credits per personal email, skipping them on a 5,000-person audience saves up to 10,000 credits.
  • Poll enrichment about every 30 seconds, or skip polling and listen for the completion webhooks.
  • Keep both the audienceId and the enrichmentId; you need the first for every call and the second to match a run to its status.
  • Keep exclusions current. After each build, turn the audience into an exclusion list so the next build skips everyone you already have.
  • Use onlyWithContacts on prospect exports headed for outreach tools, so your quota goes to rows you can act on.

Use cases

  • Outbound list builds: a RevOps script creates an audience per campaign from your ICP filters, enriches work emails only, and pushes the export to your sequencer.
  • Paid social targeting: build an account list and export it in the LinkedIn, Meta, or Google Ads format for matched-audience campaigns, without enriching at all.
  • Agent-driven prospecting: an AI agent sets filters from a plain-language brief, shows the user the enrichment estimate, and enriches only after a yes.
  • Sequential campaigns: after each build, create an exclusion list from the audience so the next quarter's build contains only new names.

Credits

StepCost
Build1 credit per company and 1 credit per prospect found, charged after the build completes
Enrichment2 credits per work email, 2 per personal email, 3 per phone number, and 1 per prospect live enrichment, charged when you trigger it, based on the estimate
Everything elseFree: create, set filters, both status checks, the estimate, list, member reads, exports, and archive

Exports cost no credits but count against your export quota. chargeInfo on every response is the authoritative record of what was charged. See Billing & credits.

On this page