Connectors
Pull documents into an index from a CMS, a sitemap, a feed or a docs crawler — and keep them in sync on a schedule.
A connector is a saved source plus a mapping. It reads documents from somewhere outside AACSearch and writes them into one index.
There are two families, and they fail in different ways, so it is worth knowing which one you are configuring.
| Family | Types | Knows about deletions | Setup |
|---|---|---|---|
| CMS | bitrix, wordpress, shopify | Yes — the platform reports them | Install a module or plugin |
| Feed | sitemap, url, json, csv, xml, yaml | Only by set difference | Paste a URL |
| Crawler | docsearch | Only by set difference | Paste a docs URL |
Choosing a type
| Your source | Type | Why |
|---|---|---|
| 1C-Bitrix store | bitrix | Incremental by product event, SKU-aware, deletions included |
| WordPress site | wordpress | Posts, pages, custom post types; trash/unpublish handled |
| Shopify store | shopify | Products, variants, collections; inventory-aware |
| Documentation site with a sitemap | sitemap | Walks every URL, extracts text |
| Docusaurus / Algolia DocSearch site | docsearch | Hierarchical headings, anchor-level results |
| ERP export, headless CMS | json | Any array in any JSON payload |
| Spreadsheet or CSV dump | csv | Delimiter and field mapping |
| RSS / Atom feed, Yandex Market YML, Google Merchant feed, XML export | xml | Format auto-detected; see XML and YAML feeds |
| YAML data file | yaml | List or map of records with field mapping |
| One hand-maintained page | url | Single fetch |
CMS types exist because a feed cannot tell you that a product was deleted. The module sits inside the platform and forwards what happened. Supported CMS platforms are Bitrix, WordPress and Shopify; they are all configured as connectors, as described on this page.
Where connectors are managed
Note: connectors are managed in the console (Search → Connectors). There is no public REST endpoint for creating or running a connector yet; the REST surface covers documents, search, and index settings. Automation should call the console's job history or drive a feed that a connector reads.
Console operations, all on the connector row:
| Action | What it does |
|---|---|
| Create | Stores type, config, schedule, mode |
| Update | Changes config or schedule; next run uses the new values |
| Run now | One synchronous run, ignores the schedule |
| Disable | Stops scheduled runs; keeps documents |
| Delete | Removes the connector; documents stay unless you prune them |
A deleted connector leaves its documents in the index on purpose. Uninstalling a
plugin should not empty your search results — to remove the documents, run a
full-mode prune or delete by source_type.
Configuration shared by all types
| Key | Used by | Notes |
|---|---|---|
url | all | must be http(s) and publicly resolvable |
rootField | json | path to the array, e.g. data.items |
idField | json, csv, docsearch | falls back to external_id, then id, then a content hash |
titleField, contentField, urlField | json, csv | field mapping |
tagsField | json, csv | array or comma-separated string |
delimiter | csv | defaults to , |
maxDocuments | all | hard cap per run, default 500 |
defaults | all | static fields merged into every document |
extractText | sitemap, url | strip HTML before indexing |
pruneDeleted | all | delete documents that vanished from the source |
mode | all | full or delta |
Crawler identity and robots
Connectors that fetch HTML (sitemap, url, docsearch) identify themselves as
AACSearchBot/1.0 (+https://aacsearch.dev/bot) on every request, including
robots.txt. Machine feeds (json, csv, xml, yaml) do not use this bot
or read robots rules — you point them at an explicit feed URL.
For each site origin, the crawler loads /robots.txt once per run (10 s
timeout, 500 KB cap). Rules follow RFC 9309:
the most specific User-agent group applies (AACSearchBot, then *), longest
path match wins, and Allow beats an equally long Disallow. If robots.txt
returns 404, everything is allowed; if it returns 5xx or times out, the run stops
with ROBOTS_UNAVAILABLE and complete: false so pruning does not delete
documents that were not re-checked.
Disallowed URLs are skipped (counted as robotsDisallowed), not errors.
Crawl-delay is honoured as a pause between requests to the same origin (capped
at 10 s); without it the default gap is 250 ms. Page-level X-Robots-Tag,
<meta name="robots">, and <meta name="aacsearchbot"> are respected:
noindex drops the page, nofollow keeps the page but does not enqueue links
(docsearch). Run history shows robotsDisallowed, noindex, and nofollow
when they explain a smaller index than expected.
idField and why it matters
The identifier determines whether a run inserts a document or updates it. Getting it wrong is the most expensive mistake in a connector: every run creates a second copy of every document, and the original is then pruned as "missing from the source".
The resolution order is:
config.idField— the field you name;external_id— the convention every CMS adapter uses;id— often present in JSON exports;- a hash of the content — last resort, and it changes when the content changes.
Only the fourth produces duplicates. If your document count doubles after a run, this is the setting to check first.
What a run does
Every run follows the same five steps:
read source → normalise → compare payloadHash → write changed → prune vanishedThe comparison is why a stable catalogue costs almost nothing: 40 000 items with three changes writes three documents. See delta sync.
Scheduling
Set cronExpr and timezone, or use a fixed interval. Deletions are only pruned
after a complete run, which is what makes a nightly full sync meaningful for a
documentation site. See scheduling.
| Scenario | Recommended |
|---|---|
| Store, ERP updates during the day | */15 * * * *, delta |
| Documentation site | 0 4 * * *, full |
| One-off import | manual |
Verifying a connector
The console lists the last 20 jobs per organisation with loaded, indexed,
skipped, pruned and failed. Reading them:
| Observation | Likely cause |
|---|---|
indexed = loaded every run | idField wrong, or a field will always differ |
skipped = 0 on an unchanged source | mapping changed, which rewrites everything once |
pruned larger than expected | incomplete run treated as complete, or maxDocuments capped the read |
failed > 0, status partial | some documents rejected — the error column names the field |
failed and no indexed | source unreachable, or auth failed |
Limits
| Limit | Value |
|---|---|
| Documents per run | 500 by default, hard ceiling 5 000 (maxDocuments) |
| Timeout | per-request; a large source needs pagination |
| Concurrent runs | one per connector — a second run is refused, not queued |
| SSRF | private ranges and metadata IPs are blocked |
CMS push module operations
Bitrix, PrestaShop and DIAFAN modules run inside your CMS and bundle the generated PHP SDK. Install the module ZIP from the connection wizard, paste its connection string, review discovered fields, apply the schema and start a full sync. Keep the module scheduler enabled: full runs resume from acknowledged batch checkpoints; commands, deltas and deletes also depend on scheduler ticks.
Use an index-bound CMS key with documents:write, indexes:write, search:read.
Keys remain on the CMS server. Switching the API endpoint or index clears the old
sync cursors. Storefront search checks current CMS visibility and falls back to
native search for stale or restricted hits or backend timeouts. Autocomplete
returns no restricted hits. Check the organization's document limit before
importing a large catalog; push modules use the same quota as other ingestion.