Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Dataforseo Laravel Package

jeffersongoncalves/laravel-dataforseo

Laravel DataForSEO is a clean integration for the DataForSEO API, letting you query SERP results, keywords, backlinks, and on-page audits from your Laravel apps. Configure credentials once and use a simple, expressive client to pull SEO data into your projects.

View on GitHub
Deep Wiki
Context7

Getting Started

The package is a fluent HTTP client, not an abstraction layer — treat it as a thin, well-typed wrapper around DataForSEO's REST API and design your own domain layer on top.

Minimal setup:

  1. composer require the package, then publish its config (php artisan vendor:publish --tag=...) and review config/dataforseo.php before touching any endpoint class. The config is the map of the whole package: base URL, sandbox toggle, timeout, retry policy, and credentials.
  2. Put credentials in .env (DATAFORSEO_LOGIN / DATAFORSEO_PASSWORD). DataForSEO uses HTTP Basic auth with account login + password, not a bearer API key — confirm the exact env keys against the config file, since this is the #1 source of 401s.
  3. php artisan config:clear after editing. If the app uses config:cache in deploy, verify the credentials are read at resolve time, not boot time.

Where to look first: the service provider (to see whether you get a facade, an injectable singleton, or both), then the endpoint namespace (Serp, KeywordsData, Backlinks, OnPage, Labs). Read one SERP class end-to-end — it's the smallest surface and mirrors the shape of the others.

First use case: a single live SERP lookup for one keyword to prove auth and response parsing work, then immediately move it into a queued job. Do not build a feature on a synchronous controller call; DataForSEO latency is measured in seconds, and several endpoints are task-based (submit → poll/callback) rather than request/response.

Implementation Patterns

Wrap the fluent client in your own service. Controllers and Livewire components should never see the package's builder — inject a SerpService / BacklinkService that returns your DTOs. This keeps the fluent chain (which changes shape per endpoint) contained in one file per capability and makes swapping to Http::fake() or a sandbox trivial.

Assume task-based semantics for anything expensive. DataForSEO has two modes: live (one call, results inline, higher cost per call) and standard/queued (submit a task, receive a task ID, then retrieve results, or receive a postback). For anything user-facing and interactive, live is correct. For bulk work — a nightly rank check across 500 keywords, an OnPage crawl, a Labs pull — use the task pattern: dispatch a job that submits, persist the task ID on your model, and either poll from a scheduled command or register a postback route. The postback route should be excluded from CSRF, idempotent, and verify the payload against the task ID you stored rather than trusting the body.

Normalize and persist raw responses. Store the full JSON in a json column alongside a normalized row (keyword, location, rank, url, checked_at). You are paying per request; the raw blob is your audit trail, your re-processing path when parsing logic changes, and your defence when DataForSEO changes a field.

Cache aggressively where the data is stable. SERP positions are volatile — cache minutes, not hours. Keywords Data (search volume), Labs, and much of Backlinks are stable for weeks; cache them for days and key the cache on the full parameter set (keyword + location + language + device + depth), not just the keyword.

Batch and throttle deliberately. Labs and Keywords Data accept multiple keywords per call and are dramatically cheaper per keyword that way. Pair batching with a Redis RateLimiter on the job middleware so concurrent workers don't blow through the account's rate limit, and set $tries = 1 on any job that submits a billable task.

Test against a fake, never the live API. Bind a fake implementation of your service interface in the container, or use Laravel's Http::fake() with recorded fixtures captured once from a real (cheap) call. If the package exposes a sandbox flag, wire it to app()->environment('local') and assert in a test that no live credentials are reachable from the test suite.

Gotchas and Tips

  • Every call costs money. The single most important operational rule: no live calls in seeders, factories, artisan tinker experiments against production credentials, or CI. Gate bulk operations behind an explicit flag or an artisan command with a confirmation prompt.
  • HTTP 200 does not mean success. DataForSEO returns application-level status codes in the body (a 20000-range code for OK, 40000-range for errors, plus per-task statuses). A 200 response can contain a fully failed task. Parse the status code and message and throw your own exception; don't rely on the package surfacing every failure as an HTTP error.
  • Empty results are normal. Nested keys (items, result arrays, individual metric fields) may be null or absent for low-volume keywords or unsupported locations. Use data_get() or null-safe accessors everywhere rather than array chains.
  • Retries can double-bill. A timeout does not mean the task wasn't created. Configure the HTTP timeout well below your queue worker timeout (a worker killed mid-request leaves you blind), and never blindly retry a submit call — reconcile by looking up existing tasks first.
  • Credentials in a base64/whitespace trap. Copy-pasted passwords with trailing newlines fail as 401 with no useful message. Sanitize on read, and log the response status and message on auth failure during setup.
  • Debugging: log the task ID and any request identifier from the response at debug level for every call. When a bulk job produces partial results, the task ID is the only thing that lets you reproduce the exact request in the DataForSEO dashboard.
  • Config caching and singletons. If you inject the client as a singleton and mutate configuration on it per-request (location, language, sandbox), you will leak state between jobs in the same worker. Build a fresh instance per operation or use immutable per-call parameters.
  • Extension points to look for: a macroable fluent builder (lets you add project-specific shortcuts without forking), a container binding you can swap for your own implementation, and any events dispatched around requests — the last is the cleanest place to hook cost accounting and structured logging.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels