Prerequisites
- PHP 8.0+
- Composer
- A Geekflare API key — get one free
Installation
No SDK is needed for cURL. To use Guzzle:composer require guzzlehttp/guzzle vlucas/phpdotenv
Set your API key
.env
GEEKFLARE_API_KEY=your_api_key_here
phpdotenv:
require_once __DIR__ . '/vendor/autoload.php';
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
$apiKey = $_ENV['GEEKFLARE_API_KEY'];
Never hardcode your API key. Add
.env to .gitignore.Web Scraping
- cURL
- Guzzle
<?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']);
<?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']);
| 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
- cURL
- Guzzle
<?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;
}
<?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;
}
Screenshot
- cURL
- Guzzle
<?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;
<?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;
Error handling
- cURL
- Guzzle
<?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}"),
};
}
<?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");
}
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 — Laravel HTTP client with service classes
- API Reference — Full endpoint documentation