Annotate a global class with @RestResource(urlMapping='/your-resource/*') to register it as a REST endpoint under /services/apexrest/your-resource/
Annotate methods with @HttpGet, @HttpPost, @HttpPut, @HttpPatch, or @HttpDelete; methods must be global static and accept no parameters (use RestContext.request to read the body and URL parameters)
Parse the request body from RestContext.request.requestBody.toString() and deserialize it using JSON.deserialize() into a typed Apex class
Build the response by setting RestContext.response.responseBody, statusCode, and headers, or simply return a typed object from the method for automatic JSON serialization
Authenticate external callers using Connected App OAuth (JWT or auth code flow) and ensure the running user's profile has API access enabled
Test using RestRequest and RestResponse instances set on RestContext.request and RestContext.response before calling the method in a test class
Known gotchas
The URL mapping supports wildcards but the entire path after /services/apexrest/ must match exactly — trailing slashes and case sensitivity cause 404 responses in some contexts
Apex REST endpoints run as the authenticated user, so field-level security and object permissions apply; callers may receive empty fields or errors if the integration user lacks access to queried fields
Returning a complex Apex object with circular references or unsupported types causes a serialization error; use a dedicated wrapper class with only primitive and supported types as fields
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp