{"openapi":"3.1.0","info":{"title":"GTM Index API","summary":"GTM Index (gtmindex.io) public read APIs","description":"GTM Index (gtmindex.io) is a catalog of people, playbooks, and tools for GTM engineers. Same-origin GET /v1/people and GET /v1/jobs plus Open WebMCP on https://gtmindex.io/mcp. No API key while public browse is on. Paginate people. Errors use RFC 9457 application/problem+json with a stable code, detail, and hint. Versioning and sunset policy: https://gtmindex.io/docs#versioning-and-deprecation (https://gtmindex.io/developers/versioning). No write API and no webhooks.","version":"1.0.0","contact":{"name":"GTM Index","url":"https://gtmindex.io/contact"},"license":{"name":"Public browse","url":"https://gtmindex.io/developers/api"}},"servers":[{"url":"https://gtmindex.io","description":"GTM Index App — WebMCP and /v1 proxy"},{"url":"https://gateway-production-a21f.up.railway.app","description":"GTM Index Gateway origin (same contracts)"}],"security":[],"tags":[{"name":"WebMCP","description":"JSON-RPC tools on https://gtmindex.io/mcp"},{"name":"People","description":"GET /v1/people — paginated GTM engineer search"},{"name":"Playbook authors","description":"GET /v1/playbook-authors — slug-keyed playbook usage"},{"name":"Jobs","description":"GET /v1/jobs — title-gated GTM roles"}],"paths":{"/mcp":{"get":{"tags":["WebMCP"],"summary":"GTM Index MCP server card","description":"Returns the Open WebMCP server card (name, tools, examples). No API key. Use POST /mcp for JSON-RPC.","operationId":"getMcpServerCard","responses":{"200":{"description":"Server card JSON","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpServerCard"}}}},"405":{"description":"Method not allowed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded — honor Retry-After and RateLimit","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["WebMCP"],"summary":"GTM Index Open WebMCP (JSON-RPC)","operationId":"postMcp","description":"No API key. Methods: initialize, tools/list, tools/call. Tools: search_people, search_tools, get_playbook, stack_cooccurrence. Paginate people. Invalid JSON returns HTTP 400 JSON-RPC parse error.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonRpcRequest"},"examples":{"initialize":{"value":{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"gtmindex-agent","version":"0"}}}},"stack":{"value":{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"stack_cooccurrence","arguments":{"query":"clay+n8n+instantly","limit":20}}}}}}}},"responses":{"200":{"description":"JSON-RPC result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonRpcResponse"}}}},"400":{"description":"JSON-RPC parse error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonRpcResponse"}}}},"405":{"description":"Method not allowed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded — honor Retry-After and RateLimit","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/people":{"get":{"tags":["People"],"summary":"Search GTM Index people","description":"Paginated public people search. Same contract as the Gateway. Max 100 rows per call. Invalid limit/offset returns RFC 9457. ?slug= is exact /p/{slug} lookup; playbook_count and used_source_urls are catalog-derived and also rendered on the live profile page.","operationId":"listPeople","parameters":[{"name":"q","in":"query","required":false,"description":"Name, headline, about, location, skills, companies","schema":{"type":"string"}},{"name":"slug","in":"query","required":false,"description":"Exact /p/{slug} author lookup. Returns playbook_count and used_source_urls. Not a free-text q= search — q= does not match public_identifier.","schema":{"type":"string"}},{"name":"skill","in":"query","required":false,"description":"stack_tags or skills contains","schema":{"type":"string"}},{"name":"company","in":"query","required":false,"schema":{"type":"string"}},{"name":"location","in":"query","required":false,"schema":{"type":"string"}},{"name":"role","in":"query","required":false,"schema":{"type":"string"}},{"name":"open_to_work","in":"query","required":false,"schema":{"type":"boolean"},"description":"Filter to people marked open to work"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Paginated people","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PeopleListResponse"}}}},"400":{"description":"Invalid request — typed Problem (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Sign in required when public browse is off","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"405":{"description":"Method not allowed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded — honor Retry-After and RateLimit","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"People/jobs Gateway unavailable","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/playbook-authors":{"get":{"tags":["Playbook authors"],"summary":"Look up playbook usage by /p/{slug}","description":"Slug-keyed playbook_count and used_source_urls derived from the live playbook catalog at request time (author.slug + source.url). Same fields appear on the live /p/{slug} page. Use ?slug= or GET /v1/playbook-authors/{slug}. Authors with a live playbook but no people-list row are included. Does not invent people or source URLs. A catalog merge is enough — no Neo4j backfill.","operationId":"listPlaybookAuthors","parameters":[{"name":"slug","in":"query","required":false,"description":"Exact /p/{slug} author slug","schema":{"type":"string"}}],"responses":{"200":{"description":"Playbook author usage","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaybookAuthorsResponse"}}}},"400":{"description":"Invalid request — typed Problem (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Sign in required when public browse is off","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No such API path or record","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"405":{"description":"Method not allowed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded — honor Retry-After and RateLimit","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"People/jobs Gateway unavailable","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/playbook-authors/{slug}":{"get":{"tags":["Playbook authors"],"summary":"One playbook author by slug","operationId":"getPlaybookAuthor","parameters":[{"name":"slug","in":"path","required":true,"description":"Live /p/{slug} author slug","schema":{"type":"string"}}],"responses":{"200":{"description":"Playbook author usage","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlaybookAuthorResponse"}}}},"401":{"description":"Sign in required when public browse is off","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No such API path or record","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"405":{"description":"Method not allowed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded — honor Retry-After and RateLimit","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"People/jobs Gateway unavailable","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/jobs":{"get":{"tags":["Jobs"],"summary":"Search GTM Index jobs","description":"Title-gated GTM roles only. Not a generic job board. Card fields only — full description is on GET /v1/jobs/{slug}. Max 50 rows per call. Invalid workplace_type or limit returns RFC 9457.","operationId":"listJobs","parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string"}},{"name":"workplace_type","in":"query","required":false,"schema":{"type":"string","enum":["remote","hybrid","onsite"]}},{"name":"function","in":"query","required":false,"schema":{"type":"string"}},{"name":"location","in":"query","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":50,"default":20}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Paginated jobs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobsListResponse"}}}},"400":{"description":"Invalid request — typed Problem (RFC 9457)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Sign in required when public browse is off","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"405":{"description":"Method not allowed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded — honor Retry-After and RateLimit","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"People/jobs Gateway unavailable","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}}},"components":{"schemas":{"Problem":{"type":"object","required":["type","title","status","code","detail"],"additionalProperties":true,"properties":{"type":{"type":"string","format":"uri"},"title":{"type":"string"},"status":{"type":"integer"},"code":{"type":"string"},"detail":{"type":"string"},"instance":{"type":"string"},"hint":{"type":"string"}}},"PaginationMeta":{"type":"object","required":["limit","offset","total","has_more"],"properties":{"limit":{"type":"integer"},"offset":{"type":"integer"},"total":{"type":"integer"},"has_more":{"type":"boolean"}}},"Person":{"type":"object","additionalProperties":true,"properties":{"linkedin_url":{"type":"string"},"public_identifier":{"type":"string"},"full_name":{"type":"string"},"headline":{"type":"string"},"location":{"type":"string"},"current_company":{"type":"string"},"open_to_work":{"type":"boolean","nullable":true},"playbook_count":{"type":"integer"},"used_source_urls":{"type":"array","items":{"type":"string","format":"uri"}}}},"PlaybookAuthor":{"type":"object","required":["slug","playbook_count","used_source_urls"],"properties":{"slug":{"type":"string"},"name":{"type":"string"},"playbook_count":{"type":"integer"},"used_source_urls":{"type":"array","items":{"type":"string","format":"uri"}}}},"PlaybookAuthorResponse":{"type":"object","required":["data"],"properties":{"data":{"type":"object","properties":{"author":{"$ref":"#/components/schemas/PlaybookAuthor"}}}}},"PlaybookAuthorsResponse":{"type":"object","required":["data"],"properties":{"data":{"type":"object","properties":{"author":{"$ref":"#/components/schemas/PlaybookAuthor"},"authors":{"type":"array","items":{"$ref":"#/components/schemas/PlaybookAuthor"}}}}}},"PeopleListResponse":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["people"],"properties":{"people":{"type":"array","items":{"$ref":"#/components/schemas/Person"}},"cohort":{"type":"string"},"plan":{"type":"string"}}},"meta":{"$ref":"#/components/schemas/PaginationMeta"}}},"Job":{"type":"object","additionalProperties":true,"properties":{"slug":{"type":"string"},"title":{"type":"string"},"company_name":{"type":"string"},"location":{"type":"string"},"workplace_type":{"type":"string"}}},"JobsListResponse":{"type":"object","required":["data"],"properties":{"data":{"type":"object","additionalProperties":true,"properties":{"jobs":{"type":"array","items":{"$ref":"#/components/schemas/Job"}}}},"meta":{"$ref":"#/components/schemas/PaginationMeta"}}},"JsonRpcRequest":{"type":"object","required":["jsonrpc","method"],"properties":{"jsonrpc":{"type":"string","const":"2.0"},"id":{},"method":{"type":"string"},"params":{"type":"object"}}},"JsonRpcResponse":{"type":"object","required":["jsonrpc"],"properties":{"jsonrpc":{"type":"string","const":"2.0"},"id":{},"result":{},"error":{"type":"object","properties":{"code":{"type":"integer"},"message":{"type":"string"}}}}},"McpServerCard":{"type":"object","additionalProperties":true,"properties":{"name":{"type":"string"},"url":{"type":"string"},"hint":{"type":"string"}}}}},"externalDocs":{"description":"GTM Index docs — versioning and deprecation","url":"https://gtmindex.io/docs#versioning-and-deprecation"}}