Bring your own Users and Accounts (with JWT)

Integrate Hull with your existing user management and automatically create and authenticate users in Hull.

Users and accounts can be authenticated with the API by using secure JSON Web Tokens (JWT).

In this scenario, you have your own user collection, and you want to track them. Tracking benefits from Single Sign-on across multiple domains.

Using Tokens with hull.js

To use server side generated tokens and log users in when hull.js is initialized, you can generate and sign a token server side and pass it to the Hull.init method.

Initialization via Snippet
Manual Javascript initialization
<script src=""></script>
   orgUrl: '',
   accessToken: token

Anatomy of a JWT Auth token

A valid JWT for use with hull MUST contain the following claims :

Mandatory claims :

  • iss : Identifier of the issuer of the token (Most of the time, it will be your Hull App ID)
  • iat : Unix timestamp of the date the token has been issued at
  • sub : Subject of the Token, it’s your Hull User’s ID

Optional claims :

  • exp : Unix timestamp of the expiration date for the token. After this date, the token will not be considered valid.
  • nbf: Unix timestamp of a date. The token will not be considered valid of used before this date.
  • io.hull.user INSTEAD OF the sub claim, to use a unique ID that you generate and manage.
  • io.hull.asUser INSTEAD OF the sub claim, to look for the best matching user.
  • io.hull.asAccount: INSTEAD OF the sub claim, to look for the best matching account.
  • io.hull.subjectType (string): Whether user or account. Indicate which object type you want to perform action on. Allow to retrieve a user’s account when used with a user identifier.
  • io.hull.create (boolean): used with io.hull.asUser|asAccount. If true and no user is found, a new user will be created with the properties listed in io.hull.asUser|asAccount. Default: true
  • (boolean) : Marks the user as active for the specified number of seconds. Allows to fast track recompute and notifications for that specific user while he remains active. Default: false
  • io.hull.scope (array) : adds scopes claim to the JWT to impersonate a User with admin rights. Currently, only supported value is [“admin”]

All JWTs MUST be signed with the secret of the issuer. App issued token must be signed with the App Secret that you can find in the App’s configuration page in Hull admin.

Making auth Transient or Permanent

If the exp claim is used in the token, all subsequent calls to Hull.init will need to include the accessToken option to keep the user logged in.

If the exp claim is not present, the token authentication will be considered “permanent” and hull will issue a cookie that will be used to keep the User logged in on subsequent page loads, even if the accessToken option is missing.

Using Tokens to authenticate users

If your application already has a User management system or if you want to migrate existing users to use Hull authentication, you can create special tokens that reference users with your own identifiers.

Those special tokens use an additional claim : io.hull.user (instead of the sub claim) which can contain those properties :

  • external_id {String} : required, A unique identifier for an existing User in your application.
  • created_at {DateTime}: optional, The creation date for the User. Defaults to Now.
  • password {String} : optional
  • email {String} : optional
  • username {String} : optional
  • name {String} : optional
  • picture {String} : optional, The User’s Avatar
  • extra {Object} : optional, A Free-form hash of data to store. Checkout Storing User-specific data for more info
  • approved {Boolean} : optional, If you require approval for your organization, pre-approves the user

Using Tokens to lookup users

If your develop a Hull connector and don’t have access to the user’s identifier, you can build a special token that will use a resolution strategy to find the best matching user.

Instead of using the io.hull.user claim, you should use the io.hull.asUser claim. Allowed properties include and will be resolved in that order :

  • external_id
  • email
  • anonymous_id

Example use with Ruby:

$ gem install hullio jwt

require 'jwt'
require 'hullio'

Hull.configure do |c|
  c.app_id     = "your-app-id"
  c.app_secret = "your-app-secret"
  c.org_url    = ""

user = User.find('1234') # Retrieve your user here.
userHash = {
  created_at : user.created_at,
  email      :,
  username   : user.username,
  name       :,
  picture    : user.picture,
  approved   : true,
  extra: {foo:'bar'}
token = Hull.user_token(user_hash)

userHash = { external_id: } # The second time around, you only need the external_id.
token = Hull.user_token(user_hash)

userHash = {external_id:, email: ''} # To update data for the user, pass the field again
token = Hull.user_token(user_hash) # Pass token to hull.js or use in Server-to-server api calls

It allows you to authenticate users with identifiers from your app without having to keep track of their Hull User ID.

If no User with a matching external_id is found, it will be created automatically.

If the User is found, he will be authenticated and updated with the additional properties passed via the io.hull.user.

Note: If an email is provided in the io.hull.user object, it will be considered as confirmed on the Hull User.

Using Tokens to lookup accounts

You can use the io.hull.asAccount claim to lookup an account using the following properties which will be resolved in that order :

  • external_id
  • domain

You can also lookup a user with any claim allowing to do that, and set the io.hull.subjectType claim to account to retrieve the matched user’s account.

Linking Users and Accounts

You can link a user to an account by providing both io.hull.asUser and io.hull.asAccount claims. The matched user and account will be linked. If no user and account match, they will be created.

When linking, you can choose if you want to retrieve the matched user or account by providing a io.hull.subjectType claim set to whether user or account.

Using Tokens with the REST API, server to server.

If you sign any API call with a JWT as described below, a User will be created on the fly if it can’t be found. For instance you could directly start creating comments on an entity with a User on your backend without any prior setup:

// npm install jwt-simple hull

import Hull from 'hull';

const client = new Hull({
  id: 'HULL_ID',
  secret: 'HULL_SECRET',

client.asUser({ external_id: "1234", email:'', name:'FooBar' }).token(optionalClaims);