Skip to main content

Rebuilding the Graph

This tutorial shows how to run a graph rebuild job: when to use one, how to choose a rebuild mode, how to keep the job scoped to the documents you mean, and how to follow it to completion. A rebuild job selects documents with an HXQL query and submits them to Context for reprocessing into the knowledge graph. Which documents are reprocessed depends on the rebuild mode.

Prerequisites​

  • A valid access token (see Authentication)
  • The base URL of your environment
  • content-lake-api.graph-jobs.create and content-lake-api.graphs.edit to submit a job, and content-lake-api.graph-jobs.read to monitor it (all three are in the Content Lake ECE Administrator role)
  • A graph database with ontology routes (see Setting Up the Knowledge Graph)

Set two variables before running the curl examples. The HTTP examples use the equivalent {{baseUrl}} and {{accessToken}} placeholders.

export BASE_URL="https://{environment_id}.content-lake.ai.experience.hyland.com"
export TOKEN="<access token from the identity provider>"
Before You Start

All endpoints require an authenticated caller with the permissions listed in the prerequisites. A caller without the required permissions receives 401 Unauthorized.

Tutorial Overview​

In this tutorial, you'll learn to:

  1. Decide when to rebuild and which mode to use
  2. Scope a rebuild to one graph database
  3. Submit a rebuild job
  4. Poll the job until it finishes
  5. List jobs and filter by state
  6. Recognize the validation errors

Step 1: Choose When and How to Rebuild​

Rebuild after you add or change ontology routes, so that documents already in the Cloud Content Repository are evaluated against them, or to recover the graph (bootstrap and disaster recovery).

ModeDescription
STANDARDEvaluates the ontology rules again. An event is fired and submitted to Context for reprocessing only for documents whose ontology references were updated. Use after ontology or route changes.
EVENT_ONLYFires events based on the results of the previous rule execution, without evaluating the rules again. Use when the rules have not changed but you want to reprocess the documents anyway.
FORCE_REPROCESSFires an event and submits it to Context for reprocessing for every document that matches the ontology configuration, including documents whose ontology references did not change. Use to force extraction to run again.

Step 2: Scope the Rebuild​

Scope a rebuild carefully

A rebuild with no graphDBId and no query covers the routes of every configured graph database. To limit a rebuild to one graph database, pass its graphDBId. The generated query is then scoped to that graph database's route conditions only, and it never falls back to "all documents": if there are no routes, the request is rejected.

graphDBId only selects which documents the job processes. Each selected document is still evaluated against the routes of every graph database, so its graph properties can also reference other graph databases whose routes match it.

FieldTypeRequiredDescription
repositorystringNoRepository name. Defaults to "default".
graphDBIdstringNoLimit the auto-generated query to the ontology routes of this graph database. If omitted, the routes of all configured graph databases are used. Cannot be combined with query.
rebuildModestringNoOne of the rebuild modes, case-insensitive. Defaults to STANDARD.
querystringNoHXQL query selecting the documents to rebuild. If omitted, the query is generated from the configured ontology routes. Cannot be combined with graphDBId.
Route conditions need the content. prefix

The generated query comes from the route conditions. A route condition that names a property without the content. prefix, such as sys_id == "...", makes the rebuild fail with 400 No global property: sys_id. See ontology routes.


Step 3: Submit the Rebuild Job​

Start a new graph rebuild job. Requests must use Content-Type: application/json. All fields are optional.

To make retries safe, send an optional Idempotency-Key header with a value unique to this request. The job is then submitted at most once per key, and a repeat call with the same key returns the original result, marked with the Idempotent-Replay response header. Keys are scoped to the caller, so two users can't replay each other's results. The key alone identifies the request: a repeat with the same key but a different body (for example another rebuildMode) returns the original job and does not submit a new one.

POST {{baseUrl}}/api/v1/graph/rebuild
Authorization: Bearer {{accessToken}}
Accept: application/vnd.hxcs.v1+json
Content-Type: application/json

