← toolkit.bot

PDF to EPUB with PHP — API Integration Guide

June 12, 2026  ·  7 min read

Integrate PDF-to-EPUB conversion into your PHP application using the toolkit.bot REST API. Here's a complete guide with cURL, Guzzle, and Laravel examples.

Basic Integration with cURL

<?php

function convertPdfToEpub(string $pdfPath, string $apiKey): string {
    $url = 'https://toolkit.bot/api/v1/convert';

    $curl = curl_init();
    curl_setopt_array($curl, [
        CURLOPT_URL            => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST           => true,
        CURLOPT_HTTPHEADER     => [
            'Authorization: Bearer ' . $apiKey,
        ],
        CURLOPT_POSTFIELDS     => [
            'file'          => new CURLFile($pdfPath, 'application/pdf'),
            'output_format' => 'epub3',
        ],
    ]);

    $response = curl_exec($curl);
    $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
    curl_close($curl);

    if ($httpCode !== 200) {
        throw new RuntimeException("Submit failed: HTTP $httpCode");
    }

    $data = json_decode($response, true);
    return $data['job_id'];
}

function pollJob(string $jobId, string $apiKey): array {
    $url = "https://toolkit.bot/api/v1/jobs/$jobId";

    do {
        sleep(2);
        $curl = curl_init();
        curl_setopt_array($curl, [
            CURLOPT_URL            => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
        ]);
        $response = json_decode(curl_exec($curl), true);
        curl_close($curl);

        $status = $response['status'];
    } while ($status === 'queued' || $status === 'processing');

    if ($status === 'failed') {
        throw new RuntimeException('Conversion failed');
    }

    return $response;
}

function downloadEpub(string $downloadUrl, string $apiKey): string {
    $curl = curl_init();
    curl_setopt_array($curl, [
        CURLOPT_URL            => $downloadUrl,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
    ]);
    $epub = curl_exec($curl);
    curl_close($curl);
    return $epub;
}

// Usage
$apiKey = getenv('TOOLKIT_API_KEY');
$jobId  = convertPdfToEpub('/path/to/document.pdf', $apiKey);
$job    = pollJob($jobId, $apiKey);
$epub   = downloadEpub($job['download_url'], $apiKey);
file_put_contents('/path/to/output.epub', $epub);
echo "Done: " . strlen($epub) . " bytes
";

Using Guzzle (Recommended for Production)

<?php

use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;

class EpubConverter {
    private Client $client;
    private string $apiKey;
    private string $baseUrl = 'https://toolkit.bot/api/v1';

    public function __construct(string $apiKey) {
        $this->apiKey = $apiKey;
        $this->client = new Client([
            'base_uri' => $this->baseUrl,
            'headers'  => ['Authorization' => 'Bearer ' . $apiKey],
            'timeout'  => 30,
        ]);
    }

    public function convert(string $pdfPath): string {
        $response = $this->client->post('/convert', [
            'multipart' => [
                ['name' => 'file', 'contents' => fopen($pdfPath, 'r'),
                 'filename' => basename($pdfPath)],
                ['name' => 'output_format', 'contents' => 'epub3'],
            ],
        ]);
        return json_decode($response->getBody(), true)['job_id'];
    }

    public function waitForCompletion(string $jobId): array {
        do {
            sleep(2);
            $response = $this->client->get("/jobs/$jobId");
            $job = json_decode($response->getBody(), true);
        } while (in_array($job['status'], ['queued', 'processing']));

        if ($job['status'] === 'failed') {
            throw new RuntimeException('Conversion failed');
        }
        return $job;
    }

    public function download(string $downloadUrl): string {
        $response = $this->client->get($downloadUrl);
        return (string) $response->getBody();
    }
}

// Usage
$converter = new EpubConverter(getenv('TOOLKIT_API_KEY'));
$jobId = $converter->convert('/path/to/document.pdf');
$job   = $converter->waitForCompletion($jobId);
file_put_contents('output.epub', $converter->download($job['download_url']));

Laravel Job Example

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

class ConvertPdfToEpub implements ShouldQueue {
    use Dispatchable, Queueable;

    public function __construct(
        private string $pdfPath,
        private string $outputPath
    ) {}

    public function handle(): void {
        $converter = new EpubConverter(config('services.toolkit.key'));
        $jobId  = $converter->convert($this->pdfPath);
        $job    = $converter->waitForCompletion($jobId);
        $epub   = $converter->download($job['download_url']);
        file_put_contents($this->outputPath, $epub);
    }
}

// Dispatch from a controller
ConvertPdfToEpub::dispatch($pdfPath, $outputPath)->onQueue('conversions');

Webhook Receiver in PHP

<?php
// webhook.php — receives POST from toolkit.bot on job completion
$payload = json_decode(file_get_contents('php://input'), true);

if ($payload['event'] === 'job.complete') {
    $jobId       = $payload['job_id'];
    $downloadUrl = $payload['download_url'];

    // Fetch and store the EPUB
    $epub = file_get_contents($downloadUrl, false, stream_context_create([
        'http' => ['header' => 'Authorization: Bearer ' . getenv('TOOLKIT_API_KEY')]
    ]));

    file_put_contents("/var/epubs/$jobId.epub", $epub);
}

http_response_code(200);
Get your API key at toolkit.bot →