Services are declared using the service keyword.


A command service lets you run commands using vsl.

service clamscan cmd = #{
    timeout: "10s",
    command: "clamscan",
    args: ["--infected", "--remove", "--recursive", "/home/jdoe"],

// run the service.
// the command executed will be:
// clamscan --infected --remove --recursive /home/jdoe
// run the service with custom arguments (based one are replaced).
// clamscan --infected /home/another
clamscan.run_cmd([ "--infected", "/home/another" ]);


The db service, enables you to communicate with a database. Here we open a csv database with the ‘connector’ field.

service greylist db:csv = #{
    connector: "/db/user_accounts.csv",
    access: "O_RDONLY",
    refresh: "always",
    delimiter: ",",

// query & update the database.
let john = greylist.get("john");
greylist.set(["new", "user", ""]);

// manipulating a record.

// ["john", "doe", ""]

// records are stored in vsl arrays.
// to get a field in a record, simply use it's index.

// ""


The smtp service enables you to use the delegate directive to delegate the email to another service via the smtp protocol. Here we send the email to the clamsmtpd antivirus.

// -- service.vsl
service clamsmtpd smtp = #{
    delegator: #{
        address: "",
        timeout: "60s",
    receiver: "",

// -- main.vsl

// you cannot use `import "service" as service;` here because `service` is
// a reserved keyword.
import "service" as svc;

    postq: [
        // this will delegate the email using the `clamsmtpd` service.
        delegate svc::clamsmtpd "delegate antivirus processing" || {
            // this is executed after the delegation results have been
            // received on port 10024.

Check out the Services file to get access to the full list of functions for services.