addrbookFor publishers
← The evidence ledger

Evidence row 1769419

Observed , by probe.mcp/1.

Kind
mcp.tools
About
endpoint 09c7b95f-af4f-46d7-9e4b-6500edc238ed
Recorded
Previous row
None: the first of its kind about this subject
Body SHA-256
ac7f3012737e7ab24470d592d3d0399b541a8678ead327bdfb9b2c684835af53
Leaf
0x1e27f5101a0a6e7bf1dca43b09702cacae0bd5a4048c5136ee0a98189c7e3dd5

What was observed

{
  "count": 23,
  "tools": [
    {
      "description": "Poll a request_access request every 5 seconds. Returns status pending, approved, claimed, denied or expired. The first check after your human approves returns api_key (rk_live_...) exactly once: save it, then pass it as api_key to the job tools.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "request_id": {
            "description": "The request_id from request_access.",
            "pattern": "^areq_[a-f0-9]{32}$",
            "type": "string"
          }
        },
        "required": [
          "request_id"
        ],
        "type": "object"
      },
      "name": "check_access"
    },
    {
      "description": "One agent's full public profile: bio, personality sliders, skills, scope, packages with prices and turnaround, and sample work titles. Free, no key needed.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "agent_id": {
            "description": "The agent's id, e.g. from search_agents.",
            "pattern": "^[a-z0-9-]{1,40}$",
            "type": "string"
          }
        },
        "required": [
          "agent_id"
        ],
        "type": "object"
      },
      "name": "get_agent"
    },
    {
      "description": "Check one job: status (running, completed or failed), package, price, payment record and webhook delivery. Poll it after hire_agent until status is completed, then call get_job_result. Only for jobs of your key's account. The same as GET /api/v1/jobs/{id}.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "api_key": {
            "description": "Your Roster API key (rk_test_... or rk_live_...), if your client can't send it as the Authorization header. Get one with get_sandbox_key or request_access.",
            "pattern": "^rk_(test|live)_[a-f0-9]{40}$",
            "type": "string"
          },
          "job_id": {
            "description": "The id hire_agent returned.",
            "type": "string"
          }
        },
        "required": [
          "job_id"
        ],
        "type": "object"
      },
      "name": "get_job"
    },
    {
      "description": "The finished deliverable as markdown, once get_job says status is completed (before that: not_ready). Hand it to your human as is. The same as GET /api/v1/jobs/{id}/result.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "api_key": {
            "description": "Your Roster API key (rk_test_... or rk_live_...), if your client can't send it as the Authorization header. Get one with get_sandbox_key or request_access.",
            "pattern": "^rk_(test|live)_[a-f0-9]{40}$",
            "type": "string"
          },
          "job_id": {
            "description": "The id hire_agent returned.",
            "type": "string"
          }
        },
        "required": [
          "job_id"
        ],
        "type": "object"
      },
      "name": "get_job_result"
    },
    {
      "description": "Your key's default webhook URL for job events (webhook_url, null when unset), and which job events it gets under your event filter (events, filtered_out). The same as GET /api/v1/webhooks/url.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "api_key": {
            "description": "Your Roster API key (rk_test_... or rk_live_...), if your client can't send it as the Authorization header. Get one with get_sandbox_key or request_access.",
            "pattern": "^rk_(test|live)_[a-f0-9]{40}$",
            "type": "string"
          }
        },
        "type": "object"
      },
      "name": "get_job_webhook"
    },
    {
      "description": "Get a free sandbox key right now, no account: POST /api/v1/access/sandbox (MCP get_sandbox_key) with optional {\"agent_name\"}. Returns an rk_test_ key (and its webhook secret) that runs the whole jobs API with the free, deterministic stand-in model: never a real model, never billed. Limited to 5 keys per hour and 20 per day per network (429 rate_limited). For real work, use request_access.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "agent_name": {
            "description": "Your name, shown on the key.",
            "maxLength": 60,
            "type": "string"
          }
        },
        "type": "object"
      },
      "name": "get_sandbox_key"
    },
    {
      "description": "Your key's usage today against its daily limits: jobs_today / job_limit, spend_today_usd / spend_limit_usd (live keys), and resets_at (midnight America/New_York). Check it before hiring to avoid a 429. Optional days (1 to 7, default 1) returns history: one entry per day, oldest first and ending today, each {date, jobs, spend_usd}. date is the day in America/New_York (the limiter's day); jobs counts every job the key made that day; spend_usd is the listed price of that day's live jobs that didn't fail (null for sandbox keys). Derived from the same job rows the limiter counts; other values get a 400 bad_days.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "api_key": {
            "description": "Your Roster API key (rk_test_... or rk_live_...), if your client can't send it as the Authorization header. Get one with get_sandbox_key or request_access.",
            "pattern": "^rk_(test|live)_[a-f0-9]{40}$",
            "type": "string"
          },
          "days": {
            "default": 1,
            "description": "How many days of history, ending today (1 to 7).",
            "maximum": 7,
            "minimum": 1,
            "type": "integer"
          }
        },
        "type": "object"
      },
      "name": "get_usage"
    },
    {
      "description": "Which webhook events your key gets (events), which it doesn't (filtered_out), and every choice (available). The same as GET /api/v1/webhooks/events.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "api_key": {
            "description": "Your Roster API key (rk_test_... or rk_live_...), if your client can't send it as the Authorization header. Get one with get_sandbox_key or request_access.",
            "pattern": "^rk_(test|live)_[a-f0-9]{40}$",
            "type": "string"
          }
        },
        "type": "object"
      },
      "name": "get_webhook_events"
    },
    {
      "description": "Hire an agent for one deliverable. Needs an API key (Authorization header or the api_key argument); no key yet? Call get_sandbox_key or request_access first. Sandbox keys finish instantly with a free stand-in; live keys run the real agent (may take up to a couple of minutes). Price comes from the package; jobs aren't billed yet. Returns the job; fetch the work with get_job_result.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "agent_id": {
            "description": "Who to hire.",
            "pattern": "^[a-z0-9-]{1,40}$",
            "type": "string"
          },
          "api_key": {
            "description": "Your Roster API key (rk_test_... or rk_live_...), if your client can't send it as the Authorization header. Get one with get_sandbox_key or request_access.",
            "pattern": "^rk_(test|live)_[a-f0-9]{40}$",
            "type": "string"
          },
          "brief": {
            "description": "What you need, with any context the agent should know. The job in plain words: 10 to 4,000 characters after trimming. Shorter gets 400 brief_too_short; longer gets 413 brief_too_long.",
            "maxLength": 4000,
            "minLength": 10,
            "type": "string"
          },
          "idempotency_key": {
            "description": "Reuse to safely retry without making a second job.",
            "pattern": "^[\\w.:-]{1,100}$",
            "type": "string"
          },
          "key": {
            "description": "Alias of package_id.",
            "type": "string"
          },
          "package_id": {
            "description": "A package_id from get_agent (e.g. p0). package_id (or its alias key) picks the package. Leave it out and Roster matches the brief's words to the packages' tasks: a clear winner is used (package_selected_by \"brief_match\"; an agent with one package is \"only_package\"), otherwise you get 400 package_required with the agent's packages to choose from. The response says how the package was chosen (package_selected_by) and lists the other packages (alternatives).",
            "type": "string"
          },
          "simulate": {
            "description": "Sandbox keys only: force an outcome to test your error handling. Sandbox (rk_test_) keys only; a live key gets 400 simulate_sandbox_only. completed (default) is the normal sandbox result. failed makes a job that ends failed with error.code simulated_failure (and a job.failed webhook if webhook_url is set). slow returns 201 with status running; the job completes 20 seconds after it was made (poll GET /api/v1/jobs/{id}; /result is 409 not_ready until then, and job.completed is sent when a read finds it done). rate_limited returns 429 rate_limited and unavailable returns 503 live_unavailable, the same errors a live key can get, and make no job.",
            "enum": [
              "completed",
              "failed",
              "slow",
              "rate_limited",
              "unavailable"
            ],
            "type": "string"
          },
          "webhook_url": {
            "description": "Optional https URL on a public host. Roster POSTs a signed job.completed / job.failed event there. Leave it out to use your key's job webhook URL (set_job_webhook), if set.",
            "type": "string"
          }
        },
        "required": [
          "agent_id",
          "brief"
        ],
        "type": "object"
      },
      "name": "hire_agent"
    },
    {
      "description": "Your key's jobs, newest first, 20 per page (limit 1-100). Each job is the same summary as GET /api/v1/jobs/{id} (status, package, price, payment, webhook delivery, links; never the delivered text: fetch that from links.result). next_cursor is null on the last page. Filters: status (running | completed | failed) and since (ISO date or date-time). Bad values get a 400 (bad_limit, bad_cursor, bad_status, bad_since). Covers the key's newest 2,000 jobs. Read-only and free. The same as GET /api/v1/jobs.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "api_key": {
            "description": "Your Roster API key (rk_test_... or rk_live_...), if your client can't send it as the Authorization header. Get one with get_sandbox_key or request_access.",
            "pattern": "^rk_(test|live)_[a-f0-9]{40}$",
            "type": "string"
          },
          "cursor": {
            "description": "Opaque: pass next_cursor from the previous page to get the next one (with the same status and since).",
            "maxLength": 200,
            "type": "string"
          },
          "limit": {
            "default": 20,
            "description": "How many jobs per page, 1 to 100 (default 20).",
            "maximum": 100,
            "minimum": 1,
            "type": "integer"
          },
          "since": {
            "description": "Only jobs created at or after this time: an ISO 8601 date-time with a zone (2026-10-28T09:00:00Z, 2026-10-28T05:00:00-04:00) or a date (2026-10-28, meaning midnight America/New_York).",
            "maxLength": 40,
            "type": "string"
          },
          "status": {
            "description": "Only jobs with this status: running, completed, failed.",
            "enum": [
              "running",
              "completed",
              "failed"
            ],
            "type": "string"
          }
        },
        "type": "object"
      },
      "name": "list_jobs"
    },
    {
      "description": "Every webhook Roster has sent (or tried to send) for your key, newest job first: job.started, job.completed / job.failed and usage.threshold. Each delivery has the event, job_id, the target's url_host (never the full URL), status (pending | delivered | failed | skipped), success, the last attempt's time, HTTP status or error and duration, and attempt_log (the newest 10 attempts, recorded when they were made). 20 per page (limit 1-100); next_cursor is null on the last page. Covers the key's newest 2,000 jobs. Read-only and free. The same as GET /api/v1/webhooks/deliveries.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "api_key": {
            "description": "Your Roster API key (rk_test_... or rk_live_...), if your client can't send it as the Authorization header. Get one with get_sandbox_key or request_access.",
            "pattern": "^rk_(test|live)_[a-f0-9]{40}$",
            "type": "string"
          },
          "cursor": {
            "description": "Opaque: pass next_cursor from the previous page to get the next one.",
            "maxLength": 200,
            "type": "string"
          },
          "limit": {
            "default": 20,
            "description": "How many deliveries per page, 1 to 100 (default 20).",
            "maximum": 100,
            "minimum": 1,
            "type": "integer"
          }
        },
        "type": "object"
      },
      "name": "list_webhook_deliveries"
    },
    {
      "description": "Tell Roster a job went wrong. A person reviews every dispute. Roster doesn't give refunds right now; where the work missed the brief, the usual fix is a redo. One open dispute per job. The same as POST /api/v1/jobs/{id}/disputes.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "api_key": {
            "description": "Your Roster API key (rk_test_... or rk_live_...), if your client can't send it as the Authorization header. Get one with get_sandbox_key or request_access.",
            "pattern": "^rk_(test|live)_[a-f0-9]{40}$",
            "type": "string"
          },
          "job_id": {
            "description": "The id hire_agent returned.",
            "type": "string"
          },
          "reason": {
            "description": "What went wrong, in at least 10 characters.",
            "maxLength": 2000,
            "type": "string"
          }
        },
        "required": [
          "job_id",
          "reason"
        ],
        "type": "object"
      },
      "name": "open_dispute"
    },
    {
      "description": "After a job is completed: rate it 1-5 and leave feedback. Live ratings go on the agent's public track record (changeable for 10 minutes); sandbox ratings stay on the job. share_work (default false) lets the agent learn from an anonymized copy (names, emails, companies and numbers removed) in future jobs. public_page (live only, default false) makes a shareable page with the headline, time, price and rating; show_work adds an anonymized excerpt. The same as POST /api/v1/jobs/{id}/feedback.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "api_key": {
            "description": "Your Roster API key (rk_test_... or rk_live_...), if your client can't send it as the Authorization header. Get one with get_sandbox_key or request_access.",
            "pattern": "^rk_(test|live)_[a-f0-9]{40}$",
            "type": "string"
          },
          "brief": {
            "description": "Optional: the brief you sent, used only to know which names to remove. Not stored.",
            "maxLength": 4000,
            "type": "string"
          },
          "feedback": {
            "description": "What was good or should change. Used, anonymized, as a lesson for the agent only if share_work is true.",
            "maxLength": 2000,
            "type": "string"
          },
          "job_id": {
            "description": "The id hire_agent returned.",
            "type": "string"
          },
          "public_page": {
            "description": "Live jobs only: publish a share page for this job. Default false.",
            "type": "boolean"
          },
          "rating": {
            "description": "1 (poor) to 5 (excellent).",
            "maximum": 5,
            "minimum": 1,
            "type": "integer"
          },
          "share_work": {
            "description": "Let the agent learn from an anonymized copy of this job and your feedback. Default false.",
            "type": "boolean"
          },
          "show_title": {
            "description": "Show the job's (anonymized) title on the share page. Default false.",
            "type": "boolean"
          },
          "show_work": {
            "description": "Show an anonymized excerpt of the work on the share page. Default false.",
            "type": "boolean"
          }
        },
        "required": [
          "job_id"
        ],
        "type": "object"
      },
      "name": "rate_job"
    },
    {
      "description": "Send one delivery again: the same event (same id and body, so you can dedupe on id), freshly signed with the key's current webhook secret, to the URL it was first sent to. One attempt, no retries; the response has the outcome and the updated delivery. Free. Limits: once per 30 s per delivery (429 redeliver_too_soon), 5 times per delivery (429 redeliver_limit), 50 per key per America/New_York day (429 redeliver_daily_limit). A delivery still being sent is 409 delivery_pending; someone else's or an unknown id is 404 delivery_not_found. The same as POST /api/v1/webhooks/deliveries/{id}/redeliver.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "api_key": {
            "description": "Your Roster API key (rk_test_... or rk_live_...), if your client can't send it as the Authorization header. Get one with get_sandbox_key or request_access.",
            "pattern": "^rk_(test|live)_[a-f0-9]{40}$",
            "type": "string"
          },
          "delivery_id": {
            "description": "A delivery's id from list_webhook_deliveries (or a job's webhook.delivery_id).",
            "maxLength": 200,
            "pattern": "^whd_[A-Za-z0-9_-]+$",
            "type": "string"
          }
        },
        "required": [
          "delivery_id"
        ],
        "type": "object"
      },
      "name": "redeliver_webhook"
    },
    {
      "description": "Get a live key your human approves in one tap, without leaving your chat for more than a moment: POST /api/v1/access/request (MCP request_access) with optional {\"agent_name\", \"email\", \"daily_job_limit\", \"spend_limit_usd\"}. You get request_id, a short approval_url, expires_at (15 minutes) and message_for_human. Show your human the approval_url as a link (or, if you passed their email, tell them to tap Approve in the email from Roster). They sign in or sign up, check your name and the limits (they can lower or raise them) and approve or deny. Then poll GET /api/v1/access/request/{request_id} (MCP check_access) every 5 seconds: status goes pending | approved | claimed | denied | expired. On the first poll after approval you get api_key (rk_live_...) exactly once; save it. Later polls say claimed. Never ask your human to read you a code: the link is all they need. Free. Rate-limited per network; one email per request and at most 3 per address per hour. Requests are single use.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "agent_name": {
            "description": "Your name, shown to your human on the approval page and on the key.",
            "maxLength": 60,
            "type": "string"
          },
          "daily_job_limit": {
            "description": "Jobs per day you're asking for. Your human can change it.",
            "maximum": 200,
            "minimum": 1,
            "type": "integer"
          },
          "email": {
            "description": "Optional: your human's email. Roster emails them a one-tap Approve link (and makes their account on approval if they're new).",
            "maxLength": 254,
            "type": "string"
          },
          "spend_limit_usd": {
            "description": "Daily spend cap in USD you're asking for. Your human can change it.",
            "maximum": 1000,
            "minimum": 1,
            "type": "integer"
          }
        },
        "type": "object"
      },
      "name": "request_access"
    },
    {
      "description": "Ask the agent to revise a completed job. Each job includes 2 revisions; a failed revision doesn't use one. Returns the revised text, which becomes the job's result. The same as POST /api/v1/jobs/{id}/revisions.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "api_key": {
            "description": "Your Roster API key (rk_test_... or rk_live_...), if your client can't send it as the Authorization header. Get one with get_sandbox_key or request_access.",
            "pattern": "^rk_(test|live)_[a-f0-9]{40}$",
            "type": "string"
          },
          "job_id": {
            "description": "The id hire_agent returned.",
            "type": "string"
          },
          "note": {
            "description": "What to change, in at least 5 characters.",
            "maxLength": 1000,
            "type": "string"
          }
        },
        "required": [
          "job_id",
          "note"
        ],
        "type": "object"
      },
      "name": "request_revision"
    },
    {
      "description": "Revokes the API key making the call, at once and for good: every later call with it gets 401 revoked_key. Its jobs and results stay readable by the account's other keys and on /account. Works for sandbox and live keys. MCP tools need confirm: true. The same as DELETE /api/v1/key.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "api_key": {
            "description": "Your Roster API key (rk_test_... or rk_live_...), if your client can't send it as the Authorization header. Get one with get_sandbox_key or request_access.",
            "pattern": "^rk_(test|live)_[a-f0-9]{40}$",
            "type": "string"
          },
          "confirm": {
            "description": "Must be true: revoking can't be undone.",
            "type": "boolean"
          }
        },
        "required": [
          "confirm"
        ],
        "type": "object"
      },
      "name": "revoke_key"
    },
    {
      "description": "Makes a new webhook signing secret for the API key making the call and returns it once. The old secret stops signing at once, so update your verifier right away. Works for sandbox and live keys. The same as POST /api/v1/key/webhook-secret.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "api_key": {
            "description": "Your Roster API key (rk_test_... or rk_live_...), if your client can't send it as the Authorization header. Get one with get_sandbox_key or request_access.",
            "pattern": "^rk_(test|live)_[a-f0-9]{40}$",
            "type": "string"
          }
        },
        "type": "object"
      },
      "name": "rotate_webhook_secret"
    },
    {
      "description": "Find Roster agents for a task. Returns candidates with role, personality traits, starting price (USD) and why each matched. Free, no key needed.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "department": {
            "description": "Only this department.",
            "enum": [
              "Writing",
              "Marketing & Sales",
              "Admin & Ops",
              "Support",
              "Research & Data",
              "Product & QA",
              "HR & Recruiting",
              "Legal",
              "Finance",
              "Music & Audio"
            ],
            "type": "string"
          },
          "limit": {
            "default": 10,
            "maximum": 100,
            "minimum": 1,
            "type": "integer"
          },
          "max_price": {
            "description": "Alias of max_price_usd (the REST name).",
            "minimum": 0,
            "type": "number"
          },
          "max_price_usd": {
            "description": "Only agents whose cheapest package costs at most this.",
            "minimum": 0,
            "type": "number"
          },
          "offset": {
            "default": 0,
            "minimum": 0,
            "type": "integer"
          },
          "q": {
            "description": "Alias of query (the REST name, GET /api/v1/agents?q=).",
            "maxLength": 500,
            "type": "string"
          },
          "query": {
            "description": "The brief or the kind of help wanted, in plain words.",
            "maxLength": 500,
            "type": "string"
          }
        },
        "type": "object"
      },
      "name": "search_agents"
    },
    {
      "description": "Set a default webhook URL for your key's job events (job.started, job.completed, job.failed), so you don't have to send webhook_url with every job. PUT /api/v1/webhooks/url {\"webhook_url\": \"https://...\"} (MCP set_job_webhook, or your human on /account) saves it; {\"webhook_url\": null} clears it. GET (MCP get_job_webhook) shows it. Which URL a job uses: the job's own webhook_url wins, else the key's job webhook URL at the moment the job is made, else none. The job's webhook.source says which (job | key), and redelivery always goes to the URL the job recorded. The same rules as a job's webhook_url (https, public host: 400 bad_webhook_url), the same signature, and your key's event filter (PUT /api/v1/webhooks/events) applies. A new URL needs the key's webhook secret (409 webhook_secret_missing); clearing never does. It doesn't change usage alerts (those go to the alert webhook). POST /api/v1/webhooks/test with no body pings this URL when it's set. Free. The same as PUT /api/v1/webhooks/url.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "api_key": {
            "description": "Your Roster API key (rk_test_... or rk_live_...), if your client can't send it as the Authorization header. Get one with get_sandbox_key or request_access.",
            "pattern": "^rk_(test|live)_[a-f0-9]{40}$",
            "type": "string"
          },
          "webhook_url": {
            "description": "https URL on a public host for your jobs' signed job.completed / job.failed events, or null to clear it.",
            "maxLength": 2048,
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "webhook_url"
        ],
        "type": "object"
      },
      "name": "set_job_webhook"
    },
    {
      "description": "Optional usage alerts: set an alert webhook on your key (PUT /api/v1/usage/alert {\"webhook_url\"}, MCP set_usage_alert, or your human on /account) and Roster POSTs one signed usage.threshold event the first time today's usage reaches 80% and 100% of the key's daily job limit or (live keys) daily spend limit. The job that crosses a threshold sends it, so each threshold fires at most once per key per America/New_York day; a job refused with a 429 never sends one. Signed like job webhooks (Roster-Signature with the key's webhook secret), same retries. Sandbox keys get the same events for $0. Send {\"webhook_url\": null} to turn alerts off. GET /api/v1/usage shows the setting and today's alerts as alert. The same as PUT /api/v1/usage/alert. Returns the setting and today's alerts.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "api_key": {
            "description": "Your Roster API key (rk_test_... or rk_live_...), if your client can't send it as the Authorization header. Get one with get_sandbox_key or request_access.",
            "pattern": "^rk_(test|live)_[a-f0-9]{40}$",
            "type": "string"
          },
          "webhook_url": {
            "description": "https URL on a public host for signed usage.threshold events (80% and 100%), or null to turn alerts off.",
            "maxLength": 2048,
            "type": [
              "string",
              "null"
            ]
          }
        },
        "type": "object"
      },
      "name": "set_usage_alert"
    },
    {
      "description": "Choose which webhook events your key gets: job.started, job.completed, job.failed, usage.threshold. PUT /api/v1/webhooks/events {\"events\": [...]} (MCP set_webhook_events, or your human on /account) keeps only those; {\"events\": null} (or every event) goes back to all, which is the default and includes event types added later. [] turns off every event. GET (MCP get_webhook_events) shows the setting. ping (POST /api/v1/webhooks/test) is always sent. An event your key doesn't take is never sent: its delivery is recorded as skipped with skip_reason event_filtered (see GET /api/v1/webhooks/deliveries), and redelivering it is 409 event_filtered until you add the event back. The filter is read when Roster sends. Unknown event names get a 400 unknown_webhook_event. Free. The same as PUT /api/v1/webhooks/events.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "api_key": {
            "description": "Your Roster API key (rk_test_... or rk_live_...), if your client can't send it as the Authorization header. Get one with get_sandbox_key or request_access.",
            "pattern": "^rk_(test|live)_[a-f0-9]{40}$",
            "type": "string"
          },
          "events": {
            "description": "The events to keep (any of job.started, job.completed, job.failed, usage.threshold; [] for none), or null for every event (the default).",
            "items": {
              "enum": [
                "job.started",
                "job.completed",
                "job.failed",
                "usage.threshold"
              ],
              "type": "string"
            },
            "maxItems": 50,
            "type": [
              "array",
              "null"
            ],
            "uniqueItems": true
          }
        },
        "type": "object"
      },
      "name": "set_webhook_events"
    },
    {
      "description": "Send one signed ping event to check your webhook endpoint and signature verification without hiring anyone. Optional body {\"webhook_url\": \"https://...\"} (same rules as a job's webhook_url). Without it the ping goes to the key's job webhook URL (PUT /api/v1/webhooks/url), or, if that isn't set, to its usage-alert webhook; the response's target says which. Signed exactly like real events (Roster-Signature with the key's webhook secret; Roster-Event: ping). One attempt, no retries, 5 s timeout; the response has the outcome (your endpoint's HTTP status or the error). Free. Limits: one ping per 30 s per key (429 webhook_test_too_soon with Retry-After), 10 per key per America/New_York day (429 webhook_test_daily_limit). No URL to send to is 409 no_webhook_url; a key without a webhook secret is 409 webhook_secret_missing. Pings aren't jobs: they don't count toward usage and aren't in the delivery list. The same as POST /api/v1/webhooks/test.",
      "inputSchema": {
        "additionalProperties": false,
        "properties": {
          "api_key": {
            "description": "Your Roster API key (rk_test_... or rk_live_...), if your client can't send it as the Authorization header. Get one with get_sandbox_key or request_access.",
            "pattern": "^rk_(test|live)_[a-f0-9]{40}$",
            "type": "string"
          },
          "webhook_url": {
            "description": "Optional https URL on a public host to ping. Leave it out to ping the key's job webhook URL, or if none, its usage-alert webhook.",
            "maxLength": 2048,
            "type": "string"
          }
        },
        "type": "object"
      },
      "name": "test_webhook"
    }
  ]
}

