Search by

georanker / serp-sdk

AlexGeoranker

PHP 8 SDK for the GeoRanker SERP API

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

This package is auto-updated.

Last update: 2026-09-13 12:34:51 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 1×
NORMAL Async by default 1×
REALTIME Sync by default 2×
INSTANT Sync by default 5×

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