RankParse

Approval inbox

How agent-proposed actions work in RankParse. An agent proposes, a person approves in the dashboard, and only then does anything run.

An AI agent that can send email and submit URLs on your behalf needs a brake. The approval inbox is that brake. Instead of acting, the agent proposes an action. The proposal lands in your inbox in the RankParse dashboard, you read exactly what would happen, and only your approval makes it run.

This page explains the model. The API details are in Proposals, Agent tasks and activity, Websites and Client report.

The one rule: approval happens only in the RankParse web app, by a signed-in person. No API key, MCP tool or connector can approve, skip or run a proposal. An agent can fill your inbox, never empty it.

How it works

Agent                     RankParse API                  Person (web app)
  |                             |                                |
  | 1. POST /v1/proposals       |                                |
  |---------------------------->| stores a pending proposal      |
  |<--- 202 awaiting_approval --|                                |
  |     proposal_id, review_url |-- daily email: items waiting ->|
  |                             |                                |
  | 2. shows review_url to user |        3. opens the inbox, reads every URL or email,
  |                             |           removes items, approves or skips
  |                             |<------------- approve ---------|
  |                             | 4. runs exactly what was approved
  |                             |    (charges credits, sends, submits)
  | 5. GET /v1/proposals/:id    |                                |
  |---------------------------->|                                |
  |<--- succeeded, result ------|                                |
  | 6. POST /v1/activity (optional note)                         |
  1. Propose. The agent calls POST /v1/proposals (or an MCP propose tool). Nothing runs. It gets back a proposal_id and a review_url.
  2. Tell the person. The agent shows the review_url. RankParse also lists the item in the website's Today page and the workspace inbox, and emails a daily digest.
  3. Review. The person sees the proposal's real content (the actual URLs, or every outreach email with its recipient, subject and body). They can remove individual emails, then approve or skip.
  4. Run. On approval RankParse runs the exact snapshot that was approved. If the content changed after approval, the run is refused.
  5. Read the outcome. The agent polls GET /v1/proposals/:id or lists with GET /v1/proposals. The status ends as succeeded, partially_succeeded or failed with an error_code.
  6. Report back (optional). The agent logs a short note to the activity feed and, for queued tasks, completes them with a summary.

What an agent can propose

KindWhat it does when approvedCreditsCan run without a person?
indexnow_submitSubmits up to 1000 URLs on one of your websites to IndexNow (Bing, Yandex, Seznam, Naver and others).1 when it runs, refunded if the submission failsOnly if you set that website's policy to Automatic
outreach_sendQueues the reviewed outreach emails for sending from your connected Gmail account.0Never. Outreach always waits for a person.

RankParse itself also creates items for your inbox, which you can approve like any other:

  • Rank-drop investigations. For websites with rank-change alerts on, a keyword that dropped can produce a proposal. Approving it creates a task asking your agent to find the cause. At most 3 a day per website.
  • Pages not confirmed as indexed. For tracked pages older than 2 days without a clean Search Console indexing result, RankParse can suggest submitting them to IndexNow, at most once a day per website.
  • Raising the sending limit. When an agent tries to raise the daily Gmail send cap or switch auto-send on, that change becomes a proposal. Lowering the cap or switching sending off always applies immediately, because stopping is always allowed.

Agents can only create indexnow_submit and outreach_send proposals through the API. The others come from RankParse.

Who can approve

Owners, admins and members of the workspace can approve proposals, subject to the permission each kind needs (outreach needs permission to send outreach; IndexNow needs permission to spend credits and edit the website). Client accounts never see the inbox. RankParse re-checks the approver's permission when the action runs, so a role removed after approval stops the run (approver_lost_permission).

What the agent may do without asking

Each website has a settings section called What the agent may do without asking. Owners and admins can change it. Each action has a mode:

ActionModesDefaultNotes
Submit pages to IndexNowAsk first, Automatic, OffAsk firstAutomatic has a daily URL limit: 200 by default, 1000 at most. Past the limit, proposals wait for approval.
Suggest indexing for pages Google has not confirmed as indexedAsk first, Automatic, OffAsk firstAutomatic uses the same IndexNow daily limit.
Send outreach emailsAsk first, OffAsk firstCannot be Automatic. You see every email before anything is sent.
Raise the daily send limit or turn sending onAsk first, OffAsk firstLowering or pausing never needs approval.
Suggest investigating ranking dropsAsk first, OffAsk firstOnly for websites with rank alerts on.

Off means the API refuses the proposal outright with 403 action_disabled_by_policy. A website's setting overrides a workspace-wide default, which overrides the built-in default.

Where approval is enforced

