We build custom applications 5x faster and cheaper 🚀
Book a Free Consultation
Stuck on an error? Book a 30-minute call with an engineer and get a direct fix + next steps. No pressure, no commitment.
To integrate Firecrawl Skills with OpenClaw, treat the Firecrawl Skill as an external service you register with OpenClaw’s skill registry, configure authentication (OAuth or API key) and webhooks, implement secure HTTP endpoints that the agent will call, and run any stateful or long-lived pieces (databases, schedulers, queues) outside the agent runtime. Configure the skill manifest or metadata in your OpenClaw management UI (ClawHub or similar), exchange and store credentials securely, validate inbound webhook signatures, and debug by inspecting logs, API responses, and credential scopes — everything explicit: no magic, only authenticated REST/GraphQL calls and properly provisioned secrets.
const express = require('express');
const crypto = require('crypto');
const app = express();
// <b>//</b> Parse raw body for HMAC verification
app.use(express.json({
verify: (req, res, buf) => {
req.rawBody = buf; // <b>//</b> store raw buffer for signature check
}
}));
const SHARED_SECRET = process.env.WEBHOOK_SECRET; // <b>//</b> set in environment or vault
app.post('/webhook', (req, res) => {
const signature = req.get('x-signature'); // <b>//</b> platform-provided header
const hmac = crypto.createHmac('sha256', SHARED_SECRET);
hmac.update(req.rawBody);
const expected = `sha256=${hmac.digest('hex')}`;
// <b>//</b> constant-time compare
const isValid = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature || ''));
if (!isValid) {
return res.status(401).send('invalid signature');
}
// <b>//</b> process event
const event = req.body;
console.log('Received webhook', event);
res.status(200).send('ok');
});
app.listen(3000, () => console.log('webhook listening'));
# <b>//</b> Exchange authorization code for tokens (generic)
curl -X POST https://auth.example.com/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code&code=AUTH_CODE&redirect_uri=https://your.skill/callback&client_id=CLIENT_ID&client_secret=CLIENT_SECRET"
// <b>//</b> Save tokens securely on your server (not in the agent process)
const tokens = await fetchTokenExchange(...);
await saveEncrypted(tokens); // <b>//</b> use your vault or encrypted DB
curl -X POST https://firecrawl-skill.example.com/invoke \
-H "Authorization: Bearer <API_OR_OAUTH_TOKEN>" \
-H "Content-Type: application/json" \
-d '{ "input": "do-something", "context": { "user_id": "user-123" } }'
Your skill should validate the token, parse the input, and respond with a clear schema (result payload, error codes, or async status URL).
Speak one‑on‑one with a senior engineer about your no‑code app, migration goals, and budget. In just half an hour you’ll leave with clear, actionable next steps—no strings attached.
1
A Firecrawl Skill fails Skill Manifest validation when its manifest doesn't match the Skill Router's expected schema or contains invalid values (missing required fields, wrong types, unreachable entrypoint, or incorrect auth/permission declarations).
2
Fix the mismatch by locating the Intent Map entry whose key or metadata differs from the Firecrawl intent name, correct the mapping so the intent key exactly matches the Action Handler registration, redeploy the skill/manifest, and verify with logs and test requests. Ensure permissions and runtime bindings are consistent so OpenClaw routes the intent to the intended handler.
const intentMap = {
'Firecrawl.Start': startHandler, <b>//</b> correct key
'firecrawl.start': wrongHandler <b>//</b> remove this entry
};
3
The quick answer: check that the Invocation Token header and the webhook signature are exactly what the skill platform expects, use the raw HTTP body to recompute the HMAC/signed value with the shared secret (stored in an environment variable), compare signatures with a constant-time compare, and ensure your web framework isn't altering the body or headers (body parsers and proxies are common causes).
const express = require('express')
const crypto = require('crypto')
const app = express()
app.use(express.raw({type: '*/*'}))
app.post('/webhook', (req, res) => {
// <b>//</b> read headers and env
const token = req.get('x-invocation-token')
const sig = req.get('x-webhook-signature')
const secret = process.env.WEBHOOK_SECRET
// <b>//</b> quick token check
if (!token || token !== process.env.INVOCATION_TOKEN) return res.sendStatus(401)
// <b>//</b> compute HMAC on raw body
const computed = 'sha256=' + crypto.createHmac('sha256', secret).update(req.body).digest('hex')
const a = Buffer.from(computed)
const b = Buffer.from(sig || '')
if (a.length !== b.length || !crypto.timingSafeEqual(a,b)) return res.sendStatus(401)
res.sendStatus(200)
})
app.listen(3000)
4
Direct answer: Slot drops usually come from schema/type mismatches, validation failures, or runtime state loss — fix by confirming Entity Schema types match incoming values, coercing/parsing user values before setting slots, and using runtime logs to find validation errors so the Skill Execution Context accepts and persists slots.
// Coerce slot to schema type before sending to skill
function coerce(value, type) {
if (type==='number') return Number(value);
if (type==='string') return String(value);
if (type==='boolean') return value==='true';
return value; // leave complex types validated by skill
}
This prompt helps an AI assistant understand your setup and guide you through the fix step by step, without assuming technical knowledge.
From startups to enterprises and everything in between, see for yourself our incredible impact.
Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We’ll discuss your project and provide a custom quote at no cost.Â