PHPackages                             georanker/serp-sdk - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. georanker/serp-sdk

ActiveLibrary[API Development](/categories/api)

georanker/serp-sdk
==================

PHP 8 SDK for the GeoRanker SERP API

00PHP

Since May 13Pushed 3w agoCompare

[ Source](https://github.com/AlexGeoranker/georanker-serp-sdk)[ Packagist](https://packagist.org/packages/georanker/serp-sdk)[ RSS](/packages/georanker-serp-sdk/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependenciesVersions (1)Used By (0)

GeoRanker SERP SDK for PHP
==========================

[](#georanker-serp-sdk-for-php)

A zero-dependency PHP 8 SDK for the [GeoRanker SERP API](https://docs.georanker.com/reference/addserp). Create SERP requests, poll for results, and work with fully typed response objects.

---

Requirements
------------

[](#requirements)

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

---

Installation
------------

[](#installation)

### Via Composer

[](#via-composer)

```
composer require georanker/serp-sdk
```

### Without Composer

[](#without-composer)

Clone or download the repository and include the autoloader:

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

---

Quick Start
-----------

[](#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
---------------------

[](#ssl-on-windows--wamp)

Windows does not ship a CA certificate bundle for PHP. Download [cacert.pem](https://curl.se/ca/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
----------------------

[](#creating-serp-requests)

### Single request (asynchronous — default)

[](#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)

[](#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

[](#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)

[](#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
----------------

[](#fetching-results)

### Single SERP by ID

[](#single-serp-by-id)

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

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

### Bulk fetch by IDs

[](#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
--------------------------

[](#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
--------------

[](#search-engines)

ValueEngineResult 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
---------------

[](#special-engines)

### Universal — crawl any URL

[](#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

[](#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

[](#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
---------------

[](#priority-levels)

ValueBehaviourCost multiplier`LOW`Async by default1×`NORMAL`Async by default1×`REALTIME`Sync by default2×`INSTANT`Sync by default5×---

Advanced Parameters
-------------------

[](#advanced-parameters)

### Custom URL 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

[](#custom-cookies)

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

### Custom User-Agent

[](#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

[](#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
--------------

[](#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
----------------------

[](#serprequest-parameters)

ParameterTypeDefaultDescription`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
-----

[](#links)

- [GeoRanker API Documentation](https://docs.georanker.com/reference)
- [Supported Languages](https://docs.georanker.com/docs/supported-languages)
- [API Limits](https://docs.georanker.com/docs/api-limits)
- [Services &amp; Costs](https://docs.georanker.com/docs/services-and-costs)
- [Valid Regions](https://docs.georanker.com/reference#region)

###  Health Score

20

—

LowBetter than 13% of packages

Maintenance62

Regular maintenance activity

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity11

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/eec2056242d7f8159de7bd12162915035cd925c5ce23d60768ab0da556f48c9a?d=identicon)[AlexGeoranker](/maintainers/AlexGeoranker)

---

Top Contributors

[![AlexGeoranker](https://avatars.githubusercontent.com/u/3987070?v=4)](https://github.com/AlexGeoranker "AlexGeoranker (4 commits)")

### Embed Badge

![Health badge](/badges/georanker-serp-sdk/health.svg)

```
[![Health](https://phpackages.com/badges/georanker-serp-sdk/health.svg)](https://phpackages.com/packages/georanker-serp-sdk)
```

###  Alternatives

[facebook/php-business-sdk

PHP SDK for Facebook Business

90923.5M35](/packages/facebook-php-business-sdk)[exsyst/swagger

A php library to manipulate Swagger specifications

35916.3M7](/packages/exsyst-swagger)[hubspot/api-client

Hubspot API client

24015.5M18](/packages/hubspot-api-client)[botman/driver-telegram

Telegram driver for BotMan

93452.6k6](/packages/botman-driver-telegram)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
