Run it by
DocsAPI referencePricingArticles
EN
EnglishEspañolPortuguêsFrançaisDeutschItaliano日本語中文
Sign inGet an API key

In this article

The short versionWhat changed at HumanLayerThe same patterns in Run it byExampleWhat’s differentAll articles

Comparison

A HumanLayer alternative for agent approvals

Nov 4, 2026 · 5 min read

The short version

HumanLayer started as an SDK that let agents ask a person before acting: require_approval to gate a function, human_as_tool to ask a question. Today HumanLayer builds a coding-agent IDE, and the approvals SDK hasn’t had a release since June 2025. If you still depend on it, Run it by covers the same two patterns, and the person who answers needs nothing but a link.

Checked against HumanLayer’s own pages in November 2026. We found no official deprecation notice, so check with HumanLayer before you plan around our reading.

What changed at HumanLayer

  • humanlayer.dev now describes a multiplayer coding agent IDE and cloud for running Claude Code, Codex and other coding agents.
  • The last release of the humanlayer package on PyPI is 0.7.9, from June 2025.
  • The approvals documentation is no longer on the site, and the repository now holds the new product.

That’s a sensible move for HumanLayer, and if you supervise coding agents as a team, their new product is built for that. It just leaves agents that need a person’s sign-off without the SDK they used.

The same patterns in Run it by

  • Gate an action (require_approval): create a request with mode: "approval", the reason and the people who decide. Act only when the verdict is approved.
  • Ask a question (human_as_tool): create a request with mode: "form" and a JSON Schema for the answer. It comes back validated against that schema.
  • Hear back: a signed webhook, getStatus with a wait of up to 25 seconds, or, over MCP on Builder and Pro, a notification the moment someone answers.

Example

A small require_approval in Python over the REST API. It waits in the call; in production, prefer the webhook.

import os, requests

API = "https://runitby.app/v1/requests"
AUTH = {"Authorization": f"Bearer {os.environ['RUNITBY_API_KEY']}"}

def require_approval(reason, approvers):
    request = requests.post(API, headers=AUTH, json={
        "mode": "approval",
        "title": reason,
        "requester": "The billing agent",
        "audience": {"kind": "named", "recipients": approvers},
        "approval": {"reason": reason, "policy": "any", "verify": "email"},
        "expiresIn": "24h",
        "sendEmail": True,
    }).json()
    while True:
        status = requests.get(
            f"{API}/{request['requestId']}?wait=25", headers=AUTH
        ).json()
        if status["verdict"]:
            return status["verdict"] == "approved"

if require_approval("Refund order #4821, $1,200",
                    [{"name": "Emily Lee", "email": "emily@acme.com"}]):
    issue_refund("4821")

declined and expired both return False, so silence never turns into a refund.

What’s different

  • Approvers don’t need Slack or an account. Each named person gets their own link by email, or you pass the link on yourself, including into Slack.
  • Several approvers with a policy (any, all, majority or a number), an optional email code per person, and an expiry that ends as expired.
  • There’s no decorator to wrap your functions; you call the API or the MCP tools. If you relied on approvals arriving as Slack messages with buttons, Run it by doesn’t do that.

For a wider look at the options, see Run it by vs approval tools.

Try it with your agent

Free for 250 requests a month, no card. Add the MCP server from Claude Code or Codex with one command, or use the REST API.

Start freeRead the docs

Run it by

Get structured data from a person with a link.

Product

DocsPricingArticlesSupport

For agents

MCP setupAPI referencellms.txtopenapi.json

Legal

PrivacyTerms
© 2026 Run it by
EnglishEspañolPortuguêsFrançaisDeutschItaliano日本語中文