endpoints
Custom REST API endpoints with authentication and helpers
Install / Use
npx skills add sanjayguwaju/himalayascontinentalInstalls into whichever agent you are using.
Cursor Rules
Cursor IDE rules (v2)
Quality Score
Category
Development & EngineeringSupported Platforms
Skill content
View source on GitHubtitle: Custom Endpoints description: Custom REST API endpoints with authentication and helpers tags: [payload, endpoints, api, routes, webhooks]
Payload Custom Endpoints
Basic Endpoint Pattern
Custom endpoints are not authenticated by default. Always check req.user.
import { APIError } from "payload";
import type { Endpoint } from "payload";
export const protectedEndpoint: Endpoint = {
path: "/protected",
method: "get",
handler: async (req) => {
if (!req.user) {
throw new APIError("Unauthorized", 401);
}
// Use req.payload for database operations
const data = await req.payload.find({
collection: "posts",
where: { author: { equals: req.user.id } },
});
return Response.json(data);
},
};
Route Parameters
export const trackingEndpoint: Endpoint = {
path: "/:id/tracking",
method: "get",
handler: async (req) => {
const { id } = req.routeParams;
const tracking = await getTrackingInfo(id);
if (!tracking) {
return Response.json({ error: "not found" }, { status: 404 });
}
return Response.json(tracking);
},
};
Request Body Handling
// Manual JSON parsing
export const createEndpoint: Endpoint = {
path: "/create",
method: "post",
handler: async (req) => {
const data = await req.json();
const result = await req.payload.create({
collection: "posts",
data,
});
return Response.json(result);
},
};
// Using helper (handles JSON + files)
import { addDataAndFileToRequest } from "payload";
export const uploadEndpoint: Endpoint = {
path: "/upload",
method: "post",
handler: async (req) => {
await addDataAndFileToRequest(req);
// req.data contains parsed body
// req.file contains uploaded file (if multipart)
const result = await req.payload.create({
collection: "media",
data: req.data,
file: req.file,
});
return Response.json(result);
},
};
Query Parameters
export const searchEndpoint: Endpoint = {
path: "/search",
method: "get",
handler: async (req) => {
const url = new URL(req.url);
const query = url.searchParams.get("q");
const limit = parseInt(url.searchParams.get("limit") || "10");
const results = await req.payload.find({
collection: "posts",
where: {
title: {
contains: query,
},
},
limit,
});
return Response.json(results);
},
};
CORS Headers
import { headersWithCors } from "payload";
export const corsEndpoint: Endpoint = {
path: "/public-data",
method: "get",
handler: async (req) => {
const data = await fetchPublicData();
return Response.json(data, {
headers: headersWithCors({
headers: new Headers(),
req,
}),
});
},
};
Error Handling
import { APIError } from "payload";
export const validateEndpoint: Endpoint = {
path: "/validate",
method: "post",
handler: async (req) => {
const data = await req.json();
if (!data.email) {
throw new APIError("Email is required", 400);
}
return Response.json({ valid: true });
},
};
Endpoint Placement
Collection Endpoints
Mounted at /api/{collection-slug}/{path}.
export const Orders: CollectionConfig = {
slug: "orders",
endpoints: [
{
path: "/:id/tracking",
method: "get",
handler: async (req) => {
// Available at: /api/orders/:id/tracking
const orderId = req.routeParams.id;
return Response.json({ orderId });
},
},
],
};
Global Endpoints
Mounted at /api/globals/{global-slug}/{path}.
export const Settings: GlobalConfig = {
slug: "settings",
endpoints: [
{
path: "/clear-cache",
method: "post",
handler: async (req) => {
// Available at: /api/globals/settings/clear-cache
await clearCache();
return Response.json({ message: "Cache cleared" });
},
},
],
};
Root Endpoints
Mounted at /api/{path}.
export default buildConfig({
endpoints: [
{
path: "/hello",
method: "get",
handler: () => {
// Available at: /api/hello
return Response.json({ message: "Hello!" });
},
},
],
});
Best Practices
- Always check authentication - Custom endpoints are not authenticated by default
- Use
req.payloadfor operations - Ensures access control and hooks execute - Use helpers for common tasks -
addDataAndFileToRequest,headersWithCors - Throw
APIErrorfor errors - Provides consistent error responses - Return Web API
Response- UseResponse.json()for consistent responses - Validate input - Check required fields, validate types
- Log errors - Use
req.payload.loggerfor debugging
Related Skills
Agent-Reach
84.2kGive your AI agent eyes to see the entire internet. Read & search Twitter, Reddit, YouTube, GitHub, Bilibili, XiaoHongShu — one CLI, zero API fees.
headroom
73.4kCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.
career-ops
72.3kOpen-source AI job search: scan job portals, evaluate listings into a structured A-H report with a global 1-5 score, tailor your CV, track applications — runs locally in your AI coding CLI (Claude Code, Codex, OpenCode, Antigravity…)
ai-job-search
43.5kThe job search that runs on your machine. AI job application framework built on Claude Code: evaluate postings, tailor CVs, write cover letters, prep interviews. Fork it and own it.
Security Score
Audited on Invalid Date
