georanker/serp-sdk

PHP 8 SDK for the GeoRanker SERP API

Maintainers

Package info

github.com/AlexGeoranker/georanker-serp-sdk

Homepage

pkg:composer/georanker/serp-sdk

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-main 2026-05-13 11:44 UTC

This package is auto-updated.

Last update: 2026-05-13 11:45:09 UTC


README

A zero-dependency PHP 8 SDK for the GeoRanker SERP API. Create SERP requests, poll for results, and work with fully typed response objects.

Requirements

  • PHP 8.0 or higher
  • ext-curl
  • ext-json

Installation

Via Composer

composer require georanker/serp-sdk

Without Composer

Clone or download the repository and include the autoloader:

require_once '/path/to/georanker-serp-sdk/autoload.php';

Quick Start

use GeoRanker\GeoRankerClient;
use GeoRanker\Serp\SerpRequest;

$client = new GeoRankerClient('your-api-key');

$pending = $client->addSerp(new SerpRequest(
    keyword: 'pizza delivery',
    region:  'New York,New York,United States',
));

// Poll until the crawl finishes
do {
    sleep(3);
    $serp = $client->getSerp($pending->id);
} while (!$serp->ready);

foreach ($serp->data->organic as $result) {
    echo $result->position . '. ' . $result->title . "\n";
    echo '   ' . $result->url . "\n";
}

SSL on Windows / WAMP

Windows does not ship a CA certificate bundle for PHP. Download cacert.pem, save it locally, then pass the path to the client:

$client = new GeoRankerClient('your-api-key', 'C:\wampserver\cacert.pem');

Alternatively, set it globally in php.ini and restart your server — then no second argument is needed:

curl.cainfo    = "C:\wampserver\cacert.pem"
openssl.cafile = "C:\wampserver\cacert.pem"

Creating SERP Requests

Single request (asynchronous — default)

$pending = $client->addSerp(new SerpRequest(
    keyword:      'best coffee shops',
    searchEngine: 'google',
    region:       'London,England,United Kingdom',
    maxResults:   10,
    isMobile:     false,
    language:     'en',
));

echo $pending->id;    // use this to fetch results later
echo $pending->ready; // false — crawl not finished yet

Single request (synchronous — waits up to 300 s)

$serp = $client->addSerp(new SerpRequest(
    keyword:      'plumber near me',
    region:       'Chicago,Illinois,United States',
    priority:     'REALTIME',  // doubles credit cost
    asynchronous: false,       // block until crawl finishes
));

var_dump($serp->data->organic);

Coordinate-based region targeting

use GeoRanker\Serp\RegionSearch;

$serp = $client->addSerp(new SerpRequest(
    keyword:      'coffee shop',
    searchEngine: 'google',
    regionSearch: new RegionSearch(
        latitude:    48.8566,
        longitude:   2.3522,
        maxDistance: 5000,           // metres (optional)
        types:       ['city', 'municipality'],
    ),
));

Note: Do not set region when using regionSearch.

Bulk create (up to 1 000)

$pendings = $client->addSerpList([
    new SerpRequest('keyword one', region: 'Paris,France'),
    new SerpRequest('keyword two', region: 'Berlin,Germany'),
    new SerpRequest('keyword three', region: 'Tokyo,Japan'),
]);

$ids = array_map(fn($r) => $r->id, $pendings);

Fetching Results

Single SERP by ID

$serp = $client->getSerp('5d16674bb45b3b17173b095b');

if ($serp->ready) {
    // access typed result sets
}

Bulk fetch by IDs

$results = $client->getSerpList([
    '5d16674bb45b3b17173b095b',
    '5d16674bb45b3b17173b095c',
]);

foreach ($results as $serp) {
    echo $serp->id . ' ready: ' . ($serp->ready ? 'yes' : 'no') . "\n";
}

Working with Response Data

All response objects are fully typed. Once $serp->ready is true:

// Region that was used
echo $serp->region->canonicalName;  // "New York,New York,United States"
echo $serp->region->countryCode;    // "US"

// Metadata
echo $serp->data->totalResults;     // 1940000000
echo $serp->keyword;
echo $serp->searchEngine;
echo $serp->createdAt;
echo $serp->generatedAt;

// Organic results
foreach ($serp->data->organic as $result) {
    echo $result->position . '. ' . $result->title;
    echo '   URL: '    . $result->url;
    echo '   Domain: ' . $result->domain;
    echo '   Snippet: '. $result->text;
}

// Maps / local pack
foreach ($serp->data->maps as $result) {
    echo $result->position . '. ' . $result->title;
}

// People Also Ask
foreach ($serp->data->paa as $result) {
    echo $result->title;  // the question
    echo $result->text;   // the answer snippet
}

// Knowledge Graph
foreach ($serp->data->knowledgeGraph as $result) {
    echo $result->title;
    echo $result->category;   // e.g. "Dish"
    echo $result->imageUrl;
}

// Related searches
foreach ($serp->data->related as $result) {
    echo $result->text;
    echo $result->url;
}

// AI results (raw array — schema varies by search engine)
var_dump($serp->data->ai);

Search Engines

Value Engine Result location
google Google Web Search data->organic, data->maps, data->paa, etc.
googlelocal Google Maps data->maps
googleimages Google Images data->organic
google-aimode Google AI Mode data->ai
bing Bing data->organic
yahoo Yahoo data->organic
youtube YouTube data->organic
naver Naver data->organic
baidu Baidu data->organic
sogou Sogou data->organic
universal Raw crawl data for any URL data->raw (array)
chatgpt ChatGPT data->ai (array)
perplexity Perplexity data->ai (array)

Special Engines

Universal — crawl any URL

Pass the target URL as the keyword. The full raw HTML of the page is returned in $serp->data->raw.

$serp = $client->addSerp(new SerpRequest(
    keyword:      'https://www.georanker.com',
    searchEngine: 'universal',
    priority:     'INSTANT',
    region:       'US',
    asynchronous: false,
));

$raw = $serp->data->raw; // array of raw crawl data

ChatGPT

Pass your prompt as the keyword. The AI answer is returned in $serp->data->ai.

$serp = $client->addSerp(new SerpRequest(
    keyword:      'What is GeoRanker?',
    searchEngine: 'chatgpt',
    priority:     'INSTANT',
    region:       'US',
    asynchronous: false,
));

var_dump($serp->data->ai);

Perplexity

Same pattern as ChatGPT — prompt goes in keyword, answer comes back in $serp->data->ai.

$serp = $client->addSerp(new SerpRequest(
    keyword:      'What is GeoRanker?',
    searchEngine: 'perplexity',
    priority:     'INSTANT',
    region:       'US',
    asynchronous: false,
));

var_dump($serp->data->ai);

Priority Levels

Value Behaviour Cost multiplier
LOW Async by default
NORMAL Async by default
REALTIME Sync by default
INSTANT Sync by default

Advanced Parameters

Custom URL parameters

Appended to every URL during the crawl. Useful for UULE location encoding or forcing locale.

new SerpRequest(
    keyword: 'pizza',
    region:  'New York,New York,United States',
    customUrlParameter: [
        ['name' => 'uule', 'value' => 'w+CAIQICIgTmV3IFlvcmssVW5pdGVkIFN0YXRlcw=='],
        ['name' => 'hl',   'value' => 'en'],
        ['name' => 'pws',  'value' => null],  // null removes the default parameter
    ],
);

Custom cookies

new SerpRequest(
    keyword: 'pizza',
    region:  'London,England,United Kingdom',
    customCookieParameter: [
        ['name' => 'CONSENT', 'value' => 'YES+'],
    ],
);

Custom User-Agent

new SerpRequest(
    keyword:         'pizza',
    region:          'London,England,United Kingdom',
    customUserAgent: 'Mozilla/5.0 (compatible; MyBot/1.0)',
    saveRawData:     true,  // recommended when using a custom UA
);

Callback URL

Called via POST when the SERP is ready. Receives id and type fields.

new SerpRequest(
    keyword:        'pizza',
    region:         'London,England,United Kingdom',
    callback:       'https://mysite.com/webhook.php',
    callbackFormat: 'JSON',   // 'SIMPLE' or 'JSON'
);

Error Handling

All exceptions extend GeoRanker\Exceptions\GeoRankerException.

use GeoRanker\Exceptions\AuthException;
use GeoRanker\Exceptions\BadRequestException;
use GeoRanker\Exceptions\CreditException;
use GeoRanker\Exceptions\NotFoundException;
use GeoRanker\Exceptions\RateLimitException;
use GeoRanker\Exceptions\ServerException;
use GeoRanker\Exceptions\GeoRankerException;

try {
    $serp = $client->addSerp(new SerpRequest('pizza', region: 'London,England,United Kingdom'));
} catch (AuthException $e) {
    // 403 — invalid API key
} catch (BadRequestException $e) {
    // 400 — wrong region, invalid search engine, etc.
} catch (CreditException $e) {
    // 402 — out of credits or rate limit exceeded
} catch (NotFoundException $e) {
    // 404 — SERP ID not found or too old
} catch (RateLimitException $e) {
    // 429 — too many concurrent requests
} catch (ServerException $e) {
    // 500 / 502 / 504 — GeoRanker server error, retry later
    echo $e->getStatusCode();
} catch (GeoRankerException $e) {
    // any other API or cURL error
    echo $e->getStatusCode() . ': ' . $e->getMessage();
}

SerpRequest Parameters

Parameter Type Default Description
keyword string Required. Exact keyword to search.
searchEngine string google Search engine to use.
region string|null null Canonical region name or country code.
regionSearch RegionSearch|null null Coordinate-based region (omit region when used).
priority string NORMAL LOW, NORMAL, REALTIME, or INSTANT.
asynchronous bool|null null false = wait for result (up to 300 s).
callback string|null null Webhook URL called when result is ready.
callbackFormat string JSON SIMPLE or JSON.
maxResults int|null null Number of organic results (min 10).
isMobile bool false Use a mobile browser.
language string en ISO 639-1 language code.
saveRawData bool false Save raw HTML. Recommended with custom UA.
customUserAgent string|null null Override the crawler User-Agent (≤ 250 chars).
customUrlParameter array|null null [["name"=>…,"value"=>…]] appended to crawl URLs.
customCookieParameter array|null null [["name"=>…,"value"=>…]] merged into cookie header.
voiceSearchHighFidelity bool false High-fidelity voice transcription (Google only).

Links