The inbox protects actions that come from an agent. RankParse treats a request as agent-origin when it carries the header X-RankParse-Client: mcp, which the RankParse MCP server sets on every call. In an account where the inbox is enforced:

RequestWhat happens
MCP tool outreach_launch_campaign (or POST /v1/outreach/campaigns/:id/launch with the header)Creates an outreach_send proposal and returns status: "awaiting_approval" with a review_url. Nothing is queued.
MCP tool submit_indexnow_urls (or POST /v1/indexnow with the header)Creates an indexnow_submit proposal instead of submitting, unless the website's policy is Automatic.
MCP tool outreach_configure_sending raising the cap or enabling auto-sendBecomes a proposal. Any decrease or disable in the same request applies immediately.
A button you click in the dashboardYour click is the approval. It runs now.
A direct REST call without that headerRuns immediately, exactly as before.
RapidAPI callsNever agent-origin, so never diverted.

The approval guarantee covers agents that go through the RankParse MCP server, or that send the X-RankParse-Client: mcp header. A script that calls the REST API directly with your key is acting as you, and is not stopped. Keep API keys private, and use Dashboard keys to revoke any you no longer trust.

Proposal lifecycle

pending --approve--> approved --> executing --> succeeded
   |                     |             |   \--> partially_succeeded
   |                     |             \------> failed --retry--> approved
   |--skip----------> skipped
   |--no decision---> expired
   |--newer proposal-> superseded
   \--all emails removed--> cancelled
StatusMeaning
pendingWaiting for a person.
approvedApproved by a person or an Automatic policy. About to run, or waiting for a retry.
executingRunning now.
succeededDone. The proposal's result has counts.
partially_succeededOutreach only: some emails were queued, others had changed or were suppressed.
failedDid not complete. error_code says why. A person can retry it in the app.
skippedA person declined it.
expiredNobody decided in time.
supersededReplaced by a newer proposal for the same outreach campaign.
cancelledA reviewer removed every email, so nothing was left to send.

Expiry

A pending proposal expires if nobody decides in time:

KindExpires after
Outreach send14 days
IndexNow submission7 days
Sending limit change3 days
Rank-drop investigation7 days

Expired proposals disappear from the pending count and the digest. Propose again if the action is still wanted.

Reliability and safety

  • Exact snapshot. An outreach proposal records each email's content hash, and an IndexNow proposal its URL list. Approval binds to that hash. If an email's content changes after you reviewed it, that email is not sent (it is reported as changed since review).
  • At most once per decision. A run is claimed with a lease. A crashed or timed-out run is picked up again by an hourly recovery job, starting 10 minutes after approval, up to 5 attempts. Charges are applied once and refunded on failure.
  • Duplicates collapse. Proposing the same content twice returns the same proposal (dedupe_hit: true), so retries are safe.
  • Text is sanitized. Agent-written notes are cleaned of control and invisible characters and shown labelled as the agent's words. The title of a proposal is always built by RankParse from the stored data, never from agent text.
  • Isolation. A proposal, task or website of another account returns 404. A workspace id can never be supplied by a caller.

Limits

LimitValue
Pending proposals per website25
New proposals per account per UTC day100
Activity notes per account per UTC day200
URLs per IndexNow proposal1000
Emails per agent outreach proposal100
Requests per minute60

Activity log

Everything that happens around an inbox item is recorded in the website's activity feed: proposal created, approved, skipped, expired, succeeded or failed; IndexNow submitted; outreach sent; tasks created, claimed and completed; policy changes.

Agents can add their own entries with POST /v1/activity (MCP tool log_activity). RankParse also attaches the calls your agent made, and the credits they used, to those notes automatically, so you can see what a piece of research cost without the agent reporting it. See Agent tasks and activity.

Agent tasks

Tasks flow the other way. A person leaves a job ("Find links my competitors have"), the agent reads its queue with GET /v1/agent-tasks, works on it using the normal tools, and calls POST /v1/agent-tasks/:id/complete with a summary the person sees in the app. Claiming is optional; completing an open task claims it. See Agent tasks.

Daily digest email

When something is waiting for a decision, RankParse emails each non-client member of the workspace at most once per day (sent in the afternoon, UTC) with the number of items waiting, per workspace and website. No items means no email. A send that fails is retried later the same day. Each person can switch it off under Account, with the toggle Daily email when items are waiting for your OK. The email never contains proposal content.

Client reports

Work that is safe to show a client appears in the weekly client report: IndexNow submissions, outreach emails sent per day, rank moves, and any agent note or task summary a team member chose to share. Approvals, policy changes, credit use and everything else stay private to the team.

Retention

