500K characters included every month. Add payment details to start.
PHP & Laravel Developer Guide

Best Translation API
for PHP & Laravel

Compare Google Translate, DeepL, and Langbly for PHP. Composer packages, setup time, Laravel service classes, queued translation jobs, and what each one costs.

Payment details required. No charge within 500K characters/month.

Pricing comparison

Real pricing based on monthly character volume. All prices in USD.

VolumeGoogle TranslateDeepLLangblyYou Save
500K chars/mo$0Check live plan$0
Both included/evaluation
1M chars/mo$10Check live plan$2.50
75% vs Google
5M chars/mo$90Check live plan$22.50
75% vs Google
25M chars/mo$490Check live plan$122.50
75% vs Google
100M chars/mo$1,990Above Growth limit$497.50
75% vs Google

Feature comparison

FeatureGoogle TranslateDeepLLangbly
Composer packagegoogle/cloud-translatedeeplcom/deepl-phplangbly/langbly-php
Install commandcomposer require google/cloud-translatecomposer require deeplcom/deepl-phpcomposer require langbly/langbly-php
Auth methodService account JSONAPI key stringAPI key string
Lines of code to translate7–9 lines3 lines3 lines
Works with plain Guzzle or Http facadeNeeds OAuth token
Auto-retry on 429 and 5xxManualManualBuilt-in
Typed exception classesGoogle exceptionsDeepLExceptionRateLimitException, AuthenticationException
Retry-After support
Batch translate in one call
HTML-safe translation
Google v2 compatible
Languages100+30+100+
Published usage rate$20/1M after 500KCheck live Growth plan$5/1M after 500K
Included/evaluation usage500K/moDeveloper: 1M total500K/mo
Translation qualityNMTNMT + AINext-gen AI
Context-awareLimited

PHP translation APIs compared: the actual code

Marketing pages all sound the same. Code does not. Here is what it takes to translate one string in PHP with each provider.

Google Translate (google/cloud-translate):

<?php
require 'vendor/autoload.php';

use Google\Cloud\Translate\V2\TranslateClient;

putenv('GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json');

$translate = new TranslateClient();

$result = $translate->translate('Hello world', [
    'target' => 'nl',
]);

echo $result['text']; // Hallo wereld

Before that snippet runs you need a Google Cloud project, the Translation API enabled, a billing account attached, a service account, and a JSON key file sitting somewhere your deploy pipeline can reach. Shipping a credentials file to production is its own small project.

DeepL (deeplcom/deepl-php):

<?php
require 'vendor/autoload.php';

$translator = new \DeepL\Translator('your-api-key');

$result = $translator->translateText('Hello world', null, 'NL');

echo $result->text;

Langbly (langbly/langbly-php):

<?php
require 'vendor/autoload.php';

$client = new \Langbly\Client('your-api-key');

$result = $client->translate('Hello world', 'nl');

echo $result->text;   // Hallo wereld
echo $result->source; // en

The Langbly package needs PHP 7.4 or newer and Guzzle 7, nothing else. Install it with composer require langbly/langbly-php, pass a key string, done. It also takes an array of strings for batch calls, exposes detect() and languages(), and retries 429 and 5xx responses with exponential backoff while respecting the Retry-After header. You do not write that loop yourself.

One more thing worth knowing before you pick: Langbly is a drop-in replacement for the Google Translate v2 API. Same request shape, same response shape. If you already have Google calls scattered through a legacy PHP codebase, you swap the base URL and the auth header and the rest of your code keeps working.

POST https://api.langbly.com/language/translate/v2
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

{"q": "Hello world", "target": "nl"}
{
  "data": {
    "translations": [
      {
        "translatedText": "Hallo wereld",
        "detectedSourceLanguage": "en"
      }
    ]
  }
}

Laravel integration: a service class you can actually ship

Most Laravel apps do not need an SDK at all. The HTTP client that ships with the framework is enough, and it keeps your dependency list short. Start with config, never with a hardcoded key.

// config/services.php
'langbly' => [
    'key' => env('LANGBLY_API_KEY'),
    'url' => env('LANGBLY_URL', 'https://api.langbly.com'),
],

Then a small service class. It returns a plain string, throws on failure, and stays easy to fake in tests.

<?php

namespace App\Services;

use Illuminate\Support\Facades\Http;

