> ## Documentation Index
> Fetch the complete documentation index at: https://docs.superoffice.com/llms.txt
> Use this file to discover all available pages before exploring further.

# How to get a system user ticket credential

> How to exchange a system user token for a system user ticket

To get the ticket, you must send a request containing a signed version of your system user token to the `partner system user service` endpoint.

The [system user token][1] is on of the claims in the `id_token` received the initial administrative authentication.

## Pre-requisites

* [Client secret][5] (obtained when application is registered)
* ContextIdentifier (tenant identity)
* [System user token][1] (application is authenticated)

There are several ways to obtain a system user ticket:

1. Use our REST API, or
2. Use one of our nuget packages

Both options require a signed version of the system user token. Please read the [How to sign a system user token][8] documentation to learn how to do that part of this flow.

## Use the REST API

SuperOffice CRM Online exposes one REST endpoint for conducting the exchange:

`https://{environment}.superoffice.com/Login/api/PartnerSystemUser/Authenticate`

The following example is demonstrates the HTTP request.

```http theme={null}
@signed_Token=YOUR_SIGNED_TOKEN
@client_Secret=YOUR_CLIENT_SECRET
@context_Identifier=YOUR_CUSTOMER_ID

POST https://{environment}.superoffice.com/Login/api/PartnerSystemUser/Authenticate
Content-Type: application/json
Accept: application/json

{
    "SignedSystemToken": "{{signed_Token}}",
    "ApplicationToken": "{{client_secret}}",
    "ContextIdentifier": "{{context_Identifier}}",
    "ReturnTokenType": "JWT"
}
```

## Use a nuget package

We provide the following .NET nuget packages to help perform the task.

### SuperOffice.WebApi (preferred)

* [SuperOffice.WebApi][9] (nuget)
* [Sample Code on GitHub][10]

## How to get system user ticket

The following example code has an extensive amount of logging to the console. This lets you see the output from each step. The final output is the system user ticket. It performs the following steps:

1. Read the partner's private PEM file.
2. [Sign system user token][8].
3. Send request to SuperOffice.
4. Gets the response to obtain the JWT.
5. [Validate JWT token][3].
6. Extract the system user ticket.

***

### REST

<Accordion title="NPM package.json file for NodeJS REST example.">
  ### package.json file

  ```json theme={null}
  {
    "name": "devnet-nodejs-systemuser-rest",
    "version": "1.0.0",
    "description": "Signs system user token and requests system user ticket",
    "main": "index.js",
    "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1",
      "start": "node index.js"
    },
    "author": "AnthonyYates",
    "license": "MIT",
    "dependencies": {
      "axios": "^0.26.1",
      "crypto": "^1.0.1",
      "jsonwebtoken": ">=9.0.0",
      "moment": "^2.22.2"
    }
  }
  ```
</Accordion>

### index.js code

```JavaScript index.js theme={null}
const crypto = require('crypto');
const moment = require('moment');
const fs = require('fs');
const axios = require('axios');
const jwt = require('jsonwebtoken');

// specify the environment
// sod      => development
// qastage  => stage
// online   => production
const env = 'sod';

// Partner Application Token (AKA Client Secret)
const appToken = 'YOUR_APPLICATION_TOKEN_GOES_HERE';

// Your Online Sandbox Customer Identifier
const contextId = 'Cust12345';

// SystemUserToken provided as a claim in the callback (Redirect URL)
// when a tenant administrator successfully signs into SuperID.
const systemToken = 'YOUR_SYSTEM_USER_TOKEN_GOES_HERE';

// Partners private key
const privKeyFile = 'privatekey.pem';

// SuperOffice public key (SOD) 
// Open SuperOfficeFederatedLogin.crt in notepad,
// save contents as SuperOfficeFederatedLogin.pem
const publKeyFile = 'SuperOfficeFederatedLogin.pem';

const getSystemUserTicket = async () => {
  try {
    const privateKeyFile = fs.readFileSync(privKeyFile,'utf8');
    const publicKeyFile  = fs.readFileSync(publKeyFile, 'utf8');
  
    // prepare the datetime stamp
    const utcTimestamp = moment.utc().format('YYYYMMDDHHmm');
    const data = `${systemToken}.${utcTimestamp}`;
    
    log('Token.Time: ' + data);
  
    // sign the System User token
    let sign = crypto.createSign('SHA256');
    sign.update(data);
    sign.end();
    sign = sign.sign(privateKeyFile, 'base64');
    const signedToken = `${data}.${sign}`;
    
    log('Signed Token: ' + signedToken);
  
    // send the request
  
    var postData = {
        'SignedSystemToken': `${signedToken}`,
        'ApplicationToken': `${appToken}`,
        'ContextIdentifier': `${contextId}`,
        'ReturnTokenType': 'JWT'
    };
    
    let axiosConfig = {
      headers: {
          'Content-Type': 'application/json;charset=UTF-8',
          "Accept": "application/json;charset=UTF-8"
      }
    };
  
    const jwtRes = await axios.post(`https://${env}.superoffice.com/Login/api/PartnerSystemUser/Authenticate`, postData, axiosConfig);
  
    if(jwtRes.data.IsSuccessful)
    {
      var token = jwtRes.data.Token;
  
      var verifyOptions = {
        ignoreExpiration: true,
        algorithm: ["RS256"]
      };
    
      // validate the JWT and extract the claims
      var decoded = jwt.verify(token, publicKeyFile, verifyOptions);
      
      // write out the ticket to the console, DONE!
      const ticket = decoded["http://schemes.superoffice.net/identity/ticket"];
      return ticket;
    } else {
      log('Getting the System User ticket was unsuccessful: ' + jwtRes.data.ErrorMessage);
    } 
  } catch (error) {
    log("Error: " + error);
  }  
}

function log(message) {
  console.log('')
  console.log(message)
}

// Finally, execute the function to get the system user ticket!

(async () => {
  try {
    const result = await getSystemUserTicket();
    log("System User Ticket: " + result);
  } catch (error) {
    log(error);
  }
})();
```

[1]: ./index

[3]: ../validate-security-tokens

[5]: ../../../../developer-portal/getting-started/index#client-id

[8]: ./sign-system-user-token

[9]: https://www.nuget.org/packages/SuperOffice.WebApi

[10]: https://github.com/SuperOffice/SuperOffice.WebApi-Samples


## Related topics

- [How to use System User Client](/en/api/web-services/proxies/superoffice-webapi/systemuserclient.md)
- [How to sign system user token](/en/api/authentication/online/auth-application/sign-system-user-token.md)
- [Requirements for Pocket CRM mobile client](/en/onsite/pocket-crm/client-requirements.md)
- [Tickets and identity transfers](/en/online/identity/id-transfer-tickets.md)
- [User contexts](/en/developer-portal/getting-started/user-contexts.md)
- [NSCredentialUser](/en/automation/crmscript/reference/CRMScript.NetServer.NSCredentialUser.md)
