Skip to main content

Laravel

This guide covers a language integration with Laravel using the Http facade (based on Guzzle), including Form Request vavalidation, a domain exception of its own, /jobs/{job_id} polling for the 202 flow, a Job queue for large files, and production recommendations (timeouts, retries, and BYOS exit).

Config

Register the URL base and API key like any other external service, in config/services.php:
Do not hardcode the API key in the controller or upload it to the repo. Always use config('services.flash_md.key'), which reads from .env.

Domain exception

A separate exception allows you to map API codes to HTTP responses that are consistent throughout the app, instead of repeating if/else for each status.

Form Request

Vavalidate the uploaded file and optional parameters before touching the API.

Cliente reutilizable

Encapsulates the calls to API in their own class to avoid repeating headers, timeouts or job polling in each controller.
Register it as a singleton in AppServiceProvider if you prefer to inject it per interface, or simply resolve it by autowiring — Laravel instantiates it automatically when requested in a controller constructor.

Controller

Job queued for large files

For large documents it is advisable not to block the HTTP request: the file is uploaded, a Job is dispatched and the conversion (including the possible polling of /jobs/{id} on the API side%) runs in the background.
ConvertLargeDocument already delegates handling of 202/polling to FlashMdClient::convertRaw(), so the Job doesn’t need its own polling logic — it just handles its own queue retries if the entire call fails.

Rutas

Production

Combine output_url with output_head_url: if the object already exists in your bucket (same content hash), API returns the cached result without reprocessing the document — useful when retrying a Job that had already completed the upload but later failed.
Don’t blindly use retry() on POST /convert with input_format or invavalid parameters: those are 400/422 errors that won’t go away by retrying. The retry() callback in the example above already filters this out — it only retries 429 and 5xx.