Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.tryhoard.com/llms.txt

Use this file to discover all available pages before exploring further.

Every time an AI assistant calls a write action against your Hoard account, it leaves a row in your activity log. Committed changes, rejections, expired plans, floor trips, all of it. This is your audit trail. This page covers where to find it, how to read a row, and the queries worth running on a quiet Sunday.

Where it lives

Today the activity log is available through the API at GET /api/v1/agent/activity (your assistant calls this for you when you ask “what did you do this week?”). A dedicated Activity tab in Settings → Assistants is on the roadmap.
GET /api/v1/agent/activity
Authenticate the same way you’d authenticate any other agent call (OAuth or bearer key). The response is a paginated list of activity rows. You can also ask your assistant directly: “show me everything you’ve done in the last 24 hours.” It will call this endpoint for you and summarize.

Anatomy of a row

A single row looks like this in the JSON:
{
  "id": 12834,
  "action_namespace": "pricing.edit_rule",
  "risk": "low",
  "outcome": "committed",
  "params_summary": {
    "rule_slug": "mythic-standard",
    "before": { "multiplier": 1.10 },
    "after": { "multiplier": 1.15 }
  },
  "floor_violation": null,
  "before_snapshot_id": 4471,
  "after_snapshot_id": 4472,
  "agent_action_plan_id": 9123,
  "request_id": "a1b2c3d4-...",
  "created_at": "2026-05-11T03:42:17Z"
}
Read it left to right.
  • action_namespace, the binding that was called, namespaced (e.g. pricing.edit_rule, pricing.mass_reprice, account.settings)
  • risk, low, medium, high, or critical
  • outcome, the verdict (see the table below)
  • params_summary, the load-bearing fields of the call. Sensitive values get redacted (see below). The exact keys depend on action_namespace.
  • floor_violation, name of the hard floor that blocked the call, if any
  • before_snapshot_id / after_snapshot_id, ids of the rule snapshots taken at preview and commit, for forensic diffing
  • agent_action_plan_id, links back to the original plan record so you can re-read the diff
  • request_id, the request UUID, useful when correlating with server logs
  • created_at, ISO-8601 timestamp of when the row was written

What each outcome means

OutcomeWhat happened
committedThe plan was approved (by you or auto) and the change applied.
rejected_by_floorA hard floor tripped. The call never committed. floor_violation tells you which one.
rejected_by_tokenThe confirmation token was wrong, expired, or already used. Usually means the 60-second window lapsed.
rejected_by_driftThe plan’s parameters changed between preview and commit. The assistant tried to commit something different from what you approved. The server caught it.
rejected_by_derivationA computed value on the plan (projected aggregate, affected count) didn’t match between preview and commit. Same idea as drift, different field.
rejected_by_rederivationThe server re-ran the projection at commit time and got a different number than at preview time, usually because your underlying inventory shifted.
rejected_by_userYou clicked Reject on the plan detail page.
expiredYou never confirmed within the 5-minute plan TTL. The plan timed out.
committed is the happy path. Everything else is a story.

Risk scores: when does each fire

Risk is computed per call against the actual numbers you’re sending plus your pricing wizard answers.
  • low, small move, well under your change_cap_pct, affects a modest count of cards, no price-source flip
  • medium, bigger move, still within caps, or a smaller move on a rule covering many cards
  • high, exceeds your change_cap_pct, or flips never_go_down, or changes the price source
  • critical, would drop your aggregate listed value by a significant percentage, or would push many cards through their floor, or is operating on a rule with very wide reach
The dial that tunes all of this is your pricing wizard. A “Stay Competitive” seller with change_cap_pct: 20 and a “Lead the Market” seller with change_cap_pct: 30 get different scores for the same call. That’s intentional.

What params_summary shows vs what’s redacted

Shown:
  • Rule names, multipliers, price sources
  • Card counts, aggregate dollar projections
  • Sale percentages, durations
  • Action verbs (edit, create, delete)
Redacted:
  • Your bearer key / API key (never logged anywhere)
  • OAuth tokens
  • Customer email addresses (replaced with anonymized identifiers)
  • Free-text fields longer than a threshold (truncated with ...)
If you ever see a value redacted in a row where you’d genuinely need it, the source of truth is the plan detail page linked from agent_action_plan_id. That page shows you everything the assistant saw.

Forensic queries worth running

A few patterns that come up.

”Find every rule edit Claude made last week”

Ask your assistant:
“Show me every committed pricing.edit_rule action between May 5 and May 11.”
Or via the endpoint:
GET /api/v1/agent/activity?namespace=pricing.edit_rule&outcome=committed&since=2026-05-05&until=2026-05-11
What you’re looking for: a steady, sensible cadence. If there’s a burst of 20 edits in 4 minutes, something prompt-injected the assistant.

”Did anyone try to commit a stale plan?”

Filter for outcome: rejected_by_drift or rejected_by_rederivation. These should be rare. A spike usually means an assistant retried a commit after your inventory shifted (e.g. you ran a sync in between preview and commit). One every couple of weeks is fine; a cluster in one session warrants a look.

”How many of my confirmations did I actually approve?”

Filter for action: pricing.edit_rule over the last 30 days and compare committed count to rejected_by_user + expired counts. If you’re rejecting or expiring more than ~20% of confirmations, your grant is probably too loose for what the assistant is suggesting, the assistant should be filtering its own proposals better, but in the meantime, tighten the grant. See Picking the right permission mode.

”Did anything trip a floor recently?”

Filter for outcome: rejected_by_floor. Each row tells you which floor (absolute_minimum, per_rule_aggregate_drop, per_session_aggregate_drop). A floor trip is the system working as designed, the assistant tried something dangerous, the floor said no. But a steady stream of trips means either the assistant is misbehaving or your floors are tuned too tight for how you actually want to operate. For what to do about each floor type, see When the agent says ‘I can’t do that’.