Docs
Documentation

Knowledge Sync API

Push FAQs, documents, rows and offerings from your own system.

On this page: Basics · Knowledge records · The 202 answer · Deletes · Credits · Offerings feed · Your original fields · Errors

Basics

EndpointPOST http://centralai.daffodil-bd.com/knowledge/api/v1/sync/
CredentialYour external API key in the X-API-Key header. It is secret: call this API from your own server only. See Security and keys.
PlansGrowth, Scale, Enterprise (the API Sync feature).
BodyJSON: action, records, and optionally source_name or "type": "offering".
Actionscreate, update, upsert, delete. Default: upsert.

Use it to keep your agent in step with a database, CRM, LMS or shop you already run: send a record when it changes, and delete it when it goes away. There are two destinations:

  • Knowledge records (the default): text your chat agent answers from.
  • Offerings ("type": "offering"): rows in What you sell, with a price.

Knowledge records

Every record needs an id: your own, stable id for it. Sending the same id again updates the record instead of adding a second one. The fields decide what kind of record it is:

ShapeWhenWhat the agent reads
FAQThe record has question and answer. The question and answer. The FAQ also appears in Training Data, with title, description, url and price when you send them.
DocumentThe record has content (and no question and answer).The content as it is.
RowAnything else.Every non-empty field except id, as field: value | field: value.
curl -X POST "http://centralai.daffodil-bd.com/knowledge/api/v1/sync/" \
  -H "X-API-Key: YOUR_EXTERNAL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "upsert",
    "source_name": "Help centre",
    "records": [
      {"id": "faq-001", "question": "Do you deliver outside Dhaka?",
       "answer": "Yes, anywhere in Bangladesh in 3 to 5 days.", "url": "https://yourshop.com/delivery"},
      {"id": "doc-001", "title": "Refund policy", "content": "You can return any item within 7 days..."},
      {"id": "row-001", "branch": "Gulshan", "hours": "10 AM to 8 PM", "phone": "+880 1XXX-XXXXXX"}
    ]
  }'
  • source_name groups the records under one source in your knowledge base. Default: API Sync.
  • A record whose text is shorter than about ten characters is skipped.
  • Each record is one piece of knowledge; it is not split. The agent is given about the first 4000 characters of a record, so send a long document as several records (one per section).
  • create refuses an id you already sent; update refuses one you never sent; upsert does either.

The 202 answer

Knowledge records are accepted at once and processed in the background, so the answer is 202 Accepted:

{"success": true, "status": "processing",
 "message": "Accepted 3 records for processing in the background.",
 "results": {"action": "upsert", "accepted": 3}}

The answer does not list per-record results. When processing finishes, your company admins get an in-app notification, API Knowledge Sync Completed, with how many records were created, updated and deleted. A record whose content has not changed is skipped. Records appear under their source in your knowledge base; check there if a record you sent is missing (it may have had no id or too little text).

Deletes

{"action": "delete", "records": [{"id": "doc-001"}, {"id": "row-001"}]}

A delete names records by id and removes them from your knowledge base. An id you never sent is ignored. An FAQ that a synced record created can stay listed in Training Data after the record is deleted; delete it there too if you see it.

Credits and limits

  • Each new record uses one knowledge credit. Updates, unchanged records and deletes use none.
  • Deleting a record does not give its credit back.
  • A create or upsert call is refused (403) when it carries more records than you have knowledge credits left, even if some of them are updates. Split the call, or buy more credits.
  • There is no other fixed limit on the number of knowledge records in one call; keep calls to a few hundred records.

Offerings feed ("type": "offering")

With "type": "offering" the records become offerings, the structured rows (with prices) that the chat agent and the AI Sales Agent sell from.

curl -X POST "http://centralai.daffodil-bd.com/knowledge/api/v1/sync/" \
  -H "X-API-Key: YOUR_EXTERNAL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "offering",
    "action": "upsert",
    "records": [
      {"id": "NN-101", "name": "Oslo 3-Seater Sofa", "kind": "product",
       "price": "48500", "currency": "BDT", "stock": 6, "category": "Sofas",
       "url": "https://yourshop.com/product/nn-101",
       "image_url": "https://yourshop.com/images/nn-101.jpg"}
    ]
  }'

Fields

FieldWhat it is
idRequired. Your own id for the offering. The same id always updates the same offering.
nameRequired to create. Up to 255 characters.
kindOne of the offering kinds below. Default: product.
priceA number that is not negative, such as 1250.00. Required unless quote_required is true.
currencyThree-letter code such as BDT or USD. Default: your company currency.
quote_requiredtrue when the offering is priced on request (no list price).
skuYour SKU, up to 100 characters.
descriptionLong description, up to 20,000 characters.
subtitleOne or two lines for the chat card, up to 500 characters.
categoryCategory name. Created when you do not have it yet; empty removes the category.
stockWhole number of units in stock; switches stock tracking on. Empty or null switches it off.
urlThe page where the customer buys, books or applies (https). Drives the card's page button.
image_urlImage link (https).
tagsA list of short words customers might search for.
activefalse archives the offering; true (or sending it again) brings it back.
featuredtrue marks the offering as featured.

Kinds: product (Product), service (Service), course_intake (Course intake), appointment (Appointment), event_date (Event date), plan (Plan), custom (Custom). A field not in this list refuses that record. At most 20 tags are kept.

How the feed behaves

  • At most 500 records per call. A larger call is refused whole.
  • The answer is immediate (200) and lists every record that was refused, with its reason. One bad record never blocks the others.
  • No knowledge credits. Offerings count against your plan’s offering limit instead: a record that would add an active offering past it is refused with Offering limit reached (N active offerings) (N is your limit).
  • Delete archives the offering (it is never erased). Sending the same id again brings it back.
  • Synced offerings are read-only on the offerings screen: change them in your system and sync again.
{"success": true, "type": "offering",
 "results": {"action": "upsert", "processed": 1, "created": 1, "updated": 0,
             "archived": 0, "skipped": 0, "errors": []}}

A refused record appears in errors as {"id": "NN-102", "error": "price: required unless quote_required is true."}.

Your original fields are kept

Central AI keeps each knowledge record exactly as you sent it (up to 32 KB of JSON per record), not only the text it made from it. That lets later features use fields the text does not carry. Today: Find what I sell takes a record’s page link from its url, link, page_url field (the first one that is an https:// address). So send a url with every record that has a page on your site.

Errors

Knowledge Sync answers errors as {"error": "<message>"}, without a code.

HTTPWhy
401Missing X-API-Key header, Invalid API key, or a message saying the widget key was sent (use your external API key).
403No active subscription, API Sync not on your plan, or not enough knowledge credits. The answer carries upgrade_url.
400The body is not a JSON object, there are no records, the action is unknown, or (offerings) the call has too many records.
500An unexpected error. Safe to retry later.

Signed in? The full reference is on your dashboard’s API reference.

Signed in? Your own keys, endpoint addresses and the full error tables are on the API reference inside your dashboard. These public pages never show anyone’s key: examples use placeholders such as YOUR_EXTERNAL_API_KEY.