Developer Documentation

API references, mechanism details, and VPS deployment configurations

⚙️ Under the Hood

RankMation SERP API uses a stealth Camoufox web browser engine to simulate real human organic searches. It parses Google search results natively on demand.

By default, the engine hardcodes the &udm=14 URL parameter. This strips away all modern SERP clutter (AI Overviews, featured snippets, Knowledge Graphs, and "People Also Ask" cards), returning the classic "10 Blue Links" directory.

This approach is crucial for AI agents and rank trackers who require the absolute true organic position of a website without interference from layout variations or dynamic AI widgets.

📡 API Endpoint Reference

Execute rank audits programmatically by invoking the endpoint:

Method Endpoint Access
POST /api/search Public

Payload Options:

Field Type Description
query string The query string to search on Google. (Required)
gl string Two-letter ISO country code. (e.g. us, pk)
hl string Two-letter language code. (e.g. en, es)
num number Number of results to extract (default: 10)

🖥️ VPS Deployment Guide

To deploy RankMation to your VPS, make sure you install browser dependencies. You can run the application directly using Docker or bare metal using **PM2**.

Method 1: Docker (Recommended)

Shell / Terminal
# 1. Build the Docker image
docker build -t rankmation-serp .

# 2. Run the container on port 3000
docker run -d -p 3000:3000 --name rankmation rankmation-serp

Method 2: Bare Metal with PM2

Shell / Terminal
# 1. Install browser requirements
npm install
npx playwright install-deps firefox

# 2. Start the scraper using PM2
pm2 start "npm start" --name "rankmation-serp"

🐍 Python Agent Script

agent_search.py
import requests

url = "http://localhost:3000/api/search"
payload = {
    "query": "artificial intelligence",
    "gl": "us",
    "hl": "en",
    "num": 10
}

response = requests.post(url, json=payload)
data = response.json()

print(f"Total Found: {data.get('totalFound')}")
for result in data.get('results', []):
    print(f"{result['position']}. {result['title']} -> {result['url']}")

👥 Cookie Profiles & Geo-Targeted Routing

RankMation supports loading persistent cookie profiles (imported as a JSON array from browser cookie exporter extensions). Each profile is assigned a target geo-location country code (e.g. sa for Saudi Arabia, us for United States).

When a search request is sent with a specific country code parameter (gl):

  • The system prioritizes active profiles whose target geo matches the requested gl.
  • If multiple matching profiles are found, they are rotated in a round-robin order based on the oldest lastUsed timestamp.
  • If no matching profiles are active, it falls back to the general active profiles pool.
  • If absolutely no profiles are active, it falls back to a clean default stateless browser context.

API Endpoints for Profiles:

Method Endpoint Payload / Parameters Description
GET /api/profiles Retrieves all stored cookie profiles and their metadata.
POST /api/profiles { "name": "sa_1", "country": "sa", "cookies": [...] } Imports or overwrites a named profile with associated target geo-location and cookies.
POST /api/profiles/:name/test Runs a test search against Google using the profile to check if it's alive or blocked.
DELETE /api/profiles/:name Deletes a profile, its cookies, and all local directory files.

🤖 AI Agent Tool Schema

Provide this JSON schema to function-calling LLMs (OpenAI, Gemini, Anthropic) so they can use RankMation natively:

tool_definition.json
{
  "name": "google_search_udm14",
  "description": "Performs a clean, clutter-free Google Search to retrieve organic ranking results. Returns organic positions, page titles, URLs, and snippets.",
  "parameters": {
    "type": "object",
    "properties": {
      "query": {
        "type": "string",
        "description": "The Google Search keywords."
      },
      "gl": {
        "type": "string",
        "description": "Two-letter country code for geo-targeting."
      },
      "hl": {
        "type": "string",
        "description": "Two-letter language code."
      },
      "num": {
        "type": "integer",
        "description": "Number of results to extract (10, 20, 30, 50, 100)."
      }
    },
    "required": ["query"]
  }
}