{ "graphDBId": "3f2b6c1e-8d4a-4b7e-9a51-2c6e0f9d7a10", "rebuildMode": "STANDARD" }

201 Created. The response reports the resolved repository, rebuild mode and the query the job runs. Fields with no value (such as graphDBId when it was omitted) are left out.

The graph database below has a single route, content.sys_id == "251691fe-cb6a-415b-8372-3f421c47a570". The generated query shows the route translated into HXQL, so you can confirm the job's scope from the response.

{
"jobId": "kgRebuild:8a310c7a-87d7-4d35-a103-3caeab2a877a",
"status": "SUBMITTED",
"message": "Job submitted successfully",
"repository": "default",
"graphDBId": "3f2b6c1e-8d4a-4b7e-9a51-2c6e0f9d7a10",
"rebuildMode": "STANDARD",
"query": "SELECT * FROM SysContent WHERE (sys_id = '251691fe-cb6a-415b-8372-3f421c47a570')"
}

The create response reports SUBMITTED, which is not a job state; it confirms the job was accepted. There is no API to cancel a job.


Step 4: Poll the Job​

Check the status of a specific rebuild job.

GET {{baseUrl}}/api/v1/graph/rebuild/{jobId}
Authorization: Bearer {{accessToken}}
Accept: application/vnd.hxcs.v1+json

Shortly after the job above was submitted. Small jobs usually finish within seconds, but a job can stay SCHEDULED for a minute or more before it runs, so keep polling until it is COMPLETED or ABORTED:

{
"jobId": "kgRebuild:8a310c7a-87d7-4d35-a103-3caeab2a877a",
"status": "COMPLETED",
"username": "76dcdf7e-...",
"submitTime": "2026-10-01T11:57:35.076Z",
"repository": "default",
"graphDBId": "3f2b6c1e-8d4a-4b7e-9a51-2c6e0f9d7a10",
"rebuildMode": "STANDARD",
"query": "SELECT * FROM SysContent WHERE (sys_id = '251691fe-cb6a-415b-8372-3f421c47a570')"
}
What COMPLETED means

COMPLETED means the job has finished submitting all matched documents for reprocessing. Graph extraction then happens downstream in Context.

Job Status Fields​

FieldDescription
jobIdThe job ID.
statusThe current job state.
usernameThe user who submitted the job.
submitTimeWhen the job was submitted (ISO 8601).
repositoryThe target repository.
graphDBIdThe graph database the query was generated for. Absent when the job covers all configured graph databases.
rebuildModeThe rebuild mode used.
queryThe HXQL query the job runs.
errorMessageError message, present only when the job reported an error.

Fields with no value are left out. The job's request parameters (repository, graphDBId, rebuildMode, query) are kept for 90 days; after that only the status fields are returned.

Job States​

StateDescription
SCHEDULEDThe job has been submitted but has not started.
SCROLLING_RUNNINGThe job is running its query and collecting the set of documents to process.
RUNNINGThe document set is known and the job is processing it.
COMPLETEDThe job has processed the whole document set.
ABORTEDThe job was aborted; it may have been partially applied.
UNKNOWNThe job's status is unknown.

Status Errors​

StatusWhen
404No job with this ID, or its state is UNKNOWN.

Example:

GET /api/v1/graph/rebuild/kgRebuild:00000000-0000-0000-0000-000000000000

404 {"entity-type":"exception","status":404,"message":"Rebuild graph task not found: kgRebuild:00000000-0000-0000-0000-000000000000"}

Step 5: List Jobs and Filter by State​

Retrieve a page of graph rebuild jobs, sorted by submission time (most recent first).

GET {{baseUrl}}/api/v1/graph/rebuild?state=completed&limit=10
Authorization: Bearer {{accessToken}}
Accept: application/vnd.hxcs.v1+json

List Parameters​

ParameterInTypeRequiredDescription
limitqueryintegerNoMax results (default 10). Must not be negative.
offsetqueryintegerNoResults to skip (default 0). Must not be negative.
statequerystringNoFilter by job state: one of the job states, case-insensitive.

