All Virtual Stadium API requests require authentication using JWT (JSON Web Token) bearer tokens. Authorization and permission checks are enforced server-side; contact your Sportradar integration contact for permission setup.
JWT authentication in Virtual Stadium serves multiple purposes:
Virtual Stadium uses JSON Web Tokens (JWT) to securely transmit information between parties. A JWT consists of three components:
For more details about JWT, refer to the official documentation: JSON Web Tokens (JWT)
Each claim in the JWT payload serves a specific purpose to ensure secure and accurate authentication. Below is a detailed description of each claim used in the Virtual Stadium API:
| Claim | Required | Description | |
|---|---|---|---|
iss | ✅ | Issuer - A unique identifier for the entity that issued the token. This is typically provided when you submit the RSA public key. | expose user IDs, use a derivation such as a salted hash of the actual ID. |
env | ✅ | Environment - "dev" or "prod" to validate against correct signing key | |
iat | ✅ | Time at which the JWT was issued. Its value is a JSON number representing the number of seconds from 1970-01-01T00:00 as measured in UTC. It is often added automatically by libraries when signing the token. We use this to limit the maximum validity time, with a default duration of 16 hours. You can also add the exp claim to limit the expiration time further. | |
scope | ✅ | Scope - Space-separated list of permissions granted to this end-user. For example, only users with av in their scope can use the video stream in Live Match Tracker. For virtual stadium use vs in the scope. And for bet concierge use sb in the scope. If user has access to multiple products, add multiple scopes separated with space. Example: 'av vs' | |
sub | ✅ | Subject - Unique end-user ID. You can use the actual user ID from your system, or if you do not want to expose user IDs, use a derivation such as a salted hash of the actual ID. | |
userId | ✅ | User ID - Unique end-user ID. You can use the actual user ID from your system, or if you do not want to expose user IDs, use a derivation such as a salted hash of the actual ID. | |
displayName | ✅ | Display Name - Name shown used in UI components | |
userType | ✅ | User Type - "Moderator" | |
apiKey | ✅ | API Key |
{
"iss": "issuer-id",
"sub": "unique-user-id",
"env": "prod",
"scope": "vs",
"iat": 1697040000,
// Virtual Stadium API requirements
"apiKey": "your-api-key-from-operator",
"userId": "unique-user-id",
"displayName": "user-display-name",
"userType": "Moderator"
}Note: Authorization and permission enforcement is performed server-side. If your integration requires specific management or moderation permissions, follow the setup instructions provided by your Sportradar contact.
# Generate private key
openssl genrsa -out rsa-private.pem 2048
# Generate public key
openssl rsa -in rsa-private.pem -pubout -outform PEM -out rsa-public.pemShare the public key with Sportradar and keep the private key secure.
const jwt = require('jsonwebtoken');
const fs = require('fs');
const privateKey = fs.readFileSync('rsa-private.pem');
const payload = {
iss: 'your-client-identifier',
sub: 'user123',
env: 'prod',
scope: 'vs',
apiKey: 'your-api-key',
userId: 'user123',
displayName: 'John Doe',
userType: 'Moderator'
};
const token = jwt.sign(payload, privateKey, {
algorithm: 'RS256',
expiresIn: '1h'
});Include the JWT in the Authorization header:
Authorization: Bearer <your-jwt-token>Example (fetch):
const response = await fetch('https://management.vs.sportradar.com/api/channel/create', {
method: 'POST',
headers: {
'Authorization': `Bearer ${jwtToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(channelData)
});cURL example:
curl -X POST https://management.vs.sportradar.com/api/channel/create \
-H "Authorization: Bearer <jwt-token>" \
-H "Content-Type: application/json" \
-d '{"channelId":"test-channel","channelName":"Test Channel",...}'"dev" vs "prod" selects validation key.exp) and implement refresh where needed.Security recommendations:
{
"success": false,
"error": "Authentication required",
"details": "Invalid or missing JWT token"
}Causes: missing Authorization header, malformed token, expired token, invalid signature.
{
"success": false,
"error": "Insufficient permissions",
"details": "Required permissions missing"
}Causes: server-side permission requirements not met for the requested operation.
"env": "dev" for development tokens.<script>
const jwtToken = 'your-jwt-token';
SIR('init', {
apiKey: 'your-api-key',
jwtToken
});
</script>class VirtualStadiumAPI {
constructor(jwtToken) {
this.token = jwtToken;
this.baseURL = 'https://management.vs.sportradar.com/api';
}
async createChannel(channelData) {
const resp = await fetch(`${this.baseURL}/channel/create`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(channelData)
});
return resp.json();
}
}Note: contact your Sportradar integration contact for permission/role setup and any environment-specific details.