A set of bindings to the Lemmy API, for Common Lisp
Implement macro to ease the defining of new api versions in asd file
Juggle metaclass implementation to fix file compilation
removed ignorable declaration for referenced variables


browse  log 



You can also use your local clone with git send-email.


This repository implements bindings to the Lemmy API.

Lemmy API interfaces, methods, enums, and types are defined according to the reference JS client implementation.

#Build Status

builds.sr.ht status


The main project page is available at https://sr.ht/~yana/cl-lemmy-api/. Bugs may be reported at https://todo.sr.ht/~yana/cl-lemmy-api/. The mailing list is used for patches and general discussion. The mailing list archives can be browsed at https://lists.sr.ht/~yana/cl-lemmy-api/.


Start by loading the ASDF system :LEMMY-API. This will load the most recent version of the api bindings, as parsed from the JS client sources. The API can now be interacted with by using the generic function LEMMY-API-OPERATE with an instance of a lemmy interface class, such as GET-POSTS. The instances of lemmy interface objects can be validated with the function VALIDATE-LEMMY-INTERFACE.

>>> (defun get-posts (server community)
     (lemmy-api-operate 'get-posts
                        (make-instance 'get-posts
                                       :community-name community
                                       :page 1
                                       :limit 20
                                       :sort 'new)

>>> (get-posts "https://myserver.com" "main")
#<LEMMY-INTERFACE "GetPostsResponse" {1003D3F093}>

>>> (car (posts *))
#<LEMMY-INTERFACE "PostView" {1004ECCA63}>

>>> (let ((post (post *)))
      (format t "~A~%~%~A~%" 
              (name post)
              (ignore-errors (body post))))
Some Title Here

With a text body here


Some slots are specified in in the typescript code as required but are not given by the server. These should be specified when calling VALIDATE-LEMMY-INTERFACE, or added to the dynamic variable *SLOTS-TO-IGNORE*. A non-comprehensive list is given at the end of this document. If you become aware of such errors, please submit a patch updating this list.

This system does not bind slots that dont have a value when generating them from a JSON response. As such, it may be helpful in certain circumstances to define custom accessors for specific slots, or alternatively to establish a handler for unbound slot errors that returns NIL when invoked with a lemmy-interface object. E.g.

(handler-bind ((unbound-slot
                (lambda (c)
                  (when (typep (unbound-slot-instance c) 'lemmy-interface)
                    (let ((r (find-restart 'use-value c)))
                      (when r
                        (invoke-restart r nil)))))))
  (code body))

Additionally, this system does not provide complete bindings. The current system of parsing bindings from the javascript sources is error prone; not all interfaces and methods parse correctly. The solution to this would be to generate an api specification from the rust sources using rust macros. While this is currently under consideration at time of writing, it appears there are numerous issues standing in the way of this. If you are interested in contributing to this endeavor, please see this issue as a starting point: https://github.com/LemmyNet/lemmy/issues/2937.


This project is broken up into three strata. The base system, LEMMY-API/BASE, defines the framework that allows interface objects to be implemented. This includes, among other things, the macros DEFINE-INTERFACE-CLASS and DEFINE-LEMMY-API-METHOD. The top level system provides a common package to expose symbols from other subsystems. In between these two is one of the versioned lemmy api systems, such as LEMMY-API/0.18.3. These contain the type, interface, and method definitions themselves, and gets USEd by LEMMY-API.

#Using Specific API Versions

The system LEMMY-API loads the latest version of the API bindings (at the time of writing this is v0.18.3), however alternate versions can be loaded by specifying the version number, e.g. LEMMY-API/0.18.3. The LEMMY-API package does not define or export any additional symbols, it is provided simply for ease of use, and the underlying versioned packages can be used in its stead.

The specific definition files for individual versions lie in the version/x.y.z/ folders. In addition, the specific version of the lemmy api currently loaded is pushed to the *FEATURES* list, and multiple versions of the api bindings can be loaded, as they reside in separate packages.


#Base System

#FILE: mop.lisp

This file defines the metaobject used for lemmy interface classes. The MOP is used to add additional parameters to slot definitions, which eases the conversion of slot values into and out of the JSON format, and allows for easier validation.

#FILE: interfaces.lisp

This file provides the interface definition macro and the validation function for interface objects.

#FILE: conditions.lisp

This file defines conditions used in the lemmy api system.

#FILE: json-to-interface.lisp

This file defines how interface objects will be parsed from JSON.

#FILE: interface-to-json.lisp

This file provides the inverse of json-to-interface.lisp.

#FILE: api-methods.lisp

This file provides the plumbing for sending and receiving information to and from a server. It defines the macro DEFINE-LEMMY-API-METHOD, as well as a host of helping functions.

#Versioned Systems

#FILE: versions/major.minor.patch/package.lisp

This file defines the specific versioned package, and registers the feature :LEMMY-API/MAJOR.MINOR.PATCH.

#FILE: versions/major.minor.patch/definitions.lisp

This file is generated automatically in two stages from the lemmy javascript client sources. First the javascript client sources are parsed into a specification file. These specifications are then used to generate the types, classes, and methods which reside in this file. In addition all types, class names, and accessors are exported.



#Slots to Ignore

  • v0.18.3