Create a proposal
Propose an IndexNow submission or outreach emails for a person to approve in RankParse.
https://api.rankparse.com/v1/proposalsFree (the action is billed only when it runs)API keyStores an action as a pending proposal and returns a review_url to show the user. Nothing runs until a person approves it in the RankParse web app. The body is a JSON object with a kind plus that kind's fields. See Proposals for statuses, idempotency and limits.
Body parameters
kindstringrequiredindexnow_submit or outreach_send. Any other value returns 400 invalid_proposal_input.
site_idstringA website id from List websites. For IndexNow it is optional and, when given, must be the website that owns the URLs' host (400 site_host_mismatch otherwise). For outreach it is required when creating a campaign, and with campaign_id it must match that campaign's website (400 campaign_site_mismatch). A website of another workspace returns 404 site_not_found.
notestringWhy you are proposing this, in one or two plain sentences. Control and invisible characters are removed, the text is cut to 1000 characters, and the reviewer sees it labelled as the agent's note. It never becomes the proposal's title.
client_request_idstring1 to 64 characters of A-Z a-z 0-9 _ -. Validated and otherwise ignored, because duplicate detection is automatic.
Kind indexnow_submit
urlsarray of stringsrequired1 to 1000 full http(s) URLs, each at most 2048 characters, no explicit port, all on one host that is one of your RankParse websites. The stored list is de-duplicated and sorted, and its total size is capped at about 1.9 MB.
The host must already have an IndexNow key (IndexNow, POST /v1/indexnow/key), otherwise the call returns 400 indexnow_key_not_found. Whether the key file is actually hosted is checked when the proposal runs.
Kind outreach_send
Two shapes. Inline contacts: pass site_id, campaign_name and contacts; RankParse reuses the live Gmail campaign with that name on that website, or creates a draft, adds the contacts and proposes them. Existing campaign: pass campaign_id, optionally with extra contacts to add first; without contacts it proposes the campaign's emails that are waiting for review.
campaign_idstringA campaign of your workspace (up to 64 characters). Must send through Gmail. Unknown ids return 404 campaign_not_found.
campaign_namestring1 to 200 characters. Required when campaign_id is omitted.
contactsarray of objects1 to 100 contacts. Required when campaign_id is omitted. Contacts follow the same rules as Add contacts: one per domain, one per email address, people emailed in an earlier campaign are skipped, 500 per campaign. Unknown keys are rejected.
Show propertiesHide properties
emailstringrequiredA researched, real address. Up to 320 characters.
domainstringrequiredThe prospect's domain. Up to 253 characters. Use the punycode (xn--) form for internationalized domains.
subjectstringrequiredUp to 500 characters.
bodystringrequiredPlain text, up to 10,000 characters.
namestringContact name, up to 200 characters.
domain_authoritynumberOptional. Values outside 0 to 100 are stored as unknown.
An agent proposal holds at most 100 emails. The website's Gmail mailbox must be connected and working, or the call returns 400 gmail_not_connected. Unknown top-level fields return 400 invalid_proposal_input.
Response
The status code and status tell you what happened:
| HTTP | status | Meaning |
|---|---|---|
202 | awaiting_approval | The proposal is pending. Nothing has happened. This is the normal result, and the only new-proposal result for outreach. |
202 | approved | Either the same action was already approved and is running (dedupe_hit: true, with a review_url), or the website's policy approved an IndexNow submission automatically and the run will be retried within the hour (the body then has only status, proposal_id and message). Do not propose it again. |
200 | executed | IndexNow only: the policy is Automatic and the submission ran immediately. The body has proposal_id and outcome. The 1 credit is charged. |
statusstringawaiting_approval, approved or executed.
proposal_idstringprp_ followed by URL-safe characters. Use it with Get a proposal.
review_urlstringThe link to show the user. For outreach it is the campaign page in RankParse, where each email is approved one by one. For IndexNow it opens the proposal on the website's Today page, or the workspace inbox when the proposal has no website. It contains only ids.
titlestringBuilt by RankParse from the stored data (counts and host), never from your text. For example Send 12 outreach emails to 12 domains.
dedupe_hitbooleantrue when an identical open proposal already existed and was returned instead of a new one.
messagestringPlain-text guidance to relay to the user.
outcomeobjectOnly with status: "executed".
Show propertiesHide properties
statusstringsucceeded or failed.
resultobjectIndexNow: host, url_count, key_location.
errorCodestring | nullA failure code, or null.
Errors
| HTTP | Code | When |
|---|---|---|
| 400 | invalid_proposal_input | Body is not a JSON object, kind is missing or unsupported, a field has the wrong type or is out of range, an unknown field was sent, or site_id is missing when creating a campaign. |
| 400 | kind_not_available | The kind exists but cannot be proposed yet. |
| 400 | indexnow_invalid_url, indexnow_too_many_urls, indexnow_host_mismatch | A URL is invalid or uses a port, there are more than 1000, or they span more than one host. |
| 400 | indexnow_host_not_a_website | The URLs' host is not one of your RankParse websites. |
| 400 | site_host_mismatch | site_id names a different website than the URLs' host. |
| 400 | indexnow_key_not_found | The host has no IndexNow key yet. |
| 400 | gmail_not_connected | The website's mailbox is not connected, or Google stopped accepting it and it needs reconnecting. |
| 400 | sending_provider_unsupported | The campaign does not send through Gmail. |
| 400 | campaign_site_mismatch | The campaign belongs to a different website than site_id. |
| 400 | no_contacts | Nothing to propose: no emails are waiting for review, or none of the contacts could be added (the message lists the skip reasons). |
| 401 | invalid_api_key | Missing, invalid or revoked API key. |
| 403 | approval_inbox_not_enabled | The approval inbox is not switched on for this account. Do not retry. |
| 403 | action_disabled_by_policy | The owner turned this action Off for the website. Do not retry. |
| 404 | site_not_found, campaign_not_found | The website (or campaign) is not in this account, or the website is archived. |
| 409 | campaign_not_editable | The campaign cannot take contacts right now, for example while a launch is running. Retry in a moment. |
| 429 | too_many_pending_proposals, daily_proposal_limit_reached, rate_limited | See Limits. |
Errors use the shape { "error": "<code>", "code": "<code>", "message": "..." }. See Errors.
Related
MCP tools: propose_indexnow_submit (urls, site_id, note) and propose_outreach_send (site_id, campaign_id, campaign_name, contacts, note).