{"openapi":"3.1.0","info":{"title":"Foldr.Space","version":"1.0.0","description":"Permanent file storage for ChatGPT. Upload a file, get a permanent direct link. Generate time-limited share links. List or delete previous uploads. Each upload costs 5¢ and is debited from the user's Foldr account credits.","contact":{"name":"Foldr.Space","email":"hello@foldr.space","url":"https://foldr.space"}},"servers":[{"url":"https://foldr.space"}],"components":{"securitySchemes":{"ApiKey":{"type":"http","scheme":"bearer","bearerFormat":"fs_<32 alphanumeric>","description":"User's Foldr API key. They can get one at https://foldr.space/developers/signup. Format: Authorization: Bearer fs_xxx"}},"schemas":{"File":{"type":"object","properties":{"id":{"type":"string","description":"Unique file ID (UUID)"},"shareToken":{"type":"string","description":"Public share token"},"downloadUrl":{"type":"string","format":"uri","description":"Direct download URL (auth-gated)"},"publicUrl":{"type":"string","format":"uri","description":"Public file page URL - share this with humans"},"originalName":{"type":"string"},"size":{"type":"integer","description":"File size in bytes"},"mimeType":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"ShortUrl":{"type":"object","properties":{"shortUrl":{"type":"string","format":"uri"},"shortCode":{"type":"string"},"destinationUrl":{"type":"string","format":"uri"},"createdAt":{"type":"string","format":"date-time"}}},"ErrorResponse":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"},"code":{"type":"string"},"retryable":{"type":"boolean"}}}}},"security":[{"ApiKey":[]}],"paths":{"/api/v1/files":{"post":{"operationId":"uploadFile","summary":"Upload a file to Foldr","description":"Upload a file and get a permanent direct download URL plus a public share URL. Costs 5¢ per upload, debited from the user's Foldr account credits. If the user has no credits, the call returns 402 - tell them to top up at https://foldr.space/developers/dashboard.","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"The file to upload (any type)"},"folder_slug":{"type":"string","description":"Optional: folder slug to place the file in. The folder must already exist."},"metadata":{"type":"string","description":"Optional: JSON-stringified metadata to attach to the file."}}}}}},"responses":{"201":{"description":"File uploaded successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"file":{"$ref":"#/components/schemas/File"}}}}}},"401":{"description":"Missing or invalid API key."},"402":{"description":"Payment required - user needs to top up account credits.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"File too large for the user's subscription tier."}}},"get":{"operationId":"listFiles","summary":"List the user's recent uploads","description":"Returns up to 100 of the user's most recent file uploads. Use this when the user asks \"what files have I uploaded?\" or \"show me my recent uploads.\"","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"description":"How many files to return (max 100, default 20)."},{"name":"q","in":"query","schema":{"type":"string"},"description":"Optional search query to filter by filename."}],"responses":{"200":{"description":"List of files.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"files":{"type":"array","items":{"$ref":"#/components/schemas/File"}},"pagination":{"type":"object","properties":{"limit":{"type":"integer"},"offset":{"type":"integer"},"total":{"type":"integer"}}}}}}}},"401":{"description":"Missing or invalid API key."}}}},"/api/v1/files/{id}":{"get":{"operationId":"getFileInfo","summary":"Get info about a specific file","description":"Returns metadata about a single file by its ID. Use when the user references a specific file from a previous upload.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"File ID (UUID)"}],"responses":{"200":{"description":"File info.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/File"}}}},"404":{"description":"File not found or not owned by this API key."}}},"delete":{"operationId":"deleteFile","summary":"Delete a file","description":"Permanently delete a file. Always confirm with the user before calling - deletion cannot be undone.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"File ID (UUID)"}],"responses":{"200":{"description":"File deleted."},"404":{"description":"File not found."}}}},"/api/v1/files/{id}/capability-tokens":{"post":{"operationId":"mintShareLink","summary":"Mint a time-limited share link for a file","description":"Create a `cap_…` token that grants short-lived access to a specific file. Use when the user asks for a share link with an expiry or use-cap. Returns the bare downloadUrl which already includes the capability token in the Authorization header - paste it directly to whoever needs the file.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"File ID (UUID)"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"expires_in":{"type":"integer","description":"Token lifetime in seconds. Default 3600 (1 hour). Max 604800 (7 days).","default":3600},"max_uses":{"type":"integer","description":"Optional cap on number of uses. Omit for unlimited within the TTL."},"description":{"type":"string","description":"Free-form note for the user's reference."}}}}}},"responses":{"201":{"description":"Capability token created.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"capability":{"type":"object","properties":{"id":{"type":"string"},"token":{"type":"string","description":"The bare cap_… token"},"expiresAt":{"type":"string","format":"date-time"}}},"downloadUrl":{"type":"string","description":"A direct URL that includes the capability - paste this to share access."}}}}}}}}},"/api/v1/urls":{"post":{"operationId":"createShortUrl","summary":"Shorten a URL with foldr.space/s/...","description":"Create a short URL with optional custom slug. Free with any API key. Use when the user wants to share a long link.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["destinationUrl"],"properties":{"destinationUrl":{"type":"string","format":"uri","description":"The long URL to shorten."},"customSlug":{"type":"string","description":"Optional: choose a custom short code (alphanumeric + dash, max 60 chars)."}}}}}},"responses":{"201":{"description":"Short URL created.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"url":{"$ref":"#/components/schemas/ShortUrl"}}}}}}}}},"/api/v1/usage":{"get":{"operationId":"getUsage","summary":"Check the user's storage and credit usage","description":"Returns current storage, bandwidth, and request counts plus the user's Foldr account credits balance. Use when the user asks \"how much storage am I using\" or \"what's my balance\".","responses":{"200":{"description":"Usage and balance.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"usage":{"type":"object","properties":{"storage_used_bytes":{"type":"integer"},"bandwidth_used_bytes":{"type":"integer"},"requests_this_month":{"type":"integer"},"credits_balance_cents":{"type":"integer"}}}}}}}}}}}}}