diff --git a/simple_oauth.api.php b/simple_oauth.api.php
new file mode 100644
index 0000000..f8838d9
--- /dev/null
+++ b/simple_oauth.api.php
@@ -0,0 +1,33 @@
+<?php
+
+/**
+ * @file
+ * Hooks specific to the Simple OAuth module.
+ */
+
+/**
+ * @defgroup simple_oauth Simple Oauth: Hooks
+ * @{
+ */
+
+/**
+ * Alter the private claims to prepare convert to JWT token.
+ *
+ * @param $private_claims
+ *   The private claims array to be altered.
+ * @param \Drupal\simple_oauth\Entities\AccessTokenEntity $access_token_entity
+ *
+ * @see \Drupal\simple_oauth\Entities\AccessTokenEntity::convertToJWT()
+ */
+function hook_simple_oauth_private_claims_alter(&$private_claims, \Drupal\simple_oauth\Entities\AccessTokenEntity $access_token_entity) {
+  $user_id = $access_token_entity->getUserIdentifier();
+  $user = \Drupal\user\Entity\User::load($user_id);
+  $private_claims = [
+    'mail' => $user->getEmail(),
+    'username' => $user->getAccountName(),
+  ];
+}
+
+/**
+ * @} End of "defgroup simple_oauth".
+ */
diff --git a/src/Entities/AccessTokenEntity.php b/src/Entities/AccessTokenEntity.php
index 11c2859..3e87935 100644
--- a/src/Entities/AccessTokenEntity.php
+++ b/src/Entities/AccessTokenEntity.php
@@ -2,6 +2,10 @@
 
 namespace Drupal\simple_oauth\Entities;
 
+use Lcobucci\JWT\Builder;
+use Lcobucci\JWT\Signer\Key;
+use Lcobucci\JWT\Signer\Rsa\Sha256;
+use League\OAuth2\Server\CryptKey;
 use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
 use League\OAuth2\Server\Entities\Traits\AccessTokenTrait;
 use League\OAuth2\Server\Entities\Traits\EntityTrait;
@@ -11,4 +15,30 @@ class AccessTokenEntity implements AccessTokenEntityInterface {
 
   use AccessTokenTrait, TokenEntityTrait, EntityTrait;
 
+  /**
+   * {@inheritdoc}
+   */
+  public function convertToJWT(CryptKey $privateKey) {
+    $private_claims = [];
+    \Drupal::moduleHandler()->alter('simple_oauth_private_claims', $private_claims, $this);
+    $builder = (new Builder())
+      ->setAudience($this->getClient()->getIdentifier())
+      ->setId($this->getIdentifier(), TRUE)
+      ->setIssuedAt(time())
+      ->setNotBefore(time())
+      ->setExpiration($this->getExpiryDateTime()->getTimestamp())
+      ->setSubject($this->getUserIdentifier())
+      ->set('scopes', $this->getScopes());
+
+    if (!empty($private_claims)) {
+      foreach ($private_claims as $key => $value) {
+        $builder->set($key, $value);
+      }
+    }
+
+    $token = $builder->sign(new Sha256(), new Key($privateKey->getKeyPath(), $privateKey->getPassPhrase()))
+      ->getToken();
+    return $token;
+  }
+
 }
