AI HOT Skill
Enable Agents to query daily AI HOT digests and all AI updates on aihot.virxact.com in natural Chinese, without opening a browser. It follows the SKILL.md standard format and is compatible with Claude Code / Codex CLI / Cursor / Gemini CLI / OpenCode / any compatible platforms.
Online:
https://aihot.virxact.com (public and accessible anonymously, no token required)
Prerequisite: Must include User-Agent (API endpoints only)
The
endpoints use an nginx UA blacklist to block commercial crawlers; the default
UA will result in 403 Forbidden.
All curl requests to the API must include a browser UA:
bash
UA="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
# Add -H "User-Agent: $UA" to all subsequent curl requests to the API, for example:
curl -sH "User-Agent: $UA" "https://aihot.virxact.com/api/public/daily"
The curl examples in the "Workflow" section below assume you have already set
for brevity——you must add
in actual calls,
do NOT forget. Missing this step will make you think the endpoint is down, but it's just blocked by 403.
Scope Clarification: This UA requirement
only applies to API endpoints. The installation entry paths
/aihot-skill/{install.sh,SKILL.md,README.md}
are
exempted from the UA blacklist on nginx (designed to support one-line installation via
), so the default curl UA will return 200 directly. Do not incorrectly extend the "prerequisite" to all paths on aihot.virxact.com.
When to Use
Routing Priority (First Principle):
Default to Selected ——it's the daily curated "main menu" of AI HOT, covering what users care about with fresh data.
- Only route to when users explicitly mention "daily report" in their query (it's an edited product sliced by UTC full day, which doesn't align with rolling windows like "past 24 hours / today")
- Only route to when users explicitly say "all / complete / full / entire" (includes unselected secondary items, large volume but messy)
- Broad queries like "Today's AI circle", "Big news in the past 24 hours", "What's new in AI recently" = Default Selected + time window (since), do not default to daily report or all items
This aligns with users' semantic priorities: Selected is the main menu, daily report and all items are optional alternatives that users specifically request, and should not take the default route.
| User Query | Corresponding Endpoint |
|---|
| Default (broad queries): "What's happening in the AI circle today", "Big news in the past 24 hours", "Latest AI circle updates", "What's new in AI" | GET /api/public/items?mode=selected&since=<semantic time window>
(default selected + narrowed by since) |
| Explicitly mentions "daily report": "AI Daily", "Today's daily report", "Check the daily report" | (latest daily report) |
| Explicitly says "all / complete / full / entire": "Check all AI updates today", "Complete list", "All AI updates" | GET /api/public/items?mode=all
(since parameter depends on user context) |
| "Yesterday/the day before yesterday's AI Daily", "Check the daily report for May 6" | GET /api/public/daily/{YYYY-MM-DD}
|
| "What daily reports are available recently", "List the daily reports", "Daily report archive" | GET /api/public/dailies?take=N
|
| "Check selected items", "AI HOT Selected" | GET /api/public/items?mode=selected
|
| "Latest model releases", "AI product launches", "AI industry dynamics", "AI papers" | GET /api/public/items?mode=selected&category=...&since=<7 days ago>
(default selected + category) |
| "AI updates in the past week", "Releases from 5 days ago to now" | GET /api/public/items?mode=selected&since=ISO-8601
|
| "Latest releases from OpenAI/Anthropic/Google"(company dimension) | GET /api/public/items?q=OpenAI
(server-side keyword search, launched on 2026-05-08) |
| "Sora-related / GPT-5-related / RAG papers" | GET /api/public/items?q=<keyword>
(matches title + Chinese title + Chinese summary columns) |
General heuristic: When users ask about "current AI industry facts", do not rely on training data to guess, always use the API. Even if you "think" you know the answer, check it——AI HOT is much newer than your training cutoff date, and focuses on topics relevant to Chinese entrepreneurs.
Endpoint Overview
| Endpoint | Purpose | Main Parameters |
|---|
| Latest daily report | None |
/api/public/daily/{YYYY-MM-DD}
| Daily report for specified date | path: |
| Daily report archive list | (1-180, default 30) |
| All AI updates | / / / / / (keyword) |
Conventions:
- Base URL:
https://aihot.virxact.com
- Authentication: None (anonymous)
- Rate Limit: 600 req/min/IP (please call serially, do not pull concurrently aggressively)
- parameter for items endpoint is limited to the last 7 days:not passing it equals since=now-7d(server-side fallback); dates earlier than 7 days ago will be automatically truncated to 7 days ago; future dates → 400. Therefore, no matter how the Skill calls it, the items API will only return content from the last 7 days. For earlier content → use
/api/public/daily/{YYYY-MM-DD}
to browse daily report archives
- upper limit is 100; use cursor for pagination if more is needed
- Complete OpenAPI 3.1 specification:
https://aihot.virxact.com/openapi.yaml
Workflow
Default Path: Pull Selected + Time Window (Preferred for Broad Queries)
Selected = AI HOT's daily curated "main menu"——covers all major AI events users care about, sorted in reverse chronological order.
For any broad queries like "Today's AI circle", "Big news in the past 24 hours", "What's new in AI recently", default to this path——compared to daily reports: ① Flexible time window (can be as narrow as 24 hours / 3 days / 1 week, aligning with user semantics) ② Fresh data (real-time rolling instead of sliced by UTC full day) ③ High quality (pool of
items, excluding secondary entries).
bash
# Pull selected items from the past 24 hours (user asks "Big news in the past 24 hours")
since=$(date -u -v-24H +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d '24 hours ago' +%Y-%m-%dT%H:%M:%SZ)
curl -sH "User-Agent: $UA" "https://aihot.virxact.com/api/public/items?mode=selected&since=$since&take=50"
# Pull latest 50 selected items (user asks "Check selected items" / no explicit time window)
curl -sH "User-Agent: $UA" "https://aihot.virxact.com/api/public/items?mode=selected&take=50" \
| jq '.items[] | {title, source, publishedAt, url}'
Pull Daily Report (When Users Explicitly Mention "Daily Report")
Trigger Keywords: The word "daily report" appears in the sentence ("AI Daily", "Today's daily report", "Check the daily report", "Daily report for May 6"). Do not route to this endpoint without the word "daily report"——daily reports are fixed daily products sliced at UTC 00:00, which do not align with rolling time windows like "past 24 hours / today".
Daily reports are the "title layer" of AI HOT——automatically generated at 08:00 Beijing time every day, divided into sections by topic (5 fixed sections). It includes an "Editor's Note" lead paragraph, which is a packaged product grouped by topic.
bash
# Pull today's (or latest available) daily report
curl -sH "User-Agent: $UA" "https://aihot.virxact.com/api/public/daily" \
| jq '{date, lead: .lead.title, sections: [.sections[] | {label, n: (.items | length)}]}'
Pull Daily Report for Specified Date
bash
# YYYY-MM-DD, based on UTC 00:00
curl -sH "User-Agent: $UA" "https://aihot.virxact.com/api/public/daily/2026-05-07"
List Daily Report Archive (discovery)
When unsure which dates are available, check the archive first:
bash
# Index of latest N daily reports (no content, only date + lead title)
curl -sH "User-Agent: $UA" "https://aihot.virxact.com/api/public/dailies?take=14" \
| jq '.items[] | {date, leadTitle}'
Pull All Items (When Users Explicitly Say "All / Complete / Full / Entire")
Trigger Keywords: The words "all", "complete", "full", "entire", "including older items" appear in the sentence——users actively want to see secondary items excluded from the selected pool (relevant but not curated content). Do not use mode=all without these keywords——selected items already cover most of what users care about, while the full pool is large and messy.
bash
# Pull all AI updates from the past 24 hours (user asks "Check all AI updates today")
since=$(date -u -v-24H +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d '24 hours ago' +%Y-%m-%dT%H:%M:%SZ)
curl -sH "User-Agent: $UA" "https://aihot.virxact.com/api/public/items?mode=all&since=$since&take=100"
Pull Items by Category
5 categories(items API uses English slugs, daily API shows Chinese section labels):
| |
|---|
| 模型发布/更新 (Model Releases/Updates) |
| 产品发布/更新 (Product Launches/Updates) |
| 行业动态 (Industry Dynamics) |
| 论文研究 (Paper Research) |
| 技巧与观点 (Tips & Insights) |
When users ask "What's new on official accounts": items API does not include official accounts (mp_hot sources are available separately on the frontend page), the Skill cannot answer such questions for now, and can prompt users to visit https://aihot.virxact.com/mp
to view the official account trending articles page.
bash
# Example: Pull latest 50 AI papers (default selected + paper category)
curl -sH "User-Agent: $UA" "https://aihot.virxact.com/api/public/items?mode=selected&category=paper&take=50" \
| jq '.items[] | {title, source, publishedAt, url}'
# Example: Selected model releases
curl -sH "User-Agent: $UA" "https://aihot.virxact.com/api/public/items?mode=selected&category=ai-models&take=20"
# Exception: Only use mode=all when users explicitly say "all papers / all model releases"
curl -sH "User-Agent: $UA" "https://aihot.virxact.com/api/public/items?mode=all&category=paper&take=100"
Pull Items by Time Window (Last N Days)
Key Rule: When users ask "
Latest X"(latest model releases / latest AI papers / latest OpenAI updates, etc.), include the
parameter to narrow the window to the user's actual intent (3d for "latest 3 days", 1d for "yesterday", 7d for "latest week").
Server-side Fallback: The items API defaults to
(hard limit to protect the server), so even if the Skill does not include since at all, it will only return content from the last 7 days, not old items from months ago. But
it is still recommended to explicitly include since: ① More precise when users ask "latest 3 days" than letting the server default to 7d ② Can write human-readable time window in metadata ③ Aligns with the publicly advertised "max 7 days" for clear intent.
bash
# Pull selected model releases from the past 7 days(user asks "Latest model releases")
since=$(date -u -v-7d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d '7 days ago' +%Y-%m-%dT%H:%M:%SZ)
curl -sH "User-Agent: $UA" "https://aihot.virxact.com/api/public/items?mode=selected&category=ai-models&since=$since&take=100"
# Pull selected updates from the past 3 days(user explicitly says "latest 3 days")
since=$(date -u -v-3d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d '3 days ago' +%Y-%m-%dT%H:%M:%SZ)
curl -sH "User-Agent: $UA" "https://aihot.virxact.com/api/public/items?mode=selected&since=$since&take=100"
Exception: When users explicitly say "
full / all / complete list / including older items" → switch mode to
, can omit since; when users ask "
Check selected items"(view selected pool instead of time window), keep mode as
and can omit since. But as long as the sentence includes "latest / newest / these two days / this week",
default to including since + mode=selected.
Pagination (cursor)
The
response includes
(opaque token), which can be passed as the
parameter in the next request.
bash
# Page 1
resp1=$(curl -sH "User-Agent: $UA" "https://aihot.virxact.com/api/public/items?mode=all&take=100")
echo "$resp1" | jq '.items | length' # 100
# Page 2
cursor=$(echo "$resp1" | jq -r '.nextCursor')
curl -sH "User-Agent: $UA" "https://aihot.virxact.com/api/public/items?mode=all&take=100&cursor=$cursor"
Stop pagination when
or
.
The cursor is an opaque token, treat it as a black box, do not attempt to parse, increment, or reuse across endpoints.
Keyword Search ("Latest from OpenAI" / "Sora-related" / "RAG papers")
The API directly supports server-side keyword search — the
parameter performs ILIKE matching on
+ Chinese
+ Chinese
columns, using PostgreSQL pg_trgm GIN index (2-6ms).
Do not use the "pull a batch + client jq grep" pattern — that can only find matches in the first 100 items, and misses keywords outside this range.
bash
# Find latest releases from OpenAI(covers full pool, not just first 100)
curl -sH "User-Agent: $UA" "https://aihot.virxact.com/api/public/items?q=OpenAI&take=30"
# Find all AI updates related to Sora(any title or summary containing Sora)
curl -sH "User-Agent: $UA" "https://aihot.virxact.com/api/public/items?q=Sora"
# Find RAG papers(category filter + keyword)
curl -sH "User-Agent: $UA" "https://aihot.virxact.com/api/public/items?category=paper&q=RAG&take=30"
# Keyword + time window(selected items from Anthropic in the past 3 days)
SINCE=$(date -u -v-3d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d '3 days ago' +%Y-%m-%dT%H:%M:%SZ)
curl -sH "User-Agent: $UA" "https://aihot.virxact.com/api/public/items?mode=selected&q=Anthropic&since=$SINCE"
- At least 2 characters(single-character GIN trigram falls back to full table scan, server treats it as no search)
- Maximum 200 characters(excess is automatically truncated)
- Orthogonal to other parameters(mode/category/since/take/cursor), can combine "selected + paper + keyword + within 7 days"
- Shares the 600r/m rate limit with other requests
Return Data Structure
Response
json
{
"date": "2026-05-07",
"generatedAt": "2026-05-07T00:01:23.456Z",
"windowStart": "2026-05-06T00:00:00.000Z",
"windowEnd": "2026-05-07T00:00:00.000Z",
"lead": { "title": "...", "leadParagraph": "..." },
"sections": [
{
"label": "模型发布/更新",
"items": [
{
"title": "...",
"summary": "...",
"sourceUrl": "https://...",
"sourceName": "OpenAI Blog"
}
]
}
],
"flashes": [
{ "title": "...", "sourceName": "...", "sourceUrl": "...", "publishedAt": "..." }
]
}
has 5 fixed values: "模型发布/更新" / "产品发布/更新" / "行业动态" / "论文研究" / "技巧与观点".
is
for very few daily reports.
Response
json
{
"count": 14,
"items": [
{ "date": "2026-05-07", "generatedAt": "...", "leadTitle": "..." }
]
}
Response
json
{
"count": 50,
"hasNext": true,
"nextCursor": "eyJhIjoxNzE0OTk1MjAwMDAwLCJpIjoiY205eHl6MTIzIn0",
"items": [
{
"id": "cm9abc456def789ghi012jkl3",
"title": "中文标题(normalize 过)",
"title_en": "原英文标题(仅当与 title 不同时存在,否则 null)",
"url": "https://...",
"source": "OpenAI Blog",
"publishedAt": "2026-05-07T15:30:00.000Z",
"summary": "中文摘要(LLM 生成)",
"category": "ai-models"
}
]
}
Field invariants:
- Required: / / /
- Optional: / / /
- values: / / / / /
- : ISO 8601 UTC (with )
- : cuid string (25 characters), do not assume it is a number
Output Format for Users
⚠️ Core Principle: This section is the final content directly presented to users——must be in markdown format, well-formatted, and human-readable plain language. Most users are non-technical AI entrepreneurs / designers / general readers, and what they see should be Chinese news briefings, not API debug logs.
All infrastructure details such as "endpoint paths / raw parameters like
/ rate limits / nginx caching / cursor / hasNext"
must not appear in the output seen by users. Human-readable metadata(time window / number of items / "sorted in reverse chronological order") can be retained——judgment standard: Can users understand it directly? Yes → retain; No → delete.
Daily Report-style Output (When using daily / daily/{date} endpoints)
markdown
**AI HOT Daily Report · 2026-05-07**
## 模型发布/更新
1. **<title>** — <source>
<summary simplified to within 50 characters>
<url>
## 产品发布/更新
2. ...
## 行业动态
3. ...
## 论文研究
4. ...
## 技巧与观点
5. ...
## 快讯(如果 flashes 有内容)
- <flash.title> — <flash.source> (<flash.publishedAt converted to human-readable time>)
Numbering runs through the entire document (1, 2, 3 ... N), do not restart counting within each ## section——this allows users to easily see "27 items today".
List-style Output (When using items endpoint)
Default to grouping by category + global numbering——users have formed expectations for the 5-section structure of "models/products/industry/papers/tips" from daily reports, so this structure is most natural when categories are mixed:
markdown
**AI HOT — Latest 30 Selected Items**
## 模型发布/更新
1. **<title>** — <source>
2 hours ago
<summary>
<url>
## 产品发布/更新
2. **<title>** — <source>
...
3. ...
## 行业动态
4. ...
When there is only 1 category (users explicitly ask "AI papers"/"model releases", etc.), use a flat numbered list:
markdown
**AI HOT — AI Papers from the Past Week** (2026-05-01 ~ 2026-05-08)
1. **<title>** — <source>
<summary>
<url>
2. ...
Subtitles / Metadata Only in Plain Language
OK (users can understand directly):
- "Time window: 2026-05-05 ~ 2026-05-07"
- "All items matching OpenAI keyword in the past 3 days"
- "Sorted in reverse chronological order"
- "Total 50 items"
- "Today's 5/8 daily report will be generated after 08:00 Beijing time, please view the 5/7 issue first"
NOT OK (infrastructure leakage, strictly prohibited):
- ❌ Raw parameter names like / /
- ❌ Endpoint path
/api/public/items?since=2026-04-30T18:39:31Z&take=50
- ❌ "Rate limit 600 req/min" / "nginx caching 60s" / "x-nginx-cache: HIT"
- ❌ "cursor" / "hasNext=true" / "Need to paginate with cursor or narrow since window"
- ❌ Any HTTP status code / cache status / backend mechanism description
At most write one sentence about the data source: "Data from aihot.virxact.com", or omit it entirely (users already know the source when using the skill).
Convert Time to Human-readable Format
is ISO 8601 UTC, when displaying it
must be converted to Beijing time + human-readable relative/absolute time:
| Internal Value | Display to Users |
|---|
| "09:48 AM today" / "2 hours ago" |
| "02:08 AM today" / "10 hours ago" |
| "00:43 on 5/7" / "Yesterday" |
Do NOT directly display ISO strings like
——users cannot understand them.
title vs title_en
Default to outputting
(normalized Chinese).
should only be used in the following scenarios:
- Users explicitly request English version ("Show me in English")
- is empty (extremely rare)
Do NOT display both.
Common Error Handling
{"error":"No daily report available yet."}
(HTTP 404): The daily report for the day has not been generated yet (before 08:00 Beijing time). Suggest pulling yesterday's daily report for users: curl /api/public/daily/{yesterday's date}
{"error":"Invalid date format..."}
(HTTP 400): Date must be in format, based on UTC
- Common 400 errors for items endpoint:
"invalid mode (must be 'selected' or 'all')"
"invalid category (must be one of: ai-models, ai-products, industry, paper, tip)"
"invalid since (must be ISO date, not in future)"
"invalid take (must be integer 1-100)"
- HTTP 429 (rate limit exceeded): Single IP exceeds 600 req/min. Call serially + add 200ms interval between pagination requests
Do NOT
- Do NOT route broad queries like "Today's AI circle", "Big news in the past 24 hours", "What's new in AI recently" to daily——these are rolling time windows, while daily reports are fixed daily products sliced at UTC 00:00 (full day from 5/6 to 5/7), which do not match in time precision. Default to
mode=selected + since=<semantic window>
. Only route to when users explicitly mention "daily report" in their query
- Do NOT default to when users do not say "all / complete / full / entire"——selected items already cover most of what users care about, while the full pool is large and messy with unselected secondary items. Default to , only switch to when users actively request "all"
- Do NOT attempt to guess / fabricate content——always rely on API responses
- Do NOT treat the summary () as original reference——the summary is generated by LLM, check back to / for references
- Do NOT perform high-frequency polling——daily reports are only updated once at 08:00, items endpoint has 5-minute server-side caching, no need to re-call the API for the same user query
- Do NOT pull pagination concurrently aggressively——call serially with natural intervals
- Do NOT attempt to parse / increment / reuse cursor across endpoints——it is an opaque token, internal encoding format is unstable and will not be notified when changed
- Use server-side for company-dimension / keyword queries, do not use "pull a batch + client jq grep"(that can only see the first 100 items and will miss results)
- Explicitly include when users ask "Latest N days of X"(clear intent + metadata can write human-readable time window). Without since, the server defaults to 7d fallback, so no old items will be pulled, but when users ask "latest 3 days", letting the server default to 7d will include 4 extra days of content
- Do NOT expose infrastructure details like endpoint paths / raw parameters / rate limits / cache TTL / cursor / hasNext in user output——these are for developers, users cannot understand them. See "Output Format for Users → Subtitles / Metadata Only in Plain Language" above
- Do NOT lose the sourceUrl of each item when compressing / merging across days / sections——even if you merge 3 daily reports into 5-category summaries for brevity, each item must retain its url (after title or on a separate line). If users see an item without a url, they cannot trace back to the original source, making the information untrustworthy
- Do NOT use "endpoint paths / call details" as the reference source in output——write (OpenAI Official Website / Anthropic Newsroom / X: Berry Xia, etc.) as the reference source, not
GET /api/public/items?...