ackDB

Create a score definition

Validates every field reference against the live schema (unknown refs → 400 with per-criterion errors in error.details.errors, each carrying criterionIndex for inline builder display). isPrimary: true transactionally takes over the grain's primary slot. Event refs are wire-BARE (event:slack.message) — the server resolves stored names. String match values on allowed-values traits are canonicalized case-insensitively.

post/api/v1/ackdb/scores

Request

  • Base URL
    http://localhost:3009
  • Auth
    HTTP bearer

Request body

scoreKeystring required

Immutable slug → the sc__<scoreKey> column. Single underscores only.

namestring required
descriptionstring nullable
grain'company' | 'person' required

Immutable after create.

normalization'absolute' | 'percentile'

absolute (default): 100 × points / max possible, clamped. percentile: rank within THIS grain's population (strictly-below semantics — a no-data row is the 0th percentile).

percentilePopulation'all' | 'active'

Percentile definitions only (#432) — 400 with absolute normalization. all (default): rank against the whole grain population (today's behavior). active: rank only against rows where at least one non-trait criterion fired (an event:/convergence/contacts/company: criterion contributed nonzero points) — on sparse books the empty rows stop being the yardstick. Excluded rows still serve a score of 0 (never NULL) and take whatever lt label band covers 0.

scopeSegmentIdstring nullable

SCOPE (#443): score ONLY the members of this saved segment. Absent/null = the whole grain (every definition before this feature). Rows outside the segment read NULL in sc__<key> and sc__<key>__label — not 0 — and are excluded from the percentile population, the preview histogram and the history sweep. ANY segment grain is legal for either score grain: a contact/person segment scoping a company score means 'the companies of those people', a company segment scoping a person score means 'the people with an active edge at those companies'. Derived segments are legal. 400s when the segment does not exist, or when its filter (or its base's) references a SCOPED score — a scored population may only be defined by whole-grain scores, which is what makes a scoring cycle impossible.

isPrimaryboolean

One primary per grain (server-enforced hand-off).

enabledboolean

Example request

{
  "scoreKey": "pql",
  "name": "PQL score",
  "groups": [
    {
      "key": "fit",
      "weight": 0.4
    }
  ],
  "criteria": [
    {
      "field": "event:slack.message",
      "valueField": "employee_count"
    }
  ],
  "labels": [
    {
      "label": "Excellent"
    }
  ]
}

Response

The created definition.

scoreKeystring required

Immutable slug → the sc__<scoreKey> column. Single underscores only.

namestring required
descriptionstring nullable
grain'company' | 'person' required

Immutable after create.

normalization'absolute' | 'percentile'

absolute (default): 100 × points / max possible, clamped. percentile: rank within THIS grain's population (strictly-below semantics — a no-data row is the 0th percentile).

percentilePopulation'all' | 'active'

Percentile definitions only (#432) — 400 with absolute normalization. all (default): rank against the whole grain population (today's behavior). active: rank only against rows where at least one non-trait criterion fired (an event:/convergence/contacts/company: criterion contributed nonzero points) — on sparse books the empty rows stop being the yardstick. Excluded rows still serve a score of 0 (never NULL) and take whatever lt label band covers 0.

scopeSegmentIdstring nullable

SCOPE (#443): score ONLY the members of this saved segment. Absent/null = the whole grain (every definition before this feature). Rows outside the segment read NULL in sc__<key> and sc__<key>__label — not 0 — and are excluded from the percentile population, the preview histogram and the history sweep. ANY segment grain is legal for either score grain: a contact/person segment scoping a company score means 'the companies of those people', a company segment scoping a person score means 'the people with an active edge at those companies'. Derived segments are legal. 400s when the segment does not exist, or when its filter (or its base's) references a SCOPED score — a scored population may only be defined by whole-grain scores, which is what makes a scoring cycle impossible.

isPrimaryboolean

One primary per grain (server-enforced hand-off).

enabledboolean
degradedboolean

True when a source deletion scrubbed criteria out of this definition, or (#443) when its scope segment was deleted (the definition is also disabled) or widened by a scrub. Any successful edit clears it.

scopeSegmentNamestring nullable

Scope segment display name, hydrated on reads (#443). Null when the definition is unscoped OR its scope segment has been deleted — a non-null scopeSegmentId with a null name is the dangling-scope state (the definition is disabled + degraded).

scopeSegmentKind'company' | 'contact' | 'person' nullable

Scope segment home grain, hydrated on reads (#443). Null when unscoped/dangling.

createdAtstring date-time
updatedAtstring date-time

Example response

{
  "scoreKey": "pql",
  "name": "PQL score",
  "groups": [
    {
      "key": "fit",
      "weight": 0.4
    }
  ],
  "criteria": [
    {
      "field": "event:slack.message",
      "valueField": "employee_count"
    }
  ],
  "labels": [
    {
      "label": "Excellent"
    }
  ]
}

Changes

No recorded changes to this operation across all 1 revision of this API.