Skip to content
Inkstand

The review engine

The check doesn’t have to live where the work does

Content gets written in a dozen places and reviewed in one. The same engine that holds the line inside our editor answers over HTTP, so the check can sit wherever the sentence is actually typed — under one set of rules, with one audit trail behind it.

Every finding, every call

How much of “our AI keeps you compliant” is a fact?

This is the question the category avoids, so it is the one the API answers on every response. Each finding carries the tier that produced it, and the body lists which of your rules landed in each.

verified

Checked in code

A deterministic check ran over your text. A clean result here is a fact about the words, not an opinion about them.

reviewed

A model looked

Useful, retrievable, and capable of being wrong. Labelled so nobody mistakes it for the row above it.

steered

Nothing checked this

The rule went into a prompt and no code has looked at the result. Reported plainly, because a rule you believe is enforced and isn’t is worse than one you know is advisory.

An empty findings array does not mean compliant. It means nothing was found by the rules that actually ran — and the response tells you which those were. An integration that renders that as a green tick is making a claim this API does not make.

One rung this endpoint does not produce

Over HTTP there is no model pass. This endpoint runs the deterministic checker and calls no model, so reviewedRuleIds is empty on every response and a rule whose check is model-assisted comes back in steeredRuleIds — reported as never inspected, which is what it is. The model pass runs inside our editor and is not exposed here yet.

Two consequences worth having. There is no model latency and no model cost on a call, so the endpoint is fast and its answers are reproducible. And nothing this API returns is an opinion: every finding it produces is a fact about the text.

What actually goes wrong

None of this is about typos

The failures that cost regulated teams money and licences are ordinary and specific, and they share a shape: somebody wrote something true-sounding in a tool nobody was checking.

01

A claim nobody substantiated

A figure in a post that appears in no published release. In a listed company that is potential selective disclosure, and it is invisible to any tool that only matches words.

02

A rule that only existed in a document

The house style says never call a patient a warrior. The document says so. The person writing at 6pm on a Friday has not read it, and nothing in their editor has either.

03

An approval that stopped being true

Legal cleared a deck. Somebody then improved a headline. The approval still says approved, and now describes content that no longer exists.

04

An override nobody can find

Someone had a good reason to publish over an objection. It was a Slack message, and the person who sent it has left.

What a connection carries

Text in, findings out, your addresses preserved

Blocks of text, each with a role and your own address for it. Findings back, each carrying that address unchanged so you can mark the exact node the sentence came from. The engine never learns what a frame, a paragraph or a cell is — which is why it can be pointed at any of them.

You send

{
  "workspaceId": "…",
  "blocks": [{
    "role":     "artwork",
    "location": "Frame 3 · title",
    "text":     "A cure for chronic fatigue.",
    "ref":      { "node": "12:445" }
  }]
}

You get back

{
  "findings": [{
    "statement":   "Never claim a cure.",
    "severity":    "block",
    "excerpt":     "cure",
    "replacement": "helps manage",
    "span":        { "start": 2, "end": 6 },
    "ref":         { "node": "12:445" },
    "tier":        "verified"
  }],
  "steeredRuleIds": ["substantiation"]
}

Roles, not fields

artwork · body · caption · metadata · alt_text · notes. Platform-neutral, so one rule reaches a slide headline, a document heading and a frame title alike.

Your ref, untouched

Put whatever addresses your content. It comes back on every finding, so the result lands on the thing it is about.

Spans, not guesses

A character range into the text you sent, so you mark the words rather than the paragraph.

One engine, not one per surface

The endpoint imports the checker the editor runs

Not a port of it. Not a reimplementation kept in step by discipline. The same function.

That sounds like an implementation detail and is the whole thing. Two implementations of “is this allowed” eventually disagree, and the day they do you have content one surface cleared and another flagged. Nothing recovers a compliance tool’s credibility after that conversation.

It follows that the API cannot be more permissive than the studio. Rules set on the account hold over it, house rules included. There is no mode that checks content against rules supplied in the request — a verdict is only meaningful against a real rule set a real account owns.

Our editor
Your plugin
Your pipeline
checkVoice()

one implementation

Everything lands in one record

Three things get called “accepting a finding”

They mean opposite things about the rule, and every other tool in this category files them as one. When somebody overrides — in our editor or through the API — which of the three they meant is recorded with it.

The rule is wrong here

It matched something it should never match.

Evidence about the rule

The rule doesn’t apply here

Correct in general, not applicable to this content.

Evidence about its scope

Shipping anyway

The rule is right, it applies, and someone decided to publish.

A record of a risk — never evidence against the rule

An override taken in another tool has to come back here rather than staying there. Five tools’ worth of overrides is not an audit trail.

Answers procurement will ask for

Keys, and what they cannot do

Who can issue one
An account owner, never an editor. A key is a standing grant of access to your rules, so it is a governance decision rather than an editing one.
What it can reach
Checking content, and recording an override. It cannot read your work, change a rule, or export — the widest key is narrower than any human role.
Where the secret lives
Nowhere. Only a SHA-256 is stored; the key is shown once and nobody, including us, can read it back. Revocation is immediate and permanent.
How tenancy is enforced
In the database, not in the application. A key resolving to one account cannot reach another’s workspace, and the refusal is identical whether that workspace belongs to someone else or does not exist.
What happens at the limits
Oversized requests are refused rather than truncated — 500 blocks, 20,000 characters in any one of them, 200,000 across the request. A checker that quietly skipped the last of your copy and reported no findings would be worse than one that said no.
The rate limit, and what it is for
120 requests a minute per key, counted and advanced in the same statement that reads it so two simultaneous calls cannot both see a fresh window. It is a ceiling on damage rather than a commercial limit: a leaked key should cost an attacker time, and a plugin looping on an error should not be able to empty an account’s allowance before anyone notices.

Which tier this is in

Part of Pro, where brands are free and seats are not

The API is not in Studio, the single-brand tier. It comes with Pro, which is priced per seat rather than per brand — so pointing the engine at another client’s content adds nothing to the bill, and one key reaches every brand in the account.

Included, then metered
Pro includes a monthly call volume and meters above it. Machine traffic is the one thing this product meters, because a pipeline can run a check a second and a person cannot — and sustained volume is also the truest signal of what the engine is worth to you.
What is never metered
Checks run in the editor, the audit trail, and being told which tier decided. Included at every plan and never priced by the unit at any of them.
Keys are not seats
A key is issued by an account owner and belongs to the account rather than to a person, so adding an integration never adds a seat. Neither does adding a reviewer: a review link needs no account at all.

The three tiers, and why there is no per-brand price →

Start where it is easiest to see.

The editor is the fastest way to watch the engine work on your own brand — set it up, paste a post, see what it refuses. If you already know where the check needs to sit, say so and we will talk about that surface specifically.

Hosted in the EU · Append-only audit trail · No tracking scripts