{
  "name": "x.md",
  "description": "Read-only HTTP API over public X (Twitter) content. Every operation is a GET, needs no authentication, and returns compact Markdown by default or JSON with `format=json` or `Accept: application/json`. x.md never posts, follows, likes, or writes anything to X.",
  "version": "v1",
  "documentation_url": "https://x.pcstyle.dev/docs",
  "openapi_url": "https://x.pcstyle.dev/openapi.json",
  "api_catalog_url": "https://x.pcstyle.dev/.well-known/api-catalog",
  "llms_txt_url": "https://x.pcstyle.dev/llms.txt",
  "mcp_url": "https://x.pcstyle.dev/mcp",
  "terms_url": "https://x.pcstyle.dev/terms",
  "contact_url": "https://x.pcstyle.dev/contact",
  "source_url": "https://github.com/pc-style/x-md",
  "authentication": {
    "required": false,
    "scheme": "Bearer",
    "description": "The public API needs no credentials. An optional `Authorization: Bearer <key>` raises the rate limits for live search."
  },
  "versioning": {
    "current": "v1",
    "base_path": "/api/v1",
    "policy_url": "https://x.pcstyle.dev/docs/versioning",
    "description": "Breaking changes ship as a new path version. The permalink routes are unversioned and stable. Deprecated routes answer with RFC 9745 `Deprecation` and RFC 8594 `Sunset` headers plus a `successor-version` link. `/api/browse` picks that link from its `resource`, and omits it when the call names none.",
    "deprecated_aliases": [
      {
        "path": "/api/convert",
        "successor": "/api/v1/posts",
        "deprecation": "@1789430400",
        "sunset": "Wed, 15 Sep 2027 00:00:00 GMT",
        "sunset_iso": "2027-09-15T00:00:00Z"
      },
      {
        "path": "/api/browse",
        "successor_parameter": "resource",
        "successors": {
          "profile": "/api/v1/profiles/{handle}",
          "followers": "/api/v1/profiles/{handle}/followers",
          "following": "/api/v1/profiles/{handle}/following",
          "search": "/api/v1/search"
        },
        "deprecation": "@1789430400",
        "sunset": "Wed, 15 Sep 2027 00:00:00 GMT",
        "sunset_iso": "2027-09-15T00:00:00Z"
      }
    ]
  },
  "endpoints": [
    {
      "operationId": "getPost",
      "method": "GET",
      "path": "/api/v1/posts",
      "description": "Read one public X post, thread, or conversation as Markdown or JSON.",
      "example": "https://x.pcstyle.dev/api/v1/posts?url=https://x.com/jack/status/20"
    },
    {
      "operationId": "getProfile",
      "method": "GET",
      "path": "/api/v1/profiles/{handle}",
      "description": "Read a public profile and its latest original posts.",
      "example": "https://x.pcstyle.dev/api/v1/profiles/jack?format=json"
    },
    {
      "operationId": "listFollowers",
      "method": "GET",
      "path": "/api/v1/profiles/{handle}/followers",
      "description": "List the accounts following a public profile.",
      "example": "https://x.pcstyle.dev/api/v1/profiles/jack/followers"
    },
    {
      "operationId": "listFollowing",
      "method": "GET",
      "path": "/api/v1/profiles/{handle}/following",
      "description": "List the accounts a public profile follows.",
      "example": "https://x.pcstyle.dev/api/v1/profiles/jack/following"
    },
    {
      "operationId": "searchPosts",
      "method": "GET",
      "path": "/api/v1/search",
      "description": "Search public posts or users.",
      "example": "https://x.pcstyle.dev/api/v1/search?q=vercel&format=json"
    },
    {
      "operationId": "getOEmbed",
      "method": "GET",
      "path": "/api/v1/oembed",
      "description": "oEmbed document for a public X status URL.",
      "example": "https://x.pcstyle.dev/api/v1/oembed?url=https://x.com/jack/status/20"
    },
    {
      "operationId": "getPostByPermalink",
      "method": "GET",
      "path": "/{handle}/status/{id}",
      "description": "The same post reader, reachable by rewriting an x.com permalink to this host.",
      "example": "https://x.pcstyle.dev/jack/status/20"
    },
    {
      "operationId": "getProfileByHandle",
      "method": "GET",
      "path": "/{handle}",
      "description": "The same profile reader, reachable by handle.",
      "example": "https://x.pcstyle.dev/jack"
    },
    {
      "operationId": "searchPostsByPath",
      "method": "GET",
      "path": "/search",
      "description": "The same search, reachable as a plain path.",
      "example": "https://x.pcstyle.dev/search?q=vercel"
    }
  ],
  "errors": {
    "media_type": "application/problem+json",
    "specification": "https://www.rfc-editor.org/rfc/rfc9457",
    "documentation_url": "https://x.pcstyle.dev/docs/reliability#errors",
    "description": "Every failure answers with RFC 9457 problem details carrying a stable `code`, a human `detail`, and a `resolution` hint.",
    "codes": [
      {
        "code": "missing_url",
        "status": 400,
        "title": "Missing url parameter",
        "resolution": "Add `?url=<public X status URL>`, or call `/{handle}/status/{id}` directly."
      },
      {
        "code": "invalid_url",
        "status": 400,
        "title": "Invalid X status URL",
        "resolution": "Pass a public x.com or twitter.com status URL in `url`, for example `?url=https://x.com/jack/status/20`."
      },
      {
        "code": "unsupported_host",
        "status": 400,
        "title": "Unsupported host",
        "resolution": "Only x.com and twitter.com status URLs are supported. Rewrite the host and retry."
      },
      {
        "code": "invalid_path",
        "status": 400,
        "title": "Not a status permalink",
        "resolution": "Use a permalink shaped like https://x.com/{handle}/status/{id}."
      },
      {
        "code": "invalid_params",
        "status": 400,
        "title": "Invalid handle or status id",
        "resolution": "Provide `handle` (1-15 word characters) and a numeric `id`."
      },
      {
        "code": "invalid_handle",
        "status": 400,
        "title": "Invalid X handle",
        "resolution": "Handles are 1-15 characters of letters, digits, or underscores, with no leading @."
      },
      {
        "code": "invalid_resource",
        "status": 400,
        "title": "Unsupported browse resource",
        "resolution": "Use `resource=profile`, `search`, `followers`, or `following`."
      },
      {
        "code": "invalid_format",
        "status": 400,
        "title": "Unsupported format",
        "resolution": "Use `format=markdown`, `format=obsidian`, or `format=json`. Browse accepts markdown or json."
      },
      {
        "code": "invalid_thread",
        "status": 400,
        "title": "Invalid thread parameter",
        "resolution": "Use `thread=off`, `full`, `conversation`, or a number from 2 to 100."
      },
      {
        "code": "invalid_userinfo",
        "status": 400,
        "title": "Invalid userinfo parameter",
        "resolution": "Use `userinfo=off`, `author`, or `all`."
      },
      {
        "code": "invalid_context",
        "status": 400,
        "title": "Invalid context parameter",
        "resolution": "Use `context=full` or `context=thread`."
      },
      {
        "code": "invalid_replies",
        "status": 400,
        "title": "Invalid replies parameter",
        "resolution": "Use `replies=top`, `recent`, or `off`."
      },
      {
        "code": "invalid_mode",
        "status": 400,
        "title": "Invalid mode parameter",
        "resolution": "See the parameter tables at https://x.pcstyle.dev/docs/responses."
      },
      {
        "code": "missing_query",
        "status": 400,
        "title": "Missing search query",
        "resolution": "Add `?q=<search terms>`, for example `/search?q=vercel`."
      },
      {
        "code": "invalid_body",
        "status": 400,
        "title": "Invalid JSON body",
        "resolution": "Send a well-formed JSON object, or omit the body entirely."
      },
      {
        "code": "invalid_key",
        "status": 401,
        "title": "Invalid or disabled API key",
        "resolution": "Remove the Authorization header to call anonymously, or present a valid `Authorization: Bearer <key>`."
      },
      {
        "code": "unauthorized",
        "status": 401,
        "title": "Unauthorized",
        "resolution": "This route is private. The public read-only API needs no credentials; see https://x.pcstyle.dev/openapi.json."
      },
      {
        "code": "not_found",
        "status": 404,
        "title": "Not found",
        "resolution": "Confirm the post or profile is public and still exists on x.com, then retry. Deleted and protected content is never available."
      },
      {
        "code": "route_not_found",
        "status": 404,
        "title": "API route not found",
        "resolution": "Discover the public API through https://x.pcstyle.dev/api, https://x.pcstyle.dev/openapi.json, or https://x.pcstyle.dev/.well-known/api-catalog."
      },
      {
        "code": "method_not_allowed",
        "status": 405,
        "title": "Method not allowed",
        "resolution": "x.md is read-only. Use GET, HEAD, or OPTIONS; the `Allow` response header lists what this route accepts."
      },
      {
        "code": "not_acceptable",
        "status": 406,
        "title": "No acceptable representation",
        "resolution": "Request `text/markdown`, `application/json`, or `text/html`, or omit the Accept header."
      },
      {
        "code": "rate_limited",
        "status": 429,
        "title": "Rate limit exceeded",
        "resolution": "Wait the number of seconds in the `Retry-After` header, then retry. Cached responses do not count against the allowance."
      },
      {
        "code": "internal_error",
        "status": 500,
        "title": "Unexpected error",
        "resolution": "Retry with exponential backoff. If it persists, open an issue at https://github.com/pc-style/x-md/issues."
      },
      {
        "code": "upstream_error",
        "status": 502,
        "title": "Upstream provider error",
        "resolution": "Retry with backoff. x.md reads a third-party provider that can fail independently."
      },
      {
        "code": "search_unavailable",
        "status": 503,
        "title": "Search temporarily unavailable",
        "resolution": "Wait the number of seconds in `Retry-After`, then retry. Photos, Videos, and Users need configured sessions."
      },
      {
        "code": "admin_unconfigured",
        "status": 503,
        "title": "Admin is not configured",
        "resolution": "Set X_MD_ADMIN_TOKEN on the deployment. This route is not part of the public API."
      }
    ]
  },
  "links": {
    "self": "https://x.pcstyle.dev/api",
    "openapi": "https://x.pcstyle.dev/openapi.json",
    "documentation": "https://x.pcstyle.dev/docs",
    "llms_txt": "https://x.pcstyle.dev/llms.txt",
    "api_catalog": "https://x.pcstyle.dev/.well-known/api-catalog",
    "mcp": "https://x.pcstyle.dev/mcp",
    "sitemap": "https://x.pcstyle.dev/sitemap.xml"
  }
}
