โก API White-Label
Build your own frontend and connect it to the TabletopCyber backend. The v2 API allows companies to manage users, simulation sessions, scenarios, webhooks, and statistics programmatically.
๐ท๏ธ What is the white-label model?
TabletopCyber's white-label model allows companies to build their own user interface and connect to the TabletopCyber simulation engine via API. Your frontend, our backend. You control the experience, we handle the simulation logic, scenarios, and scoring.
๐ค Who is it for?
Cybersecurity companies, simulation academies, IT departments, and any organization that wants to offer tabletop simulations to their users under their own brand.
๐ What can you do?
Create and manage users, start simulation games, send programmed decisions, query results, register webhooks for real-time notifications, and get usage statistics.
โ Advantages
Your own brand without developing the simulation engine. Integration with your existing systems via API and webhooks. Scalable according to your plan. Support for multiple cybersecurity scenarios based on real attacks.
๐ Authentication
All v2 API endpoints require authentication via the header X-API-Key. Your API key has the format tc_... and you can generate it from the admin panel at your profile.Keep it safe: do not expose it in publicly accessible client code.
๐ Manage keys: To create a new API key, use the endpoint POST /api/api-keys from the panel (requires session authentication, not API key). Keys have configurable scopes: users, sessions, scenarios, webhooks, stats.
# Ejemplo: autenticaciรณn con API key en todos los requests
curl https://tabletopcyber.duckdns.org/api/v2/users \
-H "X-API-Key: tc_your_api_key_here"๐ Integration flow
These are the typical steps to integrate your frontend with the TabletopCyber v2 API:
1. Create user
POST /api/v2/users โ Register a user in your tenant
2. List scenarios
GET /api/v2/scenarios โ Explore available scenarios
3. Start game
POST /api/v2/sessions โ Create a session for the user and scenario
4. Send decisions
POST /api/v2/sessions/{id}/decision โ User chooses A/B/C/D each round
5. View results
GET /api/v2/sessions/{id}/results โ Get score and feedback
6. Receive webhooks
Events user_created, session_completed, session_abandoned arrive at your URL
๐ค Endpoints โ Users
Manage your tenant users: create, list, view, update, and delete.
/api/v2/usersX-API-KeyCreate tenant user
Creates a new user within your organization. The user can start simulation sessions immediately.
| Parameter | Type | Required | Description |
|---|---|---|---|
email | string | โ | Unique user email |
name | string | โ | User full name |
password | string | โ | Password (min. 8 characters) |
Example request
curl -X POST https://tabletopcyber.duckdns.org/api/v2/users \
-H "Content-Type: application/json" \
-H "X-API-Key: tc_your_api_key_here" \
-d '{
"email": "student@company.com",
"name": "Jane Doe",
"password": "secure123"
}'Response (200 OK)
{
"id": "usr_7f3a2b",
"email": "student@company.com",
"name": "Jane Doe",
"created_at": "2026-08-10T10:49:00Z",
"tenant_id": "tnt_a1b2c3"
}/api/v2/usersX-API-KeyList tenant users
Returns all users belonging to your organization, with optional pagination.
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | integer | โ | Results per page (default 50, max 200) |
offset | integer | โ | Offset for pagination |
search | string | โ | Filter by name or email |
Example request
curl https://tabletopcyber.duckdns.org/api/v2/users \
-H "X-API-Key: tc_your_api_key_here"Response (200 OK)
{
"users": [
{
"id": "usr_7f3a2b",
"email": "student@company.com",
"name": "Jane Doe",
"created_at": "2026-08-10T10:49:00Z"
},
{
"id": "usr_9k4m1n",
"email": "analyst@company.com",
"name": "John Smith",
"created_at": "2026-08-05T14:20:00Z"
}
],
"total": 2,
"limit": 50,
"offset": 0
}/api/v2/users/{user_id}X-API-KeyGet specific user
Gets the full data of a specific tenant user.
| Parameter | Type | Required | Description |
|---|---|---|---|
user_id | string | โ | User ID (path param) |
Example request
curl https://tabletopcyber.duckdns.org/api/v2/users/usr_7f3a2b \
-H "X-API-Key: tc_your_api_key_here"Response (200 OK)
{
"id": "usr_7f3a2b",
"email": "student@company.com",
"name": "Jane Doe",
"created_at": "2026-08-10T10:49:00Z",
"last_login": "2026-08-10T12:30:00Z",
"sessions_count": 14,
"best_score": 8700
}/api/v2/users/{user_id}X-API-KeyUpdate user
Modifies the name or password of an existing user. Only sent fields are updated.
| Parameter | Type | Required | Description |
|---|---|---|---|
user_id | string | โ | User ID (path param) |
name | string | โ | New user name |
password | string | โ | New password (min. 8 characters) |
Example request
curl -X PUT https://tabletopcyber.duckdns.org/api/v2/users/usr_7f3a2b \
-H "Content-Type: application/json" \
-H "X-API-Key: tc_your_api_key_here" \
-d '{
"name": "Jane Smith",
"password": "newpassword456"
}'Response (200 OK)
{
"id": "usr_7f3a2b",
"email": "student@company.com",
"name": "Jane Smith",
"updated_at": "2026-08-10T12:50:00Z"
}/api/v2/users/{user_id}X-API-KeyDelete user
Permanently deletes a user from the tenant. Historical sessions are kept for statistics.
| Parameter | Type | Required | Description |
|---|---|---|---|
user_id | string | โ | User ID (path param) |
Example request
curl -X DELETE https://tabletopcyber.duckdns.org/api/v2/users/usr_7f3a2b \
-H "X-API-Key: tc_your_api_key_here"Response (200 OK)
{
"deleted": true,
"id": "usr_7f3a2b"
}๐ฎ Endpoints โ Game sessions
Start games, send decisions, check status, and get simulation results.
/api/v2/sessionsX-API-KeyStart game
Creates a new simulation session for a user, linked to a specific scenario.
| Parameter | Type | Required | Description |
|---|---|---|---|
scenario_id | string | โ | Scenario ID to play |
user_id | string | โ | User ID starting the game |
Example request
curl -X POST https://tabletopcyber.duckdns.org/api/v2/sessions \
-H "Content-Type: application/json" \
-H "X-API-Key: tc_your_api_key_here" \
-d '{
"scenario_id": "scn_ransomware_01",
"user_id": "usr_7f3a2b"
}'Response (200 OK)
{
"session_id": "sess_a1b2c3",
"scenario_id": "scn_ransomware_01",
"user_id": "usr_7f3a2b",
"status": "active",
"current_round": 1,
"total_rounds": 8,
"narrative": "Un ransomware ha sido detectado en los servidores de la empresa...",
"choices": [
{ "id": "A", "text": "Aislar los servidores afectados inmediatamente" },
{ "id": "B", "text": "Contactar al equipo de IR y evaluar el alcance" },
{ "id": "C", "text": "Pagar el rescato para recuperar los datos" },
{ "id": "D", "text": "Apagar todos los servidores para contener" }
],
"created_at": "2026-08-10T12:00:00Z"
}/api/v2/sessionsX-API-KeyList games
Lists simulation sessions for the tenant with optional status filters and pagination.
| Parameter | Type | Required | Description |
|---|---|---|---|
status | string | โ | Filter by status: active, completed, abandoned |
limit | integer | โ | Results per page (default 20, max 100) |
offset | integer | โ | Offset for pagination |
Example request
curl "https://tabletopcyber.duckdns.org/api/v2/sessions?status=active&limit=20" \
-H "X-API-Key: tc_your_api_key_here"Response (200 OK)
{
"sessions": [
{
"session_id": "sess_a1b2c3",
"scenario_id": "scn_ransomware_01",
"user_id": "usr_7f3a2b",
"status": "active",
"current_round": 3,
"total_rounds": 8,
"created_at": "2026-08-10T12:00:00Z"
},
{
"session_id": "sess_d4e5f6",
"scenario_id": "scn_phishing_02",
"user_id": "usr_9k4m1n",
"status": "completed",
"score": 8200,
"created_at": "2026-08-09T15:30:00Z"
}
],
"total": 2,
"limit": 20,
"offset": 0
}/api/v2/sessions/{session_id}X-API-KeyView game state
Gets the current state of a simulation session: current round, narrative, available choices, and progress.
| Parameter | Type | Required | Description |
|---|---|---|---|
session_id | string | โ | Session ID (path param) |
Example request
curl https://tabletopcyber.duckdns.org/api/v2/sessions/sess_a1b2c3 \
-H "X-API-Key: tc_your_api_key_here"Response (200 OK)
{
"session_id": "sess_a1b2c3",
"scenario_id": "scn_ransomware_01",
"user_id": "usr_7f3a2b",
"status": "active",
"current_round": 3,
"total_rounds": 8,
"narrative": "El ransomware se ha propagado a 3 servidores adicionales. El equipo de IR ha llegado...",
"choices": [
{ "id": "A", "text": "Restaurar desde backup los servidores afectados" },
{ "id": "B", "text": "Negociar con los atacantes mientras se recupera" },
{ "id": "C", "text": "Notificar a las autoridades y activar el plan de continuidad" },
{ "id": "D", "text": "Desconectar la red externa completamente" }
],
"history": [
{ "round": 1, "choice": "B", "feedback": "Buena decisiรณn: evaluar el alcance antes de actuar." },
{ "round": 2, "choice": "A", "feedback": "Aislar los servidores ha contenido la propagaciรณn parcialmente." }
],
"created_at": "2026-08-10T12:00:00Z"
}/api/v2/sessions/{session_id}/decisionX-API-KeySend decision
Sends the user decision for the current simulation round. Advances the game to the next round or finishes it.
| Parameter | Type | Required | Description |
|---|---|---|---|
session_id | string | โ | Session ID (path param) |
choice | string | โ | Choice letter: A, B, C, or D |
user_id | string | โ | User ID sending the decision |
Example request
curl -X POST https://tabletopcyber.duckdns.org/api/v2/sessions/sess_a1b2c3/decision \
-H "Content-Type: application/json" \
-H "X-API-Key: tc_your_api_key_here" \
-d '{
"choice": "B",
"user_id": "usr_7f3a2b"
}'Response (200 OK)
{
"session_id": "sess_a1b2c3",
"round": 4,
"feedback": "Contactar al equipo de IR ha sido la mejor opciรณn. Han identificado el vector de entrada.",
"status": "active",
"next_narrative": "El equipo de IR ha identificado que el vector de entrada fue un email de phishing...",
"next_choices": [
{ "id": "A", "text": "Bloquear el dominio del email de phishing" },
{ "id": "B", "text": "Enviar un alerta a todos los empleados sobre el phishing" },
{ "id": "C", "text": "Implementar filtros de correo mรกs agresivos" },
{ "id": "D", "text": "Realizar un ejercicio de phishing simulado" }
]
}/api/v2/sessions/{session_id}/resultsX-API-KeyView results
Gets the final results of a completed session: score, decisions, hits, and areas for improvement.
| Parameter | Type | Required | Description |
|---|---|---|---|
session_id | string | โ | Session ID (path param) |
Example request
curl https://tabletopcyber.duckdns.org/api/v2/sessions/sess_a1b2c3/results \
-H "X-API-Key: tc_your_api_key_here"Response (200 OK)
{
"session_id": "sess_a1b2c3",
"user_id": "usr_7f3a2b",
"scenario_id": "scn_ransomware_01",
"status": "completed",
"score": 8700,
"max_score": 10000,
"correct_decisions": 6,
"total_rounds": 8,
"accuracy": 0.75,
"time_spent_seconds": 1240,
"strengths": [
"Detecciรณn temprana del incidente",
"Comunicaciรณn efectiva con el equipo de IR"
],
"improvements": [
"No se notificรณ a las autoridades en tiempo",
"Los backups no estaban verificados"
],
"rounds": [
{ "round": 1, "choice": "B", "correct": true, "feedback": "Evaluar el alcance antes de actuar" },
{ "round": 2, "choice": "A", "correct": true, "feedback": "Aislar servidores afectados" },
{ "round": 3, "choice": "C", "correct": true, "feedback": "Notificar a las autoridades" },
{ "round": 4, "choice": "B", "correct": false, "feedback": "Negociar con atacantes no es recomendado" }
],
"completed_at": "2026-08-10T12:20:00Z"
}๐ Endpoints โ Scenarios
Explore the simulation scenarios available for your tenant.
/api/v2/scenariosX-API-KeyList available scenarios
Lists all simulation scenarios available for your tenant, with optional category and difficulty filters.
| Parameter | Type | Required | Description |
|---|---|---|---|
category | string | โ | Filter by category: incident_response, phishing, ransomware, etc. |
difficulty | string | โ | Filter by difficulty: easy, medium, hard |
limit | integer | โ | Results per page (default 50) |
Example request
curl "https://tabletopcyber.duckdns.org/api/v2/scenarios?category=incident_response&difficulty=medium" \
-H "X-API-Key: tc_your_api_key_here"Response (200 OK)
{
"scenarios": [
{
"id": "scn_ransomware_01",
"title": "Ransomware en Datacenter",
"category": "ransomware",
"difficulty": "medium",
"rounds": 8,
"description": "Un ransomware ha infectado los servidores del datacenter..."
},
{
"id": "scn_phishing_02",
"title": "Campaรฑa de Phishing Dirigida",
"category": "phishing",
"difficulty": "easy",
"rounds": 6,
"description": "Empleados reportan emails sospechosos de suplantaciรณn..."
},
{
"id": "scn_ddos_03",
"title": "Ataque DDoS a Infraestructura",
"category": "infrastructure",
"difficulty": "hard",
"rounds": 10,
"description": "Un ataque DDoS sostenido estรก afectando los servicios..."
}
],
"total": 3
}/api/v2/scenarios/{scenario_id}X-API-KeyView scenario details
Gets the full information of a scenario: description, rounds, possible choices, and learning objectives.
| Parameter | Type | Required | Description |
|---|---|---|---|
scenario_id | string | โ | Scenario ID (path param) |
Example request
curl https://tabletopcyber.duckdns.org/api/v2/scenarios/scn_ransomware_01 \
-H "X-API-Key: tc_your_api_key_here"Response (200 OK)
{
"id": "scn_ransomware_01",
"title": "Ransomware en Datacenter",
"category": "ransomware",
"difficulty": "medium",
"rounds": 8,
"description": "Un ransomware ha infectado los servidores del datacenter principal de la empresa. Como analista del SOC, debes contener la amenaza, coordinar la respuesta y minimizar el impacto.",
"learning_objectives": [
"Identificar vectores de entrada de ransomware",
"Aplicar tรฉcnicas de contenciรณn y aislamiento",
"Coordinar comunicaciรณn con stakeholders",
"Gestionar recuperaciรณn desde backups"
],
"estimated_time_minutes": 20
}๐ Endpoints โ Webhooks
Register and manage webhooks to receive real-time event notifications.
/api/v2/webhooksX-API-KeyCreate webhook
Registers an endpoint URL to receive real-time event notifications for your tenant.
| Parameter | Type | Required | Description |
|---|---|---|---|
url | string | โ | HTTPS URL that will receive webhook POSTs |
events | string[] | โ | List of events to listen to: user_created, session_completed, session_abandoned |
Example request
curl -X POST https://tabletopcyber.duckdns.org/api/v2/webhooks \
-H "Content-Type: application/json" \
-H "X-API-Key: tc_your_api_key_here" \
-d '{
"url": "https://your-app.com/webhooks/tabletop",
"events": ["user_created", "session_completed", "session_abandoned"]
}'Response (200 OK)
{
"id": "wh_9x8y7z",
"url": "https://your-app.com/webhooks/tabletop",
"events": ["user_created", "session_completed", "session_abandoned"],
"active": true,
"created_at": "2026-08-10T12:00:00Z"
}/api/v2/webhooksX-API-KeyList webhooks
Lists all webhooks configured in your tenant with their current status.
Example request
curl https://tabletopcyber.duckdns.org/api/v2/webhooks \
-H "X-API-Key: tc_your_api_key_here"Response (200 OK)
{
"webhooks": [
{
"id": "wh_9x8y7z",
"url": "https://your-app.com/webhooks/tabletop",
"events": ["user_created", "session_completed", "session_abandoned"],
"active": true,
"last_delivery": "2026-08-10T12:20:00Z",
"created_at": "2026-08-10T12:00:00Z"
},
{
"id": "wh_2m3n4p",
"url": "https://your-app.com/webhooks/alerts",
"events": ["session_abandoned"],
"active": false,
"last_delivery": null,
"created_at": "2026-08-05T10:00:00Z"
}
]
}/api/v2/webhooks/{webhook_id}X-API-KeyDelete webhook
Deletes a configured webhook. In-flight deliveries will complete but no new ones will be sent.
| Parameter | Type | Required | Description |
|---|---|---|---|
webhook_id | string | โ | Webhook ID (path param) |
Example request
curl -X DELETE https://tabletopcyber.duckdns.org/api/v2/webhooks/wh_9x8y7z \
-H "X-API-Key: tc_your_api_key_here"Response (200 OK)
{
"deleted": true,
"id": "wh_9x8y7z"
}๐ Endpoints โ Statistics
Get aggregated metrics for your organization and individual users.
/api/v2/statsX-API-KeyTenant statistics
Returns aggregated metrics for the entire organization: completed sessions, average scores, active users, etc.
| Parameter | Type | Required | Description |
|---|---|---|---|
from | string | โ | Start date (ISO 8601, e.g.: 2026-01-01) |
to | string | โ | End date (ISO 8601, e.g.: 2026-08-10) |
Example request
curl "https://tabletopcyber.duckdns.org/api/v2/stats?from=2026-01-01&to=2026-08-10" \
-H "X-API-Key: tc_your_api_key_here"Response (200 OK)
{
"tenant_id": "tnt_a1b2c3",
"period": { "from": "2026-01-01", "to": "2026-08-10" },
"total_users": 47,
"active_users": 32,
"total_sessions": 215,
"completed_sessions": 180,
"abandoned_sessions": 35,
"average_score": 7200,
"best_score": 9800,
"by_category": {
"ransomware": { "sessions": 78, "avg_score": 7400 },
"phishing": { "sessions": 92, "avg_score": 7100 },
"infrastructure": { "sessions": 45, "avg_score": 6900 }
},
"by_difficulty": {
"easy": { "sessions": 90, "avg_score": 7600 },
"medium": { "sessions": 95, "avg_score": 7100 },
"hard": { "sessions": 30, "avg_score": 6500 }
}
}/api/v2/stats/users/{user_id}X-API-KeyUser statistics
Gets detailed metrics for a specific user: progress, scores, areas for improvement, and participation.
| Parameter | Type | Required | Description |
|---|---|---|---|
user_id | string | โ | User ID (path param) |
Example request
curl https://tabletopcyber.duckdns.org/api/v2/stats/users/usr_7f3a2b \
-H "X-API-Key: tc_your_api_key_here"Response (200 OK)
{
"user_id": "usr_7f3a2b",
"name": "Jane Doe",
"email": "student@company.com",
"total_sessions": 14,
"completed_sessions": 12,
"abandoned_sessions": 2,
"average_score": 7800,
"best_score": 9200,
"current_streak": 3,
"by_category": {
"ransomware": { "sessions": 5, "avg_score": 8100 },
"phishing": { "sessions": 6, "avg_score": 7500 },
"infrastructure": { "sessions": 3, "avg_score": 7600 }
},
"skill_progression": {
"detection": 85,
"containment": 72,
"communication": 68,
"recovery": 60
},
"last_session": "2026-08-10T12:00:00Z"
}๐ Additional endpoint โ API Keys
This endpoint is not part of the v2 API. It's used from the admin panel with session authentication.
/api/api-keysPanel / SessionCreate API key (from panel)
Generates a new API key to authenticate with the v2 API. This endpoint is NOT part of the v2 API: it uses session authentication from the admin panel.
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | โ | Descriptive name for the API key |
scopes | string[] | โ | Allowed scopes: users, sessions, scenarios, webhooks, stats |
Example request
curl -X POST https://tabletopcyber.duckdns.org/api/api-keys \
-H "Content-Type: application/json" \
-H "X-API-Key: tc_your_api_key_here" \
-d '{
"name": "Production Integration",
"scopes": ["users", "sessions", "scenarios", "webhooks", "stats"]
}'Response (200 OK)
{
"id": "key_1a2b3c",
"key": "tc_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
"name": "Production Integration",
"scopes": ["users", "sessions", "scenarios", "webhooks", "stats"],
"active": true,
"created_at": "2026-08-10T12:00:00Z"
}๐ Endpoints โ Webhooks
Webhooks allow your application to receive real-time event notifications. Register an HTTPS URL via POST /api/v2/webhooks and TabletopCyber will send a POST with the event payload to that URL whenever an event occurs.
Your endpoint must respond with 200 OK within 10 seconds. If no successful response is received, it will retry up to 3 times with exponential backoff (1s, 5s, 30s).
user_createdTriggered when a new user is created in the tenant via API.
Sample payload
{
"event": "user_created",
"tenant_id": "tnt_a1b2c3",
"data": {
"user_id": "usr_7f3a2b",
"email": "student@company.com",
"name": "Jane Doe"
},
"timestamp": "2026-08-10T12:00:00Z"
}session_completedTriggered when a simulation session ends (completed or abandoned).
Sample payload
{
"event": "session_completed",
"tenant_id": "tnt_a1b2c3",
"data": {
"session_id": "sess_a1b2c3",
"user_id": "usr_7f3a2b",
"scenario_id": "scn_ransomware_01",
"status": "completed",
"score": 8700,
"accuracy": 0.75
},
"timestamp": "2026-08-10T12:20:00Z"
}session_abandonedTriggered when a session is abandoned without completion.
Sample payload
{
"event": "session_abandoned",
"tenant_id": "tnt_a1b2c3",
"data": {
"session_id": "sess_a1b2c3",
"user_id": "usr_7f3a2b",
"scenario_id": "scn_ransomware_01",
"rounds_completed": 3,
"total_rounds": 8
},
"timestamp": "2026-08-10T12:10:00Z"
}๐ก Tip: Verify webhook authenticity by including a secret in the registration URL (e.g.: https://your-app.com/webhooks/tabletop?secret=xyzand validate it on your server.
โฑ๏ธ Rate Limiting
Access to the v2 API is available only for custom plans with the API addon enabled. Free and Individual plans do not have API access. If you exceed the limit, you will receive 429 Too Many Requests.All responses include the header X-RateLimit-Remaining with the number of remaining requests in the current minute..
| Tier (custom plan) | Limit / Price |
|---|---|
| Custom โ 120 req/min | Included in API base (โฌ10/mo) |
| Custom โ 300 req/min | +โฌ8/mo |
| Custom โ 600 req/min | +โฌ15/mo |
โ ๏ธ Error Codes
| Code | Meaning |
|---|---|
| 200 | OK โ Request completed successfully. |
| 400 | Bad Request โ Missing or invalid parameters. |
| 401 | Unauthorized โ API key missing or invalid. |
| 403 | Forbidden โ Insufficient permissions or inactive API key. |
| 404 | Not Found โ The resource, user, or session does not exist. |
| 429 | Rate Limit Exceeded โ Too many requests. Check your plan. |
| 500 | Internal Server Error โ Server error. Retry later. |
Error format: All errors return JSON with the structure: { "error": { "code": 404, "message": "Session not found" } }