How to customize Scramble – Laravel OpenAPI Docs

I tried to customize the documentation of my API and was so much difficult! I'm writing this article to help devs that would to customize / add new endpoints without the route in api.php. For example: my API have a webhook to the client. So, i would like to add the webhook documentation to the documentation and I achieved. First, lets create a Scramble DocumentTransformer: /app/Transformers/AddWebhookDocumentationTransformer.php

Apr 4, 2025 - 19:35
 0
How to customize Scramble – Laravel OpenAPI Docs

I tried to customize the documentation of my API and was so much difficult!

I'm writing this article to help devs that would to customize / add new endpoints without the route in api.php. For example: my API have a webhook to the client. So, i would like to add the webhook documentation to the documentation and I achieved.

First, lets create a Scramble DocumentTransformer:

/app/Transformers/AddWebhookDocumentationTransformer.php

operationId = 'webhookNotification';
        $operation->security = [];
{% embed  %}
        $operation->summary('Webhook Notification')
            ->description(
                'This is an example of the webhook sent by us after a transaction is completed. ' .
                    'The payload below represents the data sent to the URL configured by the client.'
            );

        // Webhook schema definition
        $schema = (new ObjectType())
            ->addProperty('payer_id', new IntegerType(), fn ($p) => $p->description('Payer ID.'))
            ->addProperty('payer_name', new StringType(), fn ($p) => $p->description('Payer name.'))
            ->addProperty('payer_document', new StringType(), fn ($p) => $p->description('Payer document (CPF/CNPJ).'))
            ->addProperty('payer_email', new StringType(), fn ($p) => $p->description('Payer email.'))
            ->addProperty('product_id', new StringType(), fn ($p) => $p->description('External product ID.'))
            ->addProperty('order_id', new StringType(), fn ($p) => $p->description('Order ID.'))
            ->addProperty('status', new StringType(), fn ($p) => $p->description('Transaction status (e.g., approved, declined).'))
            ->addProperty('total', new IntegerType(), fn ($p) => $p->description('Total transaction amount in cents.'))
            ->addProperty('paid', new BooleanType(), fn ($p) => $p->description('Indicates if the transaction was paid (true/false).'))
            ->addProperty('paid_at', new StringType(), fn ($p) => $p->description('Payment date and time (ISO 8601).'));

        // Adding the request body
        $operation->addRequestBodyObject(
            RequestBodyObject::make()
                ->setContent('application/json', Schema::fromType($schema))
                ->description('Structure of the payload sent by the webhook')
        );

        // Adding the expected response
        $operation->addResponse(
            (new Response(200))
                ->description('Webhook received successfully.')
        );

        // Creating the /webhook path
        $pathItem = Path::make('/webhook')
            ->addOperation($operation);

        // Adding the path to the document
        $document->addPath($pathItem);
    }
}

Second, we will register this transformer to the Scramble:

/app/Providers/AppServiceProvider.php

Scramble::configure()
            ->routes(function (Route $route) {
                return Str::startsWith($route->uri, 'api/');
            })
            ->withDocumentTransformers(AddWebhookDocumentationTransformer::class);