> ## Documentation Index
> Fetch the complete documentation index at: https://docs.geekflare.com/llms.txt
> Use this file to discover all available pages before exploring further.

# PHP

> Use Geekflare API in any PHP project with native cURL or the Guzzle HTTP client.

No official PHP SDK exists yet, but the Geekflare REST API is straightforward to call from PHP using either native cURL or the popular Guzzle HTTP client.

## Prerequisites

* PHP **8.0+**
* Composer
* A Geekflare API key — [get one free](https://dash.geekflare.com)

## Installation

No SDK is needed for cURL. To use Guzzle:

```bash theme={null}
composer require guzzlehttp/guzzle vlucas/phpdotenv
```

## Set your API key

```bash .env theme={null}
GEEKFLARE_API_KEY=your_api_key_here
```

Load it with `phpdotenv`:

```php theme={null}
require_once __DIR__ . '/vendor/autoload.php';

$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();

$apiKey = $_ENV['GEEKFLARE_API_KEY'];
```

<Warning>Never hardcode your API key. Add `.env` to `.gitignore`.</Warning>

***

## Web Scraping

<Tabs>
  <Tab title="cURL">
    ```php theme={null}
    <?php
    require_once __DIR__ . '/vendor/autoload.php';

    $dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
    $dotenv->load();

    $apiKey = $_ENV['GEEKFLARE_API_KEY'];

    $payload = json_encode([
        'url'       => 'https://toscrape.com/',
        'renderJS'  => true,
        'blockAds'  => true,
        'format'    => 'html,markdown',
        'device'    => 'desktop',
    ]);

    $ch = curl_init('https://api.geekflare.com/webscraping');
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => $payload,
        CURLOPT_HTTPHEADER     => [
            'Content-Type: application/json',
            'x-api-key: ' . $apiKey,
        ],
    ]);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($httpCode !== 200) {
        $error = json_decode($response, true);
        throw new RuntimeException("API error [{$error['apiCode']}]: {$error['message']}");
    }

    $result = json_decode($response, true);
    print_r($result['data']);
    ```
  </Tab>

  <Tab title="Guzzle">
    ```php theme={null}
    <?php
    require_once __DIR__ . '/vendor/autoload.php';

    use GuzzleHttp\Client;
    use GuzzleHttp\Exception\ClientException;

    $dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
    $dotenv->load();

    $client = new Client([
        'base_uri' => 'https://api.geekflare.com',
        'headers'  => [
            'Content-Type' => 'application/json',
            'x-api-key'    => $_ENV['GEEKFLARE_API_KEY'],
        ],
    ]);

    $response = $client->post('/webscraping', [
        'json' => [
            'url'      => 'https://toscrape.com/',
            'renderJS' => true,
            'blockAds' => true,
            'format'   => 'html,markdown',
            'device'   => 'desktop',
        ],
    ]);

    $result = json_decode($response->getBody(), true);
    print_r($result['data']);
    ```
  </Tab>
</Tabs>

**Key parameters:**

| Parameter      | Type     | Description                         |
| -------------- | -------- | ----------------------------------- |
| `url`          | `string` | **Required.** The URL to scrape     |
| `renderJS`     | `bool`   | Wait for JavaScript to execute      |
| `blockAds`     | `bool`   | Block ads before scraping           |
| `format`       | `string` | Comma-separated: `html`, `markdown` |
| `device`       | `string` | `"desktop"` or `"mobile"`           |
| `proxyCountry` | `string` | Route via country code, e.g. `"us"` |
| `stealth`      | `bool`   | Enable stealth mode                 |
| `waitTime`     | `float`  | Extra wait in seconds               |

***

## Search

<Tabs>
  <Tab title="cURL">
    ```php theme={null}
    <?php
    require_once __DIR__ . '/vendor/autoload.php';

    $dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
    $dotenv->load();

    $payload = json_encode([
        'query'    => 'best PHP frameworks 2024',
        'limit'    => 10,
        'location' => 'us',
        'source'   => 'web',
        'time'     => 'm',
        'format'   => 'json',
    ]);

    $ch = curl_init('https://api.geekflare.com/search');
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => $payload,
        CURLOPT_HTTPHEADER     => [
            'Content-Type: application/json',
            'x-api-key: ' . $_ENV['GEEKFLARE_API_KEY'],
        ],
    ]);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    $result = json_decode($response, true);

    foreach ($result['data'] as $item) {
        echo $item['title'] . ' — ' . $item['url'] . PHP_EOL;
        echo $item['snippet'] . PHP_EOL . PHP_EOL;
    }
    ```
  </Tab>

  <Tab title="Guzzle">
    ```php theme={null}
    <?php
    require_once __DIR__ . '/vendor/autoload.php';

    use GuzzleHttp\Client;

    $dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
    $dotenv->load();

    $client = new Client([
        'base_uri' => 'https://api.geekflare.com',
        'headers'  => [
            'Content-Type' => 'application/json',
            'x-api-key'    => $_ENV['GEEKFLARE_API_KEY'],
        ],
    ]);

    $response = $client->post('/search', [
        'json' => [
            'query'    => 'best PHP frameworks 2024',
            'limit'    => 10,
            'location' => 'us',
            'source'   => 'web',
            'time'     => 'm',
            'format'   => 'json',
        ],
    ]);

    $result = json_decode($response->getBody(), true);

    foreach ($result['data'] as $item) {
        echo $item['title'] . ' — ' . $item['url'] . PHP_EOL;
        echo $item['snippet'] . PHP_EOL . PHP_EOL;
    }
    ```
  </Tab>
</Tabs>

***

## Screenshot

<Tabs>
  <Tab title="cURL">
    ```php theme={null}
    <?php
    require_once __DIR__ . '/vendor/autoload.php';

    $dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
    $dotenv->load();

    $payload = json_encode([
        'url'            => 'https://example.com',
        'type'           => 'png',
        'fullPage'       => true,
        'device'         => 'desktop',
        'viewportWidth'  => 1280,
        'viewportHeight' => 800,
        'blockAds'       => true,
        'hideCookie'     => true,
        'quality'        => 90,
    ]);

    $ch = curl_init('https://api.geekflare.com/screenshot');
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => $payload,
        CURLOPT_HTTPHEADER     => [
            'Content-Type: application/json',
            'x-api-key: ' . $_ENV['GEEKFLARE_API_KEY'],
        ],
    ]);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    $result = json_decode($response, true);
    // $result['data'] is the screenshot URL directly
    echo "Screenshot URL: " . $result['data'] . PHP_EOL;
    ```
  </Tab>

  <Tab title="Guzzle">
    ```php theme={null}
    <?php
    require_once __DIR__ . '/vendor/autoload.php';

    use GuzzleHttp\Client;

    $dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
    $dotenv->load();

    $client = new Client([
        'base_uri' => 'https://api.geekflare.com',
        'headers'  => [
            'Content-Type' => 'application/json',
            'x-api-key'    => $_ENV['GEEKFLARE_API_KEY'],
        ],
    ]);

    $response = $client->post('/screenshot', [
        'json' => [
            'url'            => 'https://example.com',
            'type'           => 'png',
            'fullPage'       => true,
            'device'         => 'desktop',
            'viewportWidth'  => 1280,
            'viewportHeight' => 800,
            'blockAds'       => true,
            'hideCookie'     => true,
            'quality'        => 90,
        ],
    ]);

    $result = json_decode($response->getBody(), true);
    // $result['data'] is the screenshot URL directly
    echo "Screenshot URL: " . $result['data'] . PHP_EOL;
    ```
  </Tab>
</Tabs>

***

## Error handling

<Tabs>
  <Tab title="cURL">
    ```php theme={null}
    <?php
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if (curl_errno($ch)) {
        throw new RuntimeException('cURL error: ' . curl_error($ch));
    }

    $result = json_decode($response, true);

    if ($httpCode !== 200 || $result['apiStatus'] !== 'success') {
        $code    = $result['apiCode'] ?? $httpCode;
        $message = $result['message'] ?? 'Unknown error';

        match ($code) {
            401 => throw new RuntimeException("Invalid or missing API key."),
            402 => throw new RuntimeException("API credits exhausted."),
            403 => throw new RuntimeException("Endpoint not available on your plan."),
            429 => throw new RuntimeException("Rate limit exceeded. Back off and retry."),
            default => throw new RuntimeException("API error [{$code}]: {$message}"),
        };
    }
    ```
  </Tab>

  <Tab title="Guzzle">
    ```php theme={null}
    <?php
    use GuzzleHttp\Exception\ClientException;
    use GuzzleHttp\Exception\ConnectException;

    try {
        $response = $client->post('/webscraping', ['json' => ['url' => 'https://toscrape.com/']]);
        $result = json_decode($response->getBody(), true);
        print_r($result['data']);

    } catch (ClientException $e) {
        $code = $e->getResponse()->getStatusCode();
        $body = json_decode($e->getResponse()->getBody(), true);
        $message = $body['message'] ?? 'Unknown error';

        match ($code) {
            401 => print("Invalid or missing API key.\n"),
            402 => print("API credits exhausted.\n"),
            403 => print("Endpoint not available on your plan.\n"),
            429 => print("Rate limit exceeded.\n"),
            default => print("API error [{$code}]: {$message}\n"),
        };

    } catch (ConnectException $e) {
        print("Connection error: " . $e->getMessage() . "\n");
    }
    ```
  </Tab>
</Tabs>

### Common error codes

| Code  | Meaning                           |
| ----- | --------------------------------- |
| `401` | Missing or invalid `x-api-key`    |
| `402` | API credits exhausted             |
| `403` | Endpoint requires a higher plan   |
| `404` | Wrong endpoint URL or HTTP method |
| `429` | Rate limit exceeded               |

***

## Next steps

* [Laravel quickstart](/api/quickstart/laravel) — Laravel HTTP client with service classes
* [API Reference](/api/endpoint/reference) — Full endpoint documentation
