{"openapi":"3.1.0","info":{"title":"TypingCoach API","version":"0.1.0","description":"Typing-speed test methodology and practice-passage generation — real WPM/accuracy computation, tiered passages, improvement tips — all local.\n\nEvery operation is read-only or compute-only. The same tools are available over MCP (streamable HTTP) at https://typingcoach.connectorbay.com/mcp.","contact":{"name":"Unify Dynamics LLC","email":"hr@unifydynamics.com","url":"https://connectorbay.com/typingcoach/docs"},"termsOfService":"https://connectorbay.com/typingcoach/terms"},"servers":[{"url":"https://typingcoach.connectorbay.com"}],"externalDocs":{"url":"https://connectorbay.com/typingcoach/docs"},"security":[{},{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"Optional. A Pro API key raises rate limits; no credentials are required."}},"schemas":{"Error":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object"}}}}},"paths":{"/v1/tools/score_typing_test":{"post":{"operationId":"score_typing_test","summary":"Compute gross WPM, net WPM and accuracy for a typed sample against a target passage. Use for","description":"Compute gross WPM, net WPM and accuracy for a typed sample against a target passage. Use for\n    \"score my typing test: here's the target and what I typed, in 45 seconds\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"target_text":{"description":"The passage the person was supposed to type.","title":"Target Text","type":"string"},"typed_text":{"description":"What the person actually typed.","title":"Typed Text","type":"string"},"elapsed_seconds":{"description":"How long the attempt took, in seconds.","exclusiveMinimum":0,"title":"Elapsed Seconds","type":"number"}},"required":["target_text","typed_text","elapsed_seconds"],"title":"score_typing_testArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/compare_texts":{"post":{"operationId":"compare_texts","summary":"Character-level and word-level diff between a typed sample and a target passage, without the","description":"Character-level and word-level diff between a typed sample and a target passage, without the\n    WPM math. Use for \"show me exactly where I made mistakes in this typing attempt\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"target_text":{"description":"The passage the person was supposed to type.","title":"Target Text","type":"string"},"typed_text":{"description":"What the person actually typed.","title":"Typed Text","type":"string"}},"required":["target_text","typed_text"],"title":"compare_textsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/practice_passage":{"post":{"operationId":"practice_passage","summary":"A typing-practice passage by difficulty tier, optionally stitched to a target word count. Use","description":"A typing-practice passage by difficulty tier, optionally stitched to a target word count. Use\n    for \"give me a punctuation-heavy typing passage\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"tier":{"default":"common_words","description":"common_words | punctuation_heavy | numbers_symbols","title":"Tier","type":"string"},"target_words":{"anyOf":[{"maximum":500,"minimum":5,"type":"integer"},{"type":"null"}],"default":null,"description":"Approximate word count to stitch the passage to.","title":"Target Words"}},"title":"practice_passageArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/tier_list":{"post":{"operationId":"tier_list","summary":"The three practice-passage difficulty tiers and what each contains. Use for \"what typing","description":"The three practice-passage difficulty tiers and what each contains. Use for \"what typing\n    practice difficulty levels are there\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{},"title":"tier_listArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/typing_tips":{"post":{"operationId":"typing_tips","summary":"Curated typing-improvement tips, optionally filtered by category. Use for \"tips to improve my","description":"Curated typing-improvement tips, optionally filtered by category. Use for \"tips to improve my\n    typing accuracy\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"category":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"posture | accuracy | speed | practice_habits","title":"Category"}},"title":"typing_tipsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/methodology_explainer":{"post":{"operationId":"methodology_explainer","summary":"Explain exactly how WPM and accuracy are computed here. Use for \"how is net WPM actually","description":"Explain exactly how WPM and accuracy are computed here. Use for \"how is net WPM actually\n    calculated\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{},"title":"methodology_explainerArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}}}}