Skip to main content

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.

Laravel’s first-party HTTP client wraps Guzzle with a fluent, expressive API. This guide creates a dedicated GeekflareService, registers it in the service container, and injects it into controllers.

Prerequisites

Installation

No extra packages needed — Laravel’s HTTP client is built in. Just add your key to .env:
.env
GEEKFLARE_API_KEY=your_api_key_here
.env is gitignored by default in Laravel. Use .env.example (without real values) for documentation.

Config file

Centralise the API settings in a config file so they’re accessible via config():
config/geekflare.php
<?php

return [
    'api_key'  => env('GEEKFLARE_API_KEY'),
    'base_url' => 'https://api.geekflare.com',
];

Service class

app/Services/GeekflareService.php
<?php

namespace App\Services;

use Illuminate\Http\Client\PendingRequest;
use Illuminate\Http\Client\RequestException;
use Illuminate\Support\Facades\Http;

class GeekflareService
{
    private PendingRequest $http;

    public function __construct()
    {
        $this->http = Http::baseUrl(config('geekflare.base_url'))
            ->withHeaders([
                'x-api-key' => config('geekflare.api_key'),
            ])
            ->acceptJson();
    }

    /**
     * Scrape web page content.
     */
    public function webScrape(array $params): array
    {
        return $this->post('/webscraping', $params);
    }

    /**
     * Perform a web search.
     */
    public function search(array $params): array
    {
        return $this->post('/search', $params);
    }

    /**
     * Take a screenshot of a URL.
     */
    public function screenshot(array $params): array
    {
        return $this->post('/screenshot', $params);
    }

    private function post(string $endpoint, array $params): array
    {
        $response = $this->http->post($endpoint, $params);
        $response->throw(); // throws RequestException on 4xx/5xx

        return $response->json();
    }
}

Register in the service container

app/Providers/AppServiceProvider.php
<?php

namespace App\Providers;

use App\Services\GeekflareService;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->singleton(GeekflareService::class);
    }
}

Web Scraping

Controller

app/Http/Controllers/ScrapeController.php
<?php

namespace App\Http\Controllers;

use App\Services\GeekflareService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Client\RequestException;

class ScrapeController extends Controller
{
    public function __construct(
        private readonly GeekflareService $geekflare
    ) {}

    public function __invoke(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'url'      => 'required|url',
            'renderJS' => 'boolean',
            'blockAds' => 'boolean',
            'format'   => 'string',
        ]);

        try {
            $result = $this->geekflare->webScrape([
                'url'      => $validated['url'],
                'renderJS' => $validated['renderJS'] ?? true,
                'blockAds' => $validated['blockAds'] ?? true,
                'format'   => $validated['format'] ?? 'html,markdown',
                'device'   => 'desktop',
            ]);

            return response()->json($result);

        } catch (RequestException $e) {
            return $this->handleApiException($e);
        }
    }

    private function handleApiException(RequestException $e): JsonResponse
    {
        $code = $e->response->status();
        $body = $e->response->json();

        return response()->json(
            ['error' => $body['message'] ?? 'API request failed', 'code' => $code],
            $code
        );
    }
}

Route

routes/api.php
use App\Http\Controllers\ScrapeController;

Route::post('/scrape', ScrapeController::class);
Test:
curl -X POST http://localhost:8000/api/scrape \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://toscrape.com/", "renderJS": true }'

Controller

app/Http/Controllers/SearchController.php
<?php

namespace App\Http\Controllers;

use App\Services\GeekflareService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Client\RequestException;

class SearchController extends Controller
{
    public function __construct(
        private readonly GeekflareService $geekflare
    ) {}

    public function __invoke(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'query'          => 'required|string',
            'limit'          => 'integer|min:1|max:100',
            'location'       => 'string|size:2',
            'source'         => 'string',
            'time'           => 'string|in:d,w,m',
            'includeDomains' => 'array',
            'excludeDomains' => 'array',
        ]);

        try {
            $result = $this->geekflare->search(array_merge(
                ['limit' => 10, 'location' => 'us', 'source' => 'web', 'format' => 'json'],
                $validated
            ));

            return response()->json($result);

        } catch (RequestException $e) {
            $code = $e->response->status();
            $body = $e->response->json();
            return response()->json(['error' => $body['message'] ?? 'Search failed'], $code);
        }
    }
}

Route

routes/api.php
use App\Http\Controllers\SearchController;

Route::post('/search', SearchController::class);
Test:
curl -X POST http://localhost:8000/api/search \
  -H "Content-Type: application/json" \
  -d '{ "query": "Laravel best practices", "limit": 5 }'

Screenshot

Controller

app/Http/Controllers/ScreenshotController.php
<?php

namespace App\Http\Controllers;

use App\Services\GeekflareService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Client\RequestException;

class ScreenshotController extends Controller
{
    public function __construct(
        private readonly GeekflareService $geekflare
    ) {}

    public function __invoke(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'url'            => 'required|url',
            'type'           => 'string|in:png,jpg,webp',
            'fullPage'       => 'boolean',
            'device'         => 'string|in:desktop,mobile',
            'viewportWidth'  => 'integer',
            'viewportHeight' => 'integer',
            'blockAds'       => 'boolean',
            'hideCookie'     => 'boolean',
            'quality'        => 'integer|min:1|max:100',
        ]);

        try {
            $result = $this->geekflare->screenshot(array_merge([
                'type'           => 'png',
                'fullPage'       => true,
                'device'         => 'desktop',
                'viewportWidth'  => 1280,
                'viewportHeight' => 800,
                'blockAds'       => true,
                'hideCookie'     => true,
                'quality'        => 90,
            ], $validated));

            return response()->json($result);

        } catch (RequestException $e) {
            $code = $e->response->status();
            $body = $e->response->json();
            return response()->json(['error' => $body['message'] ?? 'Screenshot failed'], $code);
        }
    }
}

Route

routes/api.php
use App\Http\Controllers\ScreenshotController;

Route::post('/screenshot', ScreenshotController::class);
Test:
curl -X POST http://localhost:8000/api/screenshot \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://example.com", "fullPage": true }'

All routes together

routes/api.php
<?php

use App\Http\Controllers\ScrapeController;
use App\Http\Controllers\SearchController;
use App\Http\Controllers\ScreenshotController;

Route::post('/scrape',     ScrapeController::class);
Route::post('/search',     SearchController::class);
Route::post('/screenshot', ScreenshotController::class);

Error handling

Laravel’s HTTP client throw() converts 4xx/5xx responses to RequestException. Handle them by status code:
use Illuminate\Http\Client\RequestException;

try {
    $result = $this->geekflare->webScrape(['url' => 'https://toscrape.com/']);
} catch (RequestException $e) {
    $code = $e->response->status();

    match ($code) {
        401 => abort(401, 'Invalid or missing Geekflare API key.'),
        402 => abort(402, 'API credits exhausted.'),
        403 => abort(403, 'This endpoint requires a higher plan.'),
        429 => abort(429, 'Rate limit exceeded. Try again shortly.'),
        default => abort($code, $e->response->json('message') ?? 'API error'),
    };
}

Common error codes

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

Next steps