OpenClaw ships with 50+ bundled skills and the ClawHub marketplace hosts over 5,700 community-built options. But the real competitive advantage comes from custom skills built for your exact workflows. Whether you need to integrate a proprietary API, automate a complex business process, or connect to an internal database, custom skills make it possible.
This tutorial walks through the complete lifecycle -- from architecture decisions to production deployment -- with practical examples you can adapt.
Understanding Skill Architecture
A skill in OpenClaw is a self-contained module that teaches the agent how to perform a specific task. Skills range from simple instruction files to full applications with API integrations and complex logic.
Skill Directory Structure
my-custom-skill/
SKILL.md # Required: natural language instructions
index.ts # Optional: TypeScript module for logic
config.json # Optional: configurable parameters
package.json # Optional: npm dependencies
tests/ # Optional: test files
The only required file is SKILL.md. Everything else is optional and added as complexity demands.
The SKILL.md File
This is the heart of every skill. It tells the agent what the skill does, when to activate it, how to execute, what data it needs, and how to format output. Write it in clear, natural language -- the LLM interprets these instructions.
Tutorial: Building a CRM Lookup Skill
Step 1: Define the Skill Instructions
# CRM Customer Lookup
## When to Use
Activate when the user asks about a customer, client, or account.
## Steps
1. Extract the search criteria from the user message
2. Call the CRM API search endpoint
3. If multiple results, present a numbered list
4. If single result, display the full customer profile
5. If no results, suggest alternative search terms
Step 2: Add the Code Module
For API integrations, add an index.ts file that handles API authentication, request formatting, error handling, and response parsing.
import { SkillContext, SkillResult } from "@openclaw/sdk";
export async function searchCustomer(
ctx: SkillContext,
query: string
): Promise<SkillResult> {
const apiUrl = ctx.config.get("crm_api_url");
const apiKey = ctx.config.get("crm_api_key");
const response = await fetch(
apiUrl + "/api/customers/search?q=" + encodeURIComponent(query),
{ headers: { Authorization: "Bearer " + apiKey } }
);
if (!response.ok) {
return { success: false, error: "CRM API error: " + response.status };
}
const customers = await response.json();
return {
success: true,
data: customers,
message: "Found " + customers.length + " matching customer(s)."
};
}
Step 3: Configure the Skill
Create config.json for configurable parameters with type declarations, required flags, and sensitive markers for credentials that should be encrypted at rest.
Step 4: Write Tests
Unit test the code module with mock API responses. Integration test with the real API in staging. Conversation test through your messaging app. Edge case test with malformed inputs, API failures, and timeouts.
Step 5: Deploy the Skill
Copy the skill directory to the OpenClaw skills folder, install dependencies, and restart OpenClaw. For team deployments, package skills as npm modules or Git repositories.
Build a Shopify store-management skill in OpenClaw (full example)
To build a Shopify store-management skill in OpenClaw, create a skill folder with a SKILL.md that tells the agent when to act, an index.ts that calls the Shopify Admin GraphQL API, and a config.json holding the store domain and access token. The agent can then read orders, update inventory, and adjust prices through a single skill.
This is the most-requested OpenClaw web-development use case: giving an agent hands-on control of a live Shopify store. The skill below reads recent orders and updates a variant's inventory — a real scaffold you can extend. For a deeper, end-to-end walkthrough of this exact skill — including pagination, error handling, and production deployment — see our dedicated Shopify store skill build tutorial.
1. Skill instructions (SKILL.md)
# Shopify Store Management
## When to Use
Activate when the user asks to check Shopify orders, update inventory,
adjust a product price, or report on store performance.
## Steps
1. Identify the requested action (orders, inventory, pricing, report)
2. Call the matching Shopify Admin API operation
3. Summarize the result in plain language
4. For write actions, confirm the change back to the user
2. Code module (index.ts)
import { SkillContext, SkillResult } from "@openclaw/sdk";
const API_VERSION = "2026-01";
async function shopifyGraphQL(ctx: SkillContext, query: string, variables: Record<string, unknown>) {
const domain = ctx.config.get("shopify_domain"); // my-store.myshopify.com
const token = ctx.config.get("shopify_access_token"); // sensitive: true
const res = await fetch(`https://${domain}/admin/api/${API_VERSION}/graphql.json`, {
method: "POST",
headers: {
"X-Shopify-Access-Token": token,
"Content-Type": "application/json",
},
body: JSON.stringify({ query, variables }),
});
if (!res.ok) throw new Error(`Shopify API error: ${res.status}`);
return res.json();
}
export async function recentOrders(ctx: SkillContext, first = 5): Promise<SkillResult> {
const query = `
query RecentOrders($first: Int!) {
orders(first: $first, sortKey: CREATED_AT, reverse: true) {
edges { node { name totalPriceSet { shopMoney { amount currencyCode } } displayFinancialStatus } }
}
}`;
try {
const data = await shopifyGraphQL(ctx, query, { first });
const orders = data.data.orders.edges.map((e: any) => e.node);
return { success: true, data: orders, message: `Fetched ${orders.length} recent orders.` };
} catch (err) {
return { success: false, error: (err as Error).message };
}
}
export async function setInventory(ctx: SkillContext, inventoryItemId: string, locationId: string, available: number): Promise<SkillResult> {
const mutation = `
mutation SetQty($input: InventorySetQuantitiesInput!) {
inventorySetQuantities(input: $input) { userErrors { field message } }
}`;
const input = {
name: "available",
reason: "correction",
quantities: [{ inventoryItemId, locationId, quantity: available }],
};
try {
const data = await shopifyGraphQL(ctx, mutation, { input });
const errors = data.data.inventorySetQuantities.userErrors;
if (errors.length) return { success: false, error: errors.map((e: any) => e.message).join("; ") };
return { success: true, message: `Inventory updated to ${available} units.` };
} catch (err) {
return { success: false, error: (err as Error).message };
}
}
3. Configuration (config.json)
{
"name": "shopify-store-management",
"version": "1.0.0",
"parameters": {
"shopify_domain": { "type": "string", "required": true },
"shopify_access_token": { "type": "string", "required": true, "sensitive": true }
}
}
Generate the access token from a custom app in your Shopify admin (Settings → Apps and sales channels → Develop apps) and grant only the scopes the skill needs — typically read_orders, read_inventory, and write_inventory. Because the token is marked sensitive: true, OpenClaw encrypts it at rest. From here you can extend the same pattern to price updates, fulfillment, and daily sales reports, or compose it with our OpenClaw Shopify integration skills for multi-channel automation.
Advanced Skill Patterns
Stateful Skills
Some skills maintain state across multiple interactions using OpenClaw memory API. Enable multi-step workflows like approval processes by reading and writing state between conversation turns.
Composite Skills
Skills that delegate to other skills for complex workflows. A processOrder skill might invoke crm-customer-lookup, inventory-check, and pricing-calculator skills in sequence, combining their results into a single response.
Scheduled Skills
Skills that run on a cron schedule rather than on-demand. Configure schedule, timezone, and notification channel in the skill config for automated daily reports and monitoring tasks.
Security Best Practices for Custom Skills
- Credential Management -- Never hardcode API keys. Use the config system with sensitive: true for encryption at rest.
- Input Validation -- Always validate and sanitize user inputs before passing them to APIs or databases.
- Permission Scoping -- Request only the permissions your skill needs. Read-only skills should not have write access.
- Rate Limiting -- Protect external APIs from accidental flooding with request counting.
Debugging Skills
Enable verbose logging to trace skill execution. Use the OpenClaw skill debugger for step-by-step execution:
openclaw skill debug my-custom-skill --input "Look up customer Acme Corp"
openclaw skill trace --last
Frequently Asked Questions
How complex should a single skill be?
Follow the single-responsibility principle. A skill should do one thing well. Complex workflows should use composite skills that delegate to specialized ones.
Can I use Python instead of TypeScript for skill code?
Yes. OpenClaw supports TypeScript, Python, and Go for skill code modules. The SKILL.md file and config.json remain the same regardless of language.
How do I version and update skills in production?
Use semantic versioning in config.json. Deploy new versions alongside old ones (blue-green deployment) and switch traffic gradually. OpenClaw supports skill versioning natively.
Next Steps
For enterprise skill development, ECOSIRE OpenClaw custom skills service provides architecture guidance, code review, security auditing, and production deployment support.
Need custom skills built for your specific workflows? Explore our OpenClaw services or contact us for a skills assessment.
Written by
ECOSIRE TeamTechnical Writing
The ECOSIRE technical writing team covers Odoo ERP, Shopify eCommerce, AI agents, Power BI analytics, GoHighLevel automation, and enterprise software best practices. Our guides help businesses make informed technology decisions.
ECOSIRE
Build Intelligent AI Agents
Deploy autonomous AI agents that automate workflows and boost productivity.
Related Articles
25 Business Process Automation Examples That Actually Work in 2026 (From a Team Running Them in Production)
25 real business process automation examples across finance, sales, support, and operations — with honest notes on what AI agents, RPA, and workflows do best.
GoHighLevel AI Employee in 2026: What It Does, Costs, and When to Use It
GoHighLevel AI Employee explained for 2026: Voice AI, Conversation AI, and Content AI capabilities, flat-rate vs usage pricing, limits, and when it pays.
Building an OpenClaw Skill That Runs Your Shopify Store: Step-by-Step Tutorial
How to build an OpenClaw skill that manages your Shopify store via the Admin API: skill anatomy, auth scopes, webhooks, a worked sync example, and guardrails.