How to Refry a PDF with PHP

Refry a PDF with PHP through a PDF to PostScript to PDF workflow using pdfRest resource IDs.
Share this page

This PHP walkthrough uses Guzzle to send the file and conversion options. It completes a PDF -> PostScript -> PDF roundtrip by passing a resource ID from /postscript into /pdf. The complete sample is included below so PHP developers can see the file handling, request construction, and response path together.

Why Refry a PDF with PHP?

PDF refrying converts a PDF to PostScript and then converts the PostScript into a new PDF. It can support an established print or prepress path that needs a rebuilt delivery derivative for a legacy downstream stage.

A PHP job can orchestrate that purpose as a clear two-step sequence rather than an opaque external process. The first response identifies the temporary PostScript result; the next request references that result, applies a known .joboptions profile when needed, and returns the final PDF without transferring the intermediate outside the service.

Since the route can discard interactive and structural PDF features, production code should store the original source independently and treat the generated PDF as a delivery derivative.

PHP Code Example for PDF Refrying

/* Refry a PDF by converting it to PostScript and back to PDF.
 *
 * PDF refrying is the common name for a PDF -> PostScript -> PDF roundtrip.
 * Some print, prepress, and legacy production workflows use it to rebuild or
 * normalize page content, flatten certain PDF constructs, or prepare a file
 * for downstream systems. The process is intentionally lossy and may remove
 * tags, forms, layers, annotations, transparency, metadata, and editability.
 * Use this workflow when a downstream system requires rebuilt page content or
 * a PostScript-based interchange file.
 *
 * The PostScript-to-PDF step uses a custom .joboptions profile in this sample.
 * A .joboptions file contains Adobe Distiller-compatible conversion settings;
 * it is optional, and default settings are used when omitted. pdfRest applies
 * the profile with Datalogics PDF Converter SDK. Datalogics maintains the SDK
 * in partnership with Adobe, using the same Adobe technology that powers
 * Distiller.
 *
 * Run: php refry-pdf.php   [outputPdf]
 */

require 'vendor/autoload.php';

use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Utils;

$apiUrl = rtrim(getenv('PDFREST_URL') ?: 'https://api.pdfrest.com', '/');
$apiKey = getenv('PDFREST_API_KEY') ?: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx';
$inputPath = $argv[1] ?? '/path/to/sample.pdf';
$jobOptionsPath = $argv[2] ?? '/path/to/custom.joboptions';
$outputPath = $argv[3] ?? __DIR__ . '/refried.pdf';
$client = new Client(['http_errors' => true]);

function postMultipart(Client $client, string $url, string $apiKey, array $parts): array
{
    $response = $client->post($url, [
        'headers' => ['Accept' => 'application/json', 'Api-Key' => $apiKey],
        'multipart' => $parts,
    ]);
    echo basename($url) . ': ' . $response->getStatusCode() . PHP_EOL;
    return json_decode($response->getBody(), true, 512, JSON_THROW_ON_ERROR);
}

$postscript = postMultipart($client, $apiUrl . '/postscript', $apiKey, [
    ['name' => 'file', 'contents' => Utils::tryFopen($inputPath, 'r'), 'filename' => basename($inputPath), 'headers' => ['Content-Type' => 'application/pdf']],
    ['name' => 'ps_level', 'contents' => '3'],
    ['name' => 'page_range', 'contents' => 'all'],
    ['name' => 'binary_output', 'contents' => 'true'],
    ['name' => 'scale', 'contents' => '1'],
    ['name' => 'rotate', 'contents' => 'false'],
    ['name' => 'shrink_to_fit', 'contents' => 'true'],
    ['name' => 'print_annotations', 'contents' => 'true'],
    ['name' => 'output', 'contents' => 'refry_intermediate'],
]);

$finalPdf = postMultipart($client, $apiUrl . '/pdf', $apiKey, [
    ['name' => 'id', 'contents' => $postscript['outputId']],
    ['name' => 'job_options', 'contents' => Utils::tryFopen($jobOptionsPath, 'r'), 'filename' => basename($jobOptionsPath), 'headers' => ['Content-Type' => 'application/octet-stream']],
    ['name' => 'output', 'contents' => 'refried'],
]);

$download = $client->get($apiUrl . '/resource/' . rawurlencode($finalPdf['outputId']) . '?format=file', ['headers' => ['Api-Key' => $apiKey]]);
file_put_contents($outputPath, $download->getBody()->getContents());
echo json_encode($finalPdf, JSON_PRETTY_PRINT) . PHP_EOL;
echo "Created $outputPath" . PHP_EOL;

Source: View the sample on GitHub

Breaking Down the Code

Configure the service and input

$apiUrl = rtrim(getenv('PDFREST_URL') ?: 'https://api.pdfrest.com', '/');
$apiKey = getenv('PDFREST_API_KEY') ?: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx';
$inputPath = $argv[1] ?? '/path/to/sample.pdf';
$jobOptionsPath = $argv[2] ?? '/path/to/custom.joboptions';
$outputPath = $argv[3] ?? __DIR__ . '/refried.pdf';
$client = new Client(['http_errors' => true]);

For this PDF Refrying example, PHP coordinates the two dependent API calls. The PHP samples use Guzzle for HTTP and PSR-7 stream utilities for uploads. Install Guzzle with Composer when moving the code outside the repository, and provide the API key through protected runtime configuration. The sample’s placeholder path and API key make the moving pieces visible; replace them with a real local path and protected runtime credential before using the request.

Pass the Intermediate Resource to the Next Step

]);

$finalPdf = postMultipart($client, $apiUrl . '/pdf', $apiKey, [
    ['name' => 'id', 'contents' => $postscript['outputId']],
    ['name' => 'job_options', 'contents' => Utils::tryFopen($jobOptionsPath, 'r'), 'filename' => basename($jobOptionsPath), 'headers' => ['Content-Type' => 'application/octet-stream']],
    ['name' => 'output', 'contents' => 'refried'],
]);

$download = $client->get($apiUrl . '/resource/' . rawurlencode($finalPdf['outputId']) . '?format=file', ['headers' => ['Api-Key' => $apiKey]]);
file_put_contents($outputPath, $download->getBody()->getContents());
echo json_encode($finalPdf, JSON_PRETTY_PRINT) . PHP_EOL;

In the PHP workflow, outputId from /postscript becomes the id passed to /pdf. The second request also supplies a custom .joboptions file so the return conversion has an explicit Adobe Distiller-compatible profile, even though default settings are available when the profile is omitted.

Build the multipart request

/* Refry a PDF by converting it to PostScript and back to PDF.
 *
 * PDF refrying is the common name for a PDF -> PostScript -> PDF roundtrip.
 * Some print, prepress, and legacy production workflows use it to rebuild or
 * normalize page content, flatten certain PDF constructs, or prepare a file
 * for downstream systems. The process is intentionally lossy and may remove
 * tags, forms, layers, annotations, transparency, metadata, and editability.
 * Use this workflow when a downstream system requires rebuilt page content or
 * a PostScript-based interchange file.

For the PDF Refrying form, guzzle accepts multipart fields as an array. Each entry names a field and supplies either stream content for a file or a simple string for an option, then Guzzle produces the correct multipart boundary.

Read the output resource

function postMultipart(Client $client, string $url, string $apiKey, array $parts): array
{
    $response = $client->post($url, [
        'headers' => ['Accept' => 'application/json', 'Api-Key' => $apiKey],
        'multipart' => $parts,
    ]);
    echo basename($url) . ': ' . $response->getStatusCode() . PHP_EOL;
    return json_decode($response->getBody(), true, 512, JSON_THROW_ON_ERROR);
}

$postscript = postMultipart($client, $apiUrl . '/postscript', $apiKey, [

After the PDF Refrying call, the example prints Guzzle’s response body. A production caller can decode that JSON, retain outputId, and branch on an unsuccessful response instead of assuming every submitted conversion completed.

Beyond the Tutorial

You completed the two-stage refry process in PHP and saved the final PDF after both calls succeeded. The intermediate response ID is the important handoff between conversion stages, not merely a status value to print and discard.

Try representative pdf refrying inputs in API Lab. For the authoritative request fields, accepted values, and response contract, consult the pdfRest API Reference Guide. The same request pattern can then be adapted to your PHP application’s error handling, retention policy, and delivery workflow.

Generate a self-service API Key now!
Create your FREE API Key to start processing PDFs in seconds, only possible with pdfRest.