Document Stack
Document Stack
Docs

Laravel Integration

Generate PDF documents from Laravel applications using the Document Stack REST API.

Setup

Laravel integrates with Document Stack via the REST API using Laravel's built-in HTTP client. No additional packages required.

Add your API key to .env:

.env
DS_API_KEY=your_api_key_here
DS_BASE_URL=https://api.documentstack.dev/api/v1
config/services.php
'document_stack' => [
    'api_key' => env('DS_API_KEY'),
    'base_url' => env('DS_BASE_URL', 'https://api.documentstack.dev/api/v1'),
],

Service Class

app/Services/DocumentStackService.php
<?php

namespace App\Services;

use Illuminate\Support\Facades\Http;

class DocumentStackService
{
    private string $apiKey;
    private string $baseUrl;

    public function __construct()
    {
        $this->apiKey = config('services.document_stack.api_key');
        $this->baseUrl = config('services.document_stack.base_url');
    }

    public function generate(string $templateId, array $data = []): array
    {
        $response = Http::withToken($this->apiKey)
            ->post("{$this->baseUrl}/generate", [
                'templateId' => $templateId,
                'data' => $data,
            ]);

        $response->throw();

        return $response->json('data');
    }

    public function listTemplates(int $page = 1): array
    {
        $response = Http::withToken($this->apiKey)
            ->get("{$this->baseUrl}/templates", [
                'page' => $page,
            ]);

        $response->throw();

        return $response->json('data');
    }
}

Controller

app/Http/Controllers/PdfController.php
<?php

namespace App\Http\Controllers;

use App\Services\DocumentStackService;
use Illuminate\Http\Request;

class PdfController extends Controller
{
    public function __construct(
        private DocumentStackService $ds
    ) {}

    public function generate(Request $request)
    {
        $validated = $request->validate([
            'templateId' => 'required|string',
            'data' => 'array',
        ]);

        $result = $this->ds->generate(
            $validated['templateId'],
            $validated['data'] ?? [],
        );

        return response()->json([
            'success' => true,
            'data' => $result,
        ]);
    }

    public function download(Request $request, string $templateId)
    {
        $result = $this->ds->generate($templateId, $request->all());

        $pdfContent = Http::get($result['url'])->body();

        return response($pdfContent, 200, [
            'Content-Type' => 'application/pdf',
            'Content-Disposition' => 'attachment; filename="document.pdf"',
        ]);
    }
}

Routes

routes/api.php
use App\Http\Controllers\PdfController;

Route::middleware('auth:sanctum')->group(function () {
    Route::post('/pdf/generate', [PdfController::class, 'generate']);
    Route::get('/pdf/download/{templateId}', [PdfController::class, 'download']);
});

Queued Generation

For heavy workloads, dispatch generation to a queue:

app/Jobs/GeneratePdfJob.php
<?php

namespace App\Jobs;

use App\Services\DocumentStackService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;

class GeneratePdfJob implements ShouldQueue
{
    use Queueable;

    public function __construct(
        private string $templateId,
        private array $data,
        private string $notifyEmail,
    ) {}

    public function handle(DocumentStackService $ds): void
    {
        $result = $ds->generate($this->templateId, $this->data);

        // Send email with PDF URL
        Mail::to($this->notifyEmail)->send(
            new PdfReadyMail($result['url'])
        );
    }
}
Laravel's HTTP client automatically handles retries with ->retry(3, 100). Add this to the service class for automatic retry on transient failures.

Next Steps