diff --git a/tmgmt_supertext.module b/tmgmt_supertext.module
index 94eb5ea..c07f35e 100644
--- a/tmgmt_supertext.module
+++ b/tmgmt_supertext.module
@@ -5,6 +5,8 @@
  * Module file of the translation management test module.
  */
 
+require_once dirname(__FILE__) . '/tmgmt_supertext.ui_form.inc';
+
 /**
  * Implements hook_tmgmt_translator_plugin_info().
  */
@@ -197,49 +199,3 @@ function tmgmt_supertext_callback() {
 function tmgmt_supertext_hash($id) {
   return md5(drupal_get_hash_salt() . $id);
 }
-
-/**
- * Validation for api username. Only a validation and now error
- * because quoting is also possible withouth an api username
- *
- * @todo Implement the pluginSettingsFormValidate() function when
- * http://drupal.org/node/1416372 is commited.
- */
-function tmgmt_supertext_pluginsettingsform_validate_api_username($element, &$form_state, $form) {
-  if (empty($element['#value'])) {
-    drupal_set_message(t('To submit orders, you need to enter your Supertext email address.'), 'warning', FALSE);
-    return;
-  }
-}
-
-/**
- * Validation for api token. Only a validation and now error
- * because quoting is also possible withouth an api username.
- *
- * Also checks if the api settings are correct via Supertext.
- *
- * @todo Implement the pluginSettingsFormValidate() function when
- * http://drupal.org/node/1416372 is commited.
- */
-function tmgmt_supertext_pluginsettingsform_validate_api_token($element, &$form_state, $form) {
-  if (empty($element['#value'])) {
-    drupal_set_message(t('To submit orders, you need to enter your Supertext API Token.'), 'warning', FALSE);
-    return;
-  }
-
-  $plugin = tmgmt_translator_plugin_controller('supertext');
-  $translator = $form_state['tmgmt_translator'];
-  // This is a bit of a hack, otherwise we need to change the
-  // supertextHttpRequest function just for this case.
-  $translator->settings['api_username'] = $form_state['values']['settings']['api_username'];
-  $translator->settings['api_token'] = $form_state['values']['settings']['api_token'];
-  $response = $plugin->supertextHttpRequest('accountcheck', $translator, NULL, "GET");
-  if ($response->code == "200") {
-    if ($response->data == 'false') {
-      drupal_set_message(t('Your password or username is wrong.'), 'warning', FALSE);
-    }
-  }
-  else {
-    drupal_set_message(t("Couldn't check account data with Supertext. Response: @response<br />Check the log for more details.", array('@response' => $response->data)), 'warning', FALSE);
-  }
-}
diff --git a/tmgmt_supertext.plugin.inc b/tmgmt_supertext.plugin.inc
index 4101e50..5ad5c03 100644
--- a/tmgmt_supertext.plugin.inc
+++ b/tmgmt_supertext.plugin.inc
@@ -120,10 +120,22 @@ class TMGMTSupertextPluginController extends TMGMTDefaultTranslatorPluginControl
    * @param string $method
    *   With HTTP Method should be used. Default to POST.
    *
+   * @param array|null $credentials
+   *   An optional array with credentials to use. The array format should be:
+   *   array("api_username" => {username-string}, "api_token" => {token-string})
+   *
    * @return object
    *   Returns of drupal_http_request()
    */
-  public function supertextHttpRequest($service, TMGMTTranslator $translator, $dataobject = NULL, $method = "POST") {
+  public function supertextHttpRequest($service, TMGMTTranslator $translator, $dataobject = NULL, $method = "POST", $credentials = NULL) {
+    if (isset($credentials['api_username']) && isset($credentials['api_token'])) {
+      $api_username = $credentials['api_username'];
+      $api_token = $credentials['api_token'];
+    }
+    else {
+      list($api_username, $api_token) = $this->getCredentials($translator, TRUE);
+    }
+
     // Allow to use the internal mocking URL.
     if ($custom_url = $translator->getSetting('url')) {
       $url = $custom_url;
@@ -139,7 +151,7 @@ class TMGMTSupertextPluginController extends TMGMTDefaultTranslatorPluginControl
         'Content-Type' => 'application/json',
         'Accept' => 'application/json',
         'User-Agent' => 'Drupal Supertext Translation Interface v0.1',
-        'Authorization' => 'Basic ' . base64_encode($translator->getSetting('api_username') . ':' . $translator->getSetting('api_token'))),
+        'Authorization' => 'Basic ' . base64_encode($api_username . ':' . $api_token)),
     );
 
     if (isset($dataobject)) {
@@ -166,6 +178,95 @@ class TMGMTSupertextPluginController extends TMGMTDefaultTranslatorPluginControl
   }
 
   /**
+   * Validates Supertext credentials.
+   *
+   * @param TMGMTTranslator $translator
+   *   The translator entity.
+   * @param array $credentials
+   *   An array with credentials to use. The array format should be:
+   *   array("api_username" => {username-string}, "api_token" => {token-string})
+   *
+   * @return bool|null
+   */
+  public function checkCredentials(TMGMTTranslator $translator, $credentials) {
+    $response = $this->supertextHttpRequest('accountcheck', $translator, NULL, 'GET', $credentials);
+    if ($response->code == '200') {
+      if ($response->data == 'false') {
+        return FALSE;
+      }
+      elseif ($response->data == 'true') {
+        return TRUE;
+      }
+    }
+    return NULL;
+  }
+
+  /**
+   * Returns Supertext credentials.
+   *
+   * @param TMGMTTranslator $translator
+   *   The translator entity.
+   * @param bool $show_warnings
+   *   A boolean indicating whether warning messages should be shown to the user
+   *   in case if account is not set, or in case if the default account is used.
+   *
+   * @return array
+   *   The returning array has the following format:
+   *   array(0 => {username-string}, 1 => {token-string})
+   *   Both username and token are empty strings if account is not configured.
+   */
+  public function getCredentials(TMGMTTranslator $translator, $show_warnings = FALSE) {
+
+    // First try to get user-specific account.
+    if ($accounts = $translator->getSetting('accounts')) {
+      foreach ($accounts as $account) {
+        if ($account['drupal_username'] == $GLOBALS['user']->name) {
+          return array($account['account']['api_username'], $account['account']['api_token']);
+        }
+      }
+    }
+
+    // Fallback to the default account.
+    $api_username = trim($translator->getSetting('api_username'));
+    $api_token = trim($translator->getSetting('api_token'));
+    if ($api_username !== '' && $api_token !== '') {
+      if ($show_warnings) {
+        // This message is not so important, so we show it only for users who
+        // are able to edit translator settings.
+        if (entity_access('update', $translator->entityType(), $translator)) {
+          $translator_path = 'admin/config/regional/tmgmt_translator/manage/' . $translator->name;
+          if ($translator_path == current_path()) {
+            $message = t('The default Supertext email address and API token are used. You may want to setup per-user accounts.');
+          }
+          else {
+            $message = t('The default Supertext email address and API token are used. You may want to <a href="!url">setup per-user accounts</a>.', array(
+              '!url' => url($translator_path),
+            ));
+          }
+          drupal_set_message($message, 'warning', FALSE);
+        }
+      }
+      return array($api_username, $api_token);
+    }
+
+    // No configured accounts.
+    if ($show_warnings) {
+      // This message is pretty important. Show it always.
+      $translator_path = 'admin/config/regional/tmgmt_translator/manage/' . $translator->name;
+      if ($translator_path == current_path()) {
+        $message = t('To submit orders, you need to setup your Supertext email address and API token.');
+      }
+      else {
+        $message = t('To submit orders, you need to <a href="!url">setup your Supertext email address and API token</a>.', array(
+          '!url' => url($translator_path),
+        ));
+      }
+      drupal_set_message($message, 'warning', FALSE);
+    }
+    return array('', '');
+  }
+
+  /**
    *  Generates the Order Object needed by Supertext
    *
    *  @param TMGMTJob $job
diff --git a/tmgmt_supertext.ui.inc b/tmgmt_supertext.ui.inc
index 4818684..aa6d9b5 100644
--- a/tmgmt_supertext.ui.inc
+++ b/tmgmt_supertext.ui.inc
@@ -11,23 +11,102 @@
 class TMGMTSupertextTranslatorUIController extends TMGMTDefaultTranslatorUIController {
 
   /**
-   * Overrides TMGMTDefaultTranslatorUIController::settingsForm().
+   * {@inheritdoc}
    */
   public function pluginSettingsForm($form, &$form_state, TMGMTTranslator $translator, $busy = FALSE) {
+    /** @var TMGMTSupertextPluginController $plugin */
     $plugin = tmgmt_translator_plugin_controller($this->pluginType);
+
+    // Check if current user has Supertext account configured. If not, a warning
+    // message will be shown.
+    if (empty($form_state['values'])) {
+      $plugin->getCredentials($translator, TRUE);
+    }
+
+    // Accounts.
     $form['api_username'] = array(
       '#type' => 'textfield',
-      '#title' => t('Supertext email'),
+      '#title' => t('Default Supertext email'),
       '#default_value' => $translator->getSetting('api_username', ''),
       '#description' => t("Please enter the email address of your Supertext account."),
     );
     $form['api_token'] = array(
       '#type' => 'textfield',
-      '#title' => t('Supertext API Token'),
+      '#title' => t('Default Supertext API Token'),
       '#default_value' => $translator->getSetting('api_token', ''),
       '#description' => t('Please enter your API Token (You can get it from !link).', array('!link' => l(t('Supertext Account'), 'https://www.supertext.ch/customer/accountsettings.aspx'))),
 
     );
+    $form['accounts'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Per-user accounts'),
+      '#prefix' => '<div id="tmgmt-supertext-accounts-wrapper">',
+      '#suffix' => '</div>',
+    );
+    if (isset($form_state['values']['settings']['accounts'])) {
+      $accounts = $form_state['values']['settings']['accounts'];
+      $accounts = array_intersect_key($accounts, array_flip(array_filter(array_keys($accounts), 'is_int')));
+    }
+    else {
+      $accounts = $translator->getSetting('accounts');
+      $accounts = $accounts ? $accounts : array();
+      $accounts[] = array(
+        'drupal_username' => '',
+        'account' => array(
+          'api_username' => '',
+          'api_token' => '',
+        ),
+      );
+    }
+    foreach ($accounts as $index => $data) {
+      $form['accounts'][$index] = array(
+        '#type' => 'container',
+        '#attributes' => array(
+          'class' => array('supertext-user-account'),
+        ),
+      );
+      $form['accounts'][$index]['drupal_username'] = array(
+        '#type' => 'textfield',
+        '#title' => t('Drupal user'),
+        '#default_value' => $data['drupal_username'],
+        '#autocomplete_path' => 'user/autocomplete',
+        '#size' => 40,
+      );
+      $form['accounts'][$index]['account'] = array(
+        '#type' => 'container',
+        '#attributes' => array(
+          'class' => array('form-item'),
+        ),
+      );
+      $form['accounts'][$index]['account']['api_username'] = array(
+        '#type' => 'textfield',
+        '#title' => t('Supertext email'),
+        '#default_value' => $data['account']['api_username'],
+        '#size' => 40,
+      );
+      $form['accounts'][$index]['account']['api_token'] = array(
+        '#type' => 'textfield',
+        '#title' => t('Supertext API Token'),
+        '#default_value' => $data['account']['api_token'],
+        '#size' => 40,
+      );
+    }
+    $form['accounts']['add_more'] = array(
+      '#type' => 'submit',
+      '#value' => t('Add more'),
+      '#submit' => array('tmgmt_supertext_controller_add_more_submit'),
+      '#ajax' => array(
+        'callback' => 'tmgmt_supertext_controller_add_more_callback',
+        'wrapper' => 'tmgmt-supertext-accounts-wrapper',
+      ),
+      '#limit_validation_errors' => array(array('settings', 'accounts')),
+    );
+    $form['#attached']['css'][] = array(
+      'data' => '.supertext-user-account .form-item { display: inline-block; }',
+      'type' => 'inline',
+    );
+
+    // Other settings.
     $form['currency'] = array(
       '#type' => 'select',
       '#title' => t('Your default currency'),
diff --git a/tmgmt_supertext.ui_form.inc b/tmgmt_supertext.ui_form.inc
new file mode 100644
index 0000000..b2d388e
--- /dev/null
+++ b/tmgmt_supertext.ui_form.inc
@@ -0,0 +1,123 @@
+<?php
+
+/**
+ * @file
+ * Form callbacks and alter hooks for the Supertext UI form.
+ */
+
+/**
+ * Add-more submit callback for the per-user accounts.
+ */
+function tmgmt_supertext_controller_add_more_submit($form, &$form_state) {
+  $form_state['values']['settings']['accounts'][] = array(
+    'drupal_username' => '',
+    'account' => array(
+      'api_username' => '',
+      'api_token' => '',
+    ),
+  );
+  $form_state['rebuild'] = TRUE;
+}
+
+/**
+ * Add-more callback for the per-user accounts.
+ */
+function tmgmt_supertext_controller_add_more_callback($form, $form_state) {
+  return $form['plugin_wrapper']['settings']['accounts'];
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ */
+function tmgmt_supertext_form_tmgmt_translator_form_alter(&$form, &$form_state) {
+  /** @var TMGMTTranslator $translator */
+  $translator = $form_state['tmgmt_translator'];
+  if ($translator->plugin == 'supertext') {
+    $form['#validate'][] = '_tmgmt_supertext_translator_form_validate';
+    // Add our submit callback before the default one.
+    array_unshift($form['#submit'], '_tmgmt_supertext_translator_form_submit');
+  }
+}
+
+/**
+ * Validate callback for the Supertext UI form.
+ */
+function _tmgmt_supertext_translator_form_validate(&$form, &$form_state) {
+  /** @var TMGMTTranslator $translator */
+  $translator = $form_state['tmgmt_translator'];
+  /** @var TMGMTSupertextPluginController $controller */
+  $controller = $translator->getController();
+  $plugin_settings_form =& $form['plugin_wrapper']['settings'];
+
+  // Trim and validate per-user accounts.
+  foreach ($form_state['values']['settings']['accounts'] as $key => &$data) {
+    if (!is_int($key)) {
+      continue;
+    }
+    $data['drupal_username'] = trim($data['drupal_username']);
+    $data['account']['api_username'] = trim($data['account']['api_username']);
+    $data['account']['api_token'] = trim($data['account']['api_token']);
+    if ($data['drupal_username'] === '' && $data['account']['api_username'] === '' && $data['account']['api_token'] === '') {
+      continue;
+    }
+    if ($data['drupal_username'] === '') {
+      form_error($plugin_settings_form['accounts'][$key]['drupal_username'], t('Please enter user name.'));
+    }
+    elseif (!user_load_by_name($data['drupal_username'])) {
+      form_error($plugin_settings_form['accounts'][$key]['drupal_username'], t('User %user is not found.', array('%user' => $data['drupal_username'])));
+    }
+    if ($data['account']['api_username'] === '' && $data['account']['api_token'] !== '') {
+      form_error($plugin_settings_form['accounts'][$key]['account']['api_username'], t('Please enter Supertext email.'));
+    }
+    elseif ($data['account']['api_username'] !== '' && $data['account']['api_token'] === '') {
+      form_error($plugin_settings_form['accounts'][$key]['account']['api_token'], t('Please enter Supertext API Token.'));
+    }
+    else {
+      $result = $controller->checkCredentials($translator, $data['account']);
+      if ($result === FALSE) {
+        form_error($plugin_settings_form['accounts'][$key]['account'], t('Email or token is not valid.'));
+      }
+      elseif ($result === NULL) {
+        drupal_set_message('Unable to connect to the Supertext server to check the email and API token. Check the log for more details.', 'warning', FALSE);
+      }
+    }
+  }
+  unset($data);
+
+  // Trim and validate the default account.
+  $form_state['values']['settings']['api_username'] = trim($form_state['values']['settings']['api_username']);
+  $form_state['values']['settings']['api_token'] = trim($form_state['values']['settings']['api_token']);
+  if ($form_state['values']['settings']['api_username'] === '' && $form_state['values']['settings']['api_token'] !== '') {
+    form_error($plugin_settings_form['api_username'], t('Please enter Supertext email.'));
+  }
+  elseif ($form_state['values']['settings']['api_username'] !== '' && $form_state['values']['settings']['api_token'] === '') {
+    form_error($plugin_settings_form['api_token'], t('Please enter Supertext API Token.'));
+  }
+  elseif ($form_state['values']['settings']['api_username'] !== '' && $form_state['values']['settings']['api_token'] !== '') {
+    $result = $controller->checkCredentials($translator, $form_state['values']['settings']);
+    if ($result === FALSE) {
+      form_error($plugin_settings_form['api_username'], t('Default email or token is not valid.'));
+      form_error($plugin_settings_form['api_token'], t('Default email or token is not valid.'));
+    }
+    elseif ($result === NULL) {
+      drupal_set_message('Unable to connect to the Supertext server to check the email and API token. Check the log for more details.', 'warning', FALSE);
+    }
+  }
+}
+
+/**
+ * Submit callback for the Supertext UI form.
+ */
+function _tmgmt_supertext_translator_form_submit(&$form, &$form_state) {
+  // Clean up per-user accounts.
+  foreach ($form_state['values']['settings']['accounts'] as $key => $data) {
+    if (!is_int($key)) {
+      unset($form_state['values']['settings']['accounts'][$key]);
+      continue;
+    }
+    if ($data['drupal_username'] === '' && $data['account']['api_username'] === '' && $data['account']['api_token'] === '') {
+      unset($form_state['values']['settings']['accounts'][$key]);
+    }
+  }
+  $form_state['values']['settings']['accounts'] = array_values($form_state['values']['settings']['accounts']);
+}
