OpenZeppelin Plugins API

Plugins are TypeScript functions that can be used to extend the OpenZeppelin Relayer API functionality.

OpenAPI Specification

openzeppelin-plugins-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: OpenZeppelin Relayer Health Plugins API
  description: OpenZeppelin Relayer API
  termsOfService: https://www.openzeppelin.com/tos
  contact:
    name: OpenZeppelin
    url: https://www.openzeppelin.com
  license:
    name: AGPL-3.0 license
    url: https://github.com/OpenZeppelin/openzeppelin-relayer/blob/main/LICENSE
  version: 1.5.0
tags:
- name: Plugins
  description: Plugins are TypeScript functions that can be used to extend the OpenZeppelin Relayer API functionality.
paths:
  /api/v1/plugins:
    get:
      tags:
      - Plugins
      summary: List plugins.
      operationId: listPlugins
      parameters:
      - name: page
        in: query
        description: Page number for pagination (starts at 1)
        required: false
        schema:
          type: integer
          minimum: 0
      - name: per_page
        in: query
        description: 'Number of items per page (default: 10)'
        required: false
        schema:
          type: integer
          minimum: 0
      responses:
        '200':
          description: Plugins listed successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_PaginatedResult_PluginModel'
        '400':
          description: BadRequest
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_String'
              example:
                data: null
                error: Bad Request
                success: false
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_String'
              example:
                data: null
                error: Unauthorized
                success: false
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_String'
              example:
                data: null
                error: Plugin with ID plugin_id not found
                success: false
        '429':
          description: Too Many Requests
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_String'
              example:
                data: null
                error: Too Many Requests
                success: false
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_String'
              example:
                data: null
                error: Internal Server Error
                success: false
      security:
      - bearer_auth: []
  /api/v1/plugins/{plugin_id}:
    get:
      tags:
      - Plugins
      summary: Get plugin by ID
      operationId: getPlugin
      parameters:
      - name: plugin_id
        in: path
        description: The unique identifier of the plugin
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Plugin retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_PluginModel'
              example:
                data:
                  allow_get_invocation: false
                  config:
                    featureFlag: true
                  emit_logs: false
                  emit_traces: false
                  forward_logs: false
                  id: my-plugin
                  path: plugins/my-plugin.ts
                  raw_response: false
                  timeout: 30
                error: null
                success: true
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_String'
              example:
                data: null
                error: Unauthorized
                success: false
        '404':
          description: Plugin not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_String'
              example:
                data: null
                error: Plugin with id my-plugin not found
                success: false
        '429':
          description: Too Many Requests
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_String'
              example:
                data: null
                error: Too Many Requests
                success: false
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_String'
              example:
                data: null
                error: Internal Server Error
                success: false
      security:
      - bearer_auth: []
    patch:
      tags:
      - Plugins
      summary: Update plugin configuration
      description: 'Updates mutable plugin fields such as timeout, emit_logs, emit_traces,

        raw_response, allow_get_invocation, config, and forward_logs.

        The plugin id and path cannot be changed after creation.


        All fields are optional - only the provided fields will be updated.

        To clear the `config` field, pass `"config": null`.'
      operationId: updatePlugin
      parameters:
      - name: plugin_id
        in: path
        description: The unique identifier of the plugin
        required: true
        schema:
          type: string
      requestBody:
        description: Plugin configuration update. All fields are optional.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdatePluginRequest'
            example:
              config:
                apiKey: xyz123
                featureFlag: true
              emit_logs: true
              forward_logs: true
              timeout: 60
        required: true
      responses:
        '200':
          description: Plugin updated successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_PluginModel'
              example:
                data:
                  allow_get_invocation: false
                  config:
                    apiKey: xyz123
                    featureFlag: true
                  emit_logs: true
                  emit_traces: false
                  forward_logs: true
                  id: my-plugin
                  path: plugins/my-plugin.ts
                  raw_response: false
                  timeout: 60
                error: null
                success: true
        '400':
          description: Bad Request (invalid timeout or other validation error)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_String'
              example:
                data: null
                error: Timeout must be greater than 0
                success: false
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_String'
              example:
                data: null
                error: Unauthorized
                success: false
        '404':
          description: Plugin not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_String'
              example:
                data: null
                error: Plugin with id my-plugin not found
                success: false
        '429':
          description: Too Many Requests
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_String'
              example:
                data: null
                error: Too Many Requests
                success: false
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_String'
              example:
                data: null
                error: Internal Server Error
                success: false
      security:
      - bearer_auth: []
  /api/v1/plugins/{plugin_id}/call:
    get:
      tags:
      - Plugins
      summary: Execute a plugin via GET (must be enabled per plugin)
      description: 'This endpoint is disabled by default. To enable it for a given plugin, set

        `allow_get_invocation: true` in the plugin configuration.


        When invoked via GET:

        - `params` is an empty object (`{}`)

        - query parameters are passed to the plugin handler via `context.query`

        - wildcard route routing is supported the same way as POST (see `doc_call_plugin`)

        - Use the `route` query parameter or append the route to the URL path'
      operationId: callPluginGet
      parameters:
      - name: plugin_id
        in: path
        description: The unique identifier of the plugin
        required: true
        schema:
          type: string
      - name: route
        in: query
        description: Optional route suffix for custom routing (e.g., '/verify'). Alternative to appending the route to the URL path.
        required: false
        schema:
          type: string
      responses:
        '200':
          description: Plugin call successful
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_Value'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_String'
              example:
                data: null
                error: Unauthorized
                success: false
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_String'
              example:
                data: null
                error: Plugin with ID plugin_id not found
                success: false
        '405':
          description: Method Not Allowed (GET invocation disabled for this plugin)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_String'
              example:
                data: null
                error: 'GET requests are not enabled for this plugin. Set ''allow_get_invocation: true'' in plugin configuration to enable.'
                success: false
        '429':
          description: Too Many Requests
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_String'
              example:
                data: null
                error: Too Many Requests
                success: false
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_String'
              example:
                data: null
                error: Internal Server Error
                success: false
      security:
      - bearer_auth: []
    post:
      tags:
      - Plugins
      summary: Execute a plugin with optional wildcard route routing
      description: 'Logs and traces are only returned when the plugin is configured with `emit_logs` / `emit_traces`.

        Plugin-provided errors are normalized into a consistent payload (`code`, `details`) and a derived

        message so downstream clients receive a stable shape regardless of how the handler threw.


        The endpoint supports wildcard route routing, allowing plugins to implement custom routing logic:

        - `/api/v1/plugins/{plugin_id}/call` - Default endpoint (route = "")

        - `/api/v1/plugins/{plugin_id}/call?route=/verify` - Custom route via query parameter

        - `/api/v1/plugins/{plugin_id}/call/verify` - Custom route via URL path (route = "/verify")


        The route is passed to the plugin handler via the `context.route` field.

        You can specify a custom route either by appending it to the URL path or by using the `route` query parameter.'
      operationId: callPlugin
      parameters:
      - name: plugin_id
        in: path
        description: The unique identifier of the plugin
        required: true
        schema:
          type: string
      - name: route
        in: query
        description: Optional route suffix for custom routing (e.g., '/verify'). Alternative to appending the route to the URL path.
        required: false
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PluginCallRequest'
        required: true
      responses:
        '200':
          description: Plugin call successful
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_Value'
              example:
                data: done!
                error: null
                metadata:
                  logs:
                  - level: info
                    message: Plugin started...
                  traces:
                  - method: sendTransaction
                    relayerId: sepolia-example
                    requestId: 6c1f336f-3030-4f90-bd99-ada190a1235b
                success: true
        '400':
          description: BadRequest (plugin-provided)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_PluginHandlerError'
              example:
                data:
                  code: VALIDATION_FAILED
                  details:
                    field: email
                error: Validation failed
                metadata:
                  logs:
                  - level: error
                    message: 'Validation failed for field: email'
                success: false
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_String'
              example:
                data: null
                error: Unauthorized
                success: false
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_String'
              example:
                data: null
                error: Plugin with ID plugin_id not found
                success: false
        '429':
          description: Too Many Requests
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_String'
              example:
                data: null
                error: Too Many Requests
                success: false
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse_String'
              example:
                data: null
                error: Internal Server Error
                success: false
      security:
      - bearer_auth: []
