From webflow-pack
Optimizes Webflow costs via plan recommendations, free CDN-cached reads, bulk API endpoints, and usage monitoring with alerts. Use for billing analysis or reducing costs in integrations.
npx claudepluginhub jeremylongshore/claude-code-plugins-plus-skills --plugin webflow-packThis skill is limited to using the following tools:
Optimize Webflow costs through smart plan selection, CDN-cached reads, bulk endpoint
Optimizes Webflow Data API v2 performance using CDN-cached reads, response caching, bulk batching, pagination, and connection pooling for slow responses or high throughput.
Automates Webflow CMS collections, site publishing, page management, asset uploads, and ecommerce orders via Composio tools and Rube MCP. Use for managing live sites programmatically.
Automates Webflow CMS collections, site publishing, page management, asset uploads, and ecommerce orders via Rube MCP (Composio). Useful for programmatic site and content management.
Share bugs, ideas, or general feedback.
Optimize Webflow costs through smart plan selection, CDN-cached reads, bulk endpoint usage, and proactive API usage monitoring. The biggest lever: CDN-cached live item reads are free and unlimited — shift reads to the Content Delivery API.
webflow-api SDK configured| Plan | Monthly | CMS Items | Rate Limits | Key for API |
|---|---|---|---|---|
| Starter | $0 | 50 items | Standard | Testing only |
| Basic | $18 | 2,000 items | Standard | Small sites |
| CMS | $29 | 10,000 items | Standard | Content-heavy |
| Business | $49 | 10,000 items | Higher limits | Production apps |
| Enterprise | Custom | Unlimited | Custom limits | High-volume |
| Plan | Monthly | Products | Transaction Fee |
|---|---|---|---|
| Standard | $42 | 500 | 2% |
| Plus | $84 | 1,000 | 0% |
| Advanced | $235 | 3,000 | 0% |
| Plan | Monthly | Sites | Members |
|---|---|---|---|
| Starter | $0 | 2 | 1 |
| Core | $28 | 10 | 3 |
| Growth | $60 | Unlimited | 9 |
| Enterprise | Custom | Unlimited | Unlimited |
The single biggest cost reduction: use the Content Delivery API for reads.
// EXPENSIVE: Staged item reads count against rate limits
const { items } = await webflow.collections.items.listItems(collectionId);
// FREE: CDN-cached live item reads have no rate limits
const { items } = await webflow.collections.items.listItemsLive(collectionId);
For public-facing content (blogs, product pages, team members), always use live item endpoints. Only use staged endpoints when you need draft items.
// EXPENSIVE: 1000 items = 1000 API calls
for (const item of items) {
await webflow.collections.items.createItem(collectionId, { fieldData: item });
}
// CHEAP: 1000 items = 10 API calls (100 per batch)
for (let i = 0; i < items.length; i += 100) {
await webflow.collections.items.createItemsBulk(collectionId, {
items: items.slice(i, i + 100).map(item => ({ fieldData: item })),
});
}
Collection schemas change rarely — cache them aggressively:
import { LRUCache } from "lru-cache";
const schemaCache = new LRUCache<string, any>({
max: 50,
ttl: 60 * 60 * 1000, // 1 hour — schemas change very rarely
});
async function getCollectionSchema(siteId: string) {
const key = `schema:${siteId}`;
let schema = schemaCache.get(key);
if (!schema) {
const { collections } = await webflow.collections.list(siteId);
schema = collections;
schemaCache.set(key, schema);
}
return schema;
}
class WebflowUsageTracker {
private calls = new Map<string, number>();
private startTime = Date.now();
track(operation: string) {
const count = this.calls.get(operation) || 0;
this.calls.set(operation, count + 1);
}
getReport() {
const totalCalls = Array.from(this.calls.values()).reduce((a, b) => a + b, 0);
const elapsedMinutes = (Date.now() - this.startTime) / 60000;
const callsPerMinute = totalCalls / elapsedMinutes;
return {
totalCalls,
callsPerMinute: callsPerMinute.toFixed(1),
byOperation: Object.fromEntries(this.calls),
topOperations: Array.from(this.calls.entries())
.sort((a, b) => b[1] - a[1])
.slice(0, 5),
};
}
reset() {
this.calls.clear();
this.startTime = Date.now();
}
}
const tracker = new WebflowUsageTracker();
// Wrap your client to auto-track
function trackedCall<T>(operation: string, fn: () => Promise<T>): Promise<T> {
tracker.track(operation);
return fn();
}
// Usage
const items = await trackedCall("listItemsLive", () =>
webflow.collections.items.listItemsLive(collectionId)
);
// Periodic report
setInterval(() => {
console.log("API Usage:", tracker.getReport());
tracker.reset();
}, 60 * 60 * 1000); // Hourly
// EXPENSIVE: Polling every minute = 1,440 calls/day per collection
setInterval(async () => {
const { items } = await webflow.collections.items.listItems(collectionId);
await processChanges(items);
}, 60 * 1000);
// CHEAP: Webhook-driven = only called when something changes
// Register webhook: collection_item_changed
// Your webhook handler:
app.post("/webhooks/webflow", async (req, res) => {
const event = req.body;
if (event.triggerType === "collection_item_changed") {
await processChanges([event.payload]);
}
res.status(200).send();
});
// Estimate which plan you need based on usage
function recommendPlan(usage: {
cmsItems: number;
monthlyApiCalls: number;
ecommerceProducts: number;
}) {
// CMS items determine minimum site plan
if (usage.cmsItems > 10000) return { site: "Enterprise", reason: "CMS item limit" };
if (usage.cmsItems > 2000) return { site: "CMS or Business", reason: "CMS item limit" };
if (usage.cmsItems > 50) return { site: "Basic", reason: "CMS item limit" };
// High API volume may need higher rate limits
if (usage.monthlyApiCalls > 100000) return { site: "Business+", reason: "Rate limits" };
// Ecommerce products
if (usage.ecommerceProducts > 1000) return { ecommerce: "Advanced", reason: "Product limit" };
if (usage.ecommerceProducts > 500) return { ecommerce: "Plus", reason: "Product limit" };
return { site: "Basic", reason: "Sufficient for usage" };
}
listItemsLive (CDN, no rate limit)| Issue | Cause | Solution |
|---|---|---|
| Unexpected rate limits | Too many staged reads | Switch to live item endpoints |
| High API call count | No caching | Add LRU or Redis cache |
| CMS item limit exceeded | Wrong plan | Upgrade plan or archive old items |
| Polling costs | No webhook setup | Implement webhook-driven updates |
For architecture patterns, see webflow-reference-architecture.