PHPackages                             enconvert/enconvert-php - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. enconvert/enconvert-php

ActiveLibrary[API Development](/categories/api)

enconvert/enconvert-php
=======================

PHP SDK for Enconvert — read any page or file into agent-ready Markdown, JSON, or screenshots (scored 0.0-1.0), plus file conversion. V2 perception + MCP.

v0.1.0(3w ago)50MITPHPPHP &gt;=8.1

Since Jul 15Pushed 1mo agoCompare

[ Source](https://github.com/conversionapi/php-sdk)[ Packagist](https://packagist.org/packages/enconvert/enconvert-php)[ Docs](https://enconvert.com)[ RSS](/packages/enconvert-enconvert-php/feed)WikiDiscussions master Synced 1w ago

READMEChangelogDependencies (2)Versions (3)Used By (0)

Enconvert PHP SDK
=================

[](#enconvert-php-sdk)

Honest eyes for your AI agent — the PHP SDK for [Enconvert](https://enconvert.com). PHP 8.1+.

Read any web page or file into clean Markdown, JSON, or screenshots, and get a `render_quality` score (0.0–1.0) on **every** read — so a blocked, challenge, or empty-SPA page comes back flagged with a low score and warnings, never mistaken for real content. Perceive, discover, look up, distill, ingest, and watch the web; convert 40+ file and document formats through the same key.

> Wiring an agent (Claude, Cursor, Windsurf, n8n, …)? The [MCP server](https://enconvert.com/mcp) is the native path — `npx @enconvert/mcp setup`. This SDK is the programmatic REST path for everything else.

Install
-------

[](#install)

```
composer require enconvert/enconvert-php
```

Quick Start
-----------

[](#quick-start)

```
use Enconvert\Client;

$client = new Client('sk_...');

// Read a page the way your agent should — with a quality score attached.
$op = $client->v2->perceive('https://example.com', [
    'outputs' => ['markdown', 'structured'],
]);
echo $op->outputs['markdown']->url, ' ', $op->renderQuality; // e.g. 0.93
```

---

V2 — agent-ready data (`$client->v2`)
=====================================

[](#v2--agent-ready-data-client-v2)

The V2 namespace turns web pages into agent-ready data: render, search, extract, ingest, and monitor. All V2 endpoints require a **private API key** and are plan-gated — a disabled feature or exhausted monthly quota throws `QuotaException` (HTTP 402). `$client->v2` is a public property; `$client->v2()` is an equivalent accessor method.

Every render carries `renderQuality` (0.0–1.0). A low score means the page didn't render cleanly (challenge page, cookie wall, empty shell); the content is still returned, flagged, so a bad read never quietly enters your agent's context.

### Perceive — render a URL into artifacts

[](#perceive--render-a-url-into-artifacts)

```
$op = $client->v2->perceive('https://example.com', [
    'outputs' => ['markdown', 'screenshot', 'structured'],
    'extract' => ['tables', 'metadata'],
]);
echo $op->renderQuality;              // honesty score, 0.0–1.0
echo $op->outputs['markdown']->url;   // 15-min signed URL
print_r($op->structured);

// Re-sign artifact URLs later:
$again = $client->v2->getPerceiveOperation($op->operationId);

// Batch (v2->perceiveBatch(['https://a.com', 'https://b.com'], [
    'outputs' => ['markdown'],
    'outputMode' => 'zip',
]);
$done = $client->v2->getPerceiveBatch($batch->jobId);
```

### Discover — enumerate a site's URLs (no rendering)

[](#discover--enumerate-a-sites-urls-no-rendering)

```
$found = $client->v2->discover('https://example.com', [
    'mode' => 'hybrid',              // "sitemap" | "crawl" | "hybrid"
    'maxUrls' => 200,
    'excludePatterns' => ['/tag/'],
]);
echo $found->total;
print_r($found->urls);
```

### Lookup — web search with optional auto-perceive

[](#lookup--web-search-with-optional-auto-perceive)

```
$search = $client->v2->lookup('best static site generators', [
    'category' => 'web',             // web | news | images | scholar | patents | maps
    'numResults' => 10,
    'perceiveTop' => 3,              // auto-render top 3 results (uses perceive quota)
]);
foreach ($search->results as $hit) {
    echo $hit->title, ' ', $hit->url, ' ', $hit->perceive?->renderQuality, "\n";
}
```

### Distill — schema-driven structured extraction

[](#distill--schema-driven-structured-extraction)

```
$extraction = $client->v2->distill([
    'urls' => ['https://example.com/pricing'],
    'schema' => ['plans' => 'list of plan names with monthly prices'],
    'cssSchema' => [                 // optional free CSS pass before the LLM tier
        'baseSelector' => '.plan-card',
        'fields' => [
            ['name' => 'name', 'type' => 'text', 'selector' => 'h3'],
            ['name' => 'price', 'type' => 'text', 'selector' => '.price'],
        ],
    ],
]);
print_r($extraction->results[0]->data);
echo $extraction->results[0]->extractionTier;

// Or discover-then-distill:
$client->v2->distill([
    'discoverFrom' => ['url' => 'https://example.com', 'mode' => 'sitemap', 'maxPages' => 10],
    'schema' => ['title' => 'page title', 'summary' => 'one-line summary'],
]);
```

### Ingest — site or files to RAG-ready JSONL (always async)

[](#ingest--site-or-files-to-rag-ready-jsonl-always-async)

Turn a whole site — or a set of uploaded documents — into chunked, RAG-ready JSONL through one pipeline.

```
// From a site:
$job = $client->v2->ingest([
    'mode' => 'sitemap',
    'url' => 'https://docs.example.com',
    'maxPages' => 100,
    'chunk' => ['maxWords' => 512, 'sentenceOverlap' => 1],
    'webhookUrl' => 'https://my.app/hooks/enconvert',
]);

// Or from uploaded files (PDF, DOCX, PPTX, XLSX, CSV, HTML, EPUB, TXT/MD, legacy/ODF office):
$fileJob = $client->v2->ingestFiles(['handbook.pdf', 'notes.docx'], [
    'chunk' => ['maxWords' => 512, 'sentenceOverlap' => 1],
]);

$status = $client->v2->getIngestJob($job->jobId);   // poll
if ($status->status === 'completed') {
    echo $status->outputUrl; // JSONL
}

$client->v2->listIngestJobs(['limit' => 20]);
$client->v2->cancelIngestJob($job->jobId);           // idempotent

// Webhook signing (HMAC):
$secretInfo = $client->v2->getWebhookSecret();
$client->v2->rotateWebhookSecret();                  // invalidates old secret
$client->v2->retryIngestWebhook($job->jobId);        // re-deliver
```

### Watch — recurring change monitoring

[](#watch--recurring-change-monitoring)

```
$watcher = $client->v2->createWatcher('https://example.com/pricing', [
    'frequencyMinutes' => 60,        // hourly floor
    'diffMode' => 'auto',            // auto | text | structured | tables | metadata
    'webhookUrl' => 'https://my.app/hooks/changes',
    'notifyEmail' => true,
]);

$client->v2->listWatchers();
$client->v2->getWatcher($watcher->watcherId);
$client->v2->getWatcherSnapshots($watcher->watcherId, ['limit' => 10]);
$client->v2->updateWatcher($watcher->watcherId, ['status' => 'paused']);
$client->v2->updateWatcher($watcher->watcherId, ['webhookUrl' => '']); // clears webhook
$client->v2->deleteWatcher($watcher->watcherId);      // soft-delete, idempotent
```

### V2 error handling

[](#v2-error-handling)

```
use Enconvert\Exception\QuotaException;

try {
    $client->v2->ingest(['urls' => ['https://example.com']]);
} catch (QuotaException $e) {
    echo 'Upgrade plan or wait for quota reset';
}
```

---

File conversion
===============

[](#file-conversion)

The same key also converts 40+ formats. Two "anything → X" endpoints auto-detect the input; the format-specific endpoints below give you a validated, typed path.

### Anything to Markdown / PDF

[](#anything-to-markdown--pdf)

```
// Any document → clean Markdown (a RAG-ingestion building block):
$client->convertToMarkdown('report.docx', ['saveTo' => 'report.md']);
// PDF, DOCX, PPTX, XLSX, CSV, HTML, EPUB, TXT/MD, and legacy/ODF office. (Images not supported.)

// Almost anything → PDF:
$client->convertToPdf('slides.pptx', ['saveTo' => 'slides.pdf']);
// office/ODF/Pages/Numbers/RTF/CSV, HTML, Markdown, text, images, SVG, EPUB, or a PDF passthrough.
// Only pdfOptions.grayscale is honored on this endpoint:
$client->convertToPdf('scan.pdf', ['pdfOptions' => ['grayscale' => true], 'saveTo' => 'gray.pdf']);
```

### Image Conversion

[](#image-conversion)

```
$result = $client->convertImage('photo.heic', [
    'outputFormat' => 'webp',
    'saveTo' => 'photo.webp',
]);
```

Any pair among `jpeg`, `png`, `svg`, `heic`, `webp` — plus PDF rasterization:

```
$client->convertImage('scan.pdf', ['outputFormat' => 'jpeg', 'saveTo' => 'scan.jpeg']);
```

Raw bytes are also accepted, wrapped with an explicit filename (needed to resolve the input format and MIME type):

```
$client->convertImage(
    ['data' => $rawBytes, 'filename' => 'photo.heic'],
    ['outputFormat' => 'webp', 'saveTo' => 'photo.webp']
);
```

### Document Conversion

[](#document-conversion)

```
$client->convertDocument('report.docx', ['saveTo' => 'report.pdf']);
$client->convertDocument('data.json', ['outputFormat' => 'yaml', 'saveTo' => 'data.yaml']);
$client->convertDocument('notes.md', ['outputFormat' => 'html', 'saveTo' => 'notes.html']);
```

Supported inputs: `doc`/`docx`, `xls`/`xlsx`, `ppt`/`pptx`, `odt`, `ods`, `odp`, `ots`, `pages`, `numbers`, `html`, `markdown`, `csv`, `json`, `xml`, `yaml`, `toml`. (EPUB has no dedicated document pair — use `convertToPdf` / `convertToMarkdown`.)

The SDK validates every `{input}-to-{output}` pair against the conversions the API actually implements and throws immediately — with the list of valid outputs for that input — instead of sending a doomed request. Introspect programmatically:

```
use Enconvert\Formats;

Formats::validOutputsFor('json'); // ["csv", "toml", "xml", "yaml"]
Formats::validOutputsFor('pdf');  // ["jpeg"]
Formats::IMPLEMENTED_CONVERSIONS; // the full set of 43 "{input}-to-{output}" pairs
```

### Supported conversions

[](#supported-conversions)

InputOutputsjsoncsv, toml, xml, yamlxmlcsv, jsonyamljsoncsvjson, xmltomljsonmarkdownhtml, pdfhtmlpdfdoc, excel, ppt, odt, ods, odp, ots, pages, numberspdfjpeg, png, svg, heic, webpeach other (all 20 pairs)pdfjpeg### URL to PDF / Screenshot / Markdown

[](#url-to-pdf--screenshot--markdown)

```
$client->convertUrlToPdf('https://example.com', ['saveTo' => 'page.pdf']);
$client->convertUrlToScreenshot('https://example.com', ['viewportWidth' => 1440, 'saveTo' => 'shot.png']);
$client->convertUrlToMarkdown('https://example.com/article', ['saveTo' => 'article.md']);
```

### Website to PDF / Screenshot (whole-site batch)

[](#website-to-pdf--screenshot-whole-site-batch)

Discover every page of a website (via sitemap, or full crawl on Pro/Business plans), convert each one in the background, and receive a single ZIP. Requires a private API key with crawl access.

```
$batch = $client->convertWebsiteToPdf('https://example.com', [
    'crawlMode' => 'sitemap',            // "auto" (default) | "sitemap" | "full"
    'excludePatterns' => ['/blog/tag/'], // full crawl mode only
]);
echo $batch->batchId, ' ', $batch->urlCount, ' ', $batch->discoveryMethod;

// Block until done and save the ZIP:
$status = $client->waitForBatch($batch->batchId, ['saveTo' => 'site.zip']);
echo $status->completed, ' of ', $status->total, ' pages converted';

// Or poll yourself:
$s = $client->getBatchStatus($batch->batchId);
if ($s->status !== 'processing') {
    echo $s->zipDownloadUrl;
}
```

`convertWebsiteToScreenshot` works the same way and produces a ZIP of PNGs.

### PDF Options &amp; Authenticated Pages

[](#pdf-options--authenticated-pages)

```
$result = $client->convertUrlToPdf('https://example.com', [
    'pdfOptions' => [
        'pageSize' => 'A4',              // or custom dimensions via pageWidth + pageHeight
        'orientation' => 'landscape',
        'margins' => ['top' => 10, 'bottom' => 10, 'left' => 15, 'right' => 15],
        'header' => ['content' => 'Quarterly Report', 'height' => 15],
        'footer' => ['content' => 'Confidential', 'height' => 12],
    ],
    'saveTo' => 'report.pdf',
]);
```

All URL and website conversions accept HTTP Basic Auth, cookies, and custom headers for pages behind a login:

```
$client->convertUrlToPdf('https://internal.example.com/report', [
    'auth' => ['username' => 'user', 'password' => 'pass'],
    // or cookies / headers:
    'cookies' => [['name' => 'session', 'value' => 'abc123', 'domain' => 'internal.example.com']],
    'headers' => ['X-Tenant' => 'acme'],
    'saveTo' => 'report.pdf',
]);
```

Do not combine `auth` with an `Authorization` header — the API rejects the conflict.

### Job Status (async polling)

[](#job-status-async-polling)

```
$status = $client->getJobStatus('job_abc123');
if ($status->status === 'success') {
    echo $status->presignedUrl;
}
```

---

Error Handling
--------------

[](#error-handling)

```
use Enconvert\Client;
use Enconvert\Exception\ApiException;
use Enconvert\Exception\AuthenticationException;
use Enconvert\Exception\RateLimitException;

try {
    $client->convertUrlToPdf('https://example.com');
} catch (AuthenticationException $e) {
    echo 'Invalid API key';
} catch (RateLimitException $e) {
    echo 'Too many requests — slow down';
} catch (ApiException $e) {
    echo "API error [{$e->getStatusCode()}]: {$e->getMessage()}";
}
```

`AuthenticationException`, `QuotaException`, and `RateLimitException` all extend `ApiException`, which extends the base `EnconvertException`.

Configuration
-------------

[](#configuration)

```
$client = new Client('sk_...', [
    'timeout' => 300,   // seconds, default (idiomatic PHP/Guzzle unit; node-sdk uses milliseconds)
    'base_url' => 'https://api.enconvert.com', // override, e.g. for a self-hosted gateway
]);
```

Get an API Key
--------------

[](#get-an-api-key)

Sign up at [enconvert.com](https://enconvert.com) to get your API key.

License
-------

[](#license)

MIT

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance93

Actively maintained with recent releases

Popularity5

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity33

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~21 days

Total

2

Last Release

25d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/4b94a574f00797db64d0b80b366ab1327b957f17f6a7233adc139e76dae45f03?d=identicon)[EnConvert](/maintainers/EnConvert)

---

Top Contributors

[![OmJadav9](https://avatars.githubusercontent.com/u/139232693?v=4)](https://github.com/OmJadav9 "OmJadav9 (2 commits)")

---

Tags

apipdfsdkconversionscreenshotdocx to pdfhtml-to-pdfURL to PDFimage convertenconverturl-to-screenshoturl-to-markdowndocument-convertheic-to-webp

### Embed Badge

![Health badge](/badges/enconvert-enconvert-php/health.svg)

```
[![Health](https://phpackages.com/badges/enconvert-enconvert-php/health.svg)](https://phpackages.com/packages/enconvert-enconvert-php)
```

###  Alternatives

[aws/aws-sdk-php

AWS SDK for PHP - Use Amazon Web Services in your PHP project

6.4k567.5M2.9k](/packages/aws-aws-sdk-php)[eslazarev/wildberries-sdk

Wildberries OpenAPI clients (generated).

353.6k](/packages/eslazarev-wildberries-sdk)[tencentcloud/tencentcloud-sdk-php

TencentCloudApi php sdk

3751.3M49](/packages/tencentcloud-tencentcloud-sdk-php)[resend/resend-php

Resend PHP library.

639.6M57](/packages/resend-resend-php)[checkout/checkout-sdk-php

Checkout.com SDK for PHP

563.7M17](/packages/checkout-checkout-sdk-php)[files.com/files-php-sdk

Files.com PHP SDK

2484.5k](/packages/filescom-files-php-sdk)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
