TextLens API for PHP

Add text analysis to your PHP app in 5 lines. Readability grades (8 formulas), sentiment scoring, keyword extraction, and SEO analysis — no PHP extensions to configure, no PECL packages to install.

From the team behind textlens — 96 npm downloads/week

<?php
$ch = curl_init("https://api.ckmtools.dev/v1/analyze");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        "Content-Type: application/json",
        "X-API-Key: " . $_ENV["TEXTLENS_KEY"],
    ],
    CURLOPT_POSTFIELDS => json_encode(["text" => $text]),
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);

echo $result["readability"]["consensus_grade"];  // Grade 8
echo $result["sentiment"]["label"];              // positive
Join the Waitlist

What you get

8 Readability Formulas

Flesch-Kincaid, Gunning Fog, SMOG, Coleman-Liau, ARI, Dale-Chall, Linsear Write, consensus grade. No single PHP Composer package covers all eight.

Sentiment + Keywords

AFINN sentiment calibrated for long-form content. TF-IDF keyword extraction with relevance scores. SEO quality scoring.

No PHP Extensions

No PECL packages, no FFI bindings to Python. Works in PHP 7.4+ including shared hosting, Laravel Forge, Docker.

The response

One endpoint returns everything you need:

{
  "readability": {
    "fleschKincaidGrade": 8.2,
    "gunningFog": 10.1,
    "smog": 9.4,
    "colemanLiau": 11.3,
    "ari": 9.7,
    "daleChall": 7.8,
    "linsearWrite": 8.5,
    "consensusGrade": "Grade 9",
    "fleschReadingEase": { "score": 62.3, "interpretation": "Standard" }
  },
  "sentiment": {
    "label": "positive",
    "score": 4.2,
    "confidence": 0.71
  },
  "keywords": [
    { "word": "content", "score": 5.1, "count": 4, "density": 1.87 },
    { "word": "readability", "score": 4.8, "count": 3, "density": 1.40 }
  ],
  "seo": { "score": 74, "grade": "B" },
  "statistics": { "words": 342, "sentences": 18, "paragraphs": 5 },
  "meta": { "processing_time_ms": 14 }
}

The code

curl — stdlib, zero dependencies recommended
<?php
$ch = curl_init("https://api.ckmtools.dev/v1/analyze");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        "Content-Type: application/json",
        "X-API-Key: " . $_ENV["TEXTLENS_KEY"],
    ],
    CURLOPT_POSTFIELDS => json_encode(["text" => $text]),
]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);

echo $result["readability"]["consensus_grade"];  // Grade 8
echo $result["sentiment"]["label"];              // positive
Guzzle HTTP
<?php
use GuzzleHttp\Client;

$client = new Client(["base_uri" => "https://api.ckmtools.dev"]);
$response = $client->post("/v1/analyze", [
    "json" => ["text" => $content],
    "headers" => ["X-API-Key" => env("TEXTLENS_KEY")],
]);
$result = json_decode($response->getBody(), true);
Laravel HTTP facade
<?php
use Illuminate\Support\Facades\Http;

$result = Http::withHeaders(["X-API-Key" => config("services.textlens.key")])
    ->post("https://api.ckmtools.dev/v1/analyze", ["text" => $content])
    ->json();

$grade = $result["readability"]["consensus_grade"];

Works naturally in Laravel service classes or jobs. Add textlens.key to config/services.php for environment-based key management.

No PHP NLP library covers this

PHP's text processing ecosystem is sparse. No widely-used Composer package covers all 8 readability formulas plus AFINN sentiment plus TF-IDF keyword extraction. TextLens API covers all in one HTTP call — works with curl, Guzzle, Symfony HttpClient, or Laravel's HTTP facade.

Join the Waitlist

TextLens API is in development. Join the waitlist to get notified at launch.

Backed by the textlens npm package — 96 downloads/week.

Get Early Access

$0 — no credit card required

Pricing

Free

$0 /mo
  • 1,000 requests/mo
  • 10 req/min rate limit
  • 5,000 char max per request
Get Started

Starter

$9 /mo
  • 10,000 requests/mo
  • 60 req/min rate limit
  • 25,000 char max per request
Subscribe

Team

$79 /mo
  • 500,000 requests/mo
  • 300 req/min rate limit
  • 500,000 char max per request
Subscribe

Using Ruby instead? See Ruby-specific examples →

See all library comparisons →