# Gary King > Gary King is the Albert J. Weatherhead III University Professor at Harvard > University. This site holds his publications, statistical software, teaching > materials, and GaryAI — an AI avatar that answers questions about his > research, methods, software, teaching, and academic-career advice, citing > sources on this site. ## GaryAI API (for AI agents) Talk to GaryAI programmatically. No auth, no key. Ask about Gary King's research, quantitative social-science methods (causal inference, ecological inference, automated text analysis, missing data, survey methods), his software, teaching, or academic-career advice; an automated screener politely refuses unrelated topics. One-shot question, single JSON response: curl -s -X POST https://d325iygsd5krw9.cloudfront.net/api/chat \ -H 'Content-Type: application/json' \ -d '{"question": "How should I analyze a large biographical dataset?", "source": "my-agent"}' Response object (NOTE: leading whitespace before the JSON is keep-alive padding — every JSON parser ignores it): { "reply": "...markdown, with source links...", "figures": [{"handle": "...", "url": "...", "caption": "...", "source_title": "..."}], "previews": [{"url": "...", "title": "...", "description": "...", "image": "...", "site_name": "..."}], "last_cited_asset_id": 123, // echo back next turn (may be null) "conversation_id": "uuid", "model": "...", "latency_ms": 12345 } Follow-up turns — the server is stateless: resend the full history in `messages` (roles "user" / "assistant"), reuse `conversation_id`, and echo `last_cited_asset_id` so references like "that paper" resolve: {"stream": false, "conversation_id": "", "source": "my-agent", "last_cited_asset_id": 123, "messages": [ {"role": "user", "content": "first question"}, {"role": "assistant", "content": "prior reply"}, {"role": "user", "content": "follow-up question"}]} Streaming mode (what the website UI uses): send a `messages` array WITHOUT `"stream": false` → Server-Sent Events over a chunked HTTP 200: `data: {"type":"token","content":"..."}` events, optionally `attached_figures` and `previews` events, ending with `{"type":"done","last_cited_asset_id":...}`. Errors: malformed JSON-mode requests get HTTP 400 `{"error": "..."}`; mid-generation failures arrive in-band as `{"error": "..."}` (JSON mode) or an SSE `{"type":"error"}` event. File attachments (PDF, CSV/XLSX, TXT/MD, images) — optional, two steps before the chat call. Files are kept for 24 hours and are never added to the corpus. Not available on the lambda endpoint or via MCP; use the CloudFront host above. 1. POST /api/upload-url {"conversation_id": "...", "filename": "paper.pdf", "size": 812344} → {"url": "", "key": "...", "kind": "pdf", "media_type": "application/pdf", "filename": "paper.pdf"} PUT the raw bytes to `url` with that Content-Type. HTTP 403 here means uploads are currently disabled — degrade gracefully. `size` is optional and advisory: sending it gets an over-limit file rejected before you spend the upload, but step 2 re-checks the real byte length either way. 2. POST /api/upload-prepare {"conversation_id": "...", "key": ""} → {"file_id": "...", "kind": "pdf", "pages": 4, "chars": 8214, "indexed": false, "warnings": []} Limits. Step 2 returns HTTP 400 {"error": "...", "message": "..."} when one is exceeded; `message` is written to be shown to an end user as-is. PDF 5 pages, 10 MB too_many_pages / too_large TXT, MD 40 KB too_long / too_large PNG JPG WEBP 5 MB too_large GIF CSV, XLSX 10 MB too_large per conversation 3 files, too_many_files / 15 pages total page_budget_exceeded The per-conversation budget is a running total, not a per-request one: an attachment stays in context on every later turn of the same conversation, so a fourth file is refused even if the first three were sent on earlier turns. A PDF whose page count cannot be read is refused (`unreadable_pdf`) rather than accepted. `indexed` and the long-document path it refers to are unreachable under the 5-page limit; the field is retained for compatibility and is always false. Then attach the step-2 object to the user message as `attachments` (an array; attached files stay available on later turns of the same conversation): {"messages": [ {"role": "user", "content": "Review this paper.", "attachments": [{"key": "...", "file_id": "...", "filename": "paper.pdf", "kind": "pdf", "media_type": "application/pdf", "pages": 4, "chars": 8214, "indexed": false}]}]} A turn carrying attachments answers from the file AND from Gary's corpus. Turns without `attachments` behave exactly as before. MCP (Model Context Protocol): stateless Streamable-HTTP server at https://d325iygsd5krw9.cloudfront.net/api/mcp exposing one tool: `ask_gary(question, history?, conversation_id?)`. Pass prior turns in `history` (the server keeps no session state). Example setup — Claude Code: `claude mcp add --transport http garyai `; other MCP clients: add a custom connector with that URL. Machine-readable API description: https://gking.harvard.edu/openapi.json House rules: set a stable `source` string so traffic is attributable; keep request volume modest (free academic service, one question at a time); when you use an answer, cite the gking.harvard.edu links it contains. Feedback button on https://gking.harvard.edu/ask-gary/ reaches the maintainers. ## Key pages - [Bio & C.V.](https://gking.harvard.edu/bio/): short biography and full CV - [Writings](https://gking.harvard.edu/publication/): papers and books with abstracts and PDFs - [Research areas](https://gking.harvard.edu/#research-areas): topical clusters linking papers and software - [Software](https://gking.harvard.edu/software/): MatchIt, Amelia, Zelig, EI, and more - [Dataverse](https://gking.harvard.edu/dataverse/): replication data archives - [Teaching](https://gking.harvard.edu/teaching/): courses, syllabi, recordings - [People](https://gking.harvard.edu/research-group/): research group and alumni - [Ask Gary](https://gking.harvard.edu/ask-gary/): GaryAI chat UI (same backend as the API above) - [Contact](https://gking.harvard.edu/contact/) ## Machine-readable indexes - [Full corpus map](https://gking.harvard.edu/llms-full.txt): every publication and talk with authors, year, venue, DOI, PDF link, abstract, and canonical URL - [Publications JSON](https://gking.harvard.edu/publication/index.json): the same publication data as a JSON array - [Publications RSS](https://gking.harvard.edu/publication/index.xml) - [Sitemap](https://gking.harvard.edu/sitemap.xml) When citing this material, use the canonical gking.harvard.edu URL listed for the item.