Quick Start
Get up and running with the TellsTree API in minutes
Features
Ressources
/api/projects
/api/nodes
/api/edges
/api/media
/api/comments
/api/themes
/api/designs
Rate Limits
API rate limiting prevents abuse and ensures fair usage. Limits are enforced per IP address and vary by endpoint type.
All API responses include rate limit information in the headers. When limits are exceeded, a 429 status is returned.
Header Fields
X-RateLimit-LimitMaximum requests allowed in the current windowX-RateLimit-RemainingRemaining requests in the current windowRetry-AfterSeconds to wait before retry (429 responses only)
300 requests/minute
General API limit (optimized for graph editor)
5 attempts/minute
Login attempts
30 requests/minute
Token refresh
3 attempts/10 minutes
User registration
Error Handling
The API uses conventional HTTP response codes to indicate success or failure. All error responses follow a consistent JSON format with RFC 7807 Problem Details.
Error responses include a `type` (URL to error documentation), `title` (human-readable summary), `detail` (explanation), and `status` (HTTP code).
200, 201, 204
Success responses
400, 401, 403, 404, 422, 429
Client errors
500, 503
Server errors
Authentication
The TellsTree API uses JWT (JSON Web Token) based authentication. You need to obtain a token by logging in with valid credentials.
/api/auth/login
Login / Obtain token
/api/auth/me
Get current user info
/api/auth/refresh
Refresh token
/api/auth/logout
Logout / Invalidate token
/api/.well-known/jwks.json
Public keys (JWKS)
Login
Most API endpoints require authentication. Get your JWT token through the authentication endpoint.
Required Credentials
email- Your account emailpassword- Your account password
Response
https://tellstree.com/api/auth/login{
"data": {
"user": {
"id": 105,
"name": "Owner",
"email": "***REDACTED***",
"created_at": "2025-10-01T13:25:26.000000Z"
},
"token": {
"access_token": "***REDACTED***",
"token_type": "Bearer",
"expires_in": 3600,
"expires_at": "2025-10-17T23:41:32+00:00"
}
}
}
Refresh Token
Tokens expire after 1 hour. Use the refresh endpoint to get a new access token without re-authentication.
Token Refresh
- • Refresh token is stored as HttpOnly cookie
- • No request body required
- • Returns new access token
- • Include cookies with request
Response
https://tellstree.com/api/auth/refresh{
"data": {
"token": {
"access_token": "***REDACTED***",
"token_type": "bearer",
"expires_in": 3600,
"expires_at": "2025-10-17T23:41:33+00:00"
}
}
}
Get Current User
Get information about the currently authenticated user and token details.
Authentication Required
- • Include JWT token in Authorization header
- • Returns user profile and token information
- • Useful for validating token status
Response
https://tellstree.com/api/auth/me{
"data": {
"user": {
"id": 105,
"name": "Owner",
"email": "***REDACTED***",
"created_at": "2025-10-01T13:25:26.000000Z",
"last_api_access": "2025-10-17T22:41:33.000000Z"
},
"token": {
"token_type": "Bearer",
"expires_in": 3600,
"expires_at": "2025-10-17T23:41:33+00:00",
"issued_at": "2025-10-17T22:41:33+00:00"
}
}
}
Logout
Logout and invalidate all tokens for the current user. This prevents further API access with existing tokens.
Token Invalidation
- • Invalidates current access token
- • Invalidates refresh token
- • Increments user token version
- • Clears authentication cookies
Response
https://tellstree.com/api/auth/logout
JSON Web Key Set (JWKS)
Public cryptographic keys for verifying JWT tokens issued by TellsTree. Required for external systems that need to validate TellsTree tokens independently.
Use Cases
- • Microservices: Verify TellsTree tokens without API calls
- • API Gateways: Validate tokens at gateway level
- • Single Sign-On (SSO): Enable SSO integrations
- • Third-party Apps: Verify token authenticity offline
Technical Details
- • Standard RFC 7517 compliant endpoint
- • RSA-256 public keys included
- • Key rotation support via 'kid' field
- • No authentication required (public endpoint)
Response
https://tellstree.com/api/.well-known/jwks.json{
"data": {
"keys": [
{
"kty": "RSA",
"use": "sig",
"alg": "RS256",
"kid": "23269d84700638a0",
"n": "tGkd9DTtdP223c0nKK1sEIeMffQ-Tv56fQlC3aXZkN1eL5B50oocvMH9GMQ24Z4MjvpJ6_5g61OKvf6kBVjmgNeDIRr46nCQ0Gx5-7Y6yxAQAUVP150Y0gJ4dhU5gOF1miOfN0WLJe3MNUAUw-1nGkzyTteWbfRhVgfGfQyFDGfwyJMMbQRiOTLGuC0XvlbfcuCzUieDYfEGTq7T1yrUQLtHtC2LOynty1DmE5bdJqdJ8VTqvBZLCtpkaLUJ-s2qvDBecp2mM5X5OstJvUp4dRucnk_7kp0qdwn2UXirLkKEokPHJi0SQ6Gc6s94GKNbCaDa2W3BztazsKvQmLSTPQ",
"e": "AQAB"
}
]
}
}
Using Tokens for API Access
Once you have an access token, include it in the Authorization header for all API requests.
Authorization Header
Authorization: Bearer YOUR_TOKEN- • Required for all protected endpoints
- • Token expires after 1 hour
- • Use refresh endpoint to get new tokens
Example API Call
GET /api/projectsAuthorization: Bearer eyJ0eXAiOiJKV1Q...Accept: application/json
https://tellstree.com/api/projects{
"method": "GET",
"url": "/api/projects",
"headers": {
"Authorization": [
"***REDACTED***"
]
},
"payload": null,
"recorded_at": "2025-10-17T22:41:34+00:00"
}
?? Projects
Projects are the top-level containers for your storytelling content. Each project can contain multiple nodes (story elements) and edges (connections).
/api/projects
List all projects
/api/projects
Create project
/api/projects/{id}
Get project
/api/projects/{id}
Update project
/api/projects/{id}
Delete project
List Public Projects
Retrieve all publicly available projects. No authentication required.
Query Parameters
query[is_public]
Set to true to get public projects
query[page]
Page number (default: 1)
query[per_page]
Items per page (default: 15)
Response
data.projects[] (Array of detailed Project objects with theme, design, nodes, edges, members, capabilities, comments), data.pagination{} (page, per_page, total)
https://tellstree.com/api/projects{
"data": {
"projects": [
{
"project_id": 1,
"title": "Tells Adventure",
"description": "An interactive tale of courage and consequence - guide your choices through arrows, words and fate.",
"media": null,
"is_public": true,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"is_locked": false,
"nodes": {
"nodes_count": 9
},
"edges": {
"edges_count": 6
},
"members": {
"members_count": 1,
"owner": {
"user_id": null,
"user_name": "Owner"
}
},
"theme": {
"theme_id": 9,
"name": "Dialog",
"domain": "dialog"
},
"design": {
"design_id": 11,
"name": "Original",
"domain": "original"
},
"capabilities": {
"userCanDelete": false
},
"comments": {
"comments_count": 3,
"comments_rating": 4.7
}
},
{
"project_id": 2,
"title": "The Dragon's Quest",
"description": "An epic adventure story where choices matter and every decision shapes your destiny through mystical lands.",
"media": null,
"is_public": true,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"is_locked": false,
"nodes": {
"nodes_count": 7
},
"edges": {
"edges_count": 4
},
"members": {
"members_count": 1,
"owner": {
"user_id": null,
"user_name": "Owner"
}
},
"theme": {
"theme_id": 9,
"name": "Dialog",
"domain": "dialog"
},
"design": {
"design_id": 11,
"name": "Original",
"domain": "original"
},
"capabilities": {
"userCanDelete": false
},
"comments": {
"comments_count": 3,
"comments_rating": 4
}
},
{
"project_id": 3,
"title": "Mystery at Moonlight Manor",
"description": "A thrilling mystery with multiple endings. Solve the case and uncover the dark secrets of the manor.",
"media": null,
"is_public": true,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"is_locked": false,
"nodes": {
"nodes_count": 34
},
"edges": {
"edges_count": 39
},
"members": {
"members_count": 1,
"owner": {
"user_id": null,
"user_name": "Owner"
}
},
"theme": {
"theme_id": 9,
"name": "Dialog",
"domain": "dialog"
},
"design": {
"design_id": 11,
"name": "Original",
"domain": "original"
},
"capabilities": {
"userCanDelete": false
},
"comments": {
"comments_count": 3,
"comments_rating": 4.3
}
},
{
"project_id": 4,
"title": "Galactic Romance",
"description": "Love among the stars in this sci-fi romance adventure across the galaxy and beyond.",
"media": null,
"is_public": true,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"is_locked": false,
"nodes": {
"nodes_count": 7
},
"edges": {
"edges_count": 4
},
"members": {
"members_count": 1,
"owner": {
"user_id": null,
"user_name": "Owner"
}
},
"theme": {
"theme_id": 9,
"name": "Dialog",
"domain": "dialog"
},
"design": {
"design_id": 11,
"name": "Original",
"domain": "original"
},
"capabilities": {
"userCanDelete": false
},
"comments": {
"comments_count": 3,
"comments_rating": 4.7
}
},
{
"project_id": 5,
"title": "Kaffeehaus-Gespr\u00e4ch",
"description": "Eine Demonstration des Dialog-Theme Systems mit Charakteren und Gespr\u00e4chsverl\u00e4ufen",
"media": null,
"is_public": true,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"is_locked": false,
"nodes": {
"nodes_count": 8
},
"edges": {
"edges_count": 5
},
"members": {
"members_count": 1,
"owner": {
"user_id": null,
"user_name": "Owner"
}
},
"theme": {
"theme_id": 9,
"name": "Dialog",
"domain": "dialog"
},
"design": {
"design_id": 11,
"name": "Original",
"domain": "original"
},
"capabilities": {
"userCanDelete": false
},
"comments": {
"comments_count": 3,
"comments_rating": 4.3
}
}
],
"pagination": {
"page": 1,
"per_page": 5,
"total": 5
}
}
}
List Private Projects
Retrieve all projects that the authenticated user has access to. Authentication required.
Headers
Authorization
Bearer {your_jwt_token}
Query Parameters
query[page]
Page number (optional)
query[per_page]
Items per page (optional)
Response
data.projects[] (Array of detailed Project objects with theme, design, nodes, edges, members, capabilities, comments), data.pagination{} (page, per_page, total)
https://tellstree.com/api/projects{
"data": {
"projects": [
{
"project_id": 1,
"title": "Tells Adventure",
"description": "An interactive tale of courage and consequence - guide your choices through arrows, words and fate.",
"media": null,
"is_public": true,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"is_locked": false,
"nodes": {
"nodes_count": 9
},
"edges": {
"edges_count": 6
},
"members": {
"members_count": 1,
"owner": {
"user_id": null,
"user_name": "Owner"
}
},
"theme": {
"theme_id": 9,
"name": "Dialog",
"domain": "dialog"
},
"design": {
"design_id": 11,
"name": "Original",
"domain": "original"
},
"capabilities": {
"userCanDelete": false
},
"comments": {
"comments_count": 3,
"comments_rating": 4.7
}
},
{
"project_id": 2,
"title": "The Dragon's Quest",
"description": "An epic adventure story where choices matter and every decision shapes your destiny through mystical lands.",
"media": null,
"is_public": true,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"is_locked": false,
"nodes": {
"nodes_count": 7
},
"edges": {
"edges_count": 4
},
"members": {
"members_count": 1,
"owner": {
"user_id": null,
"user_name": "Owner"
}
},
"theme": {
"theme_id": 9,
"name": "Dialog",
"domain": "dialog"
},
"design": {
"design_id": 11,
"name": "Original",
"domain": "original"
},
"capabilities": {
"userCanDelete": false
},
"comments": {
"comments_count": 3,
"comments_rating": 4
}
},
{
"project_id": 3,
"title": "Mystery at Moonlight Manor",
"description": "A thrilling mystery with multiple endings. Solve the case and uncover the dark secrets of the manor.",
"media": null,
"is_public": true,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"is_locked": false,
"nodes": {
"nodes_count": 34
},
"edges": {
"edges_count": 39
},
"members": {
"members_count": 1,
"owner": {
"user_id": null,
"user_name": "Owner"
}
},
"theme": {
"theme_id": 9,
"name": "Dialog",
"domain": "dialog"
},
"design": {
"design_id": 11,
"name": "Original",
"domain": "original"
},
"capabilities": {
"userCanDelete": false
},
"comments": {
"comments_count": 3,
"comments_rating": 4.3
}
},
{
"project_id": 4,
"title": "Galactic Romance",
"description": "Love among the stars in this sci-fi romance adventure across the galaxy and beyond.",
"media": null,
"is_public": true,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"is_locked": false,
"nodes": {
"nodes_count": 7
},
"edges": {
"edges_count": 4
},
"members": {
"members_count": 1,
"owner": {
"user_id": null,
"user_name": "Owner"
}
},
"theme": {
"theme_id": 9,
"name": "Dialog",
"domain": "dialog"
},
"design": {
"design_id": 11,
"name": "Original",
"domain": "original"
},
"capabilities": {
"userCanDelete": false
},
"comments": {
"comments_count": 3,
"comments_rating": 4.7
}
},
{
"project_id": 5,
"title": "Kaffeehaus-Gespr\u00e4ch",
"description": "Eine Demonstration des Dialog-Theme Systems mit Charakteren und Gespr\u00e4chsverl\u00e4ufen",
"media": null,
"is_public": true,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"is_locked": false,
"nodes": {
"nodes_count": 8
},
"edges": {
"edges_count": 5
},
"members": {
"members_count": 1,
"owner": {
"user_id": null,
"user_name": "Owner"
}
},
"theme": {
"theme_id": 9,
"name": "Dialog",
"domain": "dialog"
},
"design": {
"design_id": 11,
"name": "Original",
"domain": "original"
},
"capabilities": {
"userCanDelete": false
},
"comments": {
"comments_count": 3,
"comments_rating": 4.3
}
}
],
"pagination": {
"page": 1,
"per_page": 5,
"total": 5
}
}
}
Create New Project
Create a new storytelling project with a theme and design.
Response
data.project{} (Complete Project object with theme, design, nodes, edges, members, capabilities, comments)
data.errors{}
https://tellstree.com/api/projects{
"data": {
"project": {
"project_id": 93,
"title": "API Test Project 1760740895",
"description": "Created by automated test",
"is_public": false,
"created_at": "2025-10-17T22:41:35.000000Z",
"updated_at": "2025-10-17T22:41:35.000000Z",
"is_locked": false,
"nodes": {
"nodes_count": 2
},
"edges": {
"edges_count": 0
},
"members": {
"members_count": 1,
"owner": {
"user_id": null,
"user_name": "Owner"
}
},
"theme": {
"theme_id": 9,
"name": "Dialog",
"domain": "dialog"
},
"design": {
"design_id": 11,
"name": "Original",
"domain": "original"
},
"capabilities": {
"userCanDelete": true
},
"comments": {
"comments_count": 0,
"comments_rating": 0
}
}
}
}
Get Single Project
Retrieve detailed information about a specific project.
Response
data.project{} (Complete Project object with theme, design, nodes, edges, members, capabilities, comments, media, lock status)
https://tellstree.com/api/projects/{id}{
"data": {
"project": {
"project_id": 93,
"title": "API Test Project 1760740895",
"description": "Created by automated test",
"media": null,
"is_public": false,
"created_at": "2025-10-17T22:41:35.000000Z",
"updated_at": "2025-10-17T22:41:35.000000Z",
"is_locked": false,
"nodes": {
"nodes_count": 2
},
"edges": {
"edges_count": 0
},
"members": {
"members_count": 1,
"owner": {
"user_id": null,
"user_name": "Owner"
}
},
"theme": {
"theme_id": 9,
"name": "Dialog",
"domain": "dialog"
},
"design": {
"design_id": 11,
"name": "Original",
"domain": "original"
},
"capabilities": {
"userCanDelete": true
},
"comments": {
"comments_count": 0,
"comments_rating": 0
}
}
}
}
Update Project
Update an existing project's properties, theme, or design.
🔒 Lock Management
Lock/unlock functionality is integrated into the update endpoint:
- •
is_locked: true- Lock project for current user - •
is_locked: false- Unlock project (only by lock owner) - • Response includes
is_locked: true/false - • Auto-unlock: Locks expire automatically after 300 seconds when project is accessed
Response
data.project{} (Updated Project object with theme, design, nodes, edges, members, capabilities, comments)
data.errors{}
https://tellstree.com/api/projects/{id}{
"data": {
"project": {
"project_id": 93,
"title": "API Test Project 1760740895 updated",
"description": "Created by automated test",
"media": null,
"is_public": false,
"created_at": "2025-10-17T22:41:35.000000Z",
"updated_at": "2025-10-17T22:41:36.000000Z",
"is_locked": true,
"nodes": {
"nodes_count": 2
},
"edges": {
"edges_count": 0
},
"members": {
"members_count": 1,
"owner": {
"user_id": null,
"user_name": "Owner"
}
},
"theme": {
"theme_id": 9,
"name": "Dialog",
"domain": "dialog"
},
"design": {
"design_id": 11,
"name": "Original",
"domain": "original"
},
"capabilities": {
"userCanDelete": true
},
"comments": {
"comments_count": 0,
"comments_rating": 0
}
}
}
}
Delete Project
Permanently delete a project and all its content.
Response
https://tellstree.com/api/projects/{id}
📋 Nodes
Nodes are the building blocks of your story. Each node represents a narrative element like a scene, chapter or character. A Node can contain text, media, and interactive elements.
/api/nodes
List all nodes
/api/nodes
Create new node
/api/nodes?query[include]=ids
Get specific nodes (lazy loading)
/api/nodes/{node}
Get node details
/api/nodes/{node}
Update node
/api/nodes/{node}
Delete node
List Nodes
Retrieve all nodes or filter by project, including their content, position, and metadata.
Query Parameters
query[project_id]- Filter by project ID (required)query[page]- Page number (optional, default: 1)query[per_page]- Items per page (optional, default: 20)
Response
https://tellstree.com/api/nodes{
"data": {
"nodes": [
{
"node_id": 1,
"type": "dialog-start",
"label": "Start",
"content": "Starting point of your story.",
"media": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null,
"outgoing_edges": [
{
"edge_id": 1,
"from_node_id": 1,
"to_node_id": 5,
"type": "dialog-link",
"condition": "Start of conversation",
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null
}
],
"incoming_edges": [],
"pivot": {
"project_id": 1,
"node_id": 1,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z"
}
},
{
"node_id": 2,
"type": "dialog-end",
"label": "End",
"content": "Conclusion of your story.",
"media": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null,
"outgoing_edges": [],
"incoming_edges": [
{
"edge_id": 6,
"from_node_id": 7,
"to_node_id": 2,
"type": "dialog-link",
"condition": "End of conversation",
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null
}
],
"pivot": {
"project_id": 1,
"node_id": 2,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z"
}
},
{
"node_id": 3,
"type": "character",
"label": "Wilhelm Tell",
"content": "{\"name\":\"Wilhelm Tell\",\"description\":\"A silent hero of justice - a man of few words, but unshakable principles. He values freedom over obedience, and would rather risk death than bow to a tyrant.\"}",
"media": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null,
"outgoing_edges": [],
"incoming_edges": [],
"pivot": {
"project_id": 1,
"node_id": 3,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z"
}
},
{
"node_id": 4,
"type": "character",
"label": "Walter Tell",
"content": "{\"name\":\"Walter Tell\",\"description\":\"Wilhelm Tells son.\"}",
"media": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null,
"outgoing_edges": [],
"incoming_edges": [],
"pivot": {
"project_id": 1,
"node_id": 4,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z"
}
},
{
"node_id": 5,
"type": "dialog-entry",
"label": "Trust me!",
"content": "{\"text\":\"Trust me!\",\"speaker\":3}",
"media": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null,
"outgoing_edges": [
{
"edge_id": 2,
"from_node_id": 5,
"to_node_id": 6,
"type": "dialog-link",
"condition": "if Walter Tell is armed",
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null
}
],
"incoming_edges": [
{
"edge_id": 1,
"from_node_id": 1,
"to_node_id": 5,
"type": "dialog-link",
"condition": "Start of conversation",
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null
}
],
"pivot": {
"project_id": 1,
"node_id": 5,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z"
}
},
{
"node_id": 6,
"type": "dialog-entry",
"label": "Are you sure you won\u00b4t kill me?",
"content": "{\"text\":\"Are you sure you won\\u00b4t kill me?\",\"speaker\":4}",
"media": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null,
"outgoing_edges": [
{
"edge_id": 3,
"from_node_id": 6,
"to_node_id": 7,
"type": "dialog-link",
"condition": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null
},
{
"edge_id": 4,
"from_node_id": 6,
"to_node_id": 8,
"type": "dialog-link",
"condition": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null
},
{
"edge_id": 5,
"from_node_id": 6,
"to_node_id": 9,
"type": "dialog-link",
"condition": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null
}
],
"incoming_edges": [
{
"edge_id": 2,
"from_node_id": 5,
"to_node_id": 6,
"type": "dialog-link",
"condition": "if Walter Tell is armed",
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null
}
],
"pivot": {
"project_id": 1,
"node_id": 6,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z"
}
},
{
"node_id": 7,
"type": "dialog-entry",
"label": "You are right. I can't do that.",
"content": "{\"text\":\"You are right. I can't do that.\",\"speaker\":3}",
"media": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null,
"outgoing_edges": [
{
"edge_id": 6,
"from_node_id": 7,
"to_node_id": 2,
"type": "dialog-link",
"condition": "End of conversation",
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null
}
],
"incoming_edges": [
{
"edge_id": 3,
"from_node_id": 6,
"to_node_id": 7,
"type": "dialog-link",
"condition": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null
}
],
"pivot": {
"project_id": 1,
"node_id": 7,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z"
}
},
{
"node_id": 8,
"type": "dialog-entry",
"label": "Trust me son!",
"content": "{\"text\":\"Trust me son!\",\"speaker\":3}",
"media": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null,
"outgoing_edges": [],
"incoming_edges": [
{
"edge_id": 4,
"from_node_id": 6,
"to_node_id": 8,
"type": "dialog-link",
"condition": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null
}
],
"pivot": {
"project_id": 1,
"node_id": 8,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z"
}
},
{
"node_id": 9,
"type": "dialog-entry",
"label": "Son just stop shaking!",
"content": "{\"text\":\"Son just stop shaking!\",\"speaker\":3}",
"media": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null,
"outgoing_edges": [],
"incoming_edges": [
{
"edge_id": 5,
"from_node_id": 6,
"to_node_id": 9,
"type": "dialog-link",
"condition": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null
}
],
"pivot": {
"project_id": 1,
"node_id": 9,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z"
}
}
],
"pagination": {
"current_page": 1,
"total_pages": 1,
"per_page": 20,
"total_items": 9,
"page": 1
}
}
}
Load Specific Nodes
Get specific nodes by IDs for lazy loading in the TellsTreeGraph editor. Used for performance optimization when working with large projects.
Query Parameters
query[project_id]- Required project IDquery[include]- Comma-separated node IDs- • Returns canvas-ready node data
- • Optimized for editor performance
Response
https://tellstree.com/api/nodes{
"data": {
"nodes": [
{
"node_id": 1,
"type": "dialog-start",
"label": "Start",
"content": [],
"media": [],
"compactView": null,
"detailView": null
},
{
"node_id": 2,
"type": "dialog-end",
"label": "End",
"content": [],
"media": [],
"compactView": null,
"detailView": null
},
{
"node_id": 3,
"type": "character",
"label": "Wilhelm Tell",
"content": {
"name": "Wilhelm Tell",
"description": "A silent hero of justice - a man of few words, but unshakable principles. He values freedom over obedience, and would rather risk death than bow to a tyrant."
},
"media": [],
"compactView": null,
"detailView": null
}
]
}
}
Create Node
Create a new node. Nodes can exist independently or be associated with a project via project_id.
Required Fields
title- Node title
Optional Fields
project_id- Associate with projectcontent- Node content/texttype- Node typeposition_x- X coordinateposition_y- Y coordinateproperties- Custom properties
Response
https://tellstree.com/api/nodes{
"data": {
"node": {
"node_id": 336,
"type": "character",
"label": "API Test Character 1760740894",
"content": {
"name": "API Test Character 1760740894",
"description": "Node created by automated API test"
},
"media": [],
"created_at": "2025-10-17T22:41:34.000000Z",
"updated_at": "2025-10-17T22:41:34.000000Z",
"outgoing_edges_count": 0,
"incoming_edges_count": 0,
"is_locked": false
}
}
}
Get Node
Retrieve detailed information about a specific node, including all its properties and metadata.
URL Parameters
project- Project IDnode- Node ID
Response
https://tellstree.com/api/nodes/{node}{
"data": {
"nodes": [
{
"node_id": 1,
"type": "dialog-start",
"label": "Start",
"content": "Starting point of your story.",
"media": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null,
"outgoing_edges": [
{
"edge_id": 1,
"from_node_id": 1,
"to_node_id": 5,
"type": "dialog-link",
"condition": "Start of conversation",
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null
}
],
"incoming_edges": [],
"pivot": {
"project_id": 1,
"node_id": 1,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z"
}
},
{
"node_id": 2,
"type": "dialog-end",
"label": "End",
"content": "Conclusion of your story.",
"media": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null,
"outgoing_edges": [],
"incoming_edges": [
{
"edge_id": 6,
"from_node_id": 7,
"to_node_id": 2,
"type": "dialog-link",
"condition": "End of conversation",
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null
}
],
"pivot": {
"project_id": 1,
"node_id": 2,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z"
}
},
{
"node_id": 3,
"type": "character",
"label": "Wilhelm Tell",
"content": "{\"name\":\"Wilhelm Tell\",\"description\":\"A silent hero of justice - a man of few words, but unshakable principles. He values freedom over obedience, and would rather risk death than bow to a tyrant.\"}",
"media": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null,
"outgoing_edges": [],
"incoming_edges": [],
"pivot": {
"project_id": 1,
"node_id": 3,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z"
}
},
{
"node_id": 4,
"type": "character",
"label": "Walter Tell",
"content": "{\"name\":\"Walter Tell\",\"description\":\"Wilhelm Tells son.\"}",
"media": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null,
"outgoing_edges": [],
"incoming_edges": [],
"pivot": {
"project_id": 1,
"node_id": 4,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z"
}
},
{
"node_id": 5,
"type": "dialog-entry",
"label": "Trust me!",
"content": "{\"text\":\"Trust me!\",\"speaker\":3}",
"media": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null,
"outgoing_edges": [
{
"edge_id": 2,
"from_node_id": 5,
"to_node_id": 6,
"type": "dialog-link",
"condition": "if Walter Tell is armed",
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null
}
],
"incoming_edges": [
{
"edge_id": 1,
"from_node_id": 1,
"to_node_id": 5,
"type": "dialog-link",
"condition": "Start of conversation",
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null
}
],
"pivot": {
"project_id": 1,
"node_id": 5,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z"
}
},
{
"node_id": 6,
"type": "dialog-entry",
"label": "Are you sure you won\u00b4t kill me?",
"content": "{\"text\":\"Are you sure you won\\u00b4t kill me?\",\"speaker\":4}",
"media": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null,
"outgoing_edges": [
{
"edge_id": 3,
"from_node_id": 6,
"to_node_id": 7,
"type": "dialog-link",
"condition": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null
},
{
"edge_id": 4,
"from_node_id": 6,
"to_node_id": 8,
"type": "dialog-link",
"condition": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null
},
{
"edge_id": 5,
"from_node_id": 6,
"to_node_id": 9,
"type": "dialog-link",
"condition": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null
}
],
"incoming_edges": [
{
"edge_id": 2,
"from_node_id": 5,
"to_node_id": 6,
"type": "dialog-link",
"condition": "if Walter Tell is armed",
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null
}
],
"pivot": {
"project_id": 1,
"node_id": 6,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z"
}
},
{
"node_id": 7,
"type": "dialog-entry",
"label": "You are right. I can't do that.",
"content": "{\"text\":\"You are right. I can't do that.\",\"speaker\":3}",
"media": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null,
"outgoing_edges": [
{
"edge_id": 6,
"from_node_id": 7,
"to_node_id": 2,
"type": "dialog-link",
"condition": "End of conversation",
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null
}
],
"incoming_edges": [
{
"edge_id": 3,
"from_node_id": 6,
"to_node_id": 7,
"type": "dialog-link",
"condition": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null
}
],
"pivot": {
"project_id": 1,
"node_id": 7,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z"
}
},
{
"node_id": 8,
"type": "dialog-entry",
"label": "Trust me son!",
"content": "{\"text\":\"Trust me son!\",\"speaker\":3}",
"media": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null,
"outgoing_edges": [],
"incoming_edges": [
{
"edge_id": 4,
"from_node_id": 6,
"to_node_id": 8,
"type": "dialog-link",
"condition": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null
}
],
"pivot": {
"project_id": 1,
"node_id": 8,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z"
}
},
{
"node_id": 9,
"type": "dialog-entry",
"label": "Son just stop shaking!",
"content": "{\"text\":\"Son just stop shaking!\",\"speaker\":3}",
"media": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null,
"outgoing_edges": [],
"incoming_edges": [
{
"edge_id": 5,
"from_node_id": 6,
"to_node_id": 9,
"type": "dialog-link",
"condition": null,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"locked_by": null,
"locked_at": null
}
],
"pivot": {
"project_id": 1,
"node_id": 9,
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z"
}
}
],
"pagination": {
"current_page": 1,
"total_pages": 1,
"per_page": 20,
"total_items": 9,
"page": 1
}
}
}
Update Node
Update an existing node's content, position, properties, or other attributes.
🔒 Lock Management
Lock/unlock functionality is integrated into the update endpoint:
- •
is_locked: true- Lock node for current user - •
is_locked: false- Unlock node (only by lock owner) - • Response includes
is_locked: true/false - • Auto-unlock: Locks expire automatically after 300 seconds when node is accessed
Updatable Fields
title- Node titlecontent- Node contenttype- Node typeposition_x- X coordinateposition_y- Y coordinateproperties- Custom propertieslocked_by- Lock status (user_id or null)
Response
https://tellstree.com/api/nodes/{node}{
"data": {
"node": {
"node_id": 336,
"type": "character",
"label": "API Test Character 1760740894",
"content": {
"name": "Updated API Test Character"
},
"media": [],
"created_at": "2025-10-17T22:41:34.000000Z",
"updated_at": "2025-10-17T22:41:35.000000Z",
"outgoing_edges_count": 0,
"incoming_edges_count": 0,
"is_locked": true
}
}
}
Delete Node
Permanently delete a node from the project. This will also remove all connected edges.
Response
https://tellstree.com/api/nodes/{node}
?? Edges
Edges create connections between nodes, defining the flow and relationships in your interactive stories. They represent transitions, choices, and narrative pathways.
/api/edges
List all edges
/api/edges
Create new edge
/api/edges/{edge}
Get edge details
/api/edges/{edge}
Update edge
/api/edges/{edge}
Delete edge
Create Edge
Create a new edge connection between two nodes in a project.
Required Fields
source_node_id- ID of source nodetarget_node_id- ID of target node
Optional Fields
label- Display text for edgecondition- Edge activation condition
Response
https://tellstree.com/api/edges{
"data": {
"edge": {
"edge_id": 107,
"from_node_id": 332,
"to_node_id": 333,
"type": "connection",
"condition": null,
"created_at": "2025-10-17T22:41:32.000000Z",
"updated_at": "2025-10-17T22:41:32.000000Z",
"from_node": {
"node_id": 332,
"type": "character",
"label": "Edge API Node 1760740892"
},
"to_node": {
"node_id": 333,
"type": "character",
"label": "Edge API Node 2 1760740892"
},
"is_locked": false
}
}
}
Get Edge
Retrieve detailed information about a specific edge, including source and target node details.
URL Parameters
project- Project IDedge- Edge ID
Response
https://tellstree.com/api/edges/{edge}{
"data": {
"edge": {
"edge_id": 107,
"from_node_id": 332,
"to_node_id": 333,
"type": "connection",
"condition": null,
"created_at": "2025-10-17T22:41:32.000000Z",
"updated_at": "2025-10-17T22:41:32.000000Z",
"from_node": {
"node_id": 332,
"type": "character",
"label": "Edge API Node 1760740892"
},
"to_node": {
"node_id": 333,
"type": "character",
"label": "Edge API Node 2 1760740892"
},
"is_locked": false
}
}
}
Update Edge
Update properties of an existing edge. You can modify the label, condition, and connection endpoints.
🔒 Lock Management
Lock/unlock functionality is integrated into the update endpoint:
- •
is_locked: true- Lock edge for current user - •
is_locked: false- Unlock edge (only by lock owner) - • Response includes
is_locked: true/false - • Auto-unlock: Locks expire automatically after 300 seconds when edge is accessed
Request Body
source_node_id- Source node IDtarget_node_id- Target node IDlabel- Edge display labelcondition- Edge conditionlocked_by- Lock status (internal use only)
Response
https://tellstree.com/api/edges/{edge}{
"data": {
"edge": {
"edge_id": 107,
"from_node_id": 332,
"to_node_id": 333,
"type": "connection",
"condition": "updated condition",
"created_at": "2025-10-17T22:41:32.000000Z",
"updated_at": "2025-10-17T22:41:32.000000Z",
"from_node": {
"node_id": 332,
"type": "character",
"label": "Edge API Node 1760740892"
},
"to_node": {
"node_id": 333,
"type": "character",
"label": "Edge API Node 2 1760740892"
},
"is_locked": true
}
}
}
Delete Edge
Permanently delete an edge connection. This action cannot be undone and will break the connection between nodes.
Response
https://tellstree.com/api/edges/{edge}
🎬 Media
Media files can be attached to projects, nodes, or edges. Support for images, videos, audio, and documents to enrich your interactive stories with multimedia content.
/api/media
List all media
/api/media
Upload new media
/api/media/{media}
Get media details
/api/media/{media}
Update media metadata
/api/media/{media}/visibility
Update visibility
/api/media/{media}
Delete media
List Media
Retrieve all media files or filter by project, node, or edge.
Query Parameters
project_id- Filter by project ID (optional)node_id- Filter by node ID (optional)edge_id- Filter by edge ID (optional)type- Filter by media type (optional)page- Page number (optional)per_page- Items per page (optional)
Response
https://tellstree.com/api/media{
"data": {
"media": [
{
"media_id": 1,
"filename": "hero-image.jpg",
"original_name": "Hero Image.jpg",
"mime_type": "image/jpeg",
"size": 1048576,
"path": "/storage/media/hero-image.jpg",
"url": "https://tellstree.com/storage/media/hero-image.jpg",
"project_id": 42,
"node_id": null,
"edge_id": null,
"visibility": "public",
"alt_text": "Hero image for opening scene",
"description": "Main visual for the story introduction",
"metadata": {
"width": 1920,
"height": 1080,
"aspect_ratio": "16:9"
},
"created_at": "2024-01-15T10:00:00.000000Z",
"updated_at": "2024-01-15T10:00:00.000000Z"
}
],
"pagination": {
"current_page": 1,
"total_pages": 3,
"per_page": 10,
"total_items": 25
}
},
"meta": {
"request_id": "req_67890",
"timestamp": "2024-01-15T10:00:00.000000Z"
}
}
Upload Media
Upload a new media file and attach it to a project, node, or edge.
Required Fields
file- Media file to upload
Optional Fields
project_id- Attach to projectnode_id- Attach to nodeedge_id- Attach to edgealt_text- Alternative textdescription- Media descriptionvisibility- public/private
Response
https://tellstree.com/api/media{
"data": {
"media_id": 123,
"filename": "uploaded-image.jpg",
"original_name": "My Image.jpg",
"mime_type": "image/jpeg",
"size": 2097152,
"path": "/storage/media/uploaded-image.jpg",
"url": "https://tellstree.com/storage/media/uploaded-image.jpg",
"project_id": 42,
"node_id": null,
"edge_id": null,
"visibility": "public",
"alt_text": "Uploaded image",
"description": "User uploaded media file",
"metadata": {
"width": 1600,
"height": 900,
"aspect_ratio": "16:9"
},
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z"
},
"meta": {
"request_id": "req_12345",
"timestamp": "2024-01-15T10:30:00.000000Z"
}
}
Themes
Themes define the visual styling and appearance of your storytelling projects. Each theme contains color schemes, fonts, and layout configurations.
/api/themes
List all themes
/api/themes/{theme}
Get theme by domain
List All Themes
Retrieve a paginated list of all available themes. This is a public endpoint and does not require authentication.
Query Parameters
page- Page number (optional, default: 1)per_page- Items per page (optional, default: 15)
Response
https://tellstree.com/api/themes{
"data": {
"themes": [
{
"theme_id": 9,
"name": "Dialog",
"domain": "dialog",
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"statistics": {
"projects_count": 76,
"is_default": true
},
"node_types": [
"character",
"dialog-start",
"dialog-end",
"dialog-entry"
],
"forms": {
"character": {
"name": {
"form": "input",
"type": "string",
"required": true,
"label": "Character Name",
"isLabel": true,
"placeholder": "Enter character name..."
},
"description": {
"form": "textarea",
"type": "string",
"required": false,
"label": "Description",
"rows": 4,
"placeholder": "Character description..."
},
"traits": {
"form": "textarea",
"type": "string",
"required": false,
"label": "Traits",
"rows": 3,
"placeholder": "Character traits (e.g. brave, shy...)"
}
},
"dialog-end": [],
"dialog-entry": {
"speaker": {
"form": "select",
"type": "string",
"required": true,
"label": "Speaker",
"options": [
{
"label": "{{node[character].content.name}}",
"value": "{{node[character].node_id}}"
}
],
"placeholder": "Select character..."
},
"text": {
"form": "textarea",
"type": "string",
"required": true,
"label": "Text/Action",
"isLabel": true,
"rows": 4,
"placeholder": "Dialog text or action description..."
}
},
"dialog-start": {
"title": {
"form": "input",
"type": "string",
"required": true,
"label": "Dialog Title",
"isLabel": true,
"placeholder": "What is the dialog about?"
},
"description": {
"form": "textarea",
"type": "string",
"required": false,
"label": "Description",
"rows": 4,
"placeholder": "Dialog description..."
}
}
}
}
]
},
"meta": {
"total_count": 1,
"timestamp": "2025-10-17T22:41:37.016049Z"
}
}
Get Specific Theme
Retrieve detailed information about a specific theme by its domain. This is a public endpoint and does not require authentication.
URL Parameters
theme- The unique domain identifier of the theme (e.g., "dialog")
Response
https://tellstree.com/api/themes/{slug}{
"data": {
"theme": {
"theme_id": 9,
"name": "Dialog",
"domain": "dialog",
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"statistics": {
"projects_count": 76,
"is_default": true
},
"node_types": [
"character",
"dialog-start",
"dialog-end",
"dialog-entry"
],
"forms": {
"character": {
"name": {
"form": "input",
"type": "string",
"required": true,
"label": "Character Name",
"isLabel": true,
"placeholder": "Enter character name..."
},
"description": {
"form": "textarea",
"type": "string",
"required": false,
"label": "Description",
"rows": 4,
"placeholder": "Character description..."
},
"traits": {
"form": "textarea",
"type": "string",
"required": false,
"label": "Traits",
"rows": 3,
"placeholder": "Character traits (e.g. brave, shy...)"
}
},
"dialog-end": [],
"dialog-entry": {
"speaker": {
"form": "select",
"type": "string",
"required": true,
"label": "Speaker",
"options": [
{
"label": "{{node[character].content.name}}",
"value": "{{node[character].node_id}}"
}
],
"placeholder": "Select character..."
},
"text": {
"form": "textarea",
"type": "string",
"required": true,
"label": "Text/Action",
"isLabel": true,
"rows": 4,
"placeholder": "Dialog text or action description..."
}
},
"dialog-start": {
"title": {
"form": "input",
"type": "string",
"required": true,
"label": "Dialog Title",
"isLabel": true,
"placeholder": "What is the dialog about?"
},
"description": {
"form": "textarea",
"type": "string",
"required": false,
"label": "Description",
"rows": 4,
"placeholder": "Dialog description..."
}
}
}
}
},
"meta": {
"timestamp": "2025-10-17T22:41:37.076138Z"
}
}
✨ Designs
Designs provide specific styling configurations within themes, allowing fine-grained control over the visual presentation of story elements.
/api/designs
List all designs
/api/designs/{design}
Get design by domain
List All Designs
Retrieve a list of all available designs. This is a public endpoint and does not require authentication.
Response
https://tellstree.com/api/designs{
"data": {
"designs": [
{
"design_id": 11,
"name": "Original",
"domain": "original",
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"statistics": {
"projects_count": 74,
"is_default": false
},
"configuration": {
"name": "Original",
"version": "1.0.0",
"description": "The original design recipe for TellsTree - timeless, refined, and expertly crafted.",
"author": "TellsTree Team",
"category": "classic",
"preview": "foundation-preview.jpg",
"colors": {
"primary": "#3B82F6",
"secondary": "#8B5CF6",
"accent": "#10B981",
"background": "#F8FAFC",
"surface": "#FFFFFF",
"text": {
"primary": "#1F2937",
"secondary": "#6B7280",
"muted": "#9CA3AF"
},
"border": "#E5E7EB",
"shadow": "rgba(0, 0, 0, 0.1)"
},
"typography": {
"fontFamily": {
"primary": "Inter, sans-serif",
"heading": "Inter, sans-serif",
"code": "JetBrains Mono, monospace"
},
"fontSize": {
"xs": "0.75rem",
"sm": "0.875rem",
"base": "1rem",
"lg": "1.125rem",
"xl": "1.25rem",
"2xl": "1.5rem",
"3xl": "1.875rem"
},
"fontWeight": {
"normal": "400",
"medium": "500",
"semibold": "600",
"bold": "700"
},
"lineHeight": {
"tight": "1.25",
"normal": "1.5",
"relaxed": "1.75"
}
},
"spacing": {
"xs": "0.25rem",
"sm": "0.5rem",
"md": "1rem",
"lg": "1.5rem",
"xl": "2rem",
"2xl": "3rem"
},
"borderRadius": {
"sm": "0.25rem",
"md": "0.375rem",
"lg": "0.5rem",
"xl": "0.75rem",
"full": "9999px"
},
"shadows": {
"sm": "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
"md": "0 4px 6px -1px rgba(0, 0, 0, 0.1)",
"lg": "0 10px 15px -3px rgba(0, 0, 0, 0.1)",
"xl": "0 20px 25px -5px rgba(0, 0, 0, 0.1)"
},
"components": [
"Card",
"Circle",
"SpeechBubble",
"CharacterBadge",
"MediaCard"
]
},
"components": [
"Card",
"Circle",
"SpeechBubble",
"CharacterBadge",
"MediaCard"
]
}
]
},
"meta": {
"total_count": 1,
"timestamp": "2025-10-17T22:41:31.858417Z"
}
}
Get Specific Design
Retrieve detailed configuration for a specific design by its domain identifier.
URL Parameters
design- The domain identifier of the design
Response
https://tellstree.com/api/designs/{design}{
"data": {
"design": {
"design_id": 11,
"name": "Original",
"domain": "original",
"created_at": "2025-10-01T13:25:26.000000Z",
"updated_at": "2025-10-01T13:25:26.000000Z",
"statistics": {
"projects_count": 74,
"is_default": false
},
"configuration": {
"name": "Original",
"version": "1.0.0",
"description": "The original design recipe for TellsTree - timeless, refined, and expertly crafted.",
"author": "TellsTree Team",
"category": "classic",
"preview": "foundation-preview.jpg",
"colors": {
"primary": "#3B82F6",
"secondary": "#8B5CF6",
"accent": "#10B981",
"background": "#F8FAFC",
"surface": "#FFFFFF",
"text": {
"primary": "#1F2937",
"secondary": "#6B7280",
"muted": "#9CA3AF"
},
"border": "#E5E7EB",
"shadow": "rgba(0, 0, 0, 0.1)"
},
"typography": {
"fontFamily": {
"primary": "Inter, sans-serif",
"heading": "Inter, sans-serif",
"code": "JetBrains Mono, monospace"
},
"fontSize": {
"xs": "0.75rem",
"sm": "0.875rem",
"base": "1rem",
"lg": "1.125rem",
"xl": "1.25rem",
"2xl": "1.5rem",
"3xl": "1.875rem"
},
"fontWeight": {
"normal": "400",
"medium": "500",
"semibold": "600",
"bold": "700"
},
"lineHeight": {
"tight": "1.25",
"normal": "1.5",
"relaxed": "1.75"
}
},
"spacing": {
"xs": "0.25rem",
"sm": "0.5rem",
"md": "1rem",
"lg": "1.5rem",
"xl": "2rem",
"2xl": "3rem"
},
"borderRadius": {
"sm": "0.25rem",
"md": "0.375rem",
"lg": "0.5rem",
"xl": "0.75rem",
"full": "9999px"
},
"shadows": {
"sm": "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
"md": "0 4px 6px -1px rgba(0, 0, 0, 0.1)",
"lg": "0 10px 15px -3px rgba(0, 0, 0, 0.1)",
"xl": "0 20px 25px -5px rgba(0, 0, 0, 0.1)"
},
"components": [
"Card",
"Circle",
"SpeechBubble",
"CharacterBadge",
"MediaCard"
]
},
"components": [
"Card",
"Circle",
"SpeechBubble",
"CharacterBadge",
"MediaCard"
]
}
},
"meta": {
"timestamp": "2025-10-17T22:41:31.904987Z"
}
}
💬 Comments
Comments enable collaborative feedback and discussion within projects. Team members can leave notes, suggestions, and feedback to improve the narrative experience.
/api/commentsList all comments/api/commentsCreate new comment/api/comments/{comment}Get comment details/api/comments/{comment}Update comment/api/comments/{comment}Delete commentList Comments
Retrieve all comments or filter by project to see discussions and feedback.
Query Parameters
project_id- Filter by project ID (optional)user_id- Filter by author (optional)status- Filter by status (optional)page- Page number (optional)per_page- Items per page (optional)Response
https://tellstree.com/api/commentsCreate Comment
Add a new comment or feedback to a project for collaborative discussion.
Required Fields
content- Comment textproject_id- Project to attach comment toOptional Fields
priority- low/medium/highnode_id- Related node IDposition- UI position datatags- Array of tagsResponse
https://tellstree.com/api/comments