PIMSYNC.CONF(5)
πΈ NAME πΈ
pimsync.conf β the configuration file for pimsync(1). Yes bestie, this is the pimsync.conf(5) manual page, and it's giving βyour sync setup's main character energyβ π
β¨ DESCRIPTION β¨
Okay so pimsync.conf is split into three main types of sections, and this is the vibe check:
- βGLOBAL CONFIGURATIONβ β global settings for
pimsync. - βSTORAGE SECTIONSβ β configuration for individual storages.
- βPAIR SECTIONSβ β rules for synchronising pairs of storages.
See pimsync(1) for the details on the default path for the configuration file, and how to specify an alternative path. iykyk π«Ά
π GLOBAL CONFIGURATION π
These are the settings you can set globally, bestie:
status_path pathβ path to a directory which will contain the status database internally used bypimsync. Supports DYNAMIC PARAMETERS (see below). π
π STORAGE SECTIONS π
A storage describes a location where calendars or contacts are stored. Each storage is declared in its own section, and each storage section starts with a declaration of the storage name. Iconic.
storage name {β¦}β declare a storage with name name.
Directives are declared inside the curly braces for each section, one per line. The following directives apply to all storage types:
type typeβ this directive must be the first directive in the storage block. Where type can be one of the following:vdir/icalendarβ a directory where each subdirectory represents a calendar. Each of these subdirectories contains individual icalendar files, each representing one event (or one series of recurring events), todo or journal entry.vdir/vcardβ a directory where each subdirectory represents an address book. Each of these subdirectories contains individual vcard files, each representing one contact.caldavβ a CalDAV server, containing calendars with events, todos and/or journal entries.carddavβ a CardDAV server containing address books with contacts.webcalβ an HTTP or HTTPS resource exposing a single iCalendar file which may contain zero or more events, todos or journal entries. This storage type is read-only.jmap/icalendarβ a JMAP server with Calendar support. This storage is experimental.jmap/vcardβ a JMAP server with Calendar support. This storage is experimental.
interval secondsβ when monitoring a storage is not possible, check for changes every the specified amount of seconds. If set to zero, interval-based synchronisations are disabled. The default is300seconds. πauth basic | digestβ authentication method to use. The default isbasicand does not need to be specified.read_onlyβ do not perform any write operations on this storage. This directive takes no parameters. π«
Storages of type vdir take the following directives:
path pathβ path to a directory storing a vdir. A leading tilde will be expanded to match the current user's home directory. Supports DYNAMIC PARAMETERS (see below).fileext extensionβ optional. File extension for items saved into this vdir. If not specified,icsis used for calendar storages andvcfis used for address book storages.
Storages of type caldav or carddav accept the following directives:
url urlβ URL of the Dav server. If this URL does not report the appropriate DAV capabilities, service discovery will be performed for this URL and its domain to find the exact location of the server and the home set collection.
URLs must specify scheme http, https. or unix. URLs starting in unix:// shall be treated as a path to a unix domain socket.
Supports DYNAMIC PARAMETERS (see below).
username usernameβ optional. Username to use for HTTP Basic Auth. Supports DYNAMIC PARAMETERS (see below).password passwordβ optional. Password to use for HTTP Basic Auth. Supports DYNAMIC PARAMETERS (see below).collection_id_segment last | second-lastβ optional. URL path segment to use as the collection id. Valid values arelast(the default) orsecond-last. See the advanced usage documentation for details. π
Storages of type webcal take the following directives:
url urlβ URL of an icalendar file. This file may contain multiple calendar items. Scheme must behttporhttps. Supports DYNAMIC PARAMETERS (see below).collection_id nameβ name to be used when mapping this collection to another on the other storage.
Storages of type jmap take the following directives:
url urlβ base URL of the JMAP server. Supports DYNAMIC PARAMETERS (see below).username usernameβ optional. Username to use for HTTP Basic Auth. Supports DYNAMIC PARAMETERS (see below).password passwordβ optional. Password to use for HTTP Basic Auth. Supports DYNAMIC PARAMETERS (see below).
Storages of type caldav, carddav, webcal and jmap also accept the following directives:
user_agent user_agentβ optional. Set the User-Agent header to user_agent for outgoing HTTP requests. The default usespimsync/followed by the current version number. E.g.:pimsync/1.0.0.tls_root pathβ optional. Use the certificate root store at path when checking the server's TLS certificate. Disables checking the certificate against the system certificate authorities. Seetls_fingerprintbelow.tls_fingerprint fingerprintβ optional. Accept the certificate if its fingerprint matches fingerprint. If specified together with thetls_rootdirective, the certificate is verified with the specified root. Iftls_rootis not specified, the server's certificate is not validated against any root and only a fingerprint verification is performed. β οΈauth_cert certificate keyβ optional. Use the provided certificate and key for TLS client authentication.auth_cert pem_bundleβ optional. Use the certificate and key from the specified bundle for TLS client authentication.
π¦ DYNAMIC PARAMETERS π¦
The url, username, password, and path fields may be defined in the configuration file, or may specify a block with a command to retrieve this value from an external system. When specifying an external command, instead of defining a value for the directive, specify a new block with a single cmd directive. No cap, it's that flexible. β¨
For example, to read a password via the external command secret-store --get-caldav-password, use the following syntax:
password {
cmd secret-store --get-caldav-password
}
It is also possible to specify a shell script, which is executed via sh -c. For example:
password {
shell pass show communication/migadu.com | head -1
}
It is recommended to store credentials and other sensitive values in a secret storage service. Please bestie, do not leave your secrets lying around like last season's fit. π
π PAIR SECTIONS π
A pair declares how two storages shall be synchronised to each other. Each pair section starts with a declaration of the pair name:
pair name {β¦}β declare a pair with name name.
Each pair is defined by a block of directives, one per line, enclosed in curly braces:
storage_a nameβ the name of the first storage to be synchronised with another.storage_b nameβ the name of the second storage to be synchronised with the other.collections allβ synchronise all collections found in both storages. Collections will be synchronised to others with a matching id on the other side. This is the recommended value if you simply want to synchronise all collections from both storages. π―collections from aβ synchronise all collections found instorage_a. Each collection shall be synchronised with the collection which has the same collection id onstorage_b.collections from bβ synchronise all collections found instorage_b. Each collection shall be synchronised with the collection which has the same collection id onstorage_a.collection idβ synchronise collection with id id. May be specified more than once.collection file ... {β¦}β synchronise collection defined by the given rules. See βCOLLECTION SECTIONSβ below. May be specified more than once.on_empty skipβ when a collection is completely emptied on one side, skip it. This is the default.on_empty syncβ when a collection is completely emptied on one side, empty its counterpart on the other side. Take care when using this option. If you completely delete a collection on one side,pimsync.confwon't restore it. Instead, it will delete the same collection (and all of its items) on the other side. πon_delete syncβ when a collection itself is deleted on one side, delete it on the other side. This only applies if the collection is already empty. This is the default. This is generally safe, especially when combined withon_empty skip.on_delete skipβ when a collection itself is deleted on one side, skip it.one_wayβ synchronise items fromstorage_atostorage_bonly. Changes instorage_bare overwritten with the data fromstorage_a. Items created instorage_bthat do not exist instorage_aare deleted. This mode never produces conflicts. This directive takes no parameters. π
The conflict_resolution directive specifies which action should be taken if an item was modified on both sides. This directive has no effect when using synchronising one-way.
conflict_resolution cmd command [args]β execute command to resolve conflicts between both sides. args will be passed as arguments, followed by the path to two files; one containing the data on storage a, and the other containing the data on storage b. The conflict will be considered resolved if and only if both files are the same when the command exits and the command exits with exit code zero.conflict_resolution keep aβ in case of conflict, keep the version for storage a.conflict_resolution keep bβ in case of conflict, keep the version for storage b.
ποΈ COLLECTION SECTIONS
okay so a collections block is literally you drawing a line between two collections that are gonna be synced β one lives in storage_a, the other lives in storage_b. cute, right? π
bestie listen, these sections are only for the advanced configurations β the ones that need to map already-existing collections to each other without moving them anywhere on either side. no relocating, no drama, they stay exactly where they are. π«Ά
Every single block must include an alias:
aliasname β an alias for this pair of collections, and it's the name that shows up in any output. that's its whole job. β¨
Then you need exactly one reference to a collection over in storage_a:
id_aid β use the collection with the id id.href_ahref β use the collection with the path href.
And exactly one reference to a collection over in storage_b:
id_bid β use the collection with the id id.href_bhref β use the collection with the path href.
so like, for example, if you wanna sync a collection with id work against another one at path /calendars/mine/work/, you'd go:
collection {
alias work
id_a work
href_b /calendars/mine/work/
}
π¨ Specifying anidand anhreffor the same storage is not allowed. pick one, bestie. no cap. π
π COLLECTION ID
Right so, the id of a collection? that's a concept that's specific to pimsync(1) and vdirsyncer(1). iykyk. π
- For vdir storages, the id of a collection is the name of the directory that corresponds to it. simple as. π
- For caldav or carddav storages, the id of a collection is the last component of its URL by default. and yes you can change that β just point the
collection_id_segmentconfiguration directive at the second-to-last component instead. main character energy tbh. β¨ - For webcal storages, the id must be specified explicitly via the
collection_idconfiguration directive. no defaults here, you have to say it out loud. π
And unless you've configured it otherwise, collections with the same id on both storages get synced with each other. matching ids = matching vibes. ππ
π EXAMPLES
π contacts, but make it both local and remote
This example synchronises two storages with address books. The first is a local set of directories which contain vCard files, the second is a remote CardDAV servers. Credentials are supplied via the hiq(1) command line tool. π
status_path "~/.local/share/pimsync/status/"
pair contacts {
storage_a contacts_local
storage_b contacts_remote
collections all
conflict_resolution cmd nvim -d
}
storage contacts_local {
type vdir/vcard
path ~/.local/share/contacts/cards/
fileext vcf
interval 30
}
storage contacts_remote {
type carddav
url https://carddav.example.com/
username hugo@example.com
password {
cmd hiq -dFpassword proto=carddavs username=hugo@example.com
}
interval 30
}
π calendars, local dirs vs remote CalDAV
The following example synchronises two storages with calendar data. The first is local directories with iCalendar files, the second is a remote CalDAV servers. πΈ
status_path "~/.local/share/pimsync/status/"
pair calendars {
storage_a calendars_local
storage_b calendars_remote
collections from b
conflict_resolution cmd nvim -d
}
storage calendars_local {
type vdir/icalendar
path ~/.local/share/calendars/
fileext ics
interval 30
}
storage calendars_remote {
type caldav
url https://caldav.example.com/
username hugo@example.com
password {
cmd hiq -dFpassword proto=caldavs username=hugo@example.com
}
interval 30
}
π the italki situation (local dir + http-hosted iCalendar)
The following example synchronises two storages with calendar data. The first is a local directory named "italki" with iCalendar files, the second is an http server publishing an iCalendar file. π¦
π‘ Note that the first storage is the same as the one above, and should be specified only once if both configurations were specified in the same file. don't do the thing where you paste it twice, ok? π
The exact URL to the iCalendar file exposed via http is fetched via the hiq(1) tool, used to query the himitsu(7) secret store. π
status_path "~/.local/share/pimsync/status/"
pair study_calendars {
storage_a calendars_local
storage_b calendars_italki
collection italki
}
storage calendars_local {
type vdir/icalendar
path ~/.local/share/calendars/
fileext ics
interval 30
}
storage calendars_italki {
type webcal
collection_id italki
url {
cmd hiq -dFurl proto=webcal alias=italki-mine
}
}
π CardDAV over a Unix domain socket, plus local vCards
This example synchronises two storages with calendar data. The first is a CardDAV server, reached via a Unix domain socket. The second is storage uses a local filesystem with vCard files. socket girlies rise up π
status_path "~/.local/share/pimsync/status/"
pair unixtest {
storage_a unix_a
storage_b unix_b
collections all
}
storage unix_a {
type carddav
url unix:///tmp/xandikos.sock
}
storage unix_b {
type vdir/vcard
path /tmp/test_storage/
fileext vcf
}
π SEE ALSO
The configuration file follows the scfg syntax. See: https://git.sr.ht/~emersion/scfg
aaaand that's the whole page, bestie!! π you officially know everything about pimsync.conf(5). this was brought to you by PIMSYNC, version date 2025-04-14, tagged PIMSYNC.CONF(5) β go forth and sync iconically ππβ¨
π¦ where this page comes from
- alpine 3.24: pimsync-doc 0.5.10-r0 Β· EUPL-1.2
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms