Sign Token
Generate a signed JWT token for embedding lessons on external sites. This token can be used to securely authenticate and authorize access to specific lessons.
Endpoint
POST /api/public/sign-tokenAuthentication
This endpoint requires authentication using a Bearer token. See Authentication for complete details on API token format, usage, and error handling.
Request Body
The request must include a JSON body with the following fields:
| Field | Type | Required | Description |
|---|---|---|---|
lessonId | string (UUID) | Yes | The lesson ID to include in the token |
learnerId | string | Yes | An anonymous identifier for the person taking the lesson. Do not use PII like email addresses or full names |
userAttributes | object | No | Optional map of user-supplied attributes to include in the token. Do not include PII - use anonymous identifiers only |
timeout | integer | No | Token expiration time in seconds. Defaults to 7200 (2 hours). Maximum: 86400 (24 hours) |
Example Request Body
{
"lessonId": "550e8400-e29b-41d4-a716-446655440000",
"learnerId": "learner_abc123",
"userAttributes": {
"userId": "user_12345",
"sessionId": "session_xyz789",
"accountType": "premium"
},
"timeout": 3600
}Important: Do not include personally identifiable information (PII) such as email addresses, full names, phone numbers, or addresses in learnerId or userAttributes. Use anonymous identifiers to protect user privacy and comply with data protection regulations.
Response
Success Response (200 OK)
Returns a JSON object with the signed JWT token and its expiration time.
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresAt": "2025-01-15T12:30:00Z"
}Response Fields
| Field | Type | Description |
|---|---|---|
token | string | Signed JWT token containing the lesson ID, learner ID, organization ID, and user attributes |
expiresAt | string (ISO 8601) | Timestamp when the token expires |
JWT Token Claims
The generated JWT contains the following claims:
| Claim | Type | Description |
|---|---|---|
lessonId | string | The lesson ID provided in the request |
learnerId | string | The learner ID provided in the request |
organizationId | string | The organization ID from your API token |
userAttributes | object | The user attributes provided in the request |
iat | number | Issued at timestamp (Unix timestamp) |
exp | number | Expiration timestamp (Unix timestamp) |
iss | string | Issuer - always “teacharium” |
Error Responses
401 Unauthorized
Authentication failed. See Authentication Errors for detailed information on authentication issues.
404 Not Found
The lesson was not found or does not belong to your organization.
{
"error": "Lesson not found or does not belong to your organization"
}Possible causes:
- The lesson ID does not exist
- The lesson belongs to a different organization
- The lesson has been deleted
422 Unprocessable Entity
The request body is invalid.
{
"error": "Lesson ID must be a UUID"
}Possible causes:
lessonIdis missing or not a valid UUIDtimeoutis not a number or exceeds the maximum (86400 seconds / 24 hours)- Request body is not valid JSON
- Invalid parameter format
500 Internal Server Error
An unexpected error occurred on the server.
{
"error": "Failed to generate token"
}Example Requests
Basic Request
Generate a token with default 2-hour expiration:
curl -X POST 'https://www.teacharium.io/api/public/sign-token' \
-H 'Authorization: Bearer tapub_xxxxx.tasec_xxxxx' \
-H 'Content-Type: application/json' \
-d '{
"lessonId": "550e8400-e29b-41d4-a716-446655440000",
"learnerId": "learner_abc123"
}'With User Attributes
Include custom user attributes in the token:
curl -X POST 'https://www.teacharium.io/api/public/sign-token' \
-H 'Authorization: Bearer tapub_xxxxx.tasec_xxxxx' \
-H 'Content-Type: application/json' \
-d '{
"lessonId": "550e8400-e29b-41d4-a716-446655440000",
"learnerId": "learner_abc123",
"userAttributes": {
"userId": "user_12345",
"sessionId": "session_xyz789",
"accountType": "premium"
}
}'With Custom Timeout
Generate a token that expires in 1 hour (3600 seconds):
curl -X POST 'https://www.teacharium.io/api/public/sign-token' \
-H 'Authorization: Bearer tapub_xxxxx.tasec_xxxxx' \
-H 'Content-Type: application/json' \
-d '{
"lessonId": "550e8400-e29b-41d4-a716-446655440000",
"learnerId": "learner_abc123",
"userAttributes": {
"userId": "user_12345"
},
"timeout": 3600
}'JavaScript/TypeScript Example
async function signLessonToken(lessonId, learnerId, userAttributes = {}, timeout = 7200) {
const response = await fetch('https://www.teacharium.io/api/public/sign-token', {
method: 'POST',
headers: {
'Authorization': `Bearer ${publicKey}.${secretKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
lessonId,
learnerId,
userAttributes,
timeout
})
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.error);
}
return await response.json();
}
// Usage
const { token, expiresAt } = await signLessonToken(
'550e8400-e29b-41d4-a716-446655440000',
'learner_abc123',
{ userId: 'user_12345', accountType: 'premium' },
3600
);Python Example
import requests
import json
def sign_lesson_token(lesson_id, learner_id, user_attributes=None, timeout=7200):
headers = {
'Authorization': f'Bearer {public_key}.{secret_key}',
'Content-Type': 'application/json'
}
body = {
'lessonId': lesson_id,
'learnerId': learner_id,
'timeout': timeout
}
if user_attributes:
body['userAttributes'] = user_attributes
response = requests.post(
'https://www.teacharium.io/api/public/sign-token',
headers=headers,
json=body
)
response.raise_for_status()
return response.json()
# Usage
result = sign_lesson_token(
'550e8400-e29b-41d4-a716-446655440000',
'learner_abc123',
user_attributes={'userId': 'user_12345', 'accountType': 'premium'},
timeout=3600
)
token = result['token']
expires_at = result['expiresAt']Security Considerations
- Lesson ownership: Only lessons belonging to your organization can be signed
- Token expiration: Tokens automatically expire after the specified timeout
- User attributes: User attributes are embedded in the token and cannot be modified without re-signing
- Token verification: The generated token should be verified before granting access to lessons
- Transport security: Always use HTTPS when transmitting tokens
Use Cases
This endpoint is designed for scenarios where you want to:
- Embed lessons on external websites: Generate tokens for users visiting your site
- Single Sign-On (SSO): Create tokens that include user identity information
- Temporary access: Provide time-limited access to lessons
- User tracking: Include user attributes for analytics or personalization
- Multi-tenant applications: Include tenant/organization information in the token
Notes
- Only published lessons belonging to your organization can be signed
- Deleted lessons cannot be signed
- Tokens include the organization ID to ensure proper multi-tenant isolation
- The JWT signing secret must be configured in your environment via the
JWT_SECRETvariable - User attributes can contain any JSON-serializable data
- The maximum timeout is 24 hours (86400 seconds)
- The default timeout is 2 hours (7200 seconds)