components:
  schemas:
    LogEntry:
      type: object
      required:
      - level
      - message
      properties:
        level:
          $ref: '#/components/schemas/LogLevel'
        message:
          type: string
    PluginMetadata:
      type: object
      properties:
        logs:
          type:
          - array
          - 'null'
          items:
            $ref: '#/components/schemas/LogEntry'
        traces:
          type:
          - array
          - 'null'
          items: {}
    UpdatePluginRequest:
      type: object
      description: 'Request model for updating an existing plugin.

        All fields are optional to allow partial updates.

        Note: `id` and `path` are not updateable after creation.'
      properties:
        allow_get_invocation:
          type:
          - boolean
          - 'null'
          description: Whether to allow GET requests to invoke plugin logic
        config:
          type:
          - object
          - 'null'
          description: 'User-defined configuration accessible to the plugin (must be a JSON object)

            Use `null` to clear the config'
          additionalProperties: {}
          propertyNames:
            type: string
        emit_logs:
          type:
          - boolean
          - 'null'
          description: Whether to include logs in the HTTP response
        emit_traces:
          type:
          - boolean
          - 'null'
          description: Whether to include traces in the HTTP response
        forward_logs:
          type:
          - boolean
          - 'null'
          description: Whether to forward plugin logs into the relayer's tracing output
        raw_response:
          type:
          - boolean
          - 'null'
          description: Whether to return raw plugin response without ApiResponse wrapper
        timeout:
          type:
          - integer
          - 'null'
          format: int64
          description: Plugin timeout in seconds
          minimum: 0
      additionalProperties: false
    ApiResponse_PluginModel:
      type: object
      required:
      - success
      properties:
        data:
          type: object
          required:
          - id
          - path
          - timeout
          properties:
            allow_get_invocation:
              type: boolean
              description: Whether to allow GET requests to invoke plugin logic
            config:
              type:
              - object
              - 'null'
              description: User-defined configuration accessible to the plugin (must be a JSON object)
              additionalProperties: {}
              propertyNames:
                type: string
            emit_logs:
              type: boolean
              description: Whether to include logs in the HTTP response
            emit_traces:
              type: boolean
              description: Whether to include traces in the HTTP response
            forward_logs:
              type: boolean
              description: Whether to forward plugin logs into the relayer's tracing output
            id:
              type: string
              description: Plugin ID
            path:
              type: string
              description: Plugin path
            raw_response:
              type: boolean
              description: Whether to return raw plugin response without ApiResponse wrapper
            timeout:
              type: integer
              format: int64
              description: Plugin timeout
              minimum: 0
        error:
          type: string
        metadata:
          $ref: '#/components/schemas/PluginMetadata'
        pagination:
          $ref: '#/components/schemas/PaginationMeta'
        success:
          type: boolean
    LogLevel:
      type: string
      enum:
      - log
      - info
      - error
      - warn
      - debug
      - result
    ApiResponse_PluginHandlerError:
      type: object
      required:
      - success
      properties:
        data:
          type: object
          properties:
            code:
              type:
              - string
              - 'null'
            details: {}
        error:
          type: string
        metadata:
          $ref: '#/components/schemas/PluginMetadata'
        pagination:
          $ref: '#/components/schemas/PaginationMeta'
        success:
          type: boolean
    ApiResponse_PaginatedResult_PluginModel:
      type: object
      required:
      - success
      properties:
        data:
          type: object
          required:
          - items
          - total
          - page
          - per_page
          properties:
            items:
              type: array
              items:
                type: object
                required:
                - id
                - path
                - timeout
                properties:
                  allow_get_invocation:
                    type: boolean
                    description: Whether to allow GET requests to invoke plugin logic
                  config:
                    type:
                    - object
                    - 'null'
                    description: User-defined configuration accessible to the plugin (must be a JSON object)
                    additionalProperties: {}
                    propertyNames:
                      type: string
                  emit_logs:
                    type: boolean
                    description: Whether to include logs in the HTTP response
                  emit_traces:
                    type: boolean
                    description: Whether to include traces in the HTTP response
                  forward_logs:
                    type: boolean
                    description: Whether to forward plugin logs into the relayer's tracing output
                  id:
                    type: string
                    description: Plugin ID
                  path:
                    type: string
                    description: Plugin path
                  raw_response:
                    type: boolean
                    description: Whether to return raw plugin response without ApiResponse wrapper
                  timeout:
                    type: integer
                    format: int64
                    description: Plugin timeout
                    minimum: 0
            page:
              type: integer
              format: int32
              minimum: 0
            per_page:
              type: integer
              format: int32
              minimum: 0
            total:
              type: integer
              format: int64
              minimum: 0
        error:
          type: string
        metadata:
          $ref: '#/components/schemas/PluginMetadata'
        pagination:
          $ref: '#/components/schemas/PaginationMeta'
        success:
          type: boolean
    PaginationMeta:
      type: object
      required:
      - current_page
      - per_page
      - total_items
      properties:
        current_page:
          type: integer
          format: int32
          minimum: 0
        per_page:
          type: integer
          format: int32
          minimum: 0
        total_items:
          type: integer
          format: int64
          minimum: 0
    PluginCallRequest:
      type: object
      properties:
        params:
          description: Plugin parameters. If not provided, the entire request body will be used as params.
    ApiResponse_String:
      type: object
      required:
      - success
      properties:
        data:
          type: string
        error:
          type: string
        metadata:
          $ref: '#/components/schemas/PluginMetadata'
        pagination:
          $ref: '#/components/schemas/PaginationMeta'
        success:
          type: boolean
    ApiResponse_Value:
      type: object
      required:
      - success
      properties:
        data: {}
        error:
          type: string
        metadata:
          $ref: '#/components/schemas/PluginMetadata'
        pagination:
          $ref: '#/components/schemas/PaginationMeta'
        success:
          type: boolean
  securitySchemes:
    bearer_auth:
      type: http
      scheme: bearer