# Put It Online
> Put It Online (putit.online) turns any file, or a web page/site an AI just built, into a short public link. Free links last 7 days and need no account; subscribers get permanent links, passwords and custom names. AI assistants can use it through MCP (https://putit.online/mcp) or the REST API (https://putit.online/api/v1).
Every upload gets quick safety checks before it goes live and a full scan within seconds after (an upload that fails it is taken down); status "checking" means poll again in a few seconds. Some links aren't published until the uploader subscribes: status "unpublished" comes with a checkout_url, and "publishing" means it will be live soon. Uploads are always subject to safety checks and can be removed. Uploads from VPNs/proxies/Tor and banned uploaders are refused.
## Connect
- [Connect to AI](https://putit.online/connect): setup for Claude, ChatGPT, Cursor and stdio MCP clients, plus API keys
- [MCP server](https://putit.online/mcp): Streamable HTTP. Anonymous, or Bearer (OAuth 2.1 / API key) for account mode
- [MCP server, account mode](https://putit.online/mcp/account): always asks for authorization
## API
- [OpenAPI 3.1 spec](https://putit.online/api/v1/openapi.json): REST mirror of the MCP tools (for ChatGPT Actions and scripts)
- [Full agent documentation](https://putit.online/llms-full.txt): tools, auth, limits and examples in one file
- [OAuth authorization server metadata](https://putit.online/.well-known/oauth-authorization-server)
## Policies
- [Acceptable use](https://putit.online/acceptable-use)
- [Terms](https://putit.online/terms)
- [Privacy](https://putit.online/privacy)
- [Pricing](https://putit.online/pricing)
## Quick start for agents
Publish a page you generated (no account needed):
POST https://putit.online/api/v1/sites
Content-Type: application/json
{"files": {"index.html": "
Hello
", "style.css": "h1{color:#ff3d7f}"}}
Response (201): {"slug": "k3x9pq", "url": "https://putit.online/k3x9pq", "status": "live" | "checking" | "unpublished" | "publishing", "checkout_url"?: "...", "expires_at": "...", "manage_token": "...", "manage_url": "..."}
If status is "unpublished", give the person the checkout_url to subscribe; it goes online once their plan is active (and its checks pass). If status is "checking" or "publishing", GET https://putit.online/api/v1/links/k3x9pq with header X-Manage-Token: until it is "live". Only share live links.
## MCP tools (same names as REST operationIds)
- publish_site {files: {path: text}, base64_files?: {path: base64}, title?, slug?, password?}: put a page/site online (index.html required)
- upload_file {filename, content, encoding: "text"|"base64", mime_type?, slug?, password?}: share one file (max 20 MB inline)
- create_upload_session {filename, size_bytes?, slug?, password?}: returns a one-time upload_url; PUT the raw bytes there (e.g. curl -T file URL), then poll get_link
- get_link {slug, manage_token?}: status (awaiting_upload, checking, live, unpublished + checkout_url, publishing, in_review, removed + removed_reason/appeal_url, expired, deleted), expiry, views (null unless the link's account is on a paid plan)
- list_links {limit?, offset?}: account only
- delete_link {slug, manage_token?}: owners or manage-token holders
- set_password {slug, password|null}, make_permanent {slug}, extend {slug}: paid plans only; others get error code subscription_required ("… requires a paid plan") with upgrade_url (the pricing page)
- get_account {}: plan, permanent slots used/limit, features
Resources: link://{slug} for each link in the connected account. Prompts: share_file, publish_page.
## Authentication
- Anonymous: no header. 7-day links, at most 10 new links per hour per IP, a manage_token per link.
- API key: create at https://putit.online/connect, send "Authorization: Bearer pio_...". Full access to that account.
- OAuth 2.1 (MCP authorization spec): discover via the WWW-Authenticate header (resource_metadata) or https://putit.online/.well-known/oauth-protected-resource/mcp.
Authorization code + PKCE (S256), resource indicators (RFC 8707), Client ID Metadata Documents or dynamic client registration (https://putit.online/oauth/register).
Scopes: links:read links:write account:read. Access tokens last 60 minutes; refresh tokens rotate.
- Platforms acting for an end user may send X-End-User-IP with authenticated requests; it is used for abuse checks instead of the platform's IP.
## Errors
REST errors look like {"error": {"code": "...", "message": "...", "upgrade_url"?: "...", "retry_after_sec"?: n}}. MCP tool errors set isError and include the same message.
Common codes: auth_required (401), insufficient_scope (403), subscription_required (402), vpn_blocked (403), uploader_banned (403), upload_rejected (422, failed the safety check), url_blocked (400), too_large (413), rate_limited (429).