DataKept for
Activity feed events400 days
Finished proposals (any terminal status)400 days
Agent notes on finished proposalscleared after 90 days
Agent tasks400 days
Saved weekly client reports400 days
Daily limit counters35 days

Pending, approved and executing proposals are never deleted by retention.

Availability

SurfaceStatus
REST API with an API key (/v1/proposals, /v1/activity, /v1/agent-tasks, /v1/websites)Available.
API-key MCP endpoint (mcp.rankparse.com)Available. It has the propose, task and activity tools.
Secure OAuth connector for Claude and ChatGPT (connect.rankparse.com)Read-only. It can list your websites and your inbox proposals. Letting an agent put drafts in your inbox through the connector is planned but not available yet.
Give your agent a task box and stored tasksOnly on accounts where agent proposals are available. Elsewhere the box opens Claude or ChatGPT with the prompt pre-filled and nothing is stored.

If the inbox has not been switched on for an account, POST /v1/proposals returns 403 approval_inbox_not_enabled and launches and submissions behave as they did before the inbox existed.

End-to-end example

An agent wants to tell Bing and Yandex about two changed pages on example.com.

Find the website

curl "https://api.rankparse.com/v1/websites" -H "X-API-Key: rp_your_key"
{ "websites": [{ "id": "site_abc123", "host": "example.com", "name": "Example" }] }

Make sure the host has an IndexNow key

Provision the key, then have the person host the key file at the returned key_location. This is free. See IndexNow.

curl -X POST "https://api.rankparse.com/v1/indexnow/key?domain=example.com" \
  -H "X-API-Key: rp_your_key"

Propose the submission

curl -X POST "https://api.rankparse.com/v1/proposals" \
  -H "X-API-Key: rp_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "indexnow_submit",
    "site_id": "site_abc123",
    "urls": ["https://example.com/blog/new-post", "https://example.com/pricing"],
    "note": "Published a new post and changed the pricing page."
  }'
import requests

H = {"X-API-Key": "rp_your_key"}
res = requests.post(
    "https://api.rankparse.com/v1/proposals",
    headers=H,
    json={
        "kind": "indexnow_submit",
        "site_id": "site_abc123",
        "urls": ["https://example.com/blog/new-post", "https://example.com/pricing"],
        "note": "Published a new post and changed the pricing page.",
    },
)
proposal = res.json()
print(proposal["status"], proposal["review_url"])
const H = { "X-API-Key": "rp_your_key", "Content-Type": "application/json" };
const res = await fetch("https://api.rankparse.com/v1/proposals", {
  method: "POST",
  headers: H,
  body: JSON.stringify({
    kind: "indexnow_submit",
    site_id: "site_abc123",
    urls: ["https://example.com/blog/new-post", "https://example.com/pricing"],
    note: "Published a new post and changed the pricing page.",
  }),
});
const proposal = await res.json();
console.log(proposal.status, proposal.review_url);
{
  "status": "awaiting_approval",
  "proposal_id": "prp_V1StGXR8_Z5jdHi6B-myT",
  "review_url": "https://rankparse.com/dashboard/sites/site_abc123/today?proposal=prp_V1StGXR8_Z5jdHi6B-myT",
  "title": "Submit 2 URLs on example.com to IndexNow",
  "dedupe_hit": false,
  "message": "Waiting for the user's approval in RankParse: ..."
}

Ask the person to approve

The agent tells the person: "I've queued two pages for IndexNow. Review and approve here: the review_url." The person opens it, checks the URLs and approves. Nothing has been submitted and no credit has been spent yet.

Read the outcome

curl "https://api.rankparse.com/v1/proposals/prp_V1StGXR8_Z5jdHi6B-myT" \
  -H "X-API-Key: rp_your_key"
{
  "proposal": {
    "id": "prp_V1StGXR8_Z5jdHi6B-myT",
    "kind": "indexnow_submit",
    "status": "succeeded",
    "title": "Submit 2 URLs on example.com to IndexNow",
    "site_id": "site_abc123",
    "source": "agent",
    "estimated_credits": 1,
    "created_at": 1790000000000,
    "expires_at": 1790604800000,
    "decided_at": 1790003600000,
    "decided_via": "web",
    "result": { "host": "example.com", "url_count": 2, "key_location": "https://example.com/4f9c2a7e1b3d4c8aa0e6.txt" },
    "error_code": null
  }
}

While it is pending, keep waiting or stop. Do not propose it again: an identical proposal returns the same item.

Log what you did

curl -X POST "https://api.rankparse.com/v1/activity" \
  -H "X-API-Key: rp_your_key" \
  -H "Content-Type: application/json" \
  -d '{"summary": "Proposed IndexNow submission for 2 changed pages.", "site_id": "site_abc123"}'

Troubleshooting

On this page