Skip to main content

Actions

Not seeing the action your product needs?

The packs here are the actions we have already built, and each carries the assumptions of whoever asked for it first. If none of them describe your product, ask us to build the one you need rather than adopting a pack that nearly fits.

Some capability calls Lira's AI agent could not — or should not — run on its own. Those runs pause in a pending_approval state until a teammate decides. This is the human-in-the-loop edge of the Agent Runtime.

Pending runs are visible in Settings → Support → Health & audit → Agent audit log — filter the status to Pending approval. Approval and rejection are performed through the admin API (below); the dedicated Actions page that previously lived in the sidebar has been retired in favour of the consolidated audit surface.


When something needs approval

Not every capability call needs your team's attention. Most reads and low-risk writes auto-execute, and many high-stakes operations are confirmed by the customer directly in chat. A run only pauses for approval when the policy engine returns mode: "human" for one of two reasons:

  • The capability's risk tier is admin_approve — e.g. an integration write that you have explicitly chosen to require teammate approval for.
  • An admin override raised an existing capability into a tier that requires human approval.

If a call is blocked outright (insufficient auth, or a human_only tier), it never pauses for approval: it is refused and the agent escalates differently. Those records appear in the audit log with status blocked.


Second-party approval (Maker/Checker)

A capability approved with the risk tier admin_approve cannot be authorised by the person who asked for it. This is the control regulated businesses call Maker/Checker: one user requests, a different user approves, and neither can do both.

When the agent calls such a capability:

  1. The run parks. It is recorded with status pending_approval and nothing executes.
  2. The customer is told it was sent for approval. Deliberately not an approve button: showing the requester a way to authorise their own request is exactly the control being defeated.
  3. Your backend is notified, if you have set an approval webhook (below).
  4. A second party decides, from your own product.
  5. On approval Lira executes the capability and writes the outcome into the conversation. The customer sees it there even if they closed the app hours earlier.

Telling your systems something is waiting

Set approval_webhook_url and approval_webhook_secret on your support config, and we POST the moment a run parks:

{
"event": "action.pending_approval",
"run_id": "run_...",
"org_id": "org_...",
"conversation_id": "conv_...",
"action": { "tool_name": "...", "display_name": "...", "arguments": { } },
"requester": { "customer_id": "...", "external_customer_id": "...", "email": "..." },
"decision_url": "/lira/v1/support/actions/orgs/{orgId}/agent-runs/{runId}/decision",
"requested_at": "2026-08-11T16:00:00.000Z"
}

Signed the same way as the ticket outbox, so you write one verifier and reuse it:

X-Lira-Event      action.pending_approval
X-Lira-Delivery <run id>
X-Lira-Signature sha256=<HMAC-SHA256 of the raw body, hex>

Delivery is best-effort with a 5 second timeout. The parked run is durable regardless, so a webhook outage costs you a notification, not the approval. Without a webhook, poll the audit log for pending_approval.

Recording the decision

POST /lira/v1/support/actions/orgs/:orgId/agent-runs/:runId/decision
Authorization: Bearer <your Lira API key>

{ "approved": true, "approver_id": "staff-4471", "approver_name": "A. Bello", "reason": "Within limit" }

approver_id is the approver's id in your system, and it is required. The four-eyes rule is enforced server-side: if it matches the requester's customer id, visitor id or email, the request is refused with SELF_APPROVAL. It is not a warning you can click past.

The endpoint fails closed throughout:

ResponseMeaning
404 NOT_FOUNDNo such run
409 NOT_PENDINGAlready approved, rejected or executed. A decision cannot be replayed
409 SELF_APPROVALThe approver is the requester
409 EXPIREDThe parked run timed out or was superseded. The customer must ask again
409 TOOL_GONEThe capability is no longer enabled for the workspace, so nothing ran

Rejecting records the reason on the run and tells the customer their request was not approved.


Reviewing a pending run

Two approval paths

The endpoints below are the dashboard path, where a teammate approves inside Lira. The second-party path above is the one to use when approval must happen in your own product under your own approval chain, which is what regulated businesses generally need.

Each pending run in the audit log shows:

  • Capability — the resource or action the agent wants to call, e.g. stripe_cancel_subscription, create_linear_issue.
  • Risk tier — why this needed approval in the first place.
  • Conversation ID — link back to the chat that triggered the run.
  • Timestamp — when the agent requested it.
  • Input summary — redacted snapshot of the arguments the agent would pass.

Approving a run

Approving moves the run to approved; the runtime executes the capability and the status transitions to succeeded or failed depending on the outcome. The result is summarised back in the chat for the customer.

POST /lira/v1/support/actions/orgs/:orgId/:actionId/approve
Authorization: Bearer <admin-jwt>

Rejecting a run

Rejecting moves the run to cancelled and it is never executed. The agent receives a signal that it should pursue a different path — typically by escalating the conversation to a teammate.

POST /lira/v1/support/actions/orgs/:orgId/:actionId/reject
Authorization: Bearer <admin-jwt>

Both endpoints require Owner or Admin role on the org.


Action statuses explained

StatusMeaning
requestedThe agent asked, the engine has not finished evaluating. Rarely visible.
pending_approvalWaiting for your team to approve or reject.
approvedYour team approved; the runtime is about to execute.
runningThe executor is in flight.
succeededCompleted successfully.
failedThe executor threw. The error is in the run's output summary.
cancelledA teammate rejected, or the customer declined an in-chat confirmation.

Runs blocked by policy (insufficient auth, blocked tier) appear in the audit log with status blocked and never enter the approval flow.


Tips

Tighten the policy instead of approving the same kind of run twice. If you find yourself rubber-stamping the same capability call every day, the right move is to lower its risk tier in Capabilities. The agent will then handle it autonomously and only the unusual cases come to you.

Use the audit log to spot patterns. Frequent failed runs for the same capability often point at an expired integration credential or a schema mismatch — neither of which approval can fix. The error message on the audit record points you at the cause.

A rejected run does not silence the conversation. The chat stays open. Reply directly to the customer, or hand the conversation off to a teammate from the Tickets queue if they need to act outside Lira.