Skip to content

TypeScript SDK

The reference TypeScript SDK for the Docs Feedback Protocol. Package name: @fixyourdocs/sdk. Requires Node.js 20+ (uses the built-in global fetch; no runtime dependencies).

Terminal window
npm install @fixyourdocs/sdk

buildReport takes flat, ergonomic input and validates lengths and patterns locally, so most shape mistakes throw before the network round-trip.

import { Client, buildReport } from "@fixyourdocs/sdk";
const client = new Client({
apiUrl: "https://hub.fixyourdocs.io",
// token: "<opaque-bearer-token>", // optional — only if the endpoint requires auth
});
const report = buildReport({
docUrl: "https://docs.example.com/s3/quickstart",
summary: "ListBuckets returns AccessDenied with the IAM policy from the quickstart.",
kind: "incorrect",
agentName: "claude-code",
agentVersion: "1.4.2",
agentVendor: "Anthropic",
evidence: [
{ kind: "attempted_action", text: "aws s3 ls" },
{ kind: "error_message", text: "An error occurred (AccessDenied) when calling the ListBuckets operation" },
],
suggestedFix: "Add `s3:ListAllMyBuckets` to the policy in step 3.",
});
const result = await client.send(report);
console.log(result.id, result.isDuplicate ? "(duplicate)" : "(new)");

Prefer to construct the nested wire-format object by hand? The underlying types are exported too:

import { Client, type Report } from "@fixyourdocs/sdk";
const report: Report = {
protocol_version: "0",
doc_url: "https://docs.example.com/getting-started",
agent: { name: "aider" },
report: {
kind: "missing",
summary: "The page does not document how to set the AIDER_API_KEY env var.",
},
};
const client = new Client({ apiUrl: "https://hub.fixyourdocs.io" });
await client.send(report, { idempotencyKey: "01HZA4F8PD9YQF1XGM3KQ8E5VR" });

Both paths go through Client.send(report, opts?).

Client.send throws subclasses of FixYourDocsError:

ClassHTTP status
ValidationError400
AuthError401
NotFoundError404
OptedOutError410
PayloadTooLargeError413
UnsupportedMediaTypeError415
PolicyRejectedError422
RateLimitedError429
ServerError5xx

Where the response carries extra context, the typed error exposes it (OptedOutError.since, PolicyRejectedError.reason, RateLimitedError.retryAfter, ValidationError.details). The client retries once on 502/503/504; it does not auto-retry on 429 — respect RateLimitedError.retryAfter.

Found something wrong, missing, or out of date on this page? File a docs-feedback report →