List Response​

{
"offset": 0,
"limit": 10,
"totalCount": 1,
"count": 1,
"jobs": [
{
"jobId": "kgRebuild:0c4b3546-ddcc-42d4-8002-64fc95e40b1d",
"status": "COMPLETED",
"username": "admin",
"submitTime": "2026-07-21T09:15:30Z",
"repository": "default",
"rebuildMode": "STANDARD",
"query": "SELECT * FROM SysContent WHERE cinctx_kgProcessingStates/*/ontologyId = '3f2b6c1e-8d4a-4b7e-9a51-2c6e0f9d7a10_c28a73bd-3212-47d7-a782-f0f7daae3679'"
}
]
}

This job was submitted with a custom query, so it has no graphDBId: the two cannot be combined (see Scope the Rebuild).

Each entry in jobs has the same fields as Get Job Status. totalCount is the number of matching jobs across all pages; count is the number on this page.

In cinctx_kgProcessingStates, each ontologyId value is the composite <graphDBId>_<ontologyId>, not the bare ontology ID, so a query for one ontology's documents needs both parts (or cinctx_kgProcessingStates/ontologyId LIKE '%<ontologyId>').

List Examples​

No jobs (or none in the requested state)

GET /api/v1/graph/rebuild?state=completed

{"count":0,"jobs":[],"limit":10,"offset":0,"totalCount":0}

state is case-insensitive: completed and COMPLETED are equivalent.

A state that doesn't exist (there is no failed state; a failed job ends as ABORTED)

GET /api/v1/graph/rebuild?state=failed

400 {"entity-type":"exception","status":400,"message":"Unknown state 'failed'. Valid values: [UNKNOWN, SCHEDULED, SCROLLING_RUNNING, RUNNING, COMPLETED, ABORTED]"}

Negative paging values

GET /api/v1/graph/rebuild?limit=-1
400 {"entity-type":"exception","status":400,"message":"'limit' must not be negative"}

GET /api/v1/graph/rebuild?offset=-1
400 {"entity-type":"exception","status":400,"message":"'offset' must not be negative"}

Step 6: Recognize the Validation Errors​

StatusWhen
415The request has no Content-Type: application/json header: "Content-Type is not supported".
400rebuildMode is not a valid mode.
400Both query and graphDBId are supplied.
400query is not valid HXQL.
400query is omitted and it can't be generated: no graph databases are configured, no graph database matches graphDBId, no ontology routes are configured, or no route produces a usable condition.
400A route condition of the graph database can't be converted into a query, for example because it names a property without the content. prefix (see ontology routes).

These validation errors were confirmed against a live environment; none of them creates a job.

Unknown mode ({"graphDBId": "...", "rebuildMode": "BOGUS"})

400 {"entity-type":"exception","status":400,"message":"Invalid rebuild mode: BOGUS"}

query together with graphDBId

{ "graphDBId": "3f2b6c1e-8d4a-4b7e-9a51-2c6e0f9d7a10", "query": "SELECT * FROM SysContent" }

400 {"entity-type":"exception","status":400,"message":"query and graphDBId cannot be combined: graphDBId only narrows the auto-generated query, so it has no effect on a query you supply yourself. Supply one or the other."}

Invalid HXQL ({"query": "SELECT * FROM"})

400 {"entity-type":"exception","status":400,"message":"Invalid query: At position 1:13 missing {IDENTIFIER, FROM_IDENTIFIER} at '<EOF>'"}

Unknown graph database

{ "graphDBId": "00000000-0000-0000-0000-000000000000" }

400 {"entity-type":"exception","status":400,"message":"Query is required (no graphDB matches graphDbId: 00000000-0000-0000-0000-000000000000)"}

Graph database without ontology routes

400 {"entity-type":"exception","status":400,"message":"Query is required (no ontology routes configured for auto-generation)"}

Route condition without the content. prefix (route sys_id == "..." instead of content.sys_id == "...")

400 {"entity-type":"exception","status":400,"message":"No global property: sys_id"}

Next Steps​