Refinder Laravel SDK
The official Laravel SDK for Refinder AI Tools — AI-powered SEO automation and content optimization for Laravel applications.
Installation
Install the package via Composer:
composer require refinder/laravel-sdk
The package auto-registers its service provider and facade via Laravel's package discovery. Publish the configuration file:
php artisan vendor:publish --tag=refinder-config
Add your API key to the .env file:
REFINDER_API_KEY=rfnd_your_api_key_here REFINDER_BASE_URL=https://api.refinder.ai/api/v1 REFINDER_TIMEOUT=120 REFINDER_RETRIES=2 REFINDER_CACHE_ENABLED=false REFINDER_CACHE_TTL=60 REFINDER_EVENTS=true
Required: Only REFINDER_API_KEY is required. All other values have sensible defaults.
Quick Start
use Refinder\LaravelSdk\Facades\Refinder; // Execute SEO analysis $result = Refinder::seo()->execute([ 'content' => 'Your article content here...', 'content_type' => 'article', 'language' => 'en', ]); // Access the results echo $result->output->metaTitle; echo $result->output->metaDescription; echo $result->output->seoScore->overall; // 75 (0-100) // Check if score is passing (>= 60) if ($result->output->seoScore->isPassing()) { echo "SEO score is good!"; }
Shorthand Methods
// Basic analysis $result = Refinder::seo()->basic($content, 'en'); // Advanced analysis (default) $result = Refinder::seo()->advanced($content, 'en'); // Full technical analysis $result = Refinder::seo()->technical($content, 'en');
Configuration
The full configuration file (config/refinder.php):
return [ 'api_key' => env('REFINDER_API_KEY'), 'base_url' => env('REFINDER_BASE_URL', 'https://api.refinder.ai/api/v1'), 'timeout' => env('REFINDER_TIMEOUT', 120), 'retries' => env('REFINDER_RETRIES', 2), 'retry_delay_ms' => env('REFINDER_RETRY_DELAY', 1000), 'cache' => [ 'enabled' => env('REFINDER_CACHE_ENABLED', false), 'ttl' => env('REFINDER_CACHE_TTL', 60), 'prefix' => 'refinder_', ], 'events' => env('REFINDER_EVENTS', true), 'log_channel' => env('REFINDER_LOG_CHANNEL', null), ];
Authentication
Every request includes the API key in the X-API-Key header automatically.
| Property | Value |
|---|---|
| Prefix | rfnd_ |
| Total length | 53 characters |
| Format | rfnd_ + 48 alphanumeric characters |
| Storage | SHA-256 hashed server-side |
SEO Tool
The SEO tool is the primary feature. It analyzes content and generates comprehensive SEO recommendations.
Input Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
content | string | Yes | — | Text content to analyze (min 10 chars) |
url | string | No | null | Page URL for additional context |
content_type | string | No | "page" | article, product, service, page, blog |
language | string | No | "en" | Target language (en, ar, fr...) |
depth | string | No | "advanced" | basic, advanced, technical |
target_keywords | array | No | [] | Keywords to optimize around |
brand_name | string | No | null | Brand name for titles/headings |
industry | string | No | null | Industry context |
Depth Levels
| Level | Includes |
|---|---|
| basic | Meta title, meta description, primary keywords |
| advanced | Everything in basic + secondary/long-tail keywords, content analysis, heading suggestions, optimization suggestions, SEO scores |
| technical | Everything in advanced + schema markup, Open Graph tags, canonical URLs, content gap analysis |
Using the SeoInput DTO
use Refinder\LaravelSdk\DTOs\SeoInput; $input = new SeoInput( content: $article->body, url: route('articles.show', $article), contentType: 'article', language: 'en', depth: 'advanced', targetKeywords: ['AI tools', 'machine learning'], brandName: 'MyBrand', industry: 'Technology', ); $result = Refinder::seo()->execute($input);
Working with SEO Output
$result = Refinder::seo()->execute(['content' => $text]); $seo = $result->output; // Meta tags $seo->metaTitle; // string (50-60 chars) $seo->metaDescription; // string (150-160 chars) // Keywords $seo->keywords->primary; // ['keyword1', 'keyword2'] $seo->keywords->secondary; // ['keyword3', 'keyword4'] $seo->keywords->longTail; // ['long tail phrase'] $seo->keywords->all(); // All keywords merged // Content Analysis $seo->contentAnalysis->readabilityScore; // 'excellent', 'good', 'needs_improvement' $seo->contentAnalysis->contentQuality; // 'high', 'medium', 'low' // SEO Score (0-100) $seo->seoScore->overall; // 75 $seo->seoScore->content; // 70 $seo->seoScore->keywords; // 80 $seo->seoScore->structure; // 75 $seo->seoScore->isPassing(); // true (>= 60) // Optimization Suggestions foreach ($seo->optimizationSuggestions as $suggestion) { $suggestion->category; // 'content', 'technical', 'structure' $suggestion->priority; // 'high', 'medium', 'low' $suggestion->suggestion; // "Add structured data..." $suggestion->isHighPriority(); // bool } // Heading Structure $seo->headingStructure->suggestedH1; // string $seo->headingStructure->suggestedH2s; // array // Execution metadata $result->id; // UUID $result->usage->totalTokens; // 1276 $result->model->provider; // 'alibaba'
API Reference — Platform Info
$platform = Refinder::me(); $platform->id; // 1 $platform->name; // "My Platform" $platform->slug; // "my-platform" $platform->website; // "https://example.com" $platform->isActive; // true
Subscription Details
$sub = Refinder::subscription(); $sub->plan->name; // "Pro" $sub->plan->maxRequestsPerMonth; // 1000 $sub->plan->maxRequestsPerDay; // 100 $sub->plan->features; // ['advanced_seo', ...] $sub->isActive(); // true
Usage Statistics
$usage = Refinder::usage(); // Or with date range: $usage = Refinder::usage('2026-01-01', '2026-01-31'); $usage->totalRequests; // 47 $usage->totalTokens; // 62340 $usage->totalCost; // 0.12468 foreach ($usage->daily as $day) { $day->date; // "2026-02-08" $day->requestsCount; // 12 $day->tokensUsed; // 15600 }
Execution History
$executions = Refinder::executions(perPage: 10, page: 1); $executions->total; // 47 $executions->hasMorePages(); // true foreach ($executions->items as $exec) { $exec->id; // UUID $exec->tool; // "seo" $exec->status; // "completed" } // Get a specific execution $exec = Refinder::execution('uuid-here'); if ($exec->isCompleted()) { echo $exec->output->metaTitle; }
Error Handling
The SDK throws specific exception types for different error scenarios:
RefinderException (base) ├── AuthenticationException (HTTP 401) ├── SubscriptionException (HTTP 403) ├── ValidationException (HTTP 422) ├── RateLimitException (HTTP 429) ├── ToolException (HTTP 500/502) └── ConnectionException (Network errors)
use Refinder\LaravelSdk\Exceptions\AuthenticationException; use Refinder\LaravelSdk\Exceptions\RateLimitException; use Refinder\LaravelSdk\Exceptions\SubscriptionException; use Refinder\LaravelSdk\Exceptions\ToolException; use Refinder\LaravelSdk\Exceptions\ValidationException; try { $result = Refinder::seo()->execute(['content' => $text]); } catch (ValidationException $e) { // 422 — Input validation failed return response()->json(['error' => $e->errors], 422); } catch (RateLimitException $e) { // 429 — $e->limit, $e->current } catch (SubscriptionException $e) { // 403 — Subscription issue } catch (AuthenticationException $e) { // 401 — Invalid API key } catch (ToolException $e) { // 500/502 — $e->executionId for debugging }
Events
When config('refinder.events') is true, the package dispatches Laravel events:
use Refinder\LaravelSdk\Events\ToolExecuted; use Refinder\LaravelSdk\Events\ToolExecutionFailed; use Refinder\LaravelSdk\Events\RateLimitApproaching; Event::listen(ToolExecuted::class, function (ToolExecuted $event) { Log::info("Tool executed", [ 'tool' => $event->tool, 'execution_id' => $event->executionId, 'tokens' => $event->tokensUsed, ]); });
Caching
Enable response caching for identical tool inputs:
REFINDER_CACHE_ENABLED=true REFINDER_CACHE_TTL=60
- • Uses Laravel's default cache driver
- • Cache keys:
prefix + tool_slug + md5(input) - • Only successful executions are cached (never failures)
- • TTL is in minutes
Rate Limiting & Quotas
| Limit Type | Reset Period | Free | Pro | Enterprise |
|---|---|---|---|---|
| Daily | Midnight UTC | 10/day | 100/day | 1,000/day |
| Monthly | 1st of month | 50/month | 1,000/month | 10,000/month |
$usage = Refinder::usage(); $sub = Refinder::subscription(); $used = $usage->totalRequests; $limit = $sub->plan->maxRequestsPerMonth; $remaining = $limit - $used; echo "Used {$used}/{$limit} this month. {$remaining} remaining.";
Testing
The SDK provides a RefinderFake class for testing without API calls:
use Refinder\LaravelSdk\Facades\Refinder; public function test_seo_analysis() { Refinder::fake(); $result = Refinder::seo()->execute(['content' => 'Test content']); $this->assertEquals('completed', $result->status); $this->assertNotNull($result->output->metaTitle); $this->assertTrue($result->output->seoScore->isPassing()); // Assertions Refinder::assertToolExecuted('seo'); Refinder::assertToolExecutedCount('seo', 1); }
Real-World Examples
E-Commerce Product SEO
$product = Product::find(1); $result = Refinder::seo()->execute([ 'content' => $product->description, 'url' => route('products.show', $product), 'content_type' => 'product', 'brand_name' => $product->brand->name, 'target_keywords' => $product->tags->pluck('name')->toArray(), ]); if ($result->isCompleted()) { $product->seoMeta()->updateOrCreate([], [ 'title' => $result->output->metaTitle, 'description' => $result->output->metaDescription, 'score' => $result->output->seoScore->overall, ]); }
Batch Processing with Queue
class AnalyzeArticleSeo implements ShouldQueue { public int $tries = 3; public int $backoff = 60; public function handle(): void { try { $result = Refinder::seo()->execute([ 'content' => $this->article->body, 'depth' => 'advanced', ]); $this->article->update([ 'seo_score' => $result->output->seoScore->overall, ]); } catch (RateLimitException $e) { $this->release(300); // retry in 5 minutes } } }
Error Code Reference
| HTTP | Code | Description |
|---|---|---|
| 401 | MISSING_API_KEY | No API key in request header |
| 401 | INVALID_API_KEY | API key doesn't match any active key |
| 401 | API_KEY_EXPIRED | API key has expired |
| 403 | PLATFORM_INACTIVE | Platform is disabled |
| 403 | NO_ACTIVE_SUBSCRIPTION | No active subscription |
| 403 | SUBSCRIPTION_EXPIRED | Subscription has expired |
| 403 | TOOL_NOT_ALLOWED | Plan doesn't include this tool |
| 422 | VALIDATION_ERROR | Input validation failed |
| 429 | DAILY_LIMIT_EXCEEDED | Daily quota exceeded |
| 429 | MONTHLY_LIMIT_EXCEEDED | Monthly quota exceeded |
| 500 | TOOL_ERROR | Tool execution error |
| 502 | LLM_ERROR | AI provider returned an error |