diff --git a/tools/src/args.rs b/tools/src/args.rs
index 221e0b6ee67a3211709614938669d62597f0874c..3f18b6df2453605591d2ee2eabb431417418ad28 100644
--- a/tools/src/args.rs
+++ b/tools/src/args.rs
@@ -91,6 +91,8 @@ pub struct PkgsSync {
     pub pkgs: Vec<Pattern>,
     #[structopt(long="exclude")]
     pub excludes: Vec<Pattern>,
+    #[structopt(long)]
+    pub sync_method: Option<String>,
 }
 
 #[derive(Debug, StructOpt)]
diff --git a/tools/src/config.rs b/tools/src/config.rs
index 4f70d1b6f5a7865840c4fbb3593fe3da0fdd524d..1be5fa18a77991ab1232f992d975c7518456ac06 100644
--- a/tools/src/config.rs
+++ b/tools/src/config.rs
@@ -23,6 +23,7 @@ impl SyncConfigFile {
 #[derive(Debug, Deserialize)]
 pub struct SyncProfile {
     pub distro: String,
+    pub sync_method: Option<String>,
     pub suite: String,
     #[serde(default)]
     pub releases: Vec<String>,
diff --git a/tools/src/main.rs b/tools/src/main.rs
index 797d26030b6fe21f6f4e23524f3cdfeccf80b7a2..c195c9686b490c93f5895e328aa1952cc1de5774 100644
--- a/tools/src/main.rs
+++ b/tools/src/main.rs
@@ -36,11 +36,17 @@ fn print_json<S: Serialize>(x: &S) -> Result<()> {
 }
 
 pub async fn sync(client: &Client, sync: PkgsSync) -> Result<()> {
-    let mut pkgs = match sync.distro.as_str() {
+    let method = if let Some(method) = &sync.sync_method {
+        method.as_str()
+    } else {
+        sync.distro.as_str()
+    };
+
+    let mut pkgs = match method {
         "archlinux" => schedule::archlinux::sync(&sync).await?,
         "debian" => schedule::debian::sync(&sync).await?,
         "tails" => schedule::tails::sync(&sync).await?,
-        unknown => bail!("No integrated sync for {:?}, use sync-stdin instead", unknown),
+        unknown => bail!("No integrated sync for {:?}, use --sync-method or `pkgs sync-stdin` instead", unknown),
     };
     pkgs.sort_by(|a, b| a.name.cmp(&b.name));
 
@@ -130,6 +136,7 @@ async fn main() -> Result<()> {
 
             sync(client.with_auth_cookie()?, PkgsSync {
                 distro: profile.distro,
+                sync_method: profile.sync_method,
                 suite: profile.suite,
                 releases: profile.releases,
                 architectures: profile.architectures,
diff --git a/tools/src/schedule/archlinux.rs b/tools/src/schedule/archlinux.rs
index d0d009dad1306abe49c6454f7d864554c883ba88..17cb69f78d8f25116a8d64a9ecb25c977806f889 100644
--- a/tools/src/schedule/archlinux.rs
+++ b/tools/src/schedule/archlinux.rs
@@ -161,7 +161,7 @@ pub async fn sync(sync: &PkgsSync) -> Result<Vec<PkgGroup>> {
                 let mut group = PkgGroup::new(
                     pkg.base.clone(),
                     pkg.version,
-                    "archlinux".to_string(),
+                    sync.distro.to_string(),
                     sync.suite.to_string(),
                     pkg.architecture,
                     None,
diff --git a/tools/src/schedule/debian.rs b/tools/src/schedule/debian.rs
index 4f3c572b7f07cad44ceebdeb1506d5f7932e624b..d75bcd63eaf7f120b0e20a4fff64644f2c6a0f12 100644
--- a/tools/src/schedule/debian.rs
+++ b/tools/src/schedule/debian.rs
@@ -251,13 +251,13 @@ impl SyncState {
         SyncState::default()
     }
 
-    fn ensure_group_exists(&mut self, src: &DebianSourcePkg, suite: String, arch: &str) {
+    fn ensure_group_exists(&mut self, src: &DebianSourcePkg, distro: String, suite: String, arch: &str) {
         // TODO: creating a new group isn't always needed
         let buildinfo_url = src.buildinfo_url(arch);
         let new_group = PkgGroup::new(
             src.base.clone(),
             src.version.clone(),
-            "debian".to_string(),
+            distro,
             suite,
             arch.to_string(),
             Some(buildinfo_url),
@@ -276,8 +276,8 @@ impl SyncState {
         }
     }
 
-    fn get_mut_group(&mut self, src: &DebianSourcePkg, suite: String, arch: &str) -> &mut PkgGroup {
-        self.ensure_group_exists(src, suite, arch);
+    fn get_mut_group(&mut self, src: &DebianSourcePkg, distro: String, suite: String, arch: &str) -> &mut PkgGroup {
+        self.ensure_group_exists(src, distro, suite, arch);
 
         // ensure_group_exists ensures the group exists
         let list = self.groups.get_mut(&src.base).unwrap();
@@ -292,8 +292,8 @@ impl SyncState {
         unreachable!()
     }
 
-    pub fn push(&mut self, src: &DebianSourcePkg, bin: DebianBinPkg, source: &str, suite: String) {
-        let group = self.get_mut_group(src, suite, &bin.architecture);
+    pub fn push(&mut self, src: &DebianSourcePkg, bin: DebianBinPkg, source: &str, distro: String, suite: String) {
+        let group = self.get_mut_group(src, distro, suite, &bin.architecture);
         let url = format!("{}/{}/{}_{}_{}.deb",
             source,
             src.directory,
@@ -359,7 +359,7 @@ pub async fn sync(sync: &PkgsSync) -> Result<Vec<PkgGroup>> {
                 let src = sources.get(&pkg)?;
                 debug!("Matched binary package to source package: {:?} {:?}", src.base, src.version);
 
-                out.push(src, pkg, &sync.source, sync.suite.clone());
+                out.push(src, pkg, &sync.source, sync.distro.clone(), sync.suite.clone());
             }
         }
     }
diff --git a/tools/src/schedule/mod.rs b/tools/src/schedule/mod.rs
index 50a9bf5b82e536cc408a8e3e1c03fec3ad5d60d5..974d4ddffcb9763b58524e7da5345ceef0ab055e 100644
--- a/tools/src/schedule/mod.rs
+++ b/tools/src/schedule/mod.rs
@@ -68,6 +68,7 @@ mod tests {
     fn gen_filter(f: Filter) -> PkgsSync {
         PkgsSync {
             distro: "archlinux".to_string(),
+            sync_method: None,
             suite: "community".to_string(),
             architectures: vec!["x86_64".to_string()],
             source: "https://ftp.halifax.rwth-aachen.de/archlinux/$repo/os/$arch".to_string(),