Full-Stack & AI Product Engineer
harjotrana.com developer resources
Every machine-readable surface of harjotrana.com in one place, with the URL, the format, and what it is for. Everything here is public, read-only, and needs no key or account.
Start here
- llms.txt: the AI-oriented site guide, including a "When to use this site" section and how agents should call it.
- llms-full.txt: every public page of harjotrana.com rendered as one Markdown document.
- OpenAPI description: OpenAPI 3.1 document for every endpoint on this page, with typed response schemas and the error model.
- API index: JSON list of the v1 endpoints with their documentation links.
- API catalog: RFC 9727 linkset pointing at the OpenAPI description and this page.
- sitemap.xml and robots.txt: the canonical HTML pages and crawler policy.
REST API (harjotrana.com /api/v1)
A read-only JSON API over the same facts the HTML pages show. Base URL https://www.harjotrana.com/api/v1. Authentication: none. Every response is application/json; charset=utf-8, CORS-open (Access-Control-Allow-Origin: *), cacheable, and carries a Link header to the OpenAPI description and this page.
GET /api/v1: index of endpoints with documentation links.GET /api/v1/profile: who Harjot is, with email, profiles, stack, and page URLs.GET /api/v1/services: engagement types, process, and FAQ. No prices are published.GET /api/v1/projectsandGET /api/v1/projects/{name}: all projects, then one project with case study and features (name is case-insensitive, e.g.Moonshift).GET /api/v1/postsandGET /api/v1/posts/{slug}: technical writing, then one post with its Markdown body.GET /api/v1/search?q=reinstate&limit=5: keyword search across every public page.GET /api/v1/contact-options: email, booking link, inquiry form, and what to include.GET /api/contributions: last twelve months of GitHub contribution days.
Example: curl -H "Accept: application/json" https://www.harjotrana.com/api/v1/projects/Moonshift returns the Moonshift case study as JSON. Only GET, HEAD, and OPTIONS are supported; other methods return a 405 problem with an Allow header. There are no write endpoints, webhooks, or OAuth flows: to contact or hire Harjot, hand the user the links from /api/v1/contact-options.
Errors
Every 4xx and 5xx from /api/*, /mcp, the discovery documents, and content negotiation is an RFC 9457 problem-details object served as application/problem+json. Members: type (a URI that resolves to the matching entry below), title, status, detail, instance (the request path), plus two extension members: code, a stable machine-readable identifier, and hint, what to do next. Validation failures add invalidParams.
- bad_request (400)
- A query or path parameter is missing or invalid;
invalidParamsnames it. Fix the request. - not_found (404)
- No endpoint or resource at that path. The
hintnames where to list valid ones. Unknown/api/*paths always return this, never an HTML page. - method_not_allowed (405)
- The endpoint is read-only. The
Allowheader lists supported methods. - not_acceptable (406)
- The
Acceptheader on a page request allowed neithertext/htmlnortext/markdown;availablelists both. - rate_limited (429)
- Quota exhausted. Wait
Retry-Afterseconds, then retry; reuse cached responses instead of re-fetching. - internal_error (500)
- The server failed to produce a response. Retry once; if it persists, email me@harjotrana.com with the URL.
The MCP endpoint keeps JSON-RPC semantics: a malformed body is a JSON-RPC -32700 error object with HTTP 400, unknown methods are -32601, and tool-level failures set isError: true on the result.
Rate limits
/api/*, /mcp, and the discovery documents allow 120 requests per 60 seconds per client address. Every response carries the IETF RateLimit header fields (draft-ietf-httpapi-ratelimit-headers): RateLimit-Policy: "default";q=120;w=60 declares the quota, and RateLimit: "default";r=<remaining>;t=<seconds until reset> reports where you stand. Exceeding it returns a 429 problem with Retry-After, which takes precedence over RateLimit.
The counter is per server instance, so treat the headers as a live advisory signal rather than a single global cap. Text documents (/llms.txt, /llms-full.txt, /feed.xml, /sitemap.xml) and HTML pages are outside the policy.
Versioning and deprecation
The REST API is versioned in the path: /api/v1. Additive changes (new fields, new endpoints) ship in place; breaking changes ship under a new prefix (/api/v2) and never alter v1 responses. The MCP server negotiates its protocol version on initialize and advertises supported versions in its server card.
Deprecation policy: an endpoint or version scheduled for removal announces it at least 90 days in advance with the Deprecation response header (RFC 9745) and a Sunset header (RFC 8594) giving the removal date, and is listed here with its replacement. Nothing is deprecated today.
MCP server
harjotrana.com runs a read-only Model Context Protocol server over Streamable HTTP at https://www.harjotrana.com/mcp. It exposes the portfolio as tools: profile, services, projects, writing, search, and contact options. No authentication, no session state, no side effects.
- Endpoint:
POST https://www.harjotrana.com/mcp(JSON-RPC 2.0, Streamable HTTP transport, protocol versions 2025-03-26, 2025-06-18, and 2025-11-25). Responses areapplication/json; the server never opens server-initiated streams, soGET /mcpreturns a405problem as the transport spec allows. The legacy HTTP+SSE transport is not offered. - Server card: /mcp/server-card (
application/mcp-server-card+json, SEP-2127), mirrored with connection hints at /.well-known/mcp.json and listed in /.well-known/ai-catalog.json. - Tools:
get_profile,get_services,list_projects,get_project,list_posts,get_post,get_contact_options,search_site. Resources: llms.txt, llms-full.txt, openapi.json. - Client config:
{ "mcpServers": { "harjotrana": { "type": "http", "url": "https://www.harjotrana.com/mcp" } } }.
Markdown content negotiation
Every public page on harjotrana.com also has a Markdown representation, following the acceptmarkdown.com convention. Send Accept: text/markdown to any page URL and you get Content-Type: text/markdown; charset=utf-8 with Vary: Accept. Appending .md to a page path (for example /blog/turborepo-cheatsheet.md, or /index.md for the home page) returns Markdown unconditionally. Requests that accept neither HTML nor Markdown receive a 406 problem. Unknown paths return a real 404 with a short Markdown body pointing back to the sitemap and llms.txt.
Usage policy
All of the above is free to read and cache. The HTML pages are canonical; JSON, Markdown, llms.txt, and MCP responses are derived from the same source files at build time and must not be quoted as if they contained facts the HTML does not. Do not infer employment availability, client relationships, testimonials, pricing, or outcomes beyond what the pages state. Questions about these resources: me@harjotrana.com.