SUBSCRIPTION SEATS

Endpoint seats

Policy enforced inside each vendor’s own administrator hook, decided offline against a signed bundle, because a hook that phones home fails open.

Endpoint seats governs developers on Claude Code, Codex and Copilot subscriptions — credentials Token Observe never issued, to endpoints it is not in front of — by deciding inside each vendor’s own administrator hook, whose non-zero exit blocks a tool call before it executes, delivered through a managed-settings channel the developer cannot remove. The hook decides LOCALLY against a signed policy bundle it was given in advance and makes no network call at all, because every vendor fails open when a hook times out, so a hook that round-tripped to a server would convert every outage, slow VPN and DNS blip into a silent, org-wide policy bypass. The bundle is Ed25519-signed over canonical JSON and checked against a public key the device obtained out of band; no bundle, a malformed or unsigned one, a key the device does not trust, another seat’s bundle, one past its expiry or its freshness bound, and the hook’s own 50ms budget or 150ms wall all resolve to a deny. The same evaluator that decides for an agent at the gateway decides here, against the same tool namespace, so one rule about tool:github/create_pr covers the agent going through the gateway and the developer’s editor going direct. This surface is a preview with named limitations, and Token Observe does not claim it is equivalent to an inline network gateway on an unmanaged device.
Enforcement point
Each vendor’s administrator hook. Exit 2 is the one signal all three read as a pre-tool block
Policy bundle
Ed25519 over canonical JSON in its own signing domain, verified against a key delivered out of band
Decision budget
50ms soft, 150ms wall, a 1,000ms configurable ceiling, and zero network calls
Dialects generated
Claude Code, Codex CLI, Copilot CLI. Gemini CLI and Cursor can be registered but nothing is generated
LifecyclePreview. Not an inline gateway on an unmanaged device.
On this page
the problem

The seats your developers actually work in are the ones your gateway cannot see

Inline governance works by being on the wire. Token Observe issues the agent its credential, pins the endpoint, and refuses the call before it dispatches. A developer on a Claude Code, Codex or Copilot subscription defeats every part of that arrangement without trying: the credential came from the vendor, the endpoint is the vendor’s own, and the shell command or file edit the tool is about to run never traverses a gateway at all. An estate can be fully governed on its agents and completely unobserved on the people writing them.

What the vendors ship instead is an administrative extension point. Claude Code, Codex and Copilot all support a hook that runs before a tool call, whose non-zero exit blocks it, configured from a managed-settings location a device-management channel writes and the developer does not. That is a real enforcement point, and it is the only one available on this surface — so Token Observe treats it as the mechanism rather than pretending the gateway reaches further than it does.

The field that decides whether any of this is enforcement or advice is how the configuration arrived. Token Observe records managementChannel on every enrolled device as mdm, manual or unmanaged, requires it at enrolment, and never defaults it — a default there would be the product inventing the evidence for its own coverage claim. A hand-installed hook still works and still enforces every policy in the bundle it holds; it is also a file the person it governs can delete, so the seat census reports it as delivery rather than as enforcement.

And this control lives on a machine whose user is the subject of the policy. The code, the bundle and the clock are all on the developer’s laptop. The product’s threat model states that plainly and treats device management as a prerequisite rather than a mitigation: without it, this is advice with good telemetry.

the mechanism