class Translator
{
    public function translate(
        string $text,
        string $target,
        ?string $source = null,
        string $format = 'text'
    ): string {
        $response = Http::withToken(config('services.langbly.key'))
            ->acceptJson()
            ->timeout(30)
            ->post(config('services.langbly.url') . '/language/translate/v2', array_filter([
                'q' => $text,
                'target' => $target,
                'source' => $source,
                'format' => $format,
            ]))
            ->throw();

        return $response->json('data.translations.0.translatedText');
    }
}

Bind it as a singleton if you want constructor injection everywhere:

// app/Providers/AppServiceProvider.php
public function register(): void
{
    $this->app->singleton(\App\Services\Translator::class);
}

Now any controller, command, or job can type-hint Translator and get a working client. Because the endpoint follows the Google v2 contract, Http::fake() stubs written against Google responses keep passing without edits.

Prefer the SDK? Bind that instead and get retries and typed exceptions for free:

use Langbly\Client as LangblyClient;

$this->app->singleton(LangblyClient::class, fn () =>
    new LangblyClient(config('services.langbly.key'))
);

For EU data residency, point the client at new LangblyClient($key, 'https://eu.langbly.com'). Translation processing and temporary storage stay in the EU.

Queued jobs and caching: translating without blocking a request

Translating inside a web request is a trap. A page with forty strings turns into forty round trips, and your p95 goes through the roof. Push it onto the queue.

<?php

namespace App\Jobs;

use App\Models\Post;
use App\Services\Translator;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class TranslatePost implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public int $tries = 3;

    /** Seconds to wait between attempts. */
    public array $backoff = [10, 60, 300];

    public function __construct(
        public Post $post,
        public string $locale,
    ) {
    }

    public function handle(Translator $translator): void
    {
        $this->post->translations()->updateOrCreate(
            ['locale' => $this->locale],
            [
                'title' => $translator->translate($this->post->title, $this->locale, 'en'),
                'body' => $translator->translate($this->post->body, $this->locale, 'en', 'html'),
            ],
        );
    }
}

Dispatch it from an observer or a controller and move on: TranslatePost::dispatch($post, 'nl');. Note the html format on the body field. Markup and attributes are left alone, only the visible text gets translated, so your links and classes survive the trip.

The other half of the bill is repetition. UI strings, product categories, error messages, and email subjects repeat constantly. Cache them and you stop paying for the same sentence twice.

use Illuminate\Support\Facades\Cache;

public function cached(string $text, string $target): string
{
    $key = 'translation:' . $target . ':' . sha1($text);

    return Cache::remember(
        $key,
        now()->addDays(30),
        fn () => $this->translate($text, $target)
    );
}

Google and Langbly both include the first 500,000 characters each month. Langbly requires payment details to activate API access and charges $5 per million additional input characters with no base fee. DeepL Developer includes one million characters in total; check the live Growth plan for recurring use.

Frequently asked questions

What is the best translation API for PHP?

For most PHP teams, Langbly gives the best balance: a Composer package that installs in seconds, plain API key auth, built-in retries, and $5 per million characters. DeepL is a strong choice if you only translate a handful of European languages. Google Translate has broad coverage but the heaviest setup, since every call needs a service account and a credentials file.

How do I translate text in Laravel?

The simplest path is the built-in HTTP client. Call Http::withToken(config('services.langbly.key'))->post('https://api.langbly.com/language/translate/v2', ['q' => $text, 'target' => 'nl']) and read data.translations.0.translatedText from the JSON response. Wrap that in a small service class, bind it as a singleton, and dispatch it from a queued job so translation never blocks a web request.

Is there an official Langbly PHP SDK?

Yes. Install it with composer require langbly/langbly-php. It requires PHP 7.4 or newer and Guzzle 7, supports single and batch translation, language detection, HTML format, automatic retries with exponential backoff on 429 and 5xx responses, and typed exceptions such as RateLimitException and AuthenticationException.

Is the Google Translate API free for PHP developers?

Google Cloud Translation includes the first 500,000 characters each month, then charges $20 per million for standard NMT. Langbly also includes the first 500,000 input characters each month and charges $5 per million additional input characters. DeepL Developer includes one million characters in total; check the live Growth plan for recurring use.

Can I switch from Google Translate to Langbly without rewriting my PHP code?

In most cases yes. Langbly is a drop-in replacement for the Google Translate v2 API, so the request body and the response JSON are identical. Point your existing calls at https://api.langbly.com/language/translate/v2, send Authorization: Bearer YOUR_API_KEY instead of a Google OAuth token, and delete the service account file. Existing parsing code and Http::fake() test stubs keep working.

Ready to try Langbly?

500K characters included every month. Migrate in minutes.

Same API as Google Translate v2. Just change the URL.