---
title: "Create a knowledge hub from websites"
method: POST
path: "/business/knowledge-hubs"
tags: ["Knowledge hubs"]
---

# Create a knowledge hub from websites

`POST /business/knowledge-hubs`

## Request

- Base URL: `https://api.tryfuse.ai/api/v1`
- URL: `https://api.tryfuse.ai/api/v1/business/knowledge-hubs`
- Auth: HTTP basic

Creates the hub immediately with `status` `processing` and enqueues the build: every website is crawled (subpages too where `includeSubPages` is true), the content is synthesized into knowledge pages, and a company name — and, when `name` was omitted, the hub name — are generated. Poll `GET /business/knowledge-hubs/{hubId}` until `status` is `complete`; `draft` means the build did not finish — it exhausted its retries (hubs saved as drafts in the web app carry the same status without ever having been built). Until the build finishes a hub created without a name carries the placeholder "Processing...", and `websites` lists only what you sent — the crawler's subpages appear later. Building does not debit credits. Inline file attachments are not accepted here: add them per note via `POST /business/knowledge-hubs/{hubId}/attachments` once the hub is `complete`. A team holds one knowledge hub, shared by everyone on it: this answers 409 `KNOWLEDGE_HUB_ALREADY_EXISTS` while your team's is `processing` or `complete`, and the hub it creates is always your default one (`isDefault` in the body is ignored). A `draft` hub does not count: creating a hub replaces it as your default.

Errors:
- `409` `KNOWLEDGE_HUB_ALREADY_EXISTS` — Your team already has a knowledge hub that is built or building, and a team holds one. Add to it with PATCH /business/knowledge-hubs/{hubId} instead.
- `422` `VALIDATION_FAILED` — The body failed validation locally, or a website URL the crawler cannot parse was rejected by the builder.
- `500` `UNEXPECTED_ERROR` — The build workflow could not be enqueued (upstream STATE_MACHINE_ERROR); no hub was created — retry.
- `429` `RATE_LIMITED` — More than 30 knowledge-hub/campaign requests in a minute (or 1000 in a day). Knowledge hubs share the campaigns bucket.

Requires one of the following token scopes: campaigns.

## Request body

- object
  - `name` string: Hub name (1-100 characters); omit to have one generated from the crawled content once the build finishes.
  - `websites` object[], required: Websites the hub is built from: at least 1, at most 20. Accepted values for each entry's url: any http(s) web address, with or without the scheme (brightpay.com, https://brightpay.com/pricing). Every entry is crawled and all of the collected text is pooled into ONE set of knowledge pages — entries are not kept apart, and a page reached from two entries is used once. The crawl runs in the background after the 202, so a site that cannot be fetched is never reported as an error: its entry stays on the hub with lastCrawledAt null and contributes nothing. Read the hub back to check.
    - `url` string, required: Website to crawl (4-2048 characters), with or without the scheme, e.g. brightpay.com or https://brightpay.com/pricing; an unparseable URL answers 422 VALIDATION_FAILED.
    - `includeSubPages` boolean: Also crawl the site's subpages (up to 100 per crawl; a re-crawl skips subpages the hub already stores and keeps only the newly found ones); default false.
    - `isCompetitor` boolean: Treat the site as a competitor: its content feeds competitor pages instead of the company's own profile; default false.
  - `notes` object[]: Free-text notes to include as sources (up to 50). Inline file uploads are not accepted here.
    - `text` string, required: Free-text knowledge to include (1-60,000 characters), e.g. positioning, objection handling, internal docs.
    - `filename` string: Label the note is cited by in generated pages, and the key a later PATCH merges this note on (1-255 characters). Free text; omit it and the note is filed under the literal "Internal Document". Give every note a distinct value: notes that share one (two notes without a filename share the default) are all stored, but only the first is read when the hub's pages are generated — the rest contribute nothing and no error is returned.
    - `isCompetitor` boolean: Treat the note as competitor material rather than the company's own; default false.
  - `isDefault` boolean: Deprecated and ignored. A team holds one knowledge hub, so the hub created here is always its creator's default one; the field is still accepted so existing requests keep working.

## Response `202`

Success

- object
  - `knowledgeHub` object, required
    - `id` string, nullable, required
    - `name` string, nullable, required: The name you sent, or the placeholder "Processing..." until the build generates one.
    - `companyName` string, nullable, required: Always null on creation; filled in by the build.
    - `status` 'processing' | 'complete' | 'draft' | 'null', nullable, required: processing = the crawl and page synthesis are running, complete = the hub is usable, draft = the hub is not built — either it was saved as a draft in the web app and never built, or its last build exhausted its retries.
    - `isDefault` boolean, required
    - `websites` object[], required: The websites you added plus the subpages the crawler discovered from them (subpages carry parentUrl).
      - `url` string, nullable, required
      - `includeSubPages` boolean, required: Whether the site's subpages were expanded when it was added.
      - `isCompetitor` boolean, required
      - `parentUrl` string, nullable, required: Set on subpages the crawler discovered: the website they were collected from. null on a website you added yourself.
      - `lastCrawledAt` string, date-time, nullable, required: When this URL was last successfully crawled; null if it has never been crawled.
    - `notes` object[], required
      - `id` string, nullable, required: Note id; the attachment endpoints address notes by it.
      - `text` string, nullable, required
      - `filename` string, nullable, required: Label the note is cited by, and the key notes are merged on when the hub is updated.
      - `isCompetitor` boolean, required
      - `hasAttachment` boolean, required: Always false on creation — attach documents once the hub exists.
    - `createdAt` string, date-time, nullable, required
    - `updatedAt` string, date-time, nullable, required

## Other responses

- `400`: Error
- `401`: Error
- `402`: Error
- `403`: Error
- `404`: Error
- `409`: Error
- `422`: Error
- `429`: Error
- `500`: Error

---

[API](https://skmtc.dev/fuseai/apis/fuse-business-api.md) · [All operations](https://skmtc.dev/fuseai/apis/fuse-business-api/llms.txt) · [OpenAPI document](https://skmtc.dev/fuseai/apis/fuse-business-api/revisions/50d95e0536f4?raw)
