The Problem: AI Assistants Cannot Read Your API Documentation
You have spent hours writing a comprehensive API reference for TickDB. You have documented every endpoint, every parameter, every error code. You have even included code examples in Python, JavaScript, and Go.
Then a user asks an AI coding assistant: "How do I get the latest price for Bitcoin using TickDB?"
The AI responds with a hallucinated API call that looks nothing like TickDB's actual interface. The endpoint is wrong. The authentication header is missing. The parameter names are made up.
This is not a hypothetical. It is the daily reality of developers building AI-assisted workflows. Large language models are powerful, but they do not inherently understand your specific API's contract. They need a bridge.
TickDB's SKILL Protocol is that bridge. At its core is a single file — http://skill.md/ — that functions as a compact, machine-readable specification of everything an AI needs to interact with TickDB correctly.
This article dissects the SKILL protocol specification. You will learn what the skill.md file contains, how AI parsing tools interpret it, and how Function Calling definitions are structured to enable reliable, multi-turn market data conversations.
What Is the SKILL Protocol?
The SKILL Protocol is TickDB's implementation of a lightweight specification format designed specifically for AI assistant integration. Unlike OpenAPI specifications that target human developers, the SKILL protocol targets AI agents — systems that need to call APIs autonomously, maintain state across a conversation, and handle errors gracefully.
The protocol consists of three layers:
| Layer | Purpose | Format |
|---|---|---|
Skill Manifest (skill.md) |
Declares available tools, parameters, and behavioral rules | Markdown with structured YAML frontmatter |
| Function Definitions | Maps each API endpoint to a callable function with typed parameters | JSON Schema subset |
| Conversation Context | Maintains user intent and action history across turns | State managed by the AI agent |
The critical insight: the SKILL protocol is not an alternative to REST or WebSocket APIs. It is a meta-layer that describes your existing API in a way that AI systems can consume reliably.
Inside the skill.md File: Structure and Semantics
The skill.md file is the heart of the protocol. A well-formed skill.md contains four distinct sections, each serving a specific role in AI comprehension.
Section 1: Frontmatter Metadata
The file begins with YAML frontmatter that declares the skill's identity and constraints:
---
name: tickdb-market-data
version: "1.2.0"
description: Real-time and historical market data for crypto, US equities, HK stocks, and forex
provider: TickDB
authentication: API Key (X-API-Key header)
base_url: https://api.tickdb.ai/v1
max_concurrent_requests: 10
rate_limit_handling: exponential_backoff
---
This section tells the AI three things immediately:
- What the skill does — so it can route user requests appropriately.
- How to authenticate — the exact header name and format.
- Operational constraints — concurrency limits and retry behavior.
The AI does not need to guess at these parameters. They are declared explicitly.
Section 2: Tool Declarations
Each callable function is declared as a "tool" with structured metadata:
tools:
- name: get_kline
description: Retrieve historical OHLCV (candlestick) data for a given symbol and interval
category: historical_data
parameters:
symbol:
type: string
required: true
description: Exchange-symbol pair in format `SYMBOL.EXCHANGE` (e.g., BTC.USDT, AAPL.US)
examples:
- BTC.USDT
- ETH.USDT
- AAPL.US
interval:
type: string
required: true
description: Candlestick interval (e.g., 1m, 5m, 1h, 1d)
enum: [1m, 5m, 15m, 30m, 1h, 4h, 1d, 1w]
start_time:
type: integer
required: false
description: Unix timestamp in milliseconds for the start of the range
end_time:
type: integer
required: false
description: Unix timestamp in milliseconds for the end of the range
limit:
type: integer
required: false
default: 100
description: Maximum number of candles to return (1-1000)
returns:
type: object
fields: [timestamp, open, high, low, close, volume]
errors:
- code: 2002
message: Symbol not found
resolution: Verify symbol format and availability via /v1/symbols/available
This declaration is verbose by design. The AI needs to know not just what parameters exist, but what formats are valid, what defaults apply, and how to recover from errors. A sparse function declaration leads to unreliable AI behavior.
Section 3: Behavioral Rules
The skill.md file also encodes operational rules that govern how the AI should interact with the API:
behavior:
error_handling:
strategy: retry_with_backoff
max_retries: 3
backoff_base: 2
jitter: true
retryable_codes: [3001, 5000, 5001]
rate_limits:
requests_per_second: 10
burst: 20
response_action: wait_and_retry
data_freshness:
kline: "Historical — suitable for backtesting; not real-time"
depth: "Real-time — suitable for live monitoring; not historical"
trades: "Real-time — suitable for order flow analysis"
parameter_validation:
strict: true
coerce_types: false
The AI reads these rules and applies them autonomously. When a rate limit error occurs, the AI knows to wait and retry with exponential backoff. When a user asks for "the current price," the AI knows to use the depth channel rather than kline.
Section 4: Conversation Templates
Finally, the skill.md includes natural language templates that guide the AI's interaction patterns:
conversation_templates:
greeting: |
I am connected to TickDB market data. I can help you query historical prices,
monitor real-time order books, analyze trade flow, and build market data pipelines.
What would you like to explore?
clarification:
symbol_missing: |
To help you retrieve market data, I need to know the symbol you are interested in.
Format: `SYMBOL.EXCHANGE` (e.g., BTC.USDT, AAPL.US, 700.HK)
interval_missing: |
What time interval would you like for the candlestick data?
Options: 1m, 5m, 15m, 30m, 1h, 4h, 1d, 1w
These templates ensure that when the AI does not have enough information, it asks clarifying questions in a consistent, user-friendly way rather than hallucinating parameters.
Function Calling: The Bridge Between Natural Language and API Calls
Function Calling is the mechanism that transforms a user's natural language request into a structured API call. The SKILL protocol defines Function Calling through a JSON Schema specification that maps each tool's parameters to OpenAI-compatible function call objects.
The Function Call Object
When the AI decides to call a TickDB tool, it generates a function call object structured as follows:
{
"name": "get_kline",
"arguments": {
"symbol": "BTC.USDT",
"interval": "1h",
"start_time": 1717200000000,
"end_time": 1717286400000,
"limit": 100
}
}
The AI constructs this object by:
- Parsing the user's intent ("Show me Bitcoin's hourly prices for the past week").
- Selecting the appropriate tool (
get_kline). - Extracting entities from the request (symbol = "BTC.USDT", interval = "1h").
- Computing time boundaries relative to the current time.
- Validating parameters against the tool's schema.
Multi-Turn Conversation: Maintaining State Across Interactions
Raw function calls are stateless. Each call is independent. But market data workflows are inherently stateful — a user might first retrieve a list of available symbols, then fetch kline data for a selected symbol, then subscribe to real-time depth updates for the same symbol.
The SKILL protocol handles multi-turn conversations through a context stack:
class ConversationContext:
def __init__(self):
self.symbol: Optional[str] = None
self.interval: Optional[str] = None
self.last_query_result: Optional[dict] = None
self.action_history: list[dict] = []
def update(self, action: str, params: dict, result: dict):
"""Push a completed action to the context stack."""
self.action_history.append({
"action": action,
"params": params,
"timestamp": current_timestamp_ms()
})
# Propagate inferred context
if "symbol" in params:
self.symbol = params["symbol"]
if "interval" in params:
self.interval = params["interval"]
self.last_query_result = result
def get_active_symbol(self) -> Optional[str]:
"""Return the most recently used symbol."""
return self.symbol
def summarize(self) -> str:
"""Generate a human-readable context summary for prompt injection."""
lines = ["## Conversation Context"]
if self.symbol:
lines.append(f"- Active symbol: {self.symbol}")
if self.interval:
lines.append(f"- Active interval: {self.interval}")
lines.append(f"- Actions so far: {len(self.action_history)}")
return "\n".join(lines)
When a new user message arrives, the AI injects the context summary into the system prompt:
## Conversation Context
- Active symbol: BTC.USDT
- Active interval: 1h
- Actions so far: 2
## User Message
Should I subscribe to depth or trades for monitoring this?
Now the AI knows the active symbol is BTC.USDT without the user repeating it. This is what enables fluid, natural multi-turn interactions.
Error Recovery Across Turns
Error handling in multi-turn conversations is where most AI-API integrations fail. The SKILL protocol defines a structured error recovery workflow:
def handle_tickdb_error(code: int, message: str, context: ConversationContext) -> str:
"""
Generate a user-facing recovery message based on error code and conversation state.
Returns a natural language response that either resolves the issue or
requests clarification.
"""
recovery_map = {
1001: {
"user_message": "Your API key appears to be invalid. Please check that "
"the TICKDB_API_KEY environment variable is set correctly.",
"requires_user_action": True
},
2002: {
"user_message": f"The symbol '{context.get_active_symbol()}' was not found. "
f"Let me show you available symbols for this exchange.",
"fallback_action": "list_symbols",
"requires_user_action": False
},
3001: {
"user_message": "We hit a rate limit. Retrying automatically in a moment.",
"requires_user_action": False,
"retry": True
}
}
handler = recovery_map.get(code, {
"user_message": f"An unexpected error occurred ({code}): {message}. "
f"Please try again or contact support.",
"requires_user_action": True
})
return handler["user_message"]
The AI does not crash or produce gibberish. It reads the error code, consults the recovery map, and responds with either a fix or a clear request for user input.
How AI Parsing Tools Consume the Protocol
A well-formed skill.md file can be consumed by multiple AI parsing tools. The parsing pipeline typically follows three stages.
Stage 1: YAML Frontmatter Extraction
The first parsing stage extracts the YAML frontmatter using a standard YAML parser:
import yaml
import re
def parse_frontmatter(content: str) -> dict:
"""Extract YAML frontmatter from skill.md content."""
pattern = r'^---\n(.*?)\n---'
match = re.search(pattern, content, re.DOTALL)
if not match:
raise ValueError("Missing or malformed frontmatter in skill.md")
return yaml.safe_load(match.group(1))
Stage 2: Tool Registration
The second stage iterates through declared tools and registers them in the AI's function registry:
def register_tools(skill_md_content: str) -> list[dict]:
"""Parse tool declarations and convert to OpenAI-compatible function definitions."""
# Extract YAML frontmatter
frontmatter = parse_frontmatter(skill_md_content)
# Extract tools section using markdown parsing
tools_section = extract_section(skill_md_content, "tools:")
tools = yaml.safe_load(tools_section)
# Convert to OpenAI function calling format
function_definitions = []
for tool in tools:
function_def = {
"type": "function",
"function": {
"name": tool["name"],
"description": tool["description"],
"parameters": {
"type": "object",
"properties": {},
"required": []
}
}
}
for param_name, param_spec in tool.get("parameters", {}).items():
function_def["function"]["parameters"]["properties"][param_name] = {
"type": param_spec["type"],
"description": param_spec["description"]
}
if param_spec.get("required"):
function_def["function"]["parameters"]["required"].append(param_name)
function_definitions.append(function_def)
return function_definitions
Stage 3: Context Injection at Runtime
At runtime, the AI agent injects the conversation context and behavioral rules into each prompt:
def build_system_prompt(skill_md_content: str, context: ConversationContext) -> str:
"""Assemble the full system prompt from skill.md and conversation state."""
frontmatter = parse_frontmatter(skill_md_content)
behavior = extract_section(skill_md_content, "behavior:")
templates = extract_section(skill_md_content, "conversation_templates:")
prompt_parts = [
f"# TickDB Market Data Skill — v{frontmatter['version']}",
f"**Provider**: {frontmatter['provider']}",
f"**Base URL**: {frontmatter['base_url']}",
f"**Authentication**: {frontmatter['authentication']}",
"",
"## Behavioral Rules",
behavior,
"",
"## Conversation Templates",
templates,
"",
"## Context",
context.summarize(),
"",
"You have access to the following tools. "
"Use them to answer the user's request. "
"Always validate parameters against the declared schema "
"before making a call. Always handle errors gracefully."
]
return "\n".join(prompt_parts)
The resulting system prompt is self-contained. The AI knows the API's capabilities, constraints, conversation style, and current state — all without needing external documentation.
Practical Example: A Four-Turn Market Data Conversation
To make this concrete, here is a complete four-turn conversation as handled by a SKILL-aware AI agent.
Turn 1 — User: "Show me the top 5 crypto symbols by 24h volume."
AI Decision: Call get_trades (with symbol discovery) or list_symbols.
Selected: list_symbols with category filter "crypto" and sort by volume.
Call: list_symbols(category="crypto", sort_by="volume", order="desc", limit=5)
Response: [BTC.USDT, ETH.USDT, SOL.USDT, DOGE.USDT, XRP.USDT]
Context Update: symbol=None → awaiting user selection
Turn 2 — User: "Give me the hourly kline data for the first one."
AI Decision: User said "first one." Parse context to resolve.
Resolved symbol: BTC.USDT (the first result from Turn 1)
Call: get_kline(symbol="BTC.USDT", interval="1h", limit=100)
Response: Array of OHLCV candles with timestamps
Context Update: symbol=BTC.USDT, interval=1h
Turn 3 — User: "Also show me the order book depth right now."
AI Decision: symbol is already in context. Interval not needed for depth.
Call: subscribe_depth(symbol="BTC.USDT", levels=10)
Response: Real-time order book snapshot (top 10 levels bid/ask)
Context Update: active subscription = depth channel
Turn 4 — User: "Calculate the buy/sell pressure ratio."
AI Decision: No API call needed. Compute from the depth data already received.
Compute: Σ(bid sizes, top 10 levels) / Σ(ask sizes, top 10 levels)
Response: "Current buy/sell pressure ratio: 1.47 (buyers have 47% more
liquidity at the top 10 levels than sellers)"
Each turn is self-contained yet contextually aware. The AI never asks for information it already has. It never makes up an endpoint. It never ignores an error code.
Deployment Architecture: SKILL in Production
When you install the TickDB SKILL in your AI coding assistant, the integration follows this architecture:
┌─────────────────────────────────────────────────────────┐
│ User's AI Assistant │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ System Prompt│ │ Skill Registry│ │ Tool Executor│ │
│ │ (skill.md) │ │ (parsed tools)│ │ (API client) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└────────────────────────────┬────────────────────────────┘
│ Function Calls
▼
┌─────────────────────┐
│ TickDB REST API │
│ (authenticated) │
└─────────────────────┘
The SKILL file is fetched once during skill initialization, parsed into the tool registry, and used to construct every system prompt thereafter. The API calls themselves are routed through the standard TickDB REST API with the user's API key.
Best Practices for SKILL-Compatible Queries
To get the most out of the SKILL protocol, structure your queries with the following principles:
| Principle | Poor query | SKILL-friendly query |
|---|---|---|
| Be specific about symbol | "Get price data" | "Get 1h kline data for BTC.USDT" |
| State the data type explicitly | "Show me some data" | "Subscribe to depth channel for ETH.USDT" |
| Reference context when continuing | "Now show the other one" | "Show me kline data for ETH.USDT at the same interval" |
| Specify time boundaries | "Get historical prices" | "Get 4h kline for AAPL.US from 2024-01-01 to 2024-06-30" |
| Ask for derived metrics | "Is the market bullish?" | "Calculate the buy/sell pressure ratio from current depth" |
The more explicit the query, the more reliably the AI resolves it to the correct function call.
Conclusion
The SKILL Protocol transforms TickDB from an API you have to read documentation to use into an intelligence you can simply talk to.
The skill.md file is the Rosetta Stone. It translates TickDB's REST contract into a language AI systems understand — structured tool declarations, behavioral rules, conversation templates, and error recovery maps. Function Calling definitions give AI agents the mechanics to translate natural language into precise API calls. The conversation context system maintains state across turns, enabling fluid multi-step market data workflows.
When your AI assistant can say "The buy/sell pressure ratio has inverted to 0.68 — that suggests short-term downside pressure building at the top of the order book" rather than "I could not find an endpoint for that," you have a market data assistant that genuinely accelerates your workflow.
Next Steps
If you are a developer integrating AI into a trading workflow, install the tickdb-market-data SKILL in your AI coding assistant's marketplace and start with a multi-turn query using the patterns above.
If you are building an AI agent that calls TickDB, download the skill.md file from tickdb.ai and parse it using the extraction pipeline described in this article. Your agent will immediately gain access to all declared tools, error codes, and conversation templates.
If you need institutional-grade rate limits and concurrent connections, contact enterprise@tickdb.ai for plans that extend the SKILL protocol with priority routing and dedicated throughput.
This article does not constitute investment advice. Markets involve risk; past performance does not guarantee future results.