diff --git a/README.md b/README.md
index b12cd434..ee563e65 100644
--- a/README.md
+++ b/README.md
@@ -10,20 +10,29 @@ This is all you need to use iot-cloud-cli for device **provisioning**:
 
 ## Set a configuration
 
-iot-cloud-cli needs to be configured before being used. In particular a client ID and the corresponding secret ID should be set.
+iot-cloud-cli needs a configuration file to be used. At the moment, the configuration file should be contained in the same directory where the cli commands are executed.
+The configuration file contains the Arduino IoT Cloud client ID and its corresponding secret.
 You can retrieve them from the [cloud](https://create.arduino.cc/iot/integrations) by creating a new API key.
 
-Once you have the IDs, call this command with your parameters:
+Once you have the IDs, call this command to init a new configuration file:
 
-`$ iot-cloud-cli config -c <clientID> -s <secretID>`
+`$ iot-cloud-cli config init`
 
-A file named `config.yaml` will be created in the Current Working Directory containing the login credentials.
-Example
+A file named `arduino-cloud.yaml` will be created in the current working directory. 
+Then you should open such file and replace the client and secret placeholders with the value you previously retrieved.
 
-```yaml
-client: 00112233445566778899aabbccddeeff
-secret: 00112233445566778899aabbccddeeffffeeddccbbaa99887766554433221100
-```
+
+To create a configuration file in a different folder, use this command:
+
+`$ iot-cloud-cli config init --dest-dir <destinationFolder>`
+
+To reset an old configuration file, just overwrite it using this command:
+
+`$ iot-cloud-cli config init --overwrite`
+
+Configuration file is supported in two different format: json and yaml. Use the `--config-format` to choose it. Default is yaml.
+
+`$ iot-cloud-cli config init --config-format json`
 
 ## Device provisioning
 
diff --git a/cli/config/config.go b/cli/config/config.go
index f2de8b18..2319dfb7 100644
--- a/cli/config/config.go
+++ b/cli/config/config.go
@@ -1,67 +1,17 @@
 package config
 
 import (
-	"os"
-	"strings"
-
-	"github.com/arduino/arduino-cli/cli/errorcodes"
-	"github.com/arduino/arduino-cli/cli/feedback"
-	paths "github.com/arduino/go-paths-helper"
-	"github.com/arduino/iot-cloud-cli/command/config"
-	"github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
-	"github.com/spf13/viper"
 )
 
-var configFlags struct {
-	file   string
-	client string
-	secret string
-}
-
 func NewCommand() *cobra.Command {
 	configCommand := &cobra.Command{
 		Use:   "config",
-		Short: "Set the configuration file",
-		Long:  "Set the configuration file to access Arduino IoT Cloud",
-		Run:   runConfigCommand,
-	}
-	configCommand.Flags().StringVarP(&configFlags.file, "file", "f", "", "Existing configuration yaml file")
-	configCommand.Flags().StringVarP(&configFlags.client, "client", "c", "", "Client ID")
-	configCommand.Flags().StringVarP(&configFlags.secret, "secret", "s", "", "Secret ID")
-	return configCommand
-}
-
-func runConfigCommand(cmd *cobra.Command, args []string) {
-	if configFlags.file == "" && (configFlags.client == "" || configFlags.secret == "") {
-		feedback.Error("Error during config: provide either a yaml file or credentials")
-		os.Exit(errorcodes.ErrGeneric)
+		Short: "Configuration commands.",
+		Long:  "Configuration commands.",
 	}
 
-	conf := viper.New()
+	configCommand.AddCommand(initInitCommand())
 
-	if configFlags.file != "" {
-		file := paths.New(configFlags.file)
-		filename := strings.TrimSuffix(file.String(), file.Ext())
-		conf.SetConfigName(filename)
-		conf.SetConfigType(strings.Trim(file.Ext(), "."))
-		conf.AddConfigPath(".")
-		err := conf.ReadInConfig()
-		if err != nil {
-			feedback.Errorf("Error during config: fatal error config file: %v", err)
-			os.Exit(errorcodes.ErrGeneric)
-		}
-
-	} else {
-		conf.BindPFlag("client", cmd.Flag("client"))
-		conf.BindPFlag("secret", cmd.Flag("secret"))
-	}
-
-	err := config.Config(conf)
-	if err != nil {
-		feedback.Errorf("Error during config: storing config file: %v", err)
-		os.Exit(errorcodes.ErrGeneric)
-	}
-
-	logrus.Info("Configuration file updated")
+	return configCommand
 }
diff --git a/cli/config/init.go b/cli/config/init.go
new file mode 100644
index 00000000..04446a90
--- /dev/null
+++ b/cli/config/init.go
@@ -0,0 +1,50 @@
+package config
+
+import (
+	"os"
+
+	"github.com/arduino/arduino-cli/cli/errorcodes"
+	"github.com/arduino/arduino-cli/cli/feedback"
+	"github.com/arduino/iot-cloud-cli/command/config"
+	"github.com/sirupsen/logrus"
+	"github.com/spf13/cobra"
+)
+
+var initFlags struct {
+	destDir   string
+	overwrite bool
+	format    string
+}
+
+func initInitCommand() *cobra.Command {
+	initCommand := &cobra.Command{
+		Use:   "init",
+		Short: "Initialize a configuration file with default values",
+		Long:  "Initialize an Arduino IoT Cloud CLI configuration file with default values",
+		Run:   runInitCommand,
+	}
+
+	initCommand.Flags().StringVar(&initFlags.destDir, "dest-dir", ".", "Sets where to save the configuration file.")
+	initCommand.Flags().BoolVar(&initFlags.overwrite, "overwrite", false, "Overwrite existing config file.")
+	initCommand.Flags().StringVar(&initFlags.format, "config-format", "yaml", "Format of the configuration file, can be {yaml|json}")
+
+	return initCommand
+}
+
+func runInitCommand(cmd *cobra.Command, args []string) {
+	logrus.Infof("Initializing a config file in folder: %s", initFlags.destDir)
+
+	params := &config.InitParams{
+		DestDir:   initFlags.destDir,
+		Overwrite: initFlags.overwrite,
+		Format:    initFlags.format,
+	}
+
+	err := config.Init(params)
+	if err != nil {
+		feedback.Errorf("Error during config init: %v", err)
+		os.Exit(errorcodes.ErrGeneric)
+	}
+
+	logrus.Info("Config file successfully initialized")
+}
diff --git a/command/config/config.go b/command/config/config.go
deleted file mode 100644
index d04744b6..00000000
--- a/command/config/config.go
+++ /dev/null
@@ -1,20 +0,0 @@
-package config
-
-import (
-	"github.com/arduino/arduino-cli/cli/feedback"
-	"github.com/spf13/viper"
-)
-
-// Config accepts a configured viper instance and
-// saves it into a specific config file.
-func Config(conf *viper.Viper) error {
-
-	// TODO: check if conf has the correct parameters
-	// e.g. 'client' and 'secret'
-
-	if err := conf.WriteConfigAs("config.yaml"); err != nil {
-		feedback.Errorf("Cannot create config file: %v", err)
-		return err
-	}
-	return nil
-}
diff --git a/command/config/init.go b/command/config/init.go
new file mode 100644
index 00000000..46123cfd
--- /dev/null
+++ b/command/config/init.go
@@ -0,0 +1,60 @@
+package config
+
+import (
+	"errors"
+	"fmt"
+	"strings"
+
+	"github.com/arduino/go-paths-helper"
+	"github.com/arduino/iot-cloud-cli/internal/config"
+	"github.com/spf13/viper"
+)
+
+// InitParams contains the parameters needed to initialize a configuration file.
+// DestDir - destination directory in which the configuration file will be saved.
+// Overwrite - specify if existing config file should be overwritten.
+// Format - the config file format, can be 'json' or 'yaml'.
+type InitParams struct {
+	DestDir   string
+	Overwrite bool
+	Format    string
+}
+
+func validateFormatString(arg string) error {
+	if arg != "json" && arg != "yaml" {
+		return errors.New("passed format is not valid, select between 'json' and 'yaml'")
+	}
+	return nil
+}
+
+// Init initializes a configuration file with default values.
+// If the file doesn't exist, it is created.
+// If it exists, it is written to only if overwrite param is true.
+func Init(params *InitParams) error {
+	configPath, err := paths.New(params.DestDir).Abs()
+	if err != nil {
+		return fmt.Errorf("%s: %w", "cannot retrieve absolute path of passed dest-dir", err)
+	}
+	if !configPath.IsDir() {
+		return fmt.Errorf("%s: %w", "passed dest-dir is not a valid directory", err)
+	}
+
+	params.Format = strings.ToLower(params.Format)
+	if err := validateFormatString(params.Format); err != nil {
+		return err
+	}
+
+	configFile := configPath.Join(config.Filename + "." + params.Format)
+
+	if !params.Overwrite && configFile.Exist() {
+		return errors.New("config file already exists, use --overwrite to discard the existing one")
+	}
+
+	newSettings := viper.New()
+	config.SetDefaults(newSettings)
+	if err := newSettings.WriteConfigAs(configFile.String()); err != nil {
+		return fmt.Errorf("cannot create config file: %v", err)
+	}
+
+	return nil
+}
diff --git a/internal/config/config.go b/internal/config/config.go
index 7805decd..ed3ee5d1 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -10,9 +10,9 @@ import (
 // known by iot-cloud-cli
 type Config struct {
 	// Client ID of the user
-	Client string `yaml:"client"`
+	Client string `map-structure:"client"`
 	// Secret ID of the user, unique for each Client ID
-	Secret string `yaml:"secret"`
+	Secret string `map-structure:"secret"`
 }
 
 // Retrieve returns the actual parameters contained in the
@@ -20,8 +20,7 @@ type Config struct {
 func Retrieve() (*Config, error) {
 	conf := &Config{}
 	v := viper.New()
-	v.SetConfigName("config")
-	v.SetConfigType("yaml")
+	v.SetConfigName(Filename)
 	v.AddConfigPath(".")
 	err := v.ReadInConfig()
 	if err != nil {
diff --git a/internal/config/default.go b/internal/config/default.go
new file mode 100644
index 00000000..b7f359c5
--- /dev/null
+++ b/internal/config/default.go
@@ -0,0 +1,15 @@
+package config
+
+import "github.com/spf13/viper"
+
+var (
+	Filename = "arduino-cloud"
+)
+
+// SetDefaults sets the default values for configuration keys
+func SetDefaults(settings *viper.Viper) {
+	// Client ID
+	settings.SetDefault("client", "xxxxxxxxxxxxxx")
+	// Secret
+	settings.SetDefault("secret", "xxxxxxxxxxxxxx")
+}