Stop hardcoding provider choices. Let OutboundIQ tell you which provider to use based on real-time performance data, status page health, and your actual transaction history.
// Hardcoded provider - what happens when Stripe is down?
class PaymentService
{
public function charge($amount)
{
return $this->stripe->charge($amount); // 🔥 Hope it works!
}
}
// Or worse - manual checks that are always stale
if ($this->checkStripeStatus()) { // Last checked: 2 hours ago
return $this->stripe->charge($amount);
} else {
return $this->paystack->charge($amount);
}No real-time data on provider health
Failover logic based on guesswork
Find out about issues after customers
Query OutboundIQ from your code to make smart, data-driven routing decisions.
OutboundIQ::recommend()Get the best provider for a service category
// Laravel
$decision = OutboundIQ::recommend('payment-processing');
// PHP
$decision = $client->recommend('payment-processing');
// Node.js
const decision = await outboundiq.recommend('payment-processing');{
"decision": {
"use": "stripe",
"confidence": 0.94,
"confidence_label": "very_high",
"action": "proceed",
"reason": "Best performance: 99.8% success, 245ms latency"
},
"recommendation": {
"provider": { "name": "Stripe", "slug": "stripe" },
"score": 0.94,
"metrics": {
"success_rate": 99.8,
"avg_latency_ms": 245,
"total_requests": 12847,
"schema_stability": 100
},
"status": {
"current": "operational",
"indicator": "green",
"has_active_incidents": false
}
},
"alternatives": [
{
"rank": 2,
"provider": { "name": "Paystack", "slug": "paystack" },
"score": 0.87,
"gap": 0.07,
"metrics": { "success_rate": 98.2, "avg_latency_ms": 380 },
"tradeoffs": ["Higher latency (380ms vs 245ms)"]
}
]
}"proceed"Provider is healthy, safe to use
"caution"Some issues detected, add extra error handling
"avoid"Provider has outage, use alternative
OutboundIQ::providerStatus()Check if a specific provider is healthy before calling
// Check before making a critical call
$status = OutboundIQ::providerStatus('stripe');
if ($status['decision']['usable']) {
// Stripe is healthy, proceed
return $this->stripe->charge($amount);
}
if ($status['decision']['action'] === 'caution') {
// Has some issues, add retry logic
return $this->stripe->chargeWithRetry($amount, 3);
}
// Provider is down, use backup
Log::warning('Stripe unavailable', $status);
return $this->paystack->charge($amount);{
"decision": {
"usable": true,
"action": "proceed",
"reason": "Provider operational with good metrics"
},
"provider": {
"name": "Stripe",
"slug": "stripe"
},
"metrics": {
"success_rate": 99.8,
"avg_latency_ms": 245,
"total_requests": 12847,
"endpoints_tracked": 5
},
"status": {
"current": "operational",
"indicator": "green",
"last_check": "2024-01-08T10:30:00Z"
},
"incidents": [],
"affected_components": []
}OutboundIQ::endpointStatus()Get detailed metrics for a specific API endpoint
// Check specific endpoint before calling
$status = OutboundIQ::endpointStatus('stripe-post-v1-charges');
// Set timeout based on real latency data
$timeout = $status['endpoint']['latency']['p95'] * 1.5;
// Check if schema is stable
if ($status['endpoint']['schema_stability'] < 95) {
Log::warning('Schema changes detected on Stripe charges');
// Add defensive parsing
}
return Http::timeout($timeout)
->post('https://api.stripe.com/v1/charges', $data);{
"decision": {
"usable": true,
"action": "proceed",
"reason": "Endpoint performing well"
},
"endpoint": {
"url_pattern": "POST /v1/charges",
"slug": "stripe-post-v1-charges",
"metrics": {
"success_rate": 99.9,
"total_requests": 4523,
"schema_stability": 100
},
"latency": {
"avg": 245,
"p50": 220,
"p95": 380,
"p99": 520
}
},
"provider": {
"name": "Stripe",
"status": "operational"
}
}<?php
namespace App\Services;
use OutboundIQ\Laravel\Facades\OutboundIQ;
use Illuminate\Support\Facades\Log;
class SmartPaymentService
{
private array $providers = [
'stripe' => StripeGateway::class,
'paystack' => PaystackGateway::class,
'flutterwave' => FlutterwaveGateway::class,
];
public function charge(Order $order): PaymentResult
{
// Get intelligent recommendation
$decision = OutboundIQ::recommend('payment-processing');
if (!$decision || $decision['decision']['action'] === 'unavailable') {
// OutboundIQ unavailable, use default
return $this->chargeWithProvider('stripe', $order);
}
$action = $decision['decision']['action'];
$provider = $decision['decision']['use'];
$confidence = $decision['decision']['confidence'];
Log::info("Payment routing decision", [
'order_id' => $order->id,
'provider' => $provider,
'confidence' => $confidence,
'action' => $action,
]);
// Route based on action
if ($action === 'proceed') {
return $this->chargeWithProvider($provider, $order);
}
if ($action === 'caution') {
// Add retry logic for degraded providers
return $this->chargeWithRetry($provider, $order, maxAttempts: 3);
}
if ($action === 'avoid') {
// Use first healthy alternative
$alternative = $decision['alternatives'][0]['provider']['slug'] ?? 'stripe';
Log::warning("Primary provider unavailable, using {$alternative}");
return $this->chargeWithProvider($alternative, $order);
}
throw new PaymentException("No healthy payment providers available");
}
private function chargeWithProvider(string $slug, Order $order): PaymentResult
{
$gateway = app($this->providers[$slug]);
return $gateway->charge($order);
}
}Decisions based on your actual transaction data from the last 24-72 hours, not stale status pages.
Metrics are calculated from YOUR requests, not aggregate data. What matters is how APIs perform for YOU.
Build resilient systems that automatically route around failures without manual intervention.
Know how confident the recommendation is. Low confidence? Add extra error handling.
Responses are cached for 60 seconds. Sub-50ms response times won't slow down your app.
If OutboundIQ is unreachable, your app continues working. We never block your requests.
Add intelligent routing to your application in minutes. Free tier includes 10K API calls per month.