โšก โšก 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.

REST API v2White-LabelX-API-Key AuthJSON

๐Ÿท๏ธ 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.

POST/api/v2/usersX-API-Key

Create tenant user

Creates a new user within your organization. The user can start simulation sessions immediately.

ParameterTypeRequiredDescription
emailstringโœ…Unique user email
namestringโœ…User full name
passwordstringโœ…Password (min. 8 characters)
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"
  }'
{
  "id": "usr_7f3a2b",
  "email": "student@company.com",
  "name": "Jane Doe",
  "created_at": "2026-08-10T10:49:00Z",
  "tenant_id": "tnt_a1b2c3"
}
GET/api/v2/usersX-API-Key

List tenant users

Returns all users belonging to your organization, with optional pagination.

ParameterTypeRequiredDescription
limitintegerโŒResults per page (default 50, max 200)
offsetintegerโŒOffset for pagination
searchstringโŒFilter by name or email
curl https://tabletopcyber.duckdns.org/api/v2/users \
  -H "X-API-Key: tc_your_api_key_here"
{
  "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
}
GET/api/v2/users/{user_id}X-API-Key

Get specific user

Gets the full data of a specific tenant user.

ParameterTypeRequiredDescription
user_idstringโœ…User ID (path param)
curl https://tabletopcyber.duckdns.org/api/v2/users/usr_7f3a2b \
  -H "X-API-Key: tc_your_api_key_here"
{
  "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
}
PUT/api/v2/users/{user_id}X-API-Key

Update user

Modifies the name or password of an existing user. Only sent fields are updated.

ParameterTypeRequiredDescription
user_idstringโœ…User ID (path param)
namestringโŒNew user name
passwordstringโŒNew password (min. 8 characters)
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"
  }'
{
  "id": "usr_7f3a2b",
  "email": "student@company.com",
  "name": "Jane Smith",
  "updated_at": "2026-08-10T12:50:00Z"
}
DELETE/api/v2/users/{user_id}X-API-Key

Delete user

Permanently deletes a user from the tenant. Historical sessions are kept for statistics.

ParameterTypeRequiredDescription
user_idstringโœ…User ID (path param)
curl -X DELETE https://tabletopcyber.duckdns.org/api/v2/users/usr_7f3a2b \
  -H "X-API-Key: tc_your_api_key_here"
{
  "deleted": true,
  "id": "usr_7f3a2b"
}

๐ŸŽฎ Endpoints โ€” Game sessions

Start games, send decisions, check status, and get simulation results.

POST/api/v2/sessionsX-API-Key

Start game

Creates a new simulation session for a user, linked to a specific scenario.

ParameterTypeRequiredDescription
scenario_idstringโœ…Scenario ID to play
user_idstringโœ…User ID starting the game
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"
  }'
{
  "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"
}
GET/api/v2/sessionsX-API-Key

List games

Lists simulation sessions for the tenant with optional status filters and pagination.

ParameterTypeRequiredDescription
statusstringโŒFilter by status: active, completed, abandoned
limitintegerโŒResults per page (default 20, max 100)
offsetintegerโŒOffset for pagination
curl "https://tabletopcyber.duckdns.org/api/v2/sessions?status=active&limit=20" \
  -H "X-API-Key: tc_your_api_key_here"
{
  "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
}
GET/api/v2/sessions/{session_id}X-API-Key

View game state

Gets the current state of a simulation session: current round, narrative, available choices, and progress.

ParameterTypeRequiredDescription
session_idstringโœ…Session ID (path param)
curl https://tabletopcyber.duckdns.org/api/v2/sessions/sess_a1b2c3 \
  -H "X-API-Key: tc_your_api_key_here"
{
  "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"
}
POST/api/v2/sessions/{session_id}/decisionX-API-Key

Send decision

Sends the user decision for the current simulation round. Advances the game to the next round or finishes it.

ParameterTypeRequiredDescription
session_idstringโœ…Session ID (path param)
choicestringโœ…Choice letter: A, B, C, or D
user_idstringโœ…User ID sending the decision
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"
  }'
{
  "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" }
  ]
}
GET/api/v2/sessions/{session_id}/resultsX-API-Key

View results

Gets the final results of a completed session: score, decisions, hits, and areas for improvement.

