Generate a defmacro form that transforms code like this:
(define-api ensure-readtable (name &optional (default nil default-p)) (named-readtable-designator &optional (or named-readtable-designator null) => readtable) "Looks up the readtable specified by NAME and returns it if it's found. If it is not found, it registers the readtable designated by DEFAULT under the name represented by NAME; or if no default argument is given, it signals an error of type READTABLE-DOES-NOT-EXIST instead." (cond ((find-readtable name)) ((not default-p) (error 'readtable-does-not-exist :readtable-name name)) (t (setf (find-readtable name) (ensure-readtable default)))))

Pattern to recognize: Macro call that should be transformed by define-api

Macro definition:
(defmacro define-api (name lambda-list type-list &body body)
  (flet ((parse-type-list (type-list)
           (let ((pos (position '=> type-list)))
             (assert pos () "You forgot to specify return type (`=>' missing.)")
             (values (subseq type-list 0 pos)
                     `(values ,@(nthcdr (1+ pos) type-list) &optional)))))
    (multiple-value-bind (body decls docstring)
        (parse-body body :documentation t :whole `(define-api ,name))
      (multiple-value-bind (arg-typespec value-typespec)
          (parse-type-list type-list)
        (multiple-value-bind (reqs opts rest keys)
            (parse-ordinary-lambda-list lambda-list)
          (declare (ignorable reqs opts rest keys))
          `(progn
             (declaim (ftype (function ,arg-typespec ,value-typespec) ,name))
             (locally
                 ;; Muffle the annoying "&OPTIONAL and &KEY found in
                 ;; the same lambda list" style-warning
                 #+sbcl (declare (sb-ext:muffle-conditions style-warning))
               (defun ,name ,lambda-list
                 ,docstring
                 ,@decls
                 (locally
                     #+sbcl (declare (sb-ext:unmuffle-conditions style-warning))

                     ;; SBCL will interpret the ftype declaration as
                     ;; assertion and will insert type checks for us.
                     #-sbcl
                     (progn
                       ;; CHECK-TYPE required parameters
                       ,@(loop for req-arg in reqs
                               for req-type = (pop type-list)
                               do (assert req-type)
                               collect `(check-type ,req-arg ,req-type))

                       ;; CHECK-TYPE optional parameters
                       ,@(progn
                           (assert (or (null opts)
                                       (eq (pop type-list) '&optional)))
                           (loop for (opt-arg . nil) in opts
                                 for opt-type = (pop type-list)
                                 do (assert opt-type)
                                 collect `(check-type ,opt-arg ,opt-type)))

                       ;; CHECK-TYPE rest parameter
                       ,@(when rest
                           (assert (eq (pop type-list) '&rest))
                           (let ((rest-type (pop type-list)))
                             (assert rest-type)
                             `((dolist (x ,rest)
                                 (check-type x ,rest-type)))))

                       ;; CHECK-TYPE key parameters
                       ,@(progn
                           (assert (or (null keys)
                                       (eq (pop type-list) '&key)))
                           (loop for ((keyword key-arg)  . nil) in keys
                                 for (nil key-type) = (find keyword type-list
                                                            :key #'car)
                                 collect `(check-type ,key-arg ,key-type))))

                     ,@body)))))))))

Macroexpansion:
(progn (declaim (ftype (function (named-readtable-designator &optional (or named-readtable-designator null)) (values readtable &optional)) ensure-readtable)) (locally (declare (sb-ext:muffle-conditions style-warning)) (defun ensure-readtable (name &optional (default nil default-p)) "Looks up the readtable specified by NAME and returns it if it's found. If it is not found, it registers the readtable designated by DEFAULT under the name represented by NAME; or if no default argument is given, it signals an error of type READTABLE-DOES-NOT-EXIST instead." (locally (declare (sb-ext:unmuffle-conditions style-warning)) (cond ((find-readtable name)) ((not default-p) (error (quote readtable-does-not-exist) :readtable-name name)) (t (setf (find-readtable name) (ensure-readtable default))))))))