Style profile

Read the authenticated account's writing voice as typed style records with source-note evidence.

POST /v1/style/profile

Authentication

Scheme Header
Bearer Authorization: Bearer <API key>

API key must include scope style.

Request body

All fields are optional. An empty body returns the full profile, capped by limit.

Field Type Default Notes
sourceRunId uuid Limit to records produced by a single ingest run
scope string Match the scope array on the record (e.g. "technical-writing")
limit integer 8 Per-bucket cap. 1 ≤ limit ≤ 50. Applied independently to observations, preferences, and vocabulary rules

Response: 200 OK

{
  "schemaVersion": "marrow-style-profile-v1",
  "filters": { "sourceRunId": null, "scope": "technical-writing" },
  "observations": [
    {
      "id": "a01f…",
      "type": "style_observation",
      "category": "structural",
      "scope": ["technical-writing"],
      "pattern": "Prefers concrete nouns over abstractions.",
      "consumerGuidance": "Start sentences with the actor; avoid passive scaffolding.",
      "strictness": null,
      "confidenceKind": "asserted",
      "confidenceScore": 0.82,
      "sourceKind": "distilled",
      "sourceRunId": "f1a3…",
      "evidenceNoteIds": ["9b2c…"],
      "rationale": "Across five distilled paragraphs the pattern held."
    }
  ],
  "preferences": [
    {
      "id": "b22d…",
      "type": "style_preference",
      "category": "framing",
      "scope": ["technical-writing", "formal-writing"],
      "preference": "Frame the Northstar work as cross-functional delivery, not just a product launch.",
      "strictness": "strong",
      "confidenceKind": "user-asserted",
      "confidenceScore": 1.0,
      "sourceKind": "user-context",
      "sourceRunId": "c0e8…",
      "evidenceNoteIds": ["7a8b…"],
      "rationale": "Direct user-context assertion."
    }
  ],
  "vocabularyRules": [
    {
      "id": "c44e…",
      "type": "vocabulary_rule",
      "category": "casing",
      "scope": ["technical-writing"],
      "term": "Northstar",
      "rule": "Capitalize as a proper noun; never split into two words.",
      "strictness": "strong",
      "confidenceKind": "asserted",
      "confidenceScore": 0.9,
      "sourceKind": "distilled",
      "sourceRunId": "f1a3…",
      "evidenceNoteIds": ["9b2c…"],
      "rationale": null
    }
  ],
  "evidenceNotes": [
    {
      "id": "9b2c…",
      "sourceRunId": "f1a3…",
      "sourceKind": "blog-post",
      "snippet": "We did not pitch Northstar as a product launch. We pitched it as cross-functional delivery that unified Product, Design, and Operations …",
      "styleDescription": "Technical, declarative, foregrounds the subject."
    }
  ]
}

Bucket reference

Bucket Distinct field Cardinality
observations pattern + optional consumerGuidance Descriptive: what is observed
preferences preference + strictness Prescriptive: what to do
vocabularyRules term + rule + strictness Term-level rule

Common fields on every style record:

Field Type Description
type enum style_observation | style_preference | vocabulary_rule
category string? Free-form distiller-supplied category
scope string[] Writing contexts the record applies to
strictness enum? "suggested", "strong", etc. Only meaningful on preferences and rules
confidenceKind string asserted, user-asserted, inferred, etc.
confidenceScore number [0, 1]
sourceKind string distilled, user-context, feedback, …
sourceRunId uuid The run that produced the record
evidenceNoteIds uuid[] Notes substantiating the record. Present in evidenceNotes
rationale string? Distiller- or user-supplied rationale

Errors

Code error.code Reason
401 unauthorized Missing or invalid API key
403 forbidden API key lacks scope style
422 validation_error Body failed validation
429 rate_limit_exceeded Rate limit hit

CLI mapping

npm run dev -- api style-profile --scope technical-writing
npm run dev -- style profile --scope technical-writing      # local CLI against local DB