7.4 KiB
Dune API Skill For OpenClaw Agents
You are working with the Dune API, a Node.js Express service that imports Dune: Awakening data from Questlog into MongoDB and exposes it through REST endpoints for OpenClaw.
Primary Goal
Help OpenClaw retrieve complete Dune: Awakening records with the least guesswork. Prefer the detailed singular datasets for client-facing lookups and search.
Public Base URL
Use this production API base URL:
https://dune.api.coppnic.cc
Swagger/OpenAPI is available here:
https://dune.api.coppnic.cc/openapi.json
https://ui.dune.api.coppnic.cc/docs
Best Endpoints For OpenClaw
Prefer singular datasets because they contain full Questlog single-record payloads in raw:
GET /api/item
GET /api/item/{id}
GET /api/skill
GET /api/skill/{id}
GET /api/recipe
GET /api/recipe/{id}
GET /api/placeable
GET /api/placeable/{id}
GET /api/npc
GET /api/npc/{id}
Useful examples:
GET /api/item/LongRifle_Unique_Poison_03?language=en
GET /api/item/Bloodsack_02?language=en
GET /api/skill/skills_ability_poisonmine?language=en
GET /api/recipe/Bloodsack_2_Recipe?language=en
GET /api/placeable/Atre_Banner_Placeable?language=en
GET /api/npc/bs43q?language=en
For text search:
GET /api/search?q=rifle&datasets=item&language=en
GET /api/search?q=poison&datasets=item,skill,recipe&language=en
Supported languages are en and de.
Dataset Rules
Detailed singular datasets:
| Dataset | Mongo collection | Questlog detail method |
|---|---|---|
item |
item |
database.getItem |
skill |
skill |
database.getSkill |
recipe |
recipe |
database.getRecipe |
placeable |
placeable |
database.getPlaceable |
npc |
npc |
database.getNpc |
Summary plural datasets:
| Dataset | Mongo collection | Questlog page method |
|---|---|---|
items |
items |
database.getItems |
skills |
skills |
database.getSkills |
recipes |
recipes |
database.getRecipes |
placeables |
placeables |
database.getPlaceables |
npcs |
npcs |
database.getNpcs |
Use plural datasets only when a compact Questlog page-summary record is enough. If a plural lookup includes an id, for example /api/items/LongRifle_Unique_Poison_03, the API checks the matching singular collection first and falls back to the plural summary collection.
Response Shape
Stored documents have normalized metadata and the original Questlog payload:
{
"dataset": "item",
"language": "en",
"source": "questlog.gg",
"sourceMethod": "database.getItem",
"sourceId": "LongRifle_Unique_Poison_03",
"name": "Assassin's Rifle",
"raw": {}
}
For OpenClaw, inspect raw for domain-specific fields:
- Items:
raw.stats,raw.mainCategory,raw.subCategory, recipe relationships, wearable/equip fields. - Skills:
raw.levels,raw.connections, grid position, bonuses. - Recipes:
raw.recipeInputItems,raw.recipeOutputItems, crafting requirements, crafting stations. - Placeables: production types, power/water fields, craftable recipe relationships.
- NPCs:
raw.description,raw.npcTags, category metadata.
Discord Markdown Output Contract
Rich Discord embeds are not available yet. When OpenClaw asks for Discord output, return a plain Discord message string formatted with Discord-supported Markdown only. Do not return embed JSON.
Use supported Markdown:
- Headings with
#,##, or###for short section titles. - Bold with asterisks, for example
**Assassin's Rifle**. Do not use underscores for bold. - Italic sparingly for secondary text.
- Unordered lists with
-for fields and search results. - Ordered lists for ranked results.
- Inline code for ids, dataset names, stat keys, and short values.
- Fenced code blocks for compact JSON or command examples.
- Links with
[label](url)when a clean label helps. - Blockquotes with
>or>>>for quoted descriptions. - Strikethrough only when it adds useful meaning.
Avoid unsupported or unreliable formatting:
- No Markdown tables.
- No HTML.
- No horizontal rules.
- No task lists.
- No footnotes, heading ids, definition lists, subscript, superscript, or highlight syntax.
- No images in Markdown.
- Do not rely on Markdown paragraph syntax or special line-break syntax; use normal newline-separated lines.
Default Discord result format:
## Assassin's Rifle
**Type:** `item`
**Language:** `en`
**Source ID:** `LongRifle_Unique_Poison_03`
**Category:** `weapon` / `rifle`
**Stats**
- Damage: `128.25`
- Accuracy: `1.2`
- Clip Size: `2`
[Open in Dune API](https://dune.api.coppnic.cc/api/item/LongRifle_Unique_Poison_03?language=en)
Search result format:
## Search Results: poison
1. **Poison Mine** (`skill`) - `skills_ability_poisonmine`
2. **Assassin's Rifle** (`item`) - `LongRifle_Unique_Poison_03`
Use `/api/{dataset}/{id}?language=en` for details.
Discord response rules:
- Keep responses concise enough for Discord message limits.
- Show at most 10 compact search results unless the user asks for more.
- For detailed records, prefer the most useful 5 to 8 fields.
- Do not dump the full
rawobject. - Omit empty, null, unknown, or noisy fields.
- Include a Dune API link for single-record answers.
- Prefer singular datasets:
item,skill,recipe,placeable,npc.
Dataset field ideas:
item: grade, category, subcategory, weapon stats, armor stats, fillable stats.skill: category, subcategory, max skill level, level bonuses.recipe: output items, input items, crafting time, required stations.placeable: category, power, water, supported production types.npc: category, tags, description.
Repository Map
Look here when changing behavior:
src/datasets.js Dataset keys, collections, Questlog methods, API allowlists.
src/importer/questlogClient.js Questlog URL building and TRPC response extraction.
src/importer/importer.js Import orchestration, detail fetches, Mongo upserts.
src/db/indexes.js Mongo indexes for summary and singular collections.
src/routes/api.js REST API routes, search, dataset lookup behavior.
src/swagger/openapi.js OpenAPI/Swagger documentation.
src/app.js Express middleware and public top-level routes.
scripts/import.js CLI import entry point.
Import Commands
Run all imports:
npm run import
Run a safe smoke import:
npm run import:smoke
Import selected datasets:
node scripts/import.js --datasets=items,skills,recipes,placeables,npcs --languages=en,de
The importer writes both plural summaries and singular detailed records when a dataset has a detail endpoint.
Validation
Use the existing syntax check:
npm run check
Useful endpoint checks:
GET /health
GET /api/datasets
GET /api/item/LongRifle_Unique_Poison_03?language=en
GET /api/search?q=poison&datasets=item,skill,recipe&language=en
GET /SKILL.md
Important Constraints
- Do not expose secrets in public documentation or API responses.
- Keep
.envvalues private; production configuration comes from environment variables. - Keep the singular datasets first-class for OpenClaw.
- Keep changes small and consistent with the existing CommonJS/Express style.