LLM-readable documentation index

Entity Curation

Review, validate, and correct the entities bem extracts

Hand off to an LLM

bem builds an entity memory automatically as it parses documents — the nodes and edges you read through the Knowledge Graph API, shaped by the types and synonyms you define in the Customer Ontology. Curation is the human-in-the-loop layer over that memory: a reviewer works through the entities Parse extracted, approves the ones that are right, rejects the noise, and fixes types and synonyms along the way.

PATCH  /v3/entities/{id}
POST   /v3/entities/bulk-validate
x-api-key: <your API key>

Concepts

The entity lifecycle

Every entity carries a curation status. It begins pre-terminal and a reviewer moves it to a terminal state:

statusMeaning
extractedbem inferred the entity while parsing a document. Awaiting review.
proposedQueued for a reviewer's attention. Awaiting review.
approvedA reviewer confirmed the entity. Terminal.
rejectedA reviewer discarded the entity. Terminal.

Approving or rejecting is only allowed from extracted or proposed. Any other transition — re-approving a terminal entity, for example — is rejected with 409. Once an entity is validated, validatedAt and validatedByUserID record who closed it out and when.

Reviewers are a dashboard concept, not an API-key one

Curation is scoped by entity type, and someone with dashboard access can assign reviewers per type. That assignment, and the lookup of "every type a given user reviews," both live on the session-authenticated dashboard surface — /v3/entity-types/{typeID}/reviewers and /v3/users/{userID}/reviewer-assignments accept a dashboard session (JWT) only, never an x-api-key. An API-key integration can't manage or read reviewer assignments; if you need "who reviews what" in your own system, track it yourself.

There is currently no API-key-reachable way to list entities awaiting review. The read surface this page used to document (GET /v3/review-queue) doesn't exist on any surface — not the API, not the dashboard — so it isn't a scoping issue you can work around with a different auth mode. If your integration needs to discover pending entities, you need your own bookkeeping (for example, tracking entity IDs off webhooks and other events you already receive) until this gap closes. Flagging it rather than guessing at a substitute.

Alias resolution

Curation endpoints honor merges. If you hold an entity id that was later merged away, PATCH /v3/entities/{id} resolves it to the surviving canonical entity and operates on that — you never act on a dead id by accident.

Curating entities

Approve, reject, or correct one entity

PATCH /v3/entities/{id} updates a single entity. Every field is optional, but at least one must be present.

FieldNotes
statusapproved or rejected — only from extracted / proposed, else 409.
assignedTypeIDety_… to override the inferred type. The empty string clears the assignment.
canonicalReplace the canonical surface form (re-derives its normalized form).
addSynonymsstring[] — surface forms to attach as customer_defined synonyms.
removeSynonymIDsesn_… IDs to soft-delete. Only customer_defined / sme_approved synonyms; removing an extracted one is 409.
localeOptional BCP 47 tag stamped on any added synonyms.

An optional bucket query param (bkt_…) scopes the lookup to one bucket; omit it for the default bucket.

# approve an entity and pin its type in one call
curl -X PATCH "https://api.bem.ai/v3/entities/ent_acme" \
  -H "x-api-key: $BEM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "status": "approved", "assignedTypeID": "ety_manufacturer", "addSynonyms": ["Acme Inc."] }'

Approving emits an entity_validated webhook; rejecting emits entity_rejected. The response is the full updated entity record, including its new status, validatedAt, and validatedByUserID.

Validate in bulk

POST /v3/entities/bulk-validate applies one terminal status to many entities at once — the workhorse behind "approve all" in a curation session. It takes the same optional bucket query param as PATCH, above.

curl -X POST "https://api.bem.ai/v3/entities/bulk-validate" \
  -H "x-api-key: $BEM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "entityIDs": ["ent_acme", "ent_globex"], "status": "approved" }'

The response reports a per-row outcome (in request order) plus an aggregate summary, so a partially-valid batch still tells you exactly what happened:

{
  "results": [
    { "entityID": "ent_acme", "outcome": "validated" },
    {
      "entityID": "ent_globex",
      "outcome": "rejected-row",
      "reason": "already terminal"
    },
    { "entityID": "ent_missing", "outcome": "skipped", "reason": "not found" }
  ],
  "summary": { "validated": 1, "skipped": 1, "rejectedRow": 1 }
}
outcomeMeaning
validatedThe transition was applied.
skippedEntity not found, or not authorized for the caller.
rejected-rowThe transition itself was illegal (e.g. already terminal).

See also

On this page