Open API
Use the Rankhog public REST API with OpenAPI, scoped auth, idempotency, and safe Reddit workflows.
Rankhog exposes the same paid agent capabilities through REST, MCP, and the CLI. Use REST when an external service or AI agent needs stable HTTP endpoints, OpenAPI schemas, idempotent writes, and status polling.
Base URL
RANKHOG_API_BASE_URL="https://api.rankhog.com"The OpenAPI 3.1 document is available at:
curl https://api.rankhog.com/agent/openapi.jsonSee the generated API reference for every endpoint schema, response, auth mode, and example.
Authentication
REST supports three auth paths:
- Organization API key: send
Authorization: Bearer rhog_...orx-api-key. - CLI bearer token: minted by Better Auth device authorization.
- OAuth bearer token: used by MCP and trusted OAuth clients.
API keys are organization automation credentials. They can execute Reddit writes only when the key has reddit:write:dangerous and the workspace, account, billing, pacing, approval, and Desktop checks pass.
| Capability | API key | CLI/session | OAuth |
|---|---|---|---|
| Read workspaces, rules, strategy, analytics, planned jobs, opportunity conversations, credit balance | rankhog:read | Yes | rankhog:read |
| Read the credit ledger | credits:read | Yes | credits:read |
| Buy credit packs, change auto top-up, adjust credits | No | No | No |
| Start or stop Discovery, run a scan, change Radar, or replace strategy inputs | No | strategy:write | strategy:write |
| Post opportunity conversation messages | conversation:write | Yes | conversation:write |
| Create stored Reddit actions | reddit:draft:write | Yes | reddit:draft:write |
| Execute authorized Reddit actions | reddit:write:dangerous | Yes | reddit:write:dangerous |
| Open desktop browser URLs, approve legacy drafts, read one job | No | Yes | Yes |
Legacy dangerously_submit_reddit_post | No | No | OAuth only |
API key messages can steer the opportunity agent and answer its questions, but they run as automation: confirming a Reddit write from a conversation stays human-only.
Discovery and Radar
Read the current product-owned strategy:
curl "$RANKHOG_API_BASE_URL/agent/v1/strategy" \
-H "Authorization: Bearer $RANKHOG_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"organizationId": "org_...",
"websiteId": "web_..."
}'Strategy mutations require a human session, OAuth, or CLI-device actor with
strategy:write. They are unavailable to organization API keys.
curl "$RANKHOG_API_BASE_URL/agent/v1/strategy/discovery/start" \
-H "Authorization: Bearer $RANKHOG_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"organizationId": "org_...",
"websiteId": "web_...",
"direction": "Find comparison demand",
"idempotencyKey": "start-discovery-001"
}'Stopping Discovery uses /strategy/discovery/stop; running it now uses
/strategy/discovery/run. Radar coverage is
/strategy/radar/coverage, Radar control is /strategy/radar, and shared
input replacement is /strategy/inputs. These endpoints change only the named
lane or inputs.
Quickstart
List workspaces, create a Reddit action, execute it, then poll status.
export RANKHOG_API_BASE_URL="https://api.rankhog.com"
export RANKHOG_API_KEY="rhog_..."
curl "$RANKHOG_API_BASE_URL/agent/v1/workspaces" \
-H "Authorization: Bearer $RANKHOG_API_KEY" \
-H "Content-Type: application/json" \
--data '{}'Use the returned organization.id, website.id, and managedRedditAccount.id in later calls.
Read the workspace's current opportunities before creating or executing work:
curl "$RANKHOG_API_BASE_URL/agent/v1/opportunities" \
-H "Authorization: Bearer $RANKHOG_API_KEY" \
-H "Content-Type: application/json" \
--data '{
"organizationId": "org_...",
"websiteId": "web_...",
"managedRedditAccountId": "acct_...",
"includeRecent": false,
"limit": 50
}'Opportunity responses preserve evidence and may add evidenceSummary,
timeZone, and nextTransitionAt. These read fields never approve or execute
Reddit work.
Create a stored action. Every write needs an idempotency key.
curl "$RANKHOG_API_BASE_URL/agent/v1/reddit-actions" \
-H "Authorization: Bearer $RANKHOG_API_KEY" \
-H "Content-Type: application/json" \
--data '{
"organizationId": "org_...",
"managedRedditAccountId": "acct_...",
"actionType": "comment",
"targetUrl": "https://www.reddit.com/r/SaaS/comments/examplepost/example/",
"body": "We saw better activation after asking for one setup action instead of showing a long checklist.",
"riskSummary": "Contextual reply with no link and no promotional claim.",
"idempotencyKey": "action-comment-2026-06-17-001"
}'Execute the authorized action. The response is immediate and means the execution was queued, not necessarily submitted.
curl "$RANKHOG_API_BASE_URL/agent/v1/reddit-actions/execute" \
-H "Authorization: Bearer $RANKHOG_API_KEY" \
-H "Content-Type: application/json" \
--data '{
"organizationId": "org_...",
"managedRedditAccountId": "acct_...",
"plannedRedditActionId": "act_...",
"acknowledgement": "I understand this can publish or change Reddit state from the user's Reddit account.",
"requestedExecutorRedditAccountId": "ra_...",
"idempotencyKey": "execute-action-2026-06-17-001"
}'Omit requestedExecutorRedditAccountId to let Rankhog pick the first ready product-granted Reddit account.
Queued response:
{
"status": "queued",
"executionId": "job_...",
"jobId": "job_...",
"plannedRedditActionId": "act_...",
"statusUrl": "/agent/v1/reddit-action-executions/status?executionId=job_..."
}Poll status:
curl "$RANKHOG_API_BASE_URL/agent/v1/reddit-action-executions/status" \
-H "Authorization: Bearer $RANKHOG_API_KEY" \
-H "Content-Type: application/json" \
--data '{
"organizationId": "org_...",
"managedRedditAccountId": "acct_...",
"executionId": "job_..."
}'Successful status includes the final Reddit location.
{
"status": "succeeded",
"executionId": "job_...",
"plannedRedditActionId": "act_...",
"redditAction": {
"redditActionId": "ra_...",
"permalink": "https://www.reddit.com/r/SaaS/comments/examplepost/example/examplecomment/",
"currentUrl": "https://www.reddit.com/r/SaaS/comments/examplepost/example/examplecomment/",
"submittedAt": "2026-06-17T11:46:08.000Z",
"subreddit": "SaaS",
"type": "comment"
},
"failure": null
}Failed status includes machine-readable remediation.
{
"status": "failed",
"failedStepId": "validate_subreddit_rules",
"failure": {
"reasonCode": "rules_unavailable",
"message": "The subreddit rules could not be verified before execution.",
"retryable": true,
"failedStepId": "validate_subreddit_rules",
"remediation": "Refresh subreddit rules in Rankhog, review the planned action, then execute again with a new idempotency key."
}
}Credits
Posts, comments, replies, and warm-ups spend credits. Read what a product can spend before queuing work:
curl "$RANKHOG_API_BASE_URL/agent/v1/credits/balance" \
-H "Authorization: Bearer $RANKHOG_API_KEY" \
-H "Content-Type: application/json" \
--data '{
"organizationId": "org_...",
"websiteId": "web_..."
}'{
"organizationId": "org_...",
"websiteId": "web_...",
"period": {
"allotment": 100,
"remaining": 82,
"available": 82,
"periodStart": "2026-06-01T00:00:00.000Z",
"periodEnd": "2026-07-01T00:00:00.000Z",
"source": "stripe_subscription"
},
"bank": { "available": 130, "balance": 130 },
"available": 212,
"committed": 4,
"spendable": 208,
"costs": { "warmup": 50, "post": 2, "comment": 1, "reply": 1, "upvote": 0, "draft_regeneration": 1 },
"monthlyAllotmentPerProduct": 100,
"lowBalanceThreshold": 20,
"products": [{ "websiteId": "web_...", "displayName": "Example SaaS", "available": 212, "committed": 4, "spendable": 208, "period": { "allotment": 100 } }]
}period is this product's monthly credits, bank is the organization pool shared by every product, and spendable is available minus credits committed to queued actions. Omit websiteId to read the bank alone.
Page through the ledger with /agent/v1/credits/ledger (credits:read). Every grant, purchase, refund, adjustment, and debit is one row with its actorKind and the action, warm-up, purchase, or opportunity it paid for. Pass the previous nextCursor as cursor; it is null on the last page. Member names and user ids are never included.
curl "$RANKHOG_API_BASE_URL/agent/v1/credits/ledger" \
-H "Authorization: Bearer $RANKHOG_API_KEY" \
-H "Content-Type: application/json" \
--data '{
"organizationId": "org_...",
"websiteId": "web_...",
"limit": 25
}'Both reads need organization membership only, so they work on lapsed and locked workspaces. execute_reddit_action and approve_reddit_draft return 402 agentic_insufficient_credits with required, available, and spendable when the product cannot spend the action's cost. Buying credit packs, auto top-up, and admin adjustments are billing changes and stay in the Rankhog app.
Idempotency
All writes require a caller idempotencyKey. Rankhog also derives a server-side key from plannedRedditActionId.
- Duplicate execute calls for the same planned action return the existing execution.
- Already submitted actions return the existing submitted Reddit action.
- Ambiguous final-submit states return
verification_required; do not blindly retry.
Statuses
get_reddit_action_execution_status returns one of:
queued
running
succeeded
failed
blocked
cancelled
verification_requiredverification_required means Reddit may have accepted the final submit, but Rankhog could not prove it. Check Reddit or refresh state before retrying with a new idempotency key.
Safety
Rankhog validates permissions/scopes before queueing execution. The execution layer then checks billing, account grants, action readiness, pacing, URL policy, Desktop readiness, Reddit account match, challenge pages, idempotency, and final verification. Public clients send high-level workflow requests only; raw browser control is not exposed.
Every execution also respects the selected identity's Reddit account protection policy. Weighted hourly and daily budgets and minimum spacing can delay or block an action. REST and organization API keys cannot weaken that human-owned policy.
The legacy dangerously_submit_reddit_post endpoint remains for compatibility. New clients should use create_reddit_action, execute_reddit_action, and get_reddit_action_execution_status.
Errors
Errors use one shape across REST and CLI:
{
"error": {
"code": "agentic_missing_scope",
"message": "Missing required OAuth scope: reddit:draft:write.",
"details": {
"missingScopes": ["reddit:draft:write"]
}
}
}Every REST response includes x-rankhog-request-id when handled by the agentic API.
Next: use the CLI for scripts, or MCP for AI clients with OAuth.