https://patrins.com/api/
https://patrins.com/oauth/
https://patrins.com/mcp
client_id and client_secret — the secret is shown only once.GET https://patrins.com/oauth/authorize
?client_id=pclient_a1b2c3d4
&redirect_uri=https://yourapp.com/callback
&response_type=code
&scope=profile:read files:read
&state=random_csrf_token
&code_challenge=BASE64URL(SHA256(code_verifier))
&code_challenge_method=S256
redirect_uri?code=...&state=.... Verify the state matches.curl -X POST https://patrins.com/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "authorization_code",
"code": "<code_from_redirect>",
"redirect_uri": "https://yourapp.com/callback",
"client_id": "pclient_a1b2c3d4",
"client_secret": "psecret_...",
"code_verifier": "<your_pkce_verifier>"
}'
{
"access_token": "pat_...",
"refresh_token": "prt_...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "profile:read files:read"
}
# Get user profile
curl https://patrins.com/oauth/userinfo \
-H "Authorization: Bearer pat_..."
# List files
curl https://patrins.com/api/files \
-H "Authorization: Bearer pat_..."
# Refresh an expired token
curl -X POST https://patrins.com/oauth/token \
-d '{"grant_type":"refresh_token","refresh_token":"prt_...","client_id":"pclient_..."}'
| Scope | Access | What it allows | Typical use case |
|---|---|---|---|
| profile:read | Read | Username, email, plan, storage usage | Login with Patrins, identity verification |
| files:read | Read | List and download files | File browsers, backups, media players |
| files:write | Write | Rename and move files, toggle starred | File managers, sync clients |
| files:delete | Delete | Move files to trash | Cleanup tools, full-access managers |
| folders:read | Read | List and browse folders | File browsers, navigators |
| folders:write | Write | Create, rename, and move folders | File managers, sync clients |
| folders:delete | Delete | Move folders and contents to trash | Cleanup tools, full-access managers |
| webdav:access | Full | Mount storage as a WebDAV drive | Desktop apps, file system integrations |
scope=profile:read files:read files:writeAuthorization: Bearer <pat_token> (OAuth) or Authorization: Bearer <api_key> (API key) on authenticated endpoints.| Parameter | Type | Required | Description |
|---|---|---|---|
| client_id | string | required | Your registered client ID |
| redirect_uri | string | required | Must match a registered redirect URI |
| response_type | string | required | Must be code |
| scope | string | Space-separated list of scopes | |
| state | string | CSRF protection — reflected back on redirect | |
| code_challenge | string | PKCE: BASE64URL(SHA256(code_verifier)) | |
| code_challenge_method | string | Must be S256 |
| Parameter | Type | Required | Description |
|---|---|---|---|
| grant_type | string | required | authorization_code | refresh_token | client_credentials |
| code | string | Required for authorization_code grant | |
| refresh_token | string | Required for refresh_token grant | |
| code_verifier | string | PKCE verifier (if challenge was sent) | |
| redirect_uri | string | Must match original authorization request |
| Parameter | Type | Required | Description |
|---|---|---|---|
| token | string | required | The pat_ or prt_ token to revoke |
{ "id": 42, "username": "alice", "email": "[email protected]", "plan": "pro" }
| Query | Type | Description |
|---|---|---|
| page | number | Page number (default: 1) |
| limit | number | Items per page, max 100 (default: 50) |
| Metadata key | Type | Required | Description |
|---|---|---|---|
| filename | string | required | Original filename with extension |
| filetype | string | required | MIME type e.g. video/mp4 |
| folderId | string | Target folder ID — omit for root | |
| isTemp | string | Pass "true" for a temporary file (expires in 7 days, bypasses storage quota) |
import * as tus from 'tus-js-client';
const upload = new tus.Upload(file, {
endpoint: 'https://patrins.com/api/tus',
retryDelays: [0, 3000, 5000],
headers: { Authorization: `Bearer ${apiKey}` },
metadata: {
filename: file.name,
filetype: file.type,
isTemp: 'false', // 'true' for temp upload
},
onSuccess() { /* done */ },
});
upload.start();
isTemp: 'true' in metadata. Temp files expire after 7 days and bypass your plan storage quota (capped at 1.2 TB of active temp files per account). The file URL is shareable immediately — no account required to download.import * as tus from 'tus-js-client';
const upload = new tus.Upload(file, {
endpoint: 'https://patrins.com/api/tus',
retryDelays: [0, 3000, 5000],
headers: { Authorization: `Bearer ${apiKey}` },
metadata: {
filename: file.name,
filetype: file.type,
isTemp: 'true', // expires in 7 days
},
onSuccess() { /* done */ },
});
upload.start();
{
"user": {
"id": "6b1fed95-7f78-...",
"email": "[email protected]",
"username": "alice",
"display_name": "Alice",
"plan": "pro",
"storage_used": 5368709120,
"storage_limit": 107374182400,
"plan_expires_at": null,
"avatar": "https://..."
}
}
| Field | Type | Required | Description |
|---|---|---|---|
| fileName | string | required | Original filename with extension |
| fileSize | number | required | File size in bytes |
| mimeType | string | required | MIME type e.g. application/pdf |
| folderId | string | Target folder ID — omit for root |
{ "uploadId": "abc123", "uploadUrl": "/api/webdav-upload/abc123/file.pdf" }
uploadUrl returned by init. Stream the raw file bytes as the request body.| Field | Type | Required | Description |
|---|---|---|---|
| uploadId | string | required | The uploadId from the init step |
{ "success": true, "file": { "id": "6b8b413bf05f", "name": "example.pdf", "size": 1024 } }
| Field | Type | Required | Description |
|---|---|---|---|
| url | string | required | Remote file URL to download |
| fileName | string | Override the filename | |
| folderId | string | Target folder |
{ "uploadId": "550e8400-...", "status": "starting" }
GET /api/remote-upload/{uploadId}/status to track progress. Status values: queued | starting | downloading | storing | complete | error. Max 4 concurrent remote uploads server-wide.| Field | Type | Required | Description |
|---|---|---|---|
| name | string | required | New filename (with extension) |
| Field | Type | Required | Description |
|---|---|---|---|
| folderId | string | Destination folder ID — pass null to move to root |
DELETE /api/files/:id for permanent deletion.{ "success": true, "starred": true }
{ "folders": [...], "files": [...] }
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | required | Folder name |
| parentId | string | Parent folder ID — omit for root. No depth limit. |
| Query | Type | Description |
|---|---|---|
| parentId | string | Omit for root folders; pass a folder ID for its children |
{ "folder": { ... }, "breadcrumbs": [{ "id": "...", "name": "..." }] }
:id to list files at root (GET /api/files/folder).| Field | Type | Required | Description |
|---|---|---|---|
| name | string | required | New folder name |
| Field | Type | Required | Description |
|---|---|---|---|
| parentId | string | required | New parent folder ID — pass null to move to root |
| Field | Type | Description |
|---|---|---|
| expiresIn | number | Seconds until expiry — omit for permanent link |
| allowDownload | boolean | Default true — set false for browse-only |
| password | string | Optional password protection |
{ "success": true, "share": { "url": "https://patrins.com/s/{token}", "token": "...", "expiresAt": null } }
| Query | Type | Description |
|---|---|---|
| folderId | string | Navigate into a subfolder within the share |
{ "folders": [...], "files": [...], "breadcrumb": [...] }
| Field | Type | Required | Description |
|---|---|---|---|
| items | array | required | Array of { id, type: "file"|"folder" } |
| targetFolderId | string | Destination folder ID — null for root |
| Field | Type | Required | Description |
|---|---|---|---|
| fileIds | string[] | required | Array of file IDs to include in the ZIP |
application/zip directly. Rate limit: 10/hour per user.| Query | Type | Description |
|---|---|---|
| q | string required | Search term matched against filename |
| section | string | Context: starred | trash | temp — omit for normal files |
{ "files": [...], "folders": [...] } // max 50 results each
Authorization: Bearer header on every API call/oauth/revoke or wait for expirypat_ + 64 hex charactersrefresh_token grant. Never send to API endpoints./oauth/revoke — also invalidates the paired access tokenprt_ + 64 hex characters// 1. Generate code_verifier
const array = crypto.getRandomValues(new Uint8Array(32));
const verifier = btoa(String.fromCharCode(...array))
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
// 2. Hash to produce code_challenge (S256)
const hash = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(verifier));
const challenge = btoa(String.fromCharCode(...new Uint8Array(hash)))
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
https://patrins.com/mcp — once connected, the AI can list, search, move, and organize your files using natural language.https://patrins.com/mcp
profile:read files:read files:write files:delete folders:read folders:write folders:deletecurl https://patrins.com/.well-known/oauth-authorization-server
{
"issuer": "https://patrins.com",
"authorization_endpoint": "https://patrins.com/authorize",
"token_endpoint": "https://patrins.com/token",
"grant_types_supported": ["authorization_code", "refresh_token"],
"code_challenge_methods_supported": ["S256"],
"scopes_supported": [
"profile:read", "files:read", "files:write",
"files:delete", "folders:read", "folders:write",
"folders:delete", "webdav:access"
]
}
# List available tools
curl -X POST https://patrins.com/mcp -H "Authorization: Bearer pat_..." -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
# Call a tool
curl -X POST https://patrins.com/mcp -H "Authorization: Bearer pat_..." -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"list_files","arguments":{"limit":10}}}'
| Tool | Description |
|---|---|
| get_user_info | Username, email, plan |
| get_storage_info | Bytes used / limit / %, total file count |
| Tool | Description | Parameters |
|---|---|---|
| list_files | List files, filter by folder or starred | folder_id, limit, offset, starred |
| get_file_info | Full details + public download URL | file_id required |
| search_files | Search by filename, optional MIME filter, paginated | query required, folder_id, mime_type, limit, offset |
| Tool | Description | Parameters |
|---|---|---|
| rename_file | Rename a file | file_id, new_name |
| move_file | Move to a folder or root | file_id, folder_id |
| star_file | Star or unstar a file | file_id, starred |
| batch_move_files | Move up to 200 files in one call | file_ids[] required, folder_id |
| Tool | Description | Parameters |
|---|---|---|
| delete_file | Move a file to trash (soft delete) | file_id required |
| batch_delete_files | Trash up to 200 files in one call | file_ids[] required |
| Tool | Description | Parameters |
|---|---|---|
| list_folders | List child folders of a parent | parent_id, starred |
| get_folder_info | Details, file count, subfolder count, size | folder_id required |
| get_folder_tree | Nested tree up to 6 levels deep with file counts | parent_id, depth (default 3, max 6) |
| Tool | Description | Parameters |
|---|---|---|
| create_folder | Create a new folder | name required, parent_id |
| rename_folder | Rename a folder | folder_id, new_name |
| move_folder | Move to a new parent or top-level | folder_id, new_parent_id |
| star_folder | Star or unstar a folder | folder_id, starred |
| batch_move_folders | Move up to 50 folders in one call | folder_ids[] required, new_parent_id |
| Tool | Description | Parameters |
|---|---|---|
| delete_folder | Move folder and all contents to trash (recursive) | folder_id required |
<!-- Drop anywhere on your site -->
<div data-patrins-widget></div>
<script src="https://patrins.com/widget.js" data-widget="YOUR_WIDGET_ID"></script>
<!-- Or floating button (no div needed) -->
<script src="https://patrins.com/widget.js" data-widget="YOUR_WIDGET_ID"></script>Upload an HTML file to use as your custom download page. All visitors who open your /f/ links will see your page instead of the default Patrins one.
These placeholders are automatically replaced with actual file data when a visitor opens your /f/ link.
| Variable | Description | Example |
|---|---|---|
{{FILE_NAME}} | Original filename | video.mp4 |
{{FILE_SIZE}} | Human-readable size | 157.3 MB |
{{FILE_SIZE_BYTES}} | Raw size in bytes | 164956160 |
{{FILE_TYPE}} | MIME type | video/mp4 |
{{FILE_ID}} | Unique file identifier | a3b4c5d6e7f8 |
{{DOWNLOAD_URL}} | Direct download link | https://patrins.com/api/download/… |
{{UPLOAD_DATE}} | Upload date | May 14, 2026 |
{{DOWNLOAD_COUNT}} | Number of downloads | 42 |
{{EXPIRES_AT}} | Expiry date or "Never" | Never |
{{IS_ENCRYPTED}} | Client-side encryption | No |
{{SHA256}} | SHA-256 hash | a3b4c5d6… |
| Variable | Description | Example |
|---|---|---|
{{UPLOADER_NAME}} | Display name | Veel Studios |
{{UPLOADER_USERNAME}} | Patrins username | veelstudios |
{{SOCIAL_INSTAGRAM}} | Instagram handle (no @) | veelstudios |
{{SOCIAL_TWITTER}} | Twitter/X handle | veelstudios |
{{SOCIAL_DISCORD}} | Discord invite code | abc123 |
{{SOCIAL_TIKTOK}} | TikTok handle | veelstudios |
{{SOCIAL_YOUTUBE}} | YouTube channel handle | veelstudios |
{{SOCIAL_WEBSITE}} | Website URL | https://veelstudios.com |
{{SOCIAL_GITHUB}} | GitHub username | veelstudios |
<script> tags and on* event attributes are automatically stripped on uploadsrc= attributes are stripped. Embed images as base64 or use CSS-only stylingCopy this as a starting point. Variables in {{…}} are filled automatically.
When a visitor opens a link like https://files.yourbrand.com/f/abc123, Patrins detects your domain, finds your account, and serves your custom download page — or the default Patrins one if you haven't set one up.
Type Name Value A files 159.69.64.77
patrins.com routes through Cloudflare and will fail DNS verification. If you use Cloudflare DNS, set the record to DNS only (grey cloud icon, not orange)./f/ links now work on your custom domain. Share files.yourbrand.com/f/abc123 instead of patrins.com/f/abc123.Only /f/ download pages are served on your custom domain — and only files belonging to your account. Your Patrins dashboard and other users' files are not accessible through your domain.
files.yourbrand.com/f/abc123 — serves the download page for your filePatrins automatically provisions and renews a free Let's Encrypt SSL certificate for your domain. HTTPS is enforced — HTTP requests redirect to HTTPS automatically.
If you remove your custom domain, the certificate is revoked and the domain stops serving Patrins content immediately.
*.yourdomain.com) are not supportedcurl -fsSL https://patrins.com/install.sh | sh
irm https://patrins.com/install.ps1 | iex
# Browser-based login — opens patrins.com and saves your API key
patrins login
# Or supply an API key directly (Dashboard → Settings → API Keys)
patrins login --key patrins_abc123
~/.patrins/config.json. Run patrins logout to clear it.# Upload one or more files
patrins upload video.mp4
patrins upload *.mp4
# Temporary file (expires in 7 days)
patrins upload report.pdf --temp
# Upload from stdin
cat file.bin | patrins upload -
# Remote transfer — download a URL directly to your Patrins drive
patrins remote https://example.com/file.zip
| Command | Aliases | What it does |
|---|---|---|
| upload <file> | up | Upload one or more files. Pass - for stdin. Flags: --temp |
| ls | list | List your files. Flags: --starred --temp --json --limit N |
| search <query> | find | Search files by name |
| info <id|url> | stat | Full details for a file |
| share <id|url> | Print the public file URL | |
| url <id|url> | Copy URL to clipboard | |
| open <id|url> | Open file page in browser | |
| rename <id> <name> | mv | Rename a file |
| star <id> | Toggle starred on a file | |
| rm <id> | delete, trash | Move a file to trash |
| remote <url> | Remote-transfer a URL to your drive with live progress | |
| whoami | Show logged-in user and storage | |
| login | Authenticate (browser or --key) | |
| logout | Clear saved credentials | |
| help [command] | General help or per-command usage |
patrins.com/f/… URLs — the CLI extracts the ID automatically./link YOUR_CODE| Command | What it does |
|---|---|
| Account | |
| /link CODE | Connect your Patrins account |
| /unlink | Disconnect this Telegram from your account |
| /me | Profile, plan, and storage usage |
| /settings | Toggle storage warnings |
| Browse | |
| /files [page] | Paginated file list with inline star / delete buttons |
| /starred | Starred files |
| /search query | Search by filename |
| /temp | Temporary files with expiry dates |
| /trash | Trashed files |
| /folders | Your folders (tap to browse contents) |
| /stats | Breakdown by type: videos, images, audio, PDFs + download count |
| /storage | Storage bar with used / free / total |
| File actions | |
| /info ID | Full file details |
| /share ID | Get public file link |
| /download ID | Receive the file back in Telegram (≤ 50 MB) |
| /rename ID name | Rename a file |
| /star ID | Toggle starred |
| /move ID folder_id | Move to a folder |
| /delete ID | Move to trash (with confirmation) |
| /restore ID | Restore from trash |
| /empty_trash | Permanently delete all trash |
| Upload links | |
| /links | Your upload links |
| /newlink name | Create an upload link |
| File size | How it works |
|---|---|
| ≤ 50 MB | Uploaded instantly via Bot API — fastest path |
| > 50 MB (up to 4 GB) | Downloaded via MTProto and streamed to your drive. Shows a live progress bar with transfer speed and ETA. |
@patrins_bot in any Telegram chat to search your files inline and share a link without leaving the conversation.@patrins_bot video.mp4
/setinline. Results show file name, size, upload date, and download count./settings.