opbox

The invoice.* family (3 verbs). Every verb enters through the one front door: it is capability-checked, permission-checked, scope-checked and audited before it runs (see Security & permissions). Each entry below lists its capability, risk class (which fixes the minimum autonomy level), the minimum caller permission, its availability tier, whether it is idempotent, and any outbound egress.

Createinvoice.comment.create

PropertyValue
Capabilityinvoice.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - in-box (pure Postgres, no outbound call)

{ invoiceId, content, parentId?, mentions? }. Invoice fenced in ctx.workspace_id; single-level threading (a reply to a reply flattens to the grandparent).

Call POST /v/invoice.comment.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool invoice.comment.create.

Deleteinvoice.comment.delete

PropertyValue
Capabilityinvoice.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - in-box (pure Postgres, no outbound call)

Own comment unless allowAny (the route passes the workspace ADMIN/OWNER flag). Deleting a top-level comment cascades its replies in the same tx. { commentId, allowAny? }.

Call POST /v/invoice.comment.delete with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool invoice.comment.delete.

Updateinvoice.comment.update

PropertyValue
Capabilityinvoice.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - in-box (pure Postgres, no outbound call)

Edit content/mentions (author-only) and/or toggle resolved (top-level comments only). { commentId, content?, mentions?, resolved? }.

Call POST /v/invoice.comment.update with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool invoice.comment.update.