Skip to content

Reference

API reference

A small REST API over HTTPS. JSON in, JSON out, conventional status codes. The base URL is https://api.docsmithhq.com/v1.

Authentication

Create a key in Settings → API keys. Keys are shown once. Send it as a bearer token on every request.

curl https://api.docsmithhq.com/v1/repositories \
  -H "Authorization: Bearer dsk_live_7Kx2mQ..."

Keys are scoped to an organisation and carry the plan limits of that organisation. A key can be restricted to specific repositories when it is created. Rotate by creating a second key, deploying, then revoking the first — revocation takes effect within five seconds.

POST /v1/sync

The endpoint the whole product is built on. Analyse one change against one documentation page.

Request

FieldTypeNotes
diffstring, requiredA unified diff, or plain before/after text. Maximum 24,000 characters.
docstring, requiredThe documentation page as Markdown or MDX. Maximum 40,000 characters.
docPathstring, optionalUsed for attribution in the response and the audit log.
repositorystring, optionalFree text, e.g. acme/checkout-sdk.
confidenceFloornumber, optional0–1. Findings below this are not returned. Defaults to the organisation setting.

Response

{
  "id": "syn_9f31c0a7b4",
  "verdict": "stale",
  "changeSummary": "Lowered the default attempt count from 5 to 3.",
  "headline": "Two passages on this page state the old defaults.",
  "findings": [
    {
      "section": "Defaults",
      "quote": "By default the client makes up to 5 attempts",
      "why": "DEFAULT_ATTEMPTS moved from 5 to 3 in this change.",
      "severity": "breaking",
      "confidence": 0.94,
      "verified": true
    }
  ],
  "reasoning": [
    "Read the change: 9 lines removed, 12 added.",
    "Dropped 1 finding whose quoted passage could not be located verbatim."
  ],
  "draft": "# Retries\n\nThe checkout client retries...",
  "diff": [
    { "type": "del", "oldNum": 12, "newNum": null, "text": "...up to 5 attempts" },
    { "type": "add", "oldNum": null, "newNum": 12, "text": "...up to 3 attempts" }
  ],
  "stats": { "added": 3, "removed": 3 },
  "model": "gpt-4.1",
  "provider": "openai",
  "ms": 6120
}

verdict is current when nothing needed changing. In that case findings and diff are empty arrays and draft is the page exactly as you sent it.

severity is one of breaking, misleading or incomplete. verified is always true in a response — unverifiable findings are dropped server-side and counted in reasoning.

GET /v1/repositories

{
  "data": [
    {
      "id": "rep_4c1e88",
      "name": "acme/checkout-sdk",
      "host": "github",
      "paths": ["docs/**/*.md", "README.md"],
      "pagesWatched": 41,
      "indexedAt": "2026-07-28T09:14:22Z",
      "deliveryMode": "review_queue"
    }
  ],
  "hasMore": false
}

GET /v1/drafts

List drafts awaiting review. Filter with ?status=pending, ?repository=rep_4c1e88 or ?since=2026-07-01T00:00:00Z. Paginate with ?cursor= and read hasMore.

POST /v1/drafts/{id}/approve
POST /v1/drafts/{id}/reject   { "reason": "Page is correct; the change was internal." }

Approving a draft on a repository in pull-request mode opens the pull request synchronously and returns its URL.

Idempotency

Send an Idempotency-Key header on any POST. A repeated key within 24 hours returns the original response without running a second sync or consuming a second unit of quota. Use it whenever you call the API from a job that might retry.

curl https://api.docsmithhq.com/v1/sync \
  -H "Authorization: Bearer $DOCSMITH_API_KEY" \
  -H "Idempotency-Key: 2026-07-30-a4f19c2-retries-md" \
  -H "Content-Type: application/json" \
  -d @payload.json

Errors

Errors carry a machine-readable code and a message written for a human reading a log at 2am.

{
  "error": {
    "code": "quota_exhausted",
    "message": "You have used all 30 syncs on the Free plan this month. The counter resets on 1 August.",
    "resetsOn": "2026-08-01T00:00:00Z"
  }
}
StatusCodeMeaning
400invalid_requestA field is missing, malformed, or over its size limit.
401unauthenticatedMissing, malformed or revoked API key.
403forbiddenThe key is not scoped to this repository.
402quota_exhaustedMonthly sync limit reached. Never billed as overage.
429rate_limitedToo many requests. Honour the Retry-After header.
502provider_unavailableEvery routed model failed. The sync is not counted against your quota. Retry.
503maintenancePlanned maintenance. Announced 72 hours ahead on the status page.

Rate limits

60 requests an hour on Free, 600 on Team, 3,000 on Business, per organisation rather than per key. Every response carries the current state:

X-RateLimit-Limit: 600
X-RateLimit-Remaining: 583
X-RateLimit-Reset: 1785412800

A 429 always carries Retry-After in seconds. Back off exponentially from it rather than polling — we would rather you succeeded on the second attempt than hammered the first.

Versioning

The version is in the path. Additive changes — a new field, a new optional parameter, a new enum value — ship without a version bump, so parse defensively. Breaking changes get a new path and 90 days’ notice by email to every account with an active key. Nothing is ever removed from v1.