ParameterTypeRequiredDescription
session_idstringโœ…Session ID (path param)
curl https://tabletopcyber.duckdns.org/api/v2/sessions/sess_a1b2c3/results \
  -H "X-API-Key: tc_your_api_key_here"
{
  "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.

GET/api/v2/scenariosX-API-Key

List available scenarios

Lists all simulation scenarios available for your tenant, with optional category and difficulty filters.

ParameterTypeRequiredDescription
categorystringโŒFilter by category: incident_response, phishing, ransomware, etc.
difficultystringโŒFilter by difficulty: easy, medium, hard
limitintegerโŒResults per page (default 50)
curl "https://tabletopcyber.duckdns.org/api/v2/scenarios?category=incident_response&difficulty=medium" \
  -H "X-API-Key: tc_your_api_key_here"
{
  "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
}
GET/api/v2/scenarios/{scenario_id}X-API-Key

View scenario details

Gets the full information of a scenario: description, rounds, possible choices, and learning objectives.

ParameterTypeRequiredDescription
scenario_idstringโœ…Scenario ID (path param)
curl https://tabletopcyber.duckdns.org/api/v2/scenarios/scn_ransomware_01 \
  -H "X-API-Key: tc_your_api_key_here"
{
  "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.

POST/api/v2/webhooksX-API-Key

Create webhook

Registers an endpoint URL to receive real-time event notifications for your tenant.

ParameterTypeRequiredDescription
urlstringโœ…HTTPS URL that will receive webhook POSTs
eventsstring[]โœ…List of events to listen to: user_created, session_completed, session_abandoned
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"]
  }'
{
  "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"
}
GET/api/v2/webhooksX-API-Key

List webhooks

Lists all webhooks configured in your tenant with their current status.

curl https://tabletopcyber.duckdns.org/api/v2/webhooks \
  -H "X-API-Key: tc_your_api_key_here"
{
  "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"
    }
  ]
}
DELETE/api/v2/webhooks/{webhook_id}X-API-Key

Delete webhook

Deletes a configured webhook. In-flight deliveries will complete but no new ones will be sent.

ParameterTypeRequiredDescription
webhook_idstringโœ…Webhook ID (path param)
curl -X DELETE https://tabletopcyber.duckdns.org/api/v2/webhooks/wh_9x8y7z \
  -H "X-API-Key: tc_your_api_key_here"
{
  "deleted": true,
  "id": "wh_9x8y7z"
}

๐Ÿ“Š Endpoints โ€” Statistics

Get aggregated metrics for your organization and individual users.

GET/api/v2/statsX-API-Key

Tenant statistics

Returns aggregated metrics for the entire organization: completed sessions, average scores, active users, etc.

ParameterTypeRequiredDescription
fromstringโŒStart date (ISO 8601, e.g.: 2026-01-01)
tostringโŒEnd date (ISO 8601, e.g.: 2026-08-10)
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"
{
  "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 }
  }
}
GET/api/v2/stats/users/{user_id}X-API-Key

User statistics

Gets detailed metrics for a specific user: progress, scores, areas for improvement, and participation.

ParameterTypeRequiredDescription
user_idstringโœ…User ID (path param)
curl https://tabletopcyber.duckdns.org/api/v2/stats/users/usr_7f3a2b \
  -H "X-API-Key: tc_your_api_key_here"
{
  "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.

POST/api/api-keysPanel / Session

Create 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.

ParameterTypeRequiredDescription
namestringโœ…Descriptive name for the API key
scopesstring[]โŒAllowed scopes: users, sessions, scenarios, webhooks, stats
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"]
  }'
{
  "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).

EVENTuser_created

Triggered when a new user is created in the tenant via API.

{
  "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"
}
EVENTsession_completed

Triggered when a simulation session ends (completed or abandoned).

{
  "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"
}
EVENTsession_abandoned

Triggered when a session is abandoned without completion.

{
  "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/minIncluded in API base (โ‚ฌ10/mo)
Custom โ€” 300 req/min+โ‚ฌ8/mo
Custom โ€” 600 req/min+โ‚ฌ15/mo

โš ๏ธ Error Codes

CodeMeaning
200OK โ€” Request completed successfully.
400Bad Request โ€” Missing or invalid parameters.
401Unauthorized โ€” API key missing or invalid.
403Forbidden โ€” Insufficient permissions or inactive API key.
404Not Found โ€” The resource, user, or session does not exist.
429Rate Limit Exceeded โ€” Too many requests. Check your plan.
500Internal Server Error โ€” Server error. Retry later.

Error format: All errors return JSON with the structure: { "error": { "code": 404, "message": "Session not found" } }