Skip to content
XICBOT

Settings

Deutsch
Documentation · Operations and security

Background jobs

Which work XICBOT does in the background, in what order, how often a failed job is retried and how long jobs are kept.

In plain language

Some work takes longer than a single request. One example is reading a website. Such work runs in the background. You get an answer right away, and the work follows later. This page lists the kinds of jobs. It shows in which order they get their turn. It says what happens after an error. And it says how long a job is kept.

Last updated

All documentation topics

Some work takes longer than a single request: reading a website, recalculating knowledge, syncing a shop, delivering emails and webhooks, running an assistant's check questions. XICBOT accepts such work as a background job, answers right away and does the job afterwards. This page covers which jobs exist, in what order they get their turn, what happens when one fails and how long a job is kept.

What runs in the background

Every job has a type (task), a lane and a priority. The lane follows from the type; the priority is set by whatever creates the job. A lower number means an earlier turn.

TypePurposeCreated byLanePriority
source.ingestRead a website source for the first timeCreating a source of type website, in the app or through the API with an API keyindex3
source.refreshRead a website source againRe-read, optionally with Rebuild completely (3); the daily refresh run for website sources that are due, and the refresh of a stale source that an answer draws on (7)index3 or 7
knowledge.rebuildRecalculate enrichment and vectors of the sectionsCreating any source in the app other than a collection of question-answer pairs or through the API with an API key, Re-read, reading the website during a setup and POST /api/v1/knowledge/embed (5); an automatic refresh (8)index5 or 8
setup.proposeBuild a setup proposal from your websiteStarting a setupindex3
assistant.checkRun through an assistant's check questionsStart acceptance run for an assistant, see Test dialog and acceptanceindex5
shop.syncPull the catalogue from a connected shopManual sync with Sync now (5); scheduled hourly sync for active accounts with an active connection and shop integration in their plan (7)index5 or 7
webhook.deliverDeliver an event to a webhookEvery event an active webhook subscribes to, one job per webhook, provided the plan includes the feature for keys and webhooksdefault3
mail.sendSend an emailHanding a conversation over to a person (3); other emails (default 5)default3 or 5
report.weeklyBuild an account's weekly reportWeekly schedule on Monday, one job per active account that has not unsubscribed from the weekly reportdefault7

When the daily refresh run, the hourly shop sync and the weekly report start is covered in Schedules.

Lanes and order

The index lane carries the long runs: reading sources, recalculating, setup, acceptance runs and shop sync. The default lane carries everything else, namely emails, webhooks and the weekly report. The split is meant to keep an email or a webhook from waiting minutes behind a source being read.

On each lane XICBOT takes the waiting job with the lowest priority number and, with equal numbers, the older one. A job sitting out its wait after a failed attempt is skipped until that wait is over.

PriorityJobs
3Creating a website source, Re-read, setup, webhook delivery, email for a handover
5Recalculating after a source is created or re-read, after a setup has read the website and via POST /api/v1/knowledge/embed, acceptance run, manual shop sync, other emails
7Daily refresh run, refresh during an answer, scheduled shop sync, weekly report
8Recalculating after an automatic refresh

Job states

StateMeaning
pendingWaiting for its turn, including between two attempts. After a failed attempt its reason is in error.
runningBeing processed right now. The attempt has already been counted and the error text of an earlier attempt is cleared.
doneFinished. The outcome is in result and the error text is cleared.
failedFailed for good: the last attempt went wrong or the job expired. The reason is in error.

Retries after a failure

A job has up to three attempts. An attempt counts as soon as XICBOT picks the job up. If it fails and attempts are left, the job goes back to pending with a wait. If the third attempt fails, the job stays on failed for good. The error text remains on the job, cut to 500 characters. A job that has failed for good raises a critical notice with the source queue for operations; see Notices.

AfterWait on defaultWait on index
the 1st failed attempt30 seconds2 minutes
the 2nd failed attempt2 minutes10 minutes
the 3rd failed attemptno further attempt, failedno further attempt, failed

What counts as a failure

  • Reading a source: if the source is not ready after the run, the attempt has failed. Every failed attempt triggers the webhook event knowledge.failed; a successful one triggers knowledge.indexed with the number of documents and sections. If the build fails after fetching, the source shows not indexed with the reason ingest_failed, and the existing content keeps answering. If the source has been deleted in the meantime, the job counts as done without being carried out; its result carries skipped with source_deleted.
  • Acceptance: if the check run has been deleted along with its assistant, the job counts as done without being carried out (skipped with run_deleted). If the job fails for good, is recovered as failed or expires, the check run shows stopped with the reason job_failed; see Test dialog and acceptance.
  • Webhook: only a response with a 2xx status counts as delivered. XICBOT does not follow redirects (3xx); they count as a failure, as does a response that takes longer than 8 seconds. If the webhook has been deleted or switched off in the meantime, or the plan no longer includes the feature for keys and webhooks, the job counts as done without delivery.
  • Switching off a webhook: after 20 failed delivery attempts in a row XICBOT switches the webhook off; every retry counts. A successful delivery resets the counter.
  • Email: an email already recorded as sent does not go out again on a further attempt. A handover email is no longer sent if the conversation has been deleted in the meantime.
  • Shop sync: a failed fetch from the shop does not make the job fail: it ends on done, and its result carries ok: false with the reason under error. The existing catalogue stays, the error is shown on the connection, and the next scheduled sync tries again.

Webhook signatures, headers and events are covered in API keys and webhooks, connecting a shop in Catalogue, basket and shop connection.

Stuck and stale jobs

A job that has been marked as running for more than an hour, or whose worker process is no longer running, counts as orphaned. XICBOT resets it when the background service starts and during the hourly maintenance: to pending while attempts are left, otherwise to failed. The error text gives the reason; for the one-hour limit it reads „seit mehr als 3600 Sekunden ohne Fortschritt“ (more than 3600 seconds without progress).

A job that is still waiting or running 7 days after it was created expires during maintenance. It ends on failed with the error expired and is not carried out further; its end is taken as 7 days after creation. If an email was still waiting to be sent with it, that email counts as failed with the note „Versandauftrag nach 7 Tagen abgelaufen“ (send job expired after 7 days).

Duplicate jobs

In several places XICBOT creates no second job while one of the same kind is open, that is waiting or running:

  • Re-read on a source that already has an open intake or refresh job, including the first intake of a new website, takes over that job; the response carries already_open: true. If you tick Rebuild completely while a job without a rebuild is still waiting, the job picks up the rebuild. If it is already running, the API answers 409 with refresh_running and the app reports “A build is running or queued for this source. Please try again afterwards.” When an open job is taken over, the recalculation is still queued in addition.
  • The daily refresh run and the refresh during an answer skip a source that already has an open intake or refresh job.
  • POST /api/v1/knowledge/embed takes over an open recalculation job of the account, even one for a different source; a source_id you pass then has no effect.
  • A manual sync takes over an open sync; the app then reports “A sync is already waiting.”, otherwise “The sync has been queued.” If no sync is open, a lock applies until 15 minutes after the last manual request: response 429 with sync_too_soon, retry_after (seconds) and the Retry-After header. The app then reports “A manual sync is possible at most every 15 minutes. The regular sync continues independently.”
  • The scheduled hourly sync skips an account that already has an open sync.
  • The weekly schedule skips an account that already has a weekly report job this week or has already been sent the report.
  • An acceptance run for an assistant that already has an open run returns that run, provided it was created less than an hour ago.
  • While a source has an open intake or refresh job, no earlier version of that source can be restored: response 409 with refresh_running.

Tracking jobs through the API

When a request creates a job, the API answers with 202 and a job object holding id, status and task: when creating a website source, for POST /api/v1/knowledge/sources/{id}/refresh and for POST /api/v1/knowledge/embed. The manual sync via POST /api/v1/catalog/shop/sync returns the ID as job_id, together with already_pending; it requires the Administration role. GET /api/v1/knowledge/jobs/{id} returns the state of each of these jobs, including the sync.

GET /api/v1/knowledge/jobs/{id}

Returns the state of a job under job: id, task, status (pending, running, done, failed), attempts (number of attempts started), error (reason of the last failure; empty while an attempt is running and after success), result (outcome of a finished job) and finished_at (end time for done and failed in ISO 8601 format, otherwise empty). An ID that does not belong to your account returns 404 with not_found.

Authentication
Signed in, confirmed email address, any role

POST /api/v1/knowledge/sources/{id}/refresh

Reads a website source again and then queues the recalculation. The optional field rebuild (true or false) rebuilds every section, even where the text has not changed. If an intake or refresh job is already open for the source, the request takes it over. If it asks for rebuild while that job is already running without a rebuild, the API answers 409 with refresh_running. Returns 202 with job and already_open; if an open job was taken over, job names that job, and its task can then also be source.ingest. A source that does not belong to your account returns 404 with not_found; a source that is not a website returns 422 with website_only.

Authentication
Signed in, confirmed email address, Edit role or higher
Rate limit
20 per minute per signed-in user, shared with creating sources, restoring a version and POST /api/v1/knowledge/embed

POST /api/v1/knowledge/embed

Queues the recalculation of enrichment and vectors. Without source_id the job covers all sources of the account; with the optional source_id (an ID in UUID format) only that source. Only sections without a current state are calculated, at most 20000 per job; whatever is left is reported as remaining in the job result. If a recalculation job is already open for the account, the request takes it over. Returns 202 with job, already_open and the state at the time of the request across all sections of the account: vectors with chunks, embedded and pending, enrichment with chunks, enriched and pending. In the app, Build spread triggers this.

Authentication
Signed in, confirmed email address, Edit role or higher
Rate limit
20 per minute per signed-in user, shared with creating, refreshing and restoring sources

How long jobs are kept

  • Once a job is done or has failed for good, XICBOT cuts its data down to references such as source, run, account, email template, delivery, webhook and event. Recipient, email content and the content of a webhook message are dropped; if anything was dropped, the job carries the marker reduced.
  • Done and failed jobs are deleted 14 days after they end. Until then type, times and error text remain.
  • When you delete a conversation, the related email and webhook jobs go with it. Open webhook deliveries of the events lead.created and appointment.requested stay, because they report a case.
  • Your account's jobs are part of the data export. Under Legal and data, the Stored data table counts them in the Background jobs row. They are deleted together with the account.

Retention periods for conversations and other data are in Retention and deletion, export and account deletion in Privacy and legal.

Frequent questions

Why is my website source not ready yet after creating it?

It is being read in the background. Creating it answers right away, and the job gets its turn on the index lane by priority and age. After Re-read the app shows “The source is being indexed in the background. The status updates on its own.” Through the API you can check the state with GET /api/v1/knowledge/jobs/{id}.

How often does XICBOT retry a failed webhook delivery?

Up to three times in total: the second attempt no earlier than 30 seconds after the first failure, the third no earlier than 2 minutes after the second. If that one fails too, the job has failed. After 20 failed delivery attempts in a row, retries included, XICBOT switches the webhook off.

Can I restart a failed job?

Trigger the work again, for example with Re-read on the source or Sync now in the shop connection. That creates a new job, again with three attempts.

How long do the recipient and content of an email stay in the job?

Until sending is done or has failed for good. XICBOT then cuts the job down to references and deletes it 14 days after it ends. If a send waits longer than 7 days, the job expires.

Why did the knowledge.failed event arrive several times for the same source?

Every failed attempt to read the source triggers it, and a job has up to three attempts.

Something still unclear?

Tell us which page and which step you mean. We reply personally.

Enquiry in three steps

  1. 1. Topic
  2. 2. Your case
  3. 3. Contact

What is this about?

One click is enough, everything else is optional.

Tell us briefly about your case

Everything in this step is optional. It helps us reply with something concrete straight away instead of asking back.

Enquiries per month, roughly (optional)
When should it start? (optional)
How can we reach you?

Name and email address are enough. We reply personally.

We use your details to handle your enquiry. More on this in the privacy policy.