How it actually works

  1. 01

    Register the seat

    A seat names a vendor, a tool, one person by email and a team, and carries the same roles, tags, status lifecycle, window budgets and rate limits an agent does — so the same policies select it. A per-request budget is deliberately not offered: a subscription prices the seat rather than the call, so the marginal cost of one request is not knowable at the moment of deciding, and a ceiling on it could never fire.
  2. 02

    Enrol the device, and declare the channel

    Each machine is enrolled with a hostname, a platform and a managementChannel that is required and never defaulted. The hostname is self-reported and attests nothing; the channel is the field the census reads, and it too is an operator’s declaration rather than something the product verifies — which is exactly why it is required and never defaulted, and why the enrolment response warns an operator to declare it honestly. Up to 25 live devices per seat, and retirement marks a device rather than deleting it, so a coverage row from last Tuesday stays explainable after a laptop is handed back.
  3. 03

    Mint the credential

    A seat token is shown exactly once. Token Observe stores its SHA-256, never logs, echoes or audits the secret, and cannot display it again. The response that mints it also states the exact reach of a later revocation, in words rather than in a runbook: revoking stops the seat reaching Token Observe, and does not end the vendor subscription.
  4. 04

    Push the managed configuration

    The managed-settings payload carries the seat id, the device id, the install id, the trusted public key and the absolute bundle URL, through the channel the developer cannot remove. The key travels here and not with the bundle, deliberately: a verifier that reads its trust anchor out of the artifact it is verifying is not verifying anything, because whoever replaced the artifact replaced the key beside it.
  5. 05

    Fetch the bundle

    The device presents its seat credential and receives its own bundle. There is no seat id in the path, the query or the body — a request carrying one is answered with the caller’s own bundle, because nothing reads it — so a seat cannot fetch a colleague’s bundle as a property of the shape rather than a check somebody remembered to write. Every fetch mints: a new monotonic version, a fresh signature, an audit entry, and no-store on the way out.
  6. 06

    Decide locally, at the hook

    The hook reads two files, verifies the signature BEFORE it reads expiry, freshness or identity out of the bundle, and then hands the request to the same evaluator the gateway runs. Signature first is not arbitrary: checking expiry first would let a forged artifact be reported as expired, sending an operator to fix a distribution schedule when what they are holding is a forgery.
  7. 07

    Spool the evidence, then report the coverage

    One JSON line per decision is appended to a local spool — verdicts, policy ids, hashes and timings, never arguments, prompts, matched PII values or injection excerpts — and collected out of band. The append happens after the verdict is already rendered, so a full or read-only disk can lose a record and can never turn a deny into an allow. The seat census then states, per seat and per day, which controls were enforced, which were merely recorded, and which were absent.

Why the hook never asks Token Observe, and why it times itself out

Every vendor hook system fails open on timeout: the hook is slow, the client stops waiting, the tool call proceeds. A hook that round-trips to a central server therefore turns every Token Observe outage, every slow VPN and every DNS blip into a silent, org-wide policy bypass — and turns it on at precisely the moment nobody is watching. So the decision is made on the device, against a bundle it was given in advance, and the hook makes no network call at all. That is not a comment in the source; a test in the package asserts it statically and at runtime, because it is one well-meaning line away from being lost.

The consequence is that the hook has to be the strict one, since nothing downstream of it will be. Every failure it can reach — no bundle, an unreadable file, a bundle or trusted key any local account may rewrite, a wrong key, a forged payload, an expired or stale artifact, one issued to another seat or another install, an unknown vendor event, an unreadable payload, missing configuration, an internal throw, or its own deadline elapsing — refuses. There is no path through it to an allow without a verified bundle having said so.

There are two deadlines, and the reason there are two is that the vendor’s expiry is an ALLOW and the hook’s is a DENY. The soft budget of 50ms is checked at each checkpoint before more work is started: past it the runner stops, because it would rather deny at 51ms than risk being the reason the client gave up and proceeded. The hard wall of 150ms is checked once a decision exists, and a verdict that arrives later than that is discarded even when it is an allow — by then the client may already have stopped waiting and failed open, so a late allow is not an allow. An operator may widen the wall, but only to 1,000ms; a hook deadline set near the vendor’s own timeout is not a deadline, and refusing loudly is the only way an operator discovers they disabled the control by widening it.

An allow says nothing at all: exit 0, no output, and never an explicit permission decision of allow. On clients that honour one, an explicit allow suppresses the user’s own confirmation prompt, which would mean Token Observe loosening a control it never set and did not evaluate. No objection is the strongest thing a governance hook is entitled to say.

Every condition on which the seat hook refuses
no bundle | unreadable file | not valid JSON        -> DENY
no trusted key | trusted key not owned by root      -> DENY
bundle or key group- or world-writable              -> DENY
signature does not verify under the trusted key     -> DENY
envelope disagrees with the signed bytes            -> DENY
issued for another seat, or another install         -> DENY
past expiresAt, or older than maxAgeSeconds         -> DENY
claims issuance >60s in the future                  -> DENY
unknown vendor event | unreadable hook payload      -> DENY
payload over 4 MiB, or past the depth/node bounds   -> DENY
the 50ms soft budget or the 150ms wall elapses      -> DENY
an internal throw anywhere in the runner            -> DENY

allow  ->  exit 0, no output, never an explicit allow

What is inside the signature, and what deliberately is not

