# JSON Web Tokens (JWTs)

A JSON Web Token, or JWT, is an [open standard](https://tools.ietf.org/html/rfc7519) for securely sharing information as a JSON object. JWTs are small enough to be used in a GET or POST parameter or an HTTP header, and because they are digitally signed, the information inside can be trusted.

JWTs can be generated using a library. Options can be found on [JWT.io](https://jwt.io/#libraries-io) or [GitHub](https://github.com/search?utf8=%E2%9C%93\&q=json+web+token\&type=Repositories\&ref=searchresults).

{% stepper %}
{% step %}

### Collect the data object

Whether you are using a JWT with UTT or the Open Endpoints, you will need to start with the data object that you are trying to sign.

For Advocate implementations, `id` and `accountId` will always be set to the same thing.

{% tabs %}
{% tab title="JSON" %}

```json
{
  "id": "john@example.com",
  "accountId": "john@example.com",
  "firstName": "John",
  "lastName": "Doe",
  "email": "john@example.com",
  "locale": "en_US"
}
```

{% endtab %}
{% endtabs %}

{% hint style="success" %}
**Note:** The `id` and `accountId` fields should be replaced with your own unique identifier for this user. The value used will be dependent on your implementation.
{% endhint %}
{% endstep %}

{% step %}

### Assemble the JWT payload

The JWT payload structures the data trying to be signed in this format:

{% tabs %}
{% tab title="JSON" %}

```json
{  
  "user":{  
    "id": "john@example.com", //This field will be dependent on your implementation
    "accountId": "john@example.com", //This field will be dependent on your implementation
    "firstName": "John",  
    "lastName": "Doe",  
    "email": "john@example.com",  
    "locale": "en_US"  
  }  
}
```

{% endtab %}
{% endtabs %}
{% endstep %}

{% step %}

### Sign the payload

Use your chosen library to build the JWT with the payload, and sign it with your [API key and Auth Token](https://integrations.impact.com/impact-brand/reference/authentication).

{% tabs %}
{% tab title="C#" %}

```csharp
// Example uses jose-jwt: https://github.com/dvsekhvalnov/jose-jwt

using System.Collections.Generic;
using System.Text;
using Jose;

namespace JwtExample
{
  class Jwt
  {
    // An example for building a user JWT.
    //   accountSid/authToken - your impact.com API credentials
    //   userId - your unique identifier for this user
    public static string BuildJwt(string accountSid, string authToken, string userId, string email, string firstName, string lastName)
    {
      // Build the user payload. Most fields are optional, but id and accountId are required 
      // and are set to the same value. See the API documentation for more fields that you 
      // can add to your users.
      var userPayload = new Dictionary<string, object>() {
        { "id", userId },           // required
        { "accountId", userId },    // required
        { "firstName", firstName }, // optional
        { "lastName", lastName },   // optional
        { "email", email }          // optional
      };

      // Expiry date is optional, but recommended
      var expiryDate = ((DateTimeOffset)DateTime.UtcNow.Date.AddDays(7)).ToUnixTimeSeconds();

      var payload = new Dictionary<string, object>() {
        { "user", userPayload },
        { "exp", expiryDate }
      };

      var headers = new Dictionary<string, object>() {
        { "typ", "JWT" },
        { "kid", accountSid }
      };

      var byteSecret = Encoding.UTF8.GetBytes(authToken);

      return Jose.JWT.Encode(payload, byteSecret, JwsAlgorithm.HS256, extraHeaders: headers);
    }
  }
}
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
# Example uses ruby-jwt: https://github.com/jwt/ruby-jwt

require "jwt"

# An example for building a user JWT.
#   accountSid/authToken - your impact.com API credentials
#   userId - your unique identifier for this user
def build_jwt(accountSid, authToken, userId, email, firstName, lastName)

  # Build the user payload. Most fields are optional, but id and accountId are required
  # and are set to the same value. See the API documentation for more fields that you
  # can add to your users.
  userPayload = {
    id: userId,            # required
    accountId: userId,     # required
    firstName: firstName,  # optional
    lastName: lastName,    # optional
    email: email,          # optional
  }

  # Expiry date is optional, but recommended
  expiryDate = Time.now.to_i + 7 * 24 * 3600

  payload = {
    user: userPayload,
    exp: expiryDate,
  }

  headers = {
    typ: "JWT",
    kid: accountSid,
  }

  return JWT.encode(payload, authToken, algorithm = "HS256", header_fields = headers)
end
```

{% endtab %}

{% tab title="Java" %}

```java
// Example uses nimbus-jose-jwt: https://bitbucket.org/connect2id/nimbus-jose-jwt/src/master/

import java.time.Duration;
import java.time.Instant;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JOSEObjectType;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;

public class Jwt {

  // An example for building a user JWT.
  //   accountSid/authToken - your impact.com API credentials
  //   userId - your unique identifier for this user
  public static String buildJwt(String accountSid, String authToken, String userId, String email, String firstName, String lastName) {

    // Build the user payload. Most fields are optional, but id and accountId are required.
    // See the API documentation for more fields that you can add to your users.
    final Map<String, Object> userPayload = new HashMap<>();
    userPayload.put("id", userId);           // required
    userPayload.put("accountId", userId);    // required
    userPayload.put("firstName", firstName); // optional
    userPayload.put("lastName", lastName);   // optional
    userPayload.put("email", email);         // optional

    // Expiry date is optional, but recommended
    Date expiryDate = Date.from(Instant.now().plus(Duration.ofDays(7)));

    final JWTClaimsSet claimsSet = new JWTClaimsSet.Builder()
      .claim("user", userPayload)
      .expirationTime(expiryDate)
      .build();

    final JWSHeader header = new JWSHeader.Builder(JWSAlgorithm.HS256)
      .type(JOSEObjectType.JWT)
      .keyID(accountSid)
      .build();

    final SignedJWT jwt = new SignedJWT(header, claimsSet);

    try {
      jwt.sign(new MACSigner(authToken));
    } catch (JOSEException e) {
      // This will happen if your secret is shorter than 256 bits.
      // If you are using your impact.com API keys, you won't need to worry about it.
      throw new RuntimeException(e);
    }

    return jwt.serialize();
  }

}
```

{% endtab %}

{% tab title="PHP" %}

```php
// Example uses php-jwt: https://github.com/firebase/php-jwt

use Firebase\JWT\JWT;

// An example for building a user JWT.
//   accountSid/authToken - your impact.com API credentials
//   userId - your unique identifier for this user
function buildJwt($accountSid, $authToken, $userId, $email, $firstName, $lastName)
{
    // Build the user payload. Most fields are optional, but id and accountId are required 
    // and are set to the same value. See the API documentation for more fields that you 
    // can add to your users.
    $userPayload = [
        "id" => $userId,           // required
        "accountId" => $userId,    // required
        "firstName" => $firstName, // optional
        "lastName" => $lastName,   // optional
        "email" => $email,         // optional
    ];
    
    // Expiry date is optional, but recommended
    $now = new DateTime();
    $expiryDate = $now->add(new DateInterval('P7D'))->getTimestamp();

    $payload = [
        "user" => $userPayload,
        "exp" => $expiryDate
    ];
    
    $headers = [
        "typ" => "JWT",
        "kid" => $accountSid
    ];

    return JWT::encode($payload, $authToken, 'HS256', null, $headers);
}
```

{% endtab %}

{% tab title="Python" %}

```python
# Example uses PyJWT: https://github.com/jpadilla/pyjwt/

import time
import jwt

# An example for building a user JWT.
#   accountSid/authToken - your impact.com API credentials
#   userId - your unique identifier for this user
def buildJwt(accountSid, authToken, userId, email, firstName, lastName):

    # Build the user payload. Most fields are optional, but id and accountId are required 
    # and are set to the same value. See the API documentation for more fields that you 
    # can add to your users.
    userPayload = {
        'id': userId,           # required
        'accountId': userId,    # required
        'firstName': firstName, # optional
        'lastName': lastName,   # optional
        'email': email          # optional
    }
    
    # Expiry date is optional, but recommended
    expiryDate = time.time() + 7 * 24 * 3600
    
    payload = {
        'user': userPayload,
        'exp': expiryDate
    }

    headers = {
        'typ': 'JWT',
        'kid': accountSid
    }
    
    return jwt.encode(payload, authToken, algorithm='HS256', headers=headers)
```

{% endtab %}
{% endtabs %}

For other fields that can be included in user objects, visit the [User Upsert API documentation](https://integrations.impact.com/impact-brand/reference/openuserupsert).
{% endstep %}

{% step %}

### Include the JWT with your calls

After creating a JWT, it must be included with all of your calls.

{% tabs %}
{% tab title="UTT" %}
Here’s an example of how a UTT call that includes the JWT would appear:

```javascript
<script>
  window.impactToken = "JWT_GOES_HERE";
</script>

<impact-embed widget="p/program-id/w/referrerWidget"></impact-embed>
```

{% endtab %}

{% tab title="Open Endpoint API Call" %}
For Open Endpoint API calls, the JWT must be included as a header with the key `X-SaaSquatch-User-Token`. cURL uses the `-H` flag to pass an extra header. You may specify any number of extra headers.

{% hint style="success" %}
**Note:** Open Endpoint API calls made from a server should be signed with your API key. Only Open Endpoint calls from a client should be signed with a JWT.
{% endhint %}

```http
curl -X POST 'https://app.referralsaasquatch.com/api/v1/{tenant_alias}/open/account/{accountId}/user/{userId}' \
  -H "X-SaaSquatch-User-Token: {X-SaaSquatch-User-Token}" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "john@example.com",
    "accountId": "john@example.com",
    "email": "john@example.com",
    "firstName": "John",
    "lastName": "Testerson",
    "locale": "en_US",
    "referralCode": "JOHNTESTERSON"
  }'
```

{% endtab %}
{% endtabs %}
{% endstep %}
{% endstepper %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://integrations.impact.com/integration-guides/for-brands/advocate/advocate-tracking-integrations/json-web-tokens-jwts.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