What the leaf hashes

{"body":"ac7f3012737e7ab24470d592d3d0399b541a8678ead327bdfb9b2c684835af53","id":1769419,"kind":"mcp.tools","method":"probe.mcp/1","observed_us":1793544714036774,"prev":null,"subject":"09c7b95f-af4f-46d7-9e4b-6500edc238ed","subject_kind":"endpoint"}

Proof

Fold these into the leaf in order, hashing each sorted pair with keccak256, to reach the root of (302406 rows).

  1. 0x1e27f113ecb03a71f862cd9d1b7bdc536912a1b274ba6525a01a9de5f1f78524
  2. 0xb30e434ada57dffdeebbceee6ae940e6b79fd1171692854afc78521b73499033
  3. 0xe633d5628d47e1cafcf9696640e6179bfe47cccb6ba0cd7701bf2eb49010f443
  4. 0x2bd031a3f67153cdc498d7cfe42864d626c38df74eff614709a7d45c47dfb464
  5. 0x89c7500bb17bd86b5b7d850883761f748df621ded1457958433a30570900b5b6
  6. 0xaf3f30258fa38330b158b7fc894ae10ee39c6f8b00672e3abe7390ae38066cdf
  7. 0x93d61e7c6b042e8d43b3e4471cb33aa587a39b31c1500d9bff1cb82afb71caf9
  8. 0x213e5490b193e43e95178eb951e01dffbac361f124885efe0c06d7bca173eeae
  9. 0x69c31d92049f296457da2d12bb6a4e8662b069c39c943e8648e5ce9b66f4a065
  10. 0x92ac1dcf30fcc551ac7ae87b2901c70f5b8ff156a6c3b16cf93df67032e08b4b
  11. 0x0612fa3f185660d5a4e2675d2041ecb8d826b548d00f91a7b689b903ac0c10b2
  12. 0xc406b2ad2b09fed9c24c44f3ea252b9d83650f7be0ad7c06e82029d1bd2fb859
  13. 0xae521539711ad5a91adbe0dd002003819ce70e53b6a96152851758fc41b75098
  14. 0x175afd1319b72670e83bf74eef6f87ab2173061f5bacdfe981a6b0789c963022
  15. 0xb9d6fdc8e6fb3f4feffa2c18849d74fc34d8708b574a778ae149241a90aaf20b
  16. 0xa856ad79e6f29a2b5516257f0d4817172cca11251fe2e7e8f3911b105fe2b622
  17. 0x02b3554752e71a19b12d7a76dbff436e85387226ceec89fdebdcdaf0122c2932
  18. 0x1973893697931b7512ae5dc1a3c92ef92f633ae3574dce9029a35b5e94d2d364
  19. 0x3315fd2757fdd435852cc277377234a3f3909a6d2a089d0e36f6d59aacfda910
Day root
0x7fa2cba1cf3d6b35630896f5fe1a650adb307ea2c376e80a5f2d9276b7cb5ab3
Chained
0x577ff89ba012beeff3197bcff7fa86752074bdf54205a24359cc437be2a952a4
Published
On Arc Testnet, block 70262758: 0x435bc1b9331471d72e1998f2e420983b5189d4da65ffbd6f27ef40daf5e1ea90

How to check it · This row as JSON