A bundle is a snapshot of everything a local decision needs — the seat and its enrolled devices, the roles it holds, the policies whose scope selects it, the kill switches in force, a spend window and the payload-bound approvals granted to it — canonicalised and signed with the same Ed25519 machinery that anchors the audit chain, in its own signing domain so a bundle can never be replayed as an anchor or the reverse. Signing is what makes local evaluation safe at all: the bundle sits on a machine its subject administers, so an unsigned one would be a policy file the governed party can edit.

Compilation is deterministic — the same facts produce byte-identical output however the stores ordered their rows — because a signature over a non-deterministic encoding is a signature over a query plan, and two control-plane nodes reading the same rows in different orders must produce the identical artifact or a console cannot tell a re-issue from a change. The scope filter is the evaluator’s own exported predicate rather than a copy of it, because the compiler IS the filter: a policy it omits can never fire on the device, and a private copy that was stricter by one character would produce a rule an operator wrote, believes covers this person, and which is simply absent from their machine.

The envelope around the signed bytes is treated as unverified until it is cross-checked. Seat id, version, issuedAt and expiresAt are all duplicated outside the signature for a distributor to index on, and every one of them is compared against the signed payload before anything is trusted, because anything a console displays off the envelope is unsigned until it has been. The key id and algorithm are the two fields with nothing to compare against; they are routing labels, never evidence, and the only refusal that quotes them reduces them to a bounded identifier-shaped token first — the refusal reason reaches a developer’s stderr and several clients feed that straight back into the model’s context, so an attacker-chosen string quoted verbatim there would be an instruction channel rather than a diagnostic.

Issuance is never gated on a licence. Creating a seat is entitled, both as a module and as a capacity ceiling; issuing a bundle to a seat that already exists is on the list of capabilities no licence can reach, because a device whose bundle goes stale denies every tool call, so gating issuance would turn a licence lapse into an estate-wide outage of the customer’s own controls.

Two clocks, two diagnoses
expiresAt is the hard wall and maxAgeSeconds the tighter freshness bound. Both deny; the distinction is for the human fixing it — stale means the distribution channel is lagging, expired means it stopped entirely. A freshness bound looser than the lifetime is refused at compile time, because it could never fire.
Least disclosure
Only the roles the seat holds and the policies that select it are compiled in, so a laptop holds no rules about other teams. Approvals are flattened to four facts — which policy, which payload hash, what the human decided, whether it is spent — so one team’s approval prose never lands on another developer’s disk.
Skew, in one direction only
Sixty seconds of tolerance, and it forgives only a bundle that looks slightly too NEW. The direction that matters for safety is the stale one, so a bundle claiming issuance further into the future than that is refused as stale rather than trusted.
The file’s own permissions
A group- or world-writable bundle or key is a refusal: every local account could rewrite the policy the hook enforces from. A trusted key not owned by root is also a refusal, because its owner could self-sign a permissive bundle. An owner-writable signed bundle is a warning instead — that is the supported manual-install shape, and denying every call on it would make an honest deployment weakness indistinguishable from a broken hook. All three are POSIX ownership and mode checks read off the same descriptor the file was read from; where a platform reports no meaningful uid or mode, notably Windows, the answer is recorded as unchecked rather than as protected, because a check there would be theatre and the ACL is what governs.

One evaluator, one tool namespace, three vendor dialects

The hook contains no policy logic. It resolves configuration, reads two files, translates a vendor payload, and hands the result to the same evaluateGovernance the MCP gateway calls — same input, field for field — with PII from the same detectors, injection from the same scorer and permissions from the same deny-by-default RBAC evaluator. That is what a pure, dependency-free domain package buys: the same bytes of policy logic run on a laptop and in the gateway, so the verdict a seat gets and the verdict an agent gets for the same policy are the same verdict because they are produced by the same call.

The tool namespace is mapped rather than invented. An MCP tool reached through a vendor client arrives as mcp__github__create_pr and is mapped onto the same tool:github/create_pr resource and the same bare tool name the gateway uses, so one rule governs the agent going through the gateway and the developer’s editor going direct. Both halves are mapped, not just the resource: policy triggers match their tool pattern against the NAME, so mapping the resource alone would leave every rule firing for agents and silently not for seats — the exact failure this product exists to prevent. A built-in tool has no server namespace and is scoped by the vendor tool it belongs to, as tool:claude_code/Bash, which stops a built-in colliding with an MCP server that happens to share its name. A prompt submission is decided as a reserved tool name too, so it is a real RBAC resource that a role has to grant rather than an exemption taken in an adapter.

Direction is a required field rather than something an adapter guesses, because getting it backwards silently disables a policy. Pre-tool arguments are outbound and scored as user-authored input; a post-tool result is inbound and scored as a tool result, which the injection scorer weights higher because the author of a tool result is data rather than a principal. Post-tool evaluation drops the numeric ceilings and any pre-tool approval: they were consumed before execution, and re-running them would turn a completed action into a misleading post-hoc budget refusal or ask a client to repeat a side effect.

Where the three vendors differ is in how a refusal can be spoken after the action has already run, and Token Observe uses each one’s documented channel rather than a single lowest common denominator. It also refuses to pretend the weakest of them is the strongest: Claude Code’s replacement output must match each built-in tool’s schema, so a governed result there can only stop the loop, the original stays in the transcript and may reappear on resume, and the evidence record marks that as a terminal stop rather than as withheld.

How a refusal is spoken, per vendor and per hook point
pre-tool, all three      exit 2 — the signal all three read as a block
Codex, pre-tool          + permissionDecision deny on stdout
Codex, post-tool         + decision block: the result is withheld
Copilot, post-tool       modifiedResult carrying policy feedback
Claude Code, post-tool   continue false: the loop stops, result stands
Claude Code, failure     additionalContext only, recorded observe_only
Copilot, failure         exit 2 as recovery context, error not replaced
Codex, failure           no dependable event, so nothing to observe

The census is written to argue with Token Observe’s own claim

A customer who believes their developers are governed when they are not is the worst outcome this capability can produce — worse than governing nothing, because they will have stopped looking. Every enforcement point here is conditional on something Token Observe does not control: a hook a device-management channel installed, a server pin a client honours, telemetry an exporter chose to send. So the seat census is deliberately adversarial towards the product’s own coverage claim, and reports every control for every seat-day, including the absent ones, because a report listing only what was present would be a coverage claim with the gaps edited out.

Three statuses, and the line between them is the whole point. Enforced means Token Observe was in a position to refuse the action before it happened. Recorded means it holds evidence about it but could not have stopped it — shadow-mode matches and telemetry both land here, because a match that is logged and not blocked is a log line, and telemetry arrives after the fact. Absent means neither, and silence is absent rather than all clear: a day Token Observe saw nothing is a day it can evidence nothing, whatever is configured.

The local control reaches enforced only where a signed bundle and an unremovable device are the same fact, and that is a join rather than a conjunction. The census reads which device each issuance was attributed to and asks whether any of them is a live device enrolled as mdm. Asking the two questions separately — were there fetches, are there managed devices — answers yes for a seat whose managed laptop has never once collected policy while an unmanaged one collects it daily: two true facts with nothing tying them together, reported as enforcement. A fetch that named no device arms nothing, because it cannot be attributed to a machine.

Both halves are strict on purpose. A bundle must actually have been issued that day — not that a bundle exists, not that issuance is configured — because without one, any hook on the machine is past its freshness bound and denying rather than deciding, which is not the same as governing. And the device it reached must be one whose configuration the governed party cannot delete, because a hook they can remove is a speed bump. That second half rests on managementChannel, which an operator declares and nothing verifies, so it is required at enrolment and never defaulted: a default there would be the product inventing the evidence for its own coverage claim.

Two controls are held out of that promotion on purpose. Redaction never reaches enforced from a bundle, whatever the policy says: the hook can refuse a call carrying PII, it cannot rewrite the payload on its way out, and claiming a rewrite nothing performs would be exactly the overstatement the report exists to prevent. The flight recorder never does either, because a local decision leaves nothing durable centrally and what arrives afterwards is still telemetry. Every row that does claim local enforcement carries the snapshot caveat with it, because enforced and enforced with up to one freshness window of lag are different claims.

Enforced
Token Observe could have refused the action before it happened — inline at the gateway, or locally from a bundle delivered that day onto a device the developer cannot reconfigure.
Recorded
Evidence exists and nothing could have been stopped. Shadow policies, telemetry-only days, and the local control on a seat whose bundle reached only hand-installed or unmanaged devices: the artifact was delivered, and the person it governs can delete the hook that reads it.
Absent
Nothing is configured, or nothing reached Token Observe at all. A quiet day is reported as absent on every control except the local one, which is a statement about delivery and is reported the same way on a quiet day as on a busy one.
Truncated
A census that hit its read ceiling says so on the result. An incomplete census must not be read as coverage, so the bound is reported rather than absorbed.

What a signed bundle on somebody else’s laptop cannot prove

Every bound this control leans on is measured on the device’s own clock. Expiry, freshness and approval time-to-live are all now minus a timestamp, where now is whatever the caller reads from the machine the governed party administers. On an unmanaged device that party controls the clock: set it back and an expired bundle is resurrected, a stale one looks fresh, and a lapsed approval is live again — which makes the freshness bound, the stated limit on how long a retired seat keeps working, not a bound against exactly the person it exists to bound. Nothing in the current design detects it, and the skew tolerance deliberately does not try. Closing it needs an anchor the device cannot rewind: a monotonic counter, a high-water mark of the newest bundle seen, or a managed clock. The product records this in its known issues and its threat model as the sharpest edge here.

Approvals cannot be single-use offline. Whether an approval has been consumed is true as of issuance and nothing on the device can update it, so within one bundle’s freshness window a granted approval can be spent twice. The same shape allows rollback inside the window: an older bundle that is still fresh still verifies, and refusing a downgrade needs a hook that remembers the highest version it has seen. Both are runner state that has not been built, and both are stated rather than implied.

The artifact itself is weaker than a production endpoint agent should be. It ships as a Node command rather than a code-signed, notarised native binary across macOS, Windows and Linux — that work has not been done, and an unsigned executable delivered by device management is a weaker artefact than a signed one. The local evidence spool is unsigned, so a root user can delete a record or recompute its hash before collection; a real attestation claim needs a hardware-protected device key or a privileged collector, and this process has neither. The spool append is synchronous, and operating systems do not make writes to an ordinary regular file deadline-bounded, so pathological local storage can delay an already-computed refusal until the vendor’s own timeout.

The vendor is the last word on the subscription itself. Token Observe can retire a seat and revoke the credential it issued, which stops the seat reaching Token Observe and stops bundles being issued for it; the API says so in the response rather than leaving a console to imply otherwise. It cannot end the entitlement — it never held that credential — so the vendor admin console is the other half of an off-boarding, every time.

The managed-settings artifacts are generated from each vendor’s published documentation, with the URL each key was checked against recorded beside it and a linter that warns when an artifact carries a key that could not be sourced. Nothing in that generator has been exercised against a running vendor client, and it says so. Prove one seat per vendor before an estate depends on it — and note that Claude Code’s managed sources do not merge: it applies the first source that delivers a non-empty configuration, so shipping two per device means one is enforced and the other silently ignored.

Clock
Freshness and expiry are bounded by the device clock, with no monotonic anchor and no high-water mark. On a managed device that is fine; on an unmanaged one it is not a bound at all.
Approvals
Consumed is frozen as of issuance, so an approval can be spent twice inside one freshness window. Closing it needs local runner state, which does not exist yet.
Attestation
The hostname is self-reported, the spool is unsigned, and Token Observe holds no proof that the hook is installed or that it ran — only that a signed bundle was issued and that the device is one the developer cannot reconfigure.
Failed tool calls
Claude Code and Copilot expose failure hooks that Token Observe scans, fingerprints and records as observe-only; neither contract lets it replace or suppress the original error, and Codex exposes no dependable failure event. Sensitive-error prevention belongs in the tool or the pre-action control, not in an endpoint data-loss claim.
Preview
The seat list, the seat read, the provisioning payload and the census all carry lifecycle preview and productionEligible false, and any deployment with active seats keeps the onboarding readiness gate red. That is deliberate, and it is a product decision rather than a bug.
the limits

What this does not do

Stated here rather than discovered during an evaluation. Every line below closes off a reasonable assumption a reader would otherwise carry into a proof of concept.

  • Not equivalent to an inline network gateway on an unmanaged device. Token Observe declines that comparison in its own commercial-readiness document, and so does this page.
  • Token Observe cannot revoke a subscription. Retiring a seat or revoking its credential stops the seat reaching Token Observe and stops bundles being issued; the vendor admin console is what ends the entitlement.
  • The hook never redacts. It can refuse a call carrying PII; it cannot rewrite a payload on its way out, so a redact policy in enforce mode becomes a refusal on the device and the census never promotes redaction to enforced from a bundle.
  • No device attestation, and no signed endpoint artefact. The hostname is self-reported, the evidence spool is unsigned, and the hook ships as a Node command rather than a code-signed native binary.
  • Managed-settings artifacts are generated for Claude Code, Codex CLI and Copilot CLI only. Gemini CLI and Cursor can be registered as seats with nothing generated for them, and a Copilot seat whose developer works in the IDE is not covered by a CLI mechanism.

If one of those limits is the thing that decides it for you, say so and you will get a straight answer about whether it is on the roadmap or out of scope.

Talk it through

Why does the hook decide locally instead of calling Token Observe?

Because every vendor fails open when a hook times out — the client stops waiting and the tool call proceeds. A hook that round-tripped to a server would therefore convert every outage, every slow VPN and every DNS blip into a silent, org-wide policy bypass, at exactly the moment nobody is watching. So the hook makes no network call at all: it verifies a signed bundle it was given in advance and evaluates it on the device, inside its own deadline. That deadline sits far below the vendor’s, because the vendor’s expiry is an allow and this one is a deny.

What happens when the bundle stops arriving?

The device keeps deciding until the bundle passes its freshness bound, then denies every tool call rather than deciding on stale evidence. That is the intended failure and it is loud: developers stop being able to work, which is how an operator finds out the distribution channel or the signing key is theirs to fix. It also means a signing key rotated without re-pushing the managed payload takes the estate down, so the provisioning steps say to push the new payload before the old bundles go stale. Expired and stale are reported as different reasons because they send an operator to different places.

Can a developer just delete the hook?

On an unmanaged device, yes — and Token Observe reports it that way rather than counting it as coverage. The managed-settings files go to root-owned locations a device-management channel writes and the developer cannot, and the hook additionally refuses a bundle or trusted key that is group- or world-writable, and refuses a trusted key not owned by root, because its owner could self-sign a permissive bundle. Those are POSIX checks: on a platform that reports no meaningful uid or mode the file is recorded as unchecked rather than as protected, which is what stops the census counting those devices as protected. Where the configuration was hand-installed, the census reports the local control as recorded, not enforced, with the reason stated on the row: the artifact was delivered, and the person it governs can remove it.

Does a seat get different policy from an agent?

No. The hook marshals a vendor payload into the same governance input the MCP gateway builds and calls the same evaluator, with the same PII detectors, the same injection scorer and the same deny-by-default permission evaluation. Vendor tool names are mapped onto the namespace the gateway already uses, so one rule about tool:github/create_pr covers the agent going through the gateway and the developer’s editor going direct, and a built-in is scoped as tool:claude_code/Bash. What differs is the shape of the evidence, not the semantics of the decision.

Can it govern a prompt, or only a tool call?

It governs prompt submissions on Claude Code and Codex, which are the two dialects with a prompt hook; Copilot CLI has none, so a prompt payload aimed at it is treated as a misconfiguration and refused rather than waved through. A prompt is decided by the same evaluator under a reserved tool name, which makes it a real permission resource that a role has to grant, and the prompt text is what gets scanned for PII and injection. Exempting prompts from permission checks instead would have been a policy decision taken inside an adapter, which this package refuses to do.

Why is this a preview, and what would take it out of one?

Because the artefact and the observation path do not yet meet the production bar, and the code says so on the seat reads, the provisioning payload and the census rather than in a footnote: lifecycle preview, productionEligible false, and a readiness gate that stays red while any seat is active. Four things close it — a code-signed native binary in place of a Node command, a rollback-resistant freshness anchor the device cannot rewind, attested evidence collection rather than an unsigned local spool, and a live vendor and collector compatibility matrix rather than repository tests. Until then, run it in a bounded evaluation and read the census, not the configuration.

Ask about this capability
Ask how this one actually works, where it sits in the request path, or what it will not do. Answers stay inside what this page claims.

Prefer to ask a person? Write to us →

get in touch

Bring us the agent you are least comfortable with.

Write to hello@tenhaw.com with what your agents do, which providers they call and what would have to be true for you to put something in front of them. James Rooney replies. You will get a straight answer about whether Token Observe fits, including when it does not.

no form · no qualification step · no sales desk · the other three ways in