{
 "$schema": "https://agentdrives.com/schemas/tool.schema.json",
 "id": "prd_01m57vgtggve2drz78q9er5sh4",
 "ids": {
  "org": "org_01m57vgtgg20wtyks53cjwmk0g",
  "surfaces": {
   "web": "srf_01m5a8gsps5ah459b6mdp1pxet",
   "api": "srf_01m5a8gsps5dhehst9pjbhr0qj",
   "mcp": "srf_01m5a8gspsazh6pee4nyfnms7v",
   "sdk": "srf_01m5a8gspst0pgwt11jq17bkek"
  },
  "slugs": [
   "uploadthing"
  ],
  "domain": "uploadthing.com"
 },
 "slug": "uploadthing",
 "name": "UploadThing",
 "url": "https://uploadthing.com",
 "domain": "uploadthing.com",
 "category": "file-storage",
 "category_name": "File storage",
 "tested_at": "2026-10-24",
 "run": "20261024T050146Z",
 "draft": false,
 "reviewed": true,
 "owner_verified": null,
 "origin": "editorial",
 "history": [
  {
   "run": "20261006T044837Z",
   "date": "2026-10-06",
   "level": 1,
   "engine": {
    "runner": "omp",
    "model": "claude-opus-5-5",
    "driver": 2,
    "signed": true,
    "inbox": null,
    "robots": "start"
   },
   "stop": "signup"
  },
  {
   "run": "20261017T054146Z",
   "date": "2026-10-17",
   "level": 1,
   "engine": {
    "runner": "omp",
    "model": "claude-opus-5-5",
    "driver": 4,
    "signed": true,
    "inbox": null,
    "robots": "skip"
   },
   "stop": "signup",
   "drives": 2
  },
  {
   "run": "20261024T050146Z",
   "date": "2026-10-24",
   "level": 1,
   "engine": {
    "runner": "omp",
    "model": "claude-opus-5-5",
    "driver": 4,
    "signed": true,
    "inbox": null,
    "robots": "skip"
   },
   "stop": "signup"
  }
 ],
 "level": 1,
 "level_name": "Needs a person",
 "level_selfhost": null,
 "entry": "closed",
 "door": {
  "passed": 0,
  "tries": 3,
  "self_start": false
 },
 "badges": [],
 "not_counted": null,
 "stages": [
  {
   "key": "in",
   "label": "Access",
   "state": "no",
   "text": "Sign-up only through GitHub",
   "at": "signup"
  },
  {
   "key": "work",
   "label": "Use",
   "state": "unreached",
   "text": "Work not measured"
  },
  {
   "key": "pay",
   "label": "Pay",
   "state": "unreached",
   "text": "Payment not reached",
   "value": "unreached",
   "route": "portal"
  },
  {
   "key": "leave",
   "label": "Leave",
   "state": "unreached",
   "text": "Leaving not reached",
   "how": "no-account"
  }
 ],
 "outcomes": [
  {
   "key": "find",
   "label": "Learn",
   "state": "yes",
   "text": "Docs it can act on: an OpenAPI and an MCP server",
   "have": [
    "openapi",
    "mcp"
   ],
   "docs": "gaps"
  },
  {
   "key": "access",
   "label": "Access",
   "state": "no",
   "text": "Sign-up only through GitHub",
   "at": "signup",
   "stage": "in"
  },
  {
   "key": "use",
   "label": "Use",
   "state": "unreached",
   "text": "Work not measured",
   "stage": "work"
  },
  {
   "key": "pay",
   "label": "Pay",
   "state": "unreached",
   "text": "Payment not reached",
   "value": "unreached",
   "route": "portal",
   "stage": "pay"
  },
  {
   "key": "leave",
   "label": "Leave",
   "state": "unreached",
   "text": "Leaving not reached",
   "how": "no-account",
   "stage": "leave"
  }
 ],
 "access": [
  {
   "key": "person",
   "label": "A person sets it up",
   "routes": [],
   "minutes": null,
   "core": null
  }
 ],
 "minutes": null,
 "next": {
  "to": 2,
  "text": "Next: let an agent sign up with its own email address"
 },
 "stop": "signup",
 "core": "0/8",
 "scores": {
  "coverage": null,
  "reliability": null,
  "resilience": null,
  "setup": 70,
  "surface_coverage": null,
  "docs_accuracy": null,
  "docs_completeness": null
 },
 "parts": {
  "holds_up": null,
  "docs_match": null,
  "setup": 70,
  "security": null,
  "standards": [
   {
    "standard": "OpenAPI",
    "state": "behind",
    "behind": 2,
    "value": "3.0.0"
   }
  ]
 },
 "reliability_method": null,
 "resilience": null,
 "stress": [],
 "surface_audit": null,
 "coverage_core": null,
 "coverage_own": null,
 "after_wall": null,
 "coverage_source": "computed",
 "driver": {
  "version": 4,
  "model": "claude-opus-5-5",
  "profile": "full",
  "assisted": false,
  "handoff": false,
  "prompt_sha": "4f1dda8e94a1",
  "kb_version": "4+overlay-50116b4a41",
  "identity": "e8a92f24a9a8"
 },
 "methodology": 24,
 "rules_date": "2026-10-20",
 "engine": {
  "runner": "omp",
  "model": "claude-opus-5-5",
  "driver": 4,
  "signed": true,
  "inbox": null,
  "robots": "skip"
 },
 "same_level_drives": 2,
 "drives": 2,
 "same_stop_drives": 4,
 "works_assisted": null,
 "freshness": "fresh",
 "newer_drives": null,
 "nothing_to_pay": false,
 "core_gated": false,
 "profiles": {},
 "agent_check": null,
 "agent_pass": null,
 "who_gets_in": {
  "server": {
   "state": "closed"
  },
  "signed": {
   "state": "page",
   "kind": "home",
   "at": "2026-10-24"
  },
  "browser": {
   "state": "unknown",
   "measured": false
  },
  "our_key": "pending",
  "robots": null,
  "tip": false
 },
 "ladder": {
  "docs": {
   "status": "headless",
   "note": "Docs at docs.uploadthing.com (41 pages, fresh) and an OpenAPI 3.0.0 spec at api.uploadthing.com/openapi-spec.json, fetched without a browser. No llms.txt, no markdown pages."
  },
  "signup": {
   "status": "blocked",
   "cause": "other",
   "note": "Sign-up only through GitHub: no way in for an agent's own account. https://uploadthing.com/sign-in offers only \"Sign In with GitHub\" (no email or password field); /sign-up is a 404; every pricing \"Get Started\" goes to /sign-in."
  },
  "verify": {
   "status": "",
   "cause": "other",
   "note": "Not reached: no account. Sign-up only through GitHub: no way in for an agent's own account.",
   "reached": false
  },
  "credentials": {
   "status": "",
   "cause": "other",
   "note": "Not reached. The token (UPLOADTHING_TOKEN) comes only from the dashboard's API Keys tab; the API has no key or sign-up operation.",
   "reached": false
  },
  "first_call": {
   "status": "",
   "cause": "other",
   "route": "account",
   "note": "Every API call needs x-uploadthing-api-key: without one POST /v6/listFiles answers 400 \"Missing API Key\"; no documented no-account route.",
   "reached": false
  },
  "first_action": {
   "status": "",
   "note": "Not reached: no account.",
   "reached": false
  },
  "pay": {
   "status": "",
   "grade": "P1",
   "rails": [],
   "rail_ids": [],
   "first_party": false,
   "rail_scope": "none",
   "trial_path": "free tier",
   "route": "portal",
   "checkout": {
    "reached": "no",
    "processor": "none",
    "captcha": "none",
    "three_ds": "not_seen",
    "card_form": false,
    "phone_field": "none",
    "wallets": [],
    "rail_offer": "none",
    "price": "10.00",
    "currency": "USD",
    "period": "month",
    "plan": "$10/month app (100GB)",
    "last_button": ""
   },
   "person": "none",
   "ours": "no account",
   "note": "No 402, x402, MPP, Stripe Projects listing or billing API (nothing paid, no 402). Plans: free $0 (2GB), $10/month (100GB), usage-based from $25/month. Every \"Get Started\" leads to the GitHub-only sign-in, so the checkout was not reached and buying needs a person's GitHub account.",
   "reached": false
  },
  "cancel": {
   "status": "",
   "grade": "n/a",
   "note": "Nothing to cancel: no account or plan was started. The docs we read say nothing about cancelling by API.",
   "reached": false
  },
  "delete": {
   "status": "",
   "note": "No account was made; the only calls were unauthenticated reads that stored nothing.",
   "account": false,
   "reached": false
  }
 },
 "routes": [
  {
   "route": "sso_github",
   "offered": "seen",
   "tried": false,
   "not_tried": "policy",
   "result": null,
   "wall": null,
   "person": null,
   "brings": null,
   "fresh": null,
   "minutes": null,
   "browser": null
  },
  {
   "route": "person_key",
   "offered": "documented",
   "tried": false,
   "not_tried": "assisted_only",
   "result": null,
   "wall": null,
   "person": null,
   "brings": null,
   "fresh": null,
   "minutes": null,
   "browser": null
  }
 ],
 "checkout": {
  "reached": "no",
  "rail_offer": "none",
  "period": "month",
  "price": "10.00",
  "currency": "USD",
  "plan": "$10/month app (100GB)"
 },
 "docs": {
  "at": "2026-10-24",
  "read": 41,
  "listed": 41,
  "sampled": false,
  "overall": "gaps",
  "getting_started": "found",
  "auth": "found",
  "errors": "found",
  "examples": "good",
  "freshness": "fresh",
  "newest": "2026-09-30",
  "core_pages": "5 of 8",
  "capabilities": "gaps"
 },
 "claims": null,
 "pay_options": {
  "checked": "2026-10-24",
  "source": "probe",
  "options": [],
  "agentic": [],
  "paid": null,
  "exercised": null,
  "detected_grade": null,
  "trial": {
   "no_card": null,
   "card_required": null,
   "free_plan": true
  },
  "owner_fixes": [
   {
    "title": "Accept x402 or MPP on your API",
    "how": "Answer an unpaid call with 402 and a payment challenge, so an agent pays per call or buys credits without an account or a card."
   },
   {
    "title": "List your plans on Stripe Projects",
    "how": "Agents buy a plan with `stripe projects add`, paid with a token under a spend cap the owner sets (projects.dev)."
   }
  ]
 },
 "surfaces": {
  "api": true,
  "openapi": true,
  "cli": false,
  "sdk": true,
  "mcp": "third-party",
  "llms_txt": false,
  "webhooks": true,
  "sandbox": false
 },
 "surface_notes": {
  "api": "REST, 14 operations, header x-uploadthing-api-key",
  "openapi": "3.0.0 (info 6.10.0), behind 3.2.1",
  "sdk": "uploadthing JS SDK (UTApi, React/Solid/Vue/Svelte/Expo)",
  "mcp": "third-party stdio only, needs a token"
 },
 "can_do": [
  "Read the docs and the OpenAPI spec without an account"
 ],
 "cannot_do": [
  {
   "what": "Make an account",
   "why": "Sign-up only through GitHub"
  },
  {
   "what": "Get an API token",
   "why": "Only from the dashboard's API Keys tab, behind the GitHub sign-in"
  },
  {
   "what": "Upload, list, rename or delete files",
   "why": "Every API call needs a token"
  },
  {
   "what": "Buy a plan",
   "why": "The checkout sits behind the GitHub-only sign-in; no agent payment rail"
  }
 ],
 "blockers": [
  "Sign-up only through GitHub: no way in for an agent's own account."
 ],
 "tips_for_agents": [
  "You need a person's GitHub sign-in to get UPLOADTHING_TOKEN; ask for it up front.",
  "With a token, the REST API (x-uploadthing-api-key) and UTApi cover upload, upload from URL, list, rename and delete; the spec is at api.uploadthing.com/openapi-spec.json.",
  "There is no official MCP server; a third-party stdio one needs the same token."
 ],
 "selfhost": null,
 "summary": "UploadThing's only sign-up is \"Sign In with GitHub\": no email, API or CLI sign-up, so an agent cannot make its own account or get the token every API call needs. The docs and a 14-operation OpenAPI 3.0.0 spec are public, but there is no llms.txt, no official MCP server and no agent payment rail.",
 "wall": "Sign-up only through GitHub",
 "plan_scope": "",
 "robots_stop": null,
 "robots": null,
 "terms": null,
 "plain": {
  "summary": "UploadThing lets agents sign up only through a human's GitHub account, so an agent cannot create its own account or get the API key every file operation needs. It could read the public docs and API spec on its own, but nothing past sign-in was reachable.",
  "can_do": [
   "Read the product's documentation and API reference without an account"
  ],
  "cannot_do": [
   {
    "what": "Create an account",
    "why": "Sign-up only works through a person's GitHub login"
   },
   {
    "what": "Get an API key",
    "why": "Keys are only issued in the dashboard, behind that GitHub sign-in"
   },
   {
    "what": "Upload, list, rename or delete files",
    "why": "Every file action needs the API key that requires an account"
   },
   {
    "what": "Buy a paid plan",
    "why": "The checkout is behind the same GitHub-only sign-in"
   }
  ]
 },
 "plan_gated": [],
 "reply": null,
 "capabilities": [
  {
   "id": "cap-01",
   "group": "Uploading",
   "capability": "Upload a file from the browser via a prebuilt UI component",
   "weight": "core",
   "plan": "free",
   "surfaces": {
    "api": null,
    "mcp": null,
    "cli": null,
    "ui": "UploadButton / UploadDropzone React components (also Solid/Vue/Svelte helpers)"
   },
   "check": "File appears in dashboard file browser and GET on the returned ufs.sh URL returns 200",
   "source": "https://uploadthing.com (home page code sample); https://docs.uploadthing.com/api-reference/react",
   "result": "blocked",
   "via": null
  },
  {
   "id": "cap-02",
   "group": "Uploading",
   "capability": "Define a file route with type, size and count restrictions",
   "weight": "core",
   "plan": "free",
   "surfaces": {
    "api": null,
    "mcp": null,
    "cli": null,
    "ui": "server-side fileRouter config, not in dashboard UI"
   },
   "check": "An upload exceeding maxFileSize/maxFileCount is rejected client-side with a matching error",
   "source": "https://docs.uploadthing.com/file-routes",
   "result": "blocked",
   "via": null
  },
  {
   "id": "cap-03",
   "group": "Uploading",
   "capability": "Authorize or block an upload before it starts (server middleware)",
   "weight": "core",
   "plan": "free",
   "surfaces": {
    "api": null,
    "mcp": null,
    "cli": null,
    "ui": null
   },
   "check": "Request without valid auth throws UploadThingError and no file is created",
   "source": "https://uploadthing.com (home page code sample); https://docs.uploadthing.com/concepts/auth-security",
   "result": "blocked",
   "via": null
  },
  {
   "id": "cap-04",
   "group": "Uploading",
   "capability": "Run server-side logic when an upload finishes",
   "weight": "core",
   "plan": "free",
   "surfaces": {
    "api": null,
    "mcp": null,
    "cli": null,
    "ui": null
   },
   "check": "onUploadComplete side effect (e.g. DB write) is observable right after client upload resolves",
   "source": "https://uploadthing.com (home page code sample); https://docs.uploadthing.com/concepts/file-routes",
   "result": "blocked",
   "via": null
  },
  {
   "id": "cap-05",
   "group": "Uploading",
   "capability": "Upload a file directly from the server (no browser)",
   "weight": "core",
   "plan": "free",
   "surfaces": {
    "api": "UTApi.uploadFiles",
    "mcp": null,
    "cli": null,
    "ui": null
   },
   "check": "listFiles / dashboard shows the new file key immediately after the call returns",
   "source": "https://docs.uploadthing.com/api-reference/ut-api",
   "result": "blocked",
   "via": null
  },
  {
   "id": "cap-06",
   "group": "Uploading",
   "capability": "Import a file into UploadThing from an external URL",
   "weight": "core",
   "plan": "free",
   "surfaces": {
    "api": "UTApi.uploadFilesFromUrl",
    "mcp": null,
    "cli": null,
    "ui": null
   },
   "check": "Resulting file key exists and its CDN URL content matches the source URL",
   "source": "https://docs.uploadthing.com/api-reference/ut-api",
   "result": "blocked",
   "via": null
  },
  {
   "id": "cap-07",
   "group": "File management",
   "capability": "Delete an uploaded file",
   "weight": "core",
   "plan": "free",
   "surfaces": {
    "api": "UTApi.deleteFiles",
    "mcp": null,
    "cli": null,
    "ui": "dashboard file browser delete action"
   },
   "check": "Subsequent listFiles call or dashboard view no longer shows the key; CDN URL returns 404",
   "source": "https://docs.uploadthing.com/api-reference/ut-api; https://uploadthing.com/dashboard",
   "result": "blocked",
   "via": null
  },
  {
   "id": "cap-08",
   "group": "File management",
   "capability": "Browse and manage uploaded files in a dashboard",
   "weight": "core",
   "plan": "free",
   "surfaces": {
    "api": null,
    "mcp": null,
    "cli": null,
    "ui": "dashboard file browser"
   },
   "check": "Uploaded file key/thumbnail/size is visible in the dashboard file list",
   "source": "https://uploadthing.com (\"Easily manage your files\" section); https://uploadthing.com/dashboard",
   "result": "blocked",
   "via": null
  },
  {
   "id": "cap-09",
   "group": "File management",
   "capability": "List files with pagination and filters",
   "weight": "secondary",
   "plan": "free",
   "surfaces": {
    "api": "UTApi.listFiles",
    "mcp": null,
    "cli": null,
    "ui": "dashboard file browser"
   },
   "check": "Response page contains the expected subset of keys matching the filter",
   "source": "https://docs.uploadthing.com/api-reference/ut-api",
   "result": "blocked",
   "via": null
  },
  {
   "id": "cap-10",
   "group": "File management",
   "capability": "Rename an uploaded file",
   "weight": "secondary",
   "plan": "free",
   "surfaces": {
    "api": "UTApi.renameFiles",
    "mcp": null,
    "cli": null,
    "ui": "dashboard file browser rename action"
   },
   "check": "listFiles / dashboard shows the new name for the same file key",
   "source": "https://docs.uploadthing.com/api-reference/ut-api; https://uploadthing.com/dashboard",
   "result": "blocked",
   "via": null
  },
  {
   "id": "cap-11",
   "group": "File management",
   "capability": "Assign a custom ID to a file instead of the generated key",
   "weight": "secondary",
   "plan": "free",
   "surfaces": {
    "api": "UTFiles symbol in onUploadComplete / middleware",
    "mcp": null,
    "cli": null,
    "ui": null
   },
   "check": "File is retrievable by the supplied customId via the API",
   "source": "https://docs.uploadthing.com/working-with-files; https://docs.uploadthing.com/concepts/auth-security",
   "result": "blocked",
   "via": null
  },
  {
   "id": "cap-12",
   "group": "Access control",
   "capability": "Mark a file public (CDN-URL readable) or private",
   "weight": "secondary",
   "plan": "paid",
   "surfaces": {
    "api": "acl option (public-read|private) in file router / UTApi",
    "mcp": null,
    "cli": null,
    "ui": "dashboard ACL setting"
   },
   "check": "Unsigned GET on a private file's ufs.sh URL returns 403; a public file returns 200",
   "source": "https://docs.uploadthing.com/concepts/regions-acl; https://uploadthing.com/pricing",
   "result": "blocked",
   "via": null
  },
  {
   "id": "cap-13",
   "group": "Access control",
   "capability": "Generate a time-limited signed URL to access a private file",
   "weight": "secondary",
   "plan": "paid",
   "surfaces": {
    "api": "UTApi.generateSignedURL / POST /requestFileAccess",
    "mcp": null,
    "cli": null,
    "ui": null
   },
   "check": "Signed URL grants 200 before expiry and 403 after expiry",
   "source": "https://docs.uploadthing.com/working-with-files; https://docs.uploadthing.com/api-reference/openapi-spec",
   "result": "blocked",
   "via": null
  },
  {
   "id": "cap-14",
   "group": "Uploading",
   "capability": "Validate custom input/metadata attached to an upload with a schema",
   "weight": "secondary",
   "plan": "free",
   "surfaces": {
    "api": ".input on the file route builder (Zod/Valibot/ArkType/Standard Schema)",
    "mcp": null,
    "cli": null,
    "ui": null
   },
   "check": "Upload request with input failing the schema is rejected before middleware runs",
   "source": "https://docs.uploadthing.com/concepts/file-routes",
   "result": "blocked",
   "via": null
  },
  {
   "id": "cap-15",
   "group": "Uploading",
   "capability": "Resume an interrupted upload",
   "weight": "secondary",
   "plan": "free",
   "surfaces": {
    "api": "client SDK createUpload (pause/resume)",
    "mcp": null,
    "cli": null,
    "ui": null
   },
   "check": "Pausing mid-transfer and resuming completes the upload without re-sending already-sent bytes",
   "source": "https://docs.uploadthing.com/api-reference/client",
   "result": "blocked",
   "via": null
  },
  {
   "id": "cap-16",
   "group": "Uploading",
   "capability": "Track live upload progress in the UI",
   "weight": "secondary",
   "plan": "free",
   "surfaces": {
    "api": null,
    "mcp": null,
    "cli": null,
    "ui": "onUploadProgress callback on UploadButton/UploadDropzone/useUploadThing"
   },
   "check": "Progress callback fires with increasing percentage values during a large upload",
   "source": "https://docs.uploadthing.com/api-reference/react",
   "result": "blocked",
   "via": null
  },
  {
   "id": "cap-17",
   "group": "Storage",
   "capability": "Choose the storage region a file is uploaded to",
   "weight": "secondary",
   "plan": "paid",
   "surfaces": {
    "api": "experimental_UTRegion metadata tag",
    "mcp": null,
    "cli": null,
    "ui": "dashboard region setting"
   },
   "check": "File's reported storage region matches the selected region (e.g. fra1 vs sea1)",
   "source": "https://docs.uploadthing.com/concepts/regions-acl; https://uploadthing.com/pricing",
   "result": "blocked",
   "via": null
  },
  {
   "id": "cap-18",
   "group": "Monitoring",
   "capability": "View account usage (storage, bandwidth, requests)",
   "weight": "secondary",
   "plan": "free",
   "surfaces": {
    "api": "UTApi.getUsageInfo",
    "mcp": null,
    "cli": null,
    "ui": "dashboard usage/analytics page"
   },
   "check": "Usage figures increase after an upload is performed",
   "source": "https://docs.uploadthing.com/api-reference/ut-api; https://uploadthing.com/dashboard",
   "result": "blocked",
   "via": null
  },
  {
   "id": "cap-19",
   "group": "Monitoring",
   "capability": "View an audit log of account activity",
   "weight": "secondary",
   "plan": "free",
   "surfaces": {
    "api": null,
    "mcp": null,
    "cli": null,
    "ui": "dashboard audit log"
   },
   "check": "An upload/delete action appears as a new audit log entry within its plan's retention window",
   "source": "https://uploadthing.com/pricing",
   "result": "blocked",
   "via": null
  },
  {
   "id": "cap-20",
   "group": "Configuration",
   "capability": "Set a webhook/callback URL for upload events",
   "weight": "secondary",
   "plan": "free",
   "surfaces": {
    "api": "callbackUrl config on createRouteHandler",
    "mcp": null,
    "cli": null,
    "ui": "dashboard webhook setting"
   },
   "check": "POST is received at the configured callback URL when an upload completes",
   "source": "https://docs.uploadthing.com/api-reference/server",
   "result": "blocked",
   "via": null
  },
  {
   "id": "cap-21",
   "group": "Configuration",
   "capability": "Control whether a file opens inline or downloads (content-disposition)",
   "weight": "secondary",
   "plan": "free",
   "surfaces": {
    "api": "contentDisposition option (inline|attachment) in file route config",
    "mcp": null,
    "cli": null,
    "ui": null
   },
   "check": "Response header Content-Disposition on the file URL matches the configured value",
   "source": "https://docs.uploadthing.com/file-routes",
   "result": "blocked",
   "via": null
  },
  {
   "id": "cap-22",
   "group": "Configuration",
   "capability": "Customize the look of the upload UI components",
   "weight": "peripheral",
   "plan": "free",
   "surfaces": {
    "api": null,
    "mcp": null,
    "cli": null,
    "ui": "appearance/className props, Tailwind withUt wrapper"
   },
   "check": "Rendered component reflects the custom class/appearance callback for a given state",
   "source": "https://docs.uploadthing.com/concepts/theming",
   "result": "blocked",
   "via": null
  },
  {
   "id": "cap-23",
   "group": "Account admin",
   "capability": "Create and manage API keys",
   "weight": "peripheral",
   "plan": "free",
   "surfaces": {
    "api": null,
    "mcp": null,
    "cli": null,
    "ui": "dashboard API keys page"
   },
   "check": "A newly created key authenticates a server SDK/API call; a revoked key is rejected",
   "source": "https://uploadthing.com/dashboard",
   "result": "blocked",
   "via": null
  },
  {
   "id": "cap-24",
   "group": "Account admin",
   "capability": "Invite and manage team members on an app",
   "weight": "peripheral",
   "plan": "paid",
   "surfaces": {
    "api": null,
    "mcp": null,
    "cli": null,
    "ui": "dashboard team management"
   },
   "check": "Invited member appears in the team list and can access the app's dashboard",
   "source": "https://uploadthing.com/dashboard; https://uploadthing.com/pricing",
   "result": "blocked",
   "via": null
  },
  {
   "id": "cap-25",
   "group": "Account admin",
   "capability": "Serve files from a custom domain",
   "weight": "peripheral",
   "plan": "paid",
   "surfaces": {
    "api": null,
    "mcp": null,
    "cli": null,
    "ui": "dashboard custom domain setting"
   },
   "check": "File URL on the custom domain resolves to the same content as the default ufs.sh URL",
   "source": "https://uploadthing.com/dashboard",
   "result": "blocked",
   "via": null
  }
 ],
 "stale": false,
 "unreachable_since": null,
 "not_driven_since": null,
 "icon": "/logos/uploadthing.png",
 "agent_kinds": {
  "browser": {
   "who": "An assistant in a browser",
   "passed": [],
   "stop": "signup",
   "why": "sign-up only through GitHub",
   "tone": "wall",
   "text": "Stops at sign-up: sign-up only through GitHub."
  },
  "direct": {
   "who": "An agent talking to it directly",
   "passed": [],
   "stop": "signup",
   "why": "sign-up only through GitHub",
   "tone": "wall",
   "text": "Stops at sign-up: sign-up only through GitHub."
  }
 },
 "stop_evidence": {
  "at": "signup",
  "date": "2026-10-24",
  "line": "Sign-up only through GitHub: no way in for an agent's own account. https://uploadthing.com/sign-in offers only \"Sign In with GitHub\" (no email or password field); /sign-up is a 404; every pricing \"Get Started\" goes to /sign-in."
 },
 "stop_shot": null,
 "attempts_count": 43,
 "detail": {
  "public": false,
  "in": [
   "report",
   "api"
  ],
  "since": "2026-10-17"
 },
 "what_it_does": null,
 "rules_version": "rules-2026-10-20-24",
 "rules_url": "https://agentdrives.com/method/changelog#rules-2026-10-20-24",
 "category_median": null,
 "probe": null,
 "probe_history": [],
 "agent_reports": null,
 "verdict": null,
 "changes": {
  "source": "store",
  "drives": [
   {
    "run": "20261006T044837Z",
    "date": "2026-10-06",
    "level": 1,
    "stop": "signup",
    "entry": "closed",
    "driver": 2,
    "listed": true
   },
   {
    "run": "20261024T050146Z",
    "date": "2026-10-24",
    "level": 1,
    "stop": "signup",
    "entry": "closed",
    "driver": 4,
    "listed": true
   }
  ],
  "events": [],
  "feed": "https://agentdrives.com/api/tools/uploadthing/changes.json"
 },
 "agreement": {
  "drives": 2,
  "agree": 2
 },
 "method_release": "2026-Q4.9",
 "rank": null,
 "rank_of": 1,
 "rank_change": null,
 "rank_since": null,
 "capability_matrix": [
  {
   "id": "cap-01",
   "name": "Upload a file from the browser via a prebuilt UI component",
   "core": true,
   "result": "blocked",
   "surfaces": {
    "api": "none",
    "mcp": "none",
    "cli": "none",
    "ui": "untried"
   }
  },
  {
   "id": "cap-02",
   "name": "Define a file route with type, size and count restrictions",
   "core": true,
   "result": "blocked",
   "surfaces": {
    "api": "none",
    "mcp": "none",
    "cli": "none",
    "ui": "untried"
   }
  },
  {
   "id": "cap-03",
   "name": "Authorize or block an upload before it starts (server middleware)",
   "core": true,
   "result": "blocked",
   "surfaces": {
    "api": "none",
    "mcp": "none",
    "cli": "none",
    "ui": "none"
   }
  },
  {
   "id": "cap-04",
   "name": "Run server-side logic when an upload finishes",
   "core": true,
   "result": "blocked",
   "surfaces": {
    "api": "none",
    "mcp": "none",
    "cli": "none",
    "ui": "none"
   }
  },
  {
   "id": "cap-05",
   "name": "Upload a file directly from the server (no browser)",
   "core": true,
   "result": "blocked",
   "surfaces": {
    "api": "untried",
    "mcp": "none",
    "cli": "none",
    "ui": "none"
   }
  },
  {
   "id": "cap-06",
   "name": "Import a file into UploadThing from an external URL",
   "core": true,
   "result": "blocked",
   "surfaces": {
    "api": "untried",
    "mcp": "none",
    "cli": "none",
    "ui": "none"
   }
  },
  {
   "id": "cap-07",
   "name": "Delete an uploaded file",
   "core": true,
   "result": "blocked",
   "surfaces": {
    "api": "untried",
    "mcp": "none",
    "cli": "none",
    "ui": "untried"
   }
  },
  {
   "id": "cap-08",
   "name": "Browse and manage uploaded files in a dashboard",
   "core": true,
   "result": "blocked",
   "surfaces": {
    "api": "none",
    "mcp": "none",
    "cli": "none",
    "ui": "untried"
   }
  },
  {
   "id": "cap-09",
   "name": "List files with pagination and filters",
   "core": false,
   "result": "blocked",
   "surfaces": {
    "api": "untried",
    "mcp": "none",
    "cli": "none",
    "ui": "untried"
   }
  },
  {
   "id": "cap-10",
   "name": "Rename an uploaded file",
   "core": false,
   "result": "blocked",
   "surfaces": {
    "api": "untried",
    "mcp": "none",
    "cli": "none",
    "ui": "untried"
   }
  },
  {
   "id": "cap-11",
   "name": "Assign a custom ID to a file instead of the generated key",
   "core": false,
   "result": "blocked",
   "surfaces": {
    "api": "untried",
    "mcp": "none",
    "cli": "none",
    "ui": "none"
   }
  },
  {
   "id": "cap-12",
   "name": "Mark a file public (CDN-URL readable) or private",
   "core": false,
   "result": "blocked",
   "surfaces": {
    "api": "untried",
    "mcp": "none",
    "cli": "none",
    "ui": "untried"
   }
  },
  {
   "id": "cap-13",
   "name": "Generate a time-limited signed URL to access a private file",
   "core": false,
   "result": "blocked",
   "surfaces": {
    "api": "untried",
    "mcp": "none",
    "cli": "none",
    "ui": "none"
   }
  },
  {
   "id": "cap-14",
   "name": "Validate custom input/metadata attached to an upload with a schema",
   "core": false,
   "result": "blocked",
   "surfaces": {
    "api": "untried",
    "mcp": "none",
    "cli": "none",
    "ui": "none"
   }
  },
  {
   "id": "cap-15",
   "name": "Resume an interrupted upload",
   "core": false,
   "result": "blocked",
   "surfaces": {
    "api": "untried",
    "mcp": "none",
    "cli": "none",
    "ui": "none"
   }
  },
  {
   "id": "cap-16",
   "name": "Track live upload progress in the UI",
   "core": false,
   "result": "blocked",
   "surfaces": {
    "api": "none",
    "mcp": "none",
    "cli": "none",
    "ui": "untried"
   }
  },
  {
   "id": "cap-17",
   "name": "Choose the storage region a file is uploaded to",
   "core": false,
   "result": "blocked",
   "surfaces": {
    "api": "untried",
    "mcp": "none",
    "cli": "none",
    "ui": "untried"
   }
  },
  {
   "id": "cap-18",
   "name": "View account usage (storage, bandwidth, requests)",
   "core": false,
   "result": "blocked",
   "surfaces": {
    "api": "untried",
    "mcp": "none",
    "cli": "none",
    "ui": "untried"
   }
  },
  {
   "id": "cap-19",
   "name": "View an audit log of account activity",
   "core": false,
   "result": "blocked",
   "surfaces": {
    "api": "none",
    "mcp": "none",
    "cli": "none",
    "ui": "untried"
   }
  },
  {
   "id": "cap-20",
   "name": "Set a webhook/callback URL for upload events",
   "core": false,
   "result": "blocked",
   "surfaces": {
    "api": "untried",
    "mcp": "none",
    "cli": "none",
    "ui": "untried"
   }
  },
  {
   "id": "cap-21",
   "name": "Control whether a file opens inline or downloads (content-disposition)",
   "core": false,
   "result": "blocked",
   "surfaces": {
    "api": "untried",
    "mcp": "none",
    "cli": "none",
    "ui": "none"
   }
  },
  {
   "id": "cap-22",
   "name": "Customize the look of the upload UI components",
   "core": false,
   "result": "blocked",
   "surfaces": {
    "api": "none",
    "mcp": "none",
    "cli": "none",
    "ui": "untried"
   }
  },
  {
   "id": "cap-23",
   "name": "Create and manage API keys",
   "core": false,
   "result": "blocked",
   "surfaces": {
    "api": "none",
    "mcp": "none",
    "cli": "none",
    "ui": "untried"
   }
  },
  {
   "id": "cap-24",
   "name": "Invite and manage team members on an app",
   "core": false,
   "result": "blocked",
   "surfaces": {
    "api": "none",
    "mcp": "none",
    "cli": "none",
    "ui": "untried"
   }
  },
  {
   "id": "cap-25",
   "name": "Serve files from a custom domain",
   "core": false,
   "result": "blocked",
   "surfaces": {
    "api": "none",
    "mcp": "none",
    "cli": "none",
    "ui": "untried"
   }
  }
 ],
 "category_place": {
  "category": "file-storage",
  "products": 6,
  "higher": 1,
  "same_level": 4,
  "as_of": "2026-10-24",
  "stop": "signup",
  "rivals_by": "stop",
  "rivals": [
   "backblaze",
   "box",
   "dropbox",
   "pinata"
  ]
 },
 "page": "https://agentdrives.com/tools/uploadthing?via=api"
}