{"openapi":"3.0.3","info":{"title":"CDNForge API","version":"1.0.0","description":"HTTP API for CDNForge. Tokens live on an organization, not one user.\n\n**Game server keys** (Authorize with Bearer):\n- `cnf_img_` images via `POST /api/v1/upload`, `/api/v1/upload/presign`, `/api/v1/upload/chunked/*`\n- `cnf_vid_` / `cnf_aud_` video or audio via the same media upload family\n- `cnf_fil_` any file as-is via `POST /api/v1/file`, `/api/v1/file/presign`, `/api/v1/file/chunked/*`\n- `cnf_log_` structured logs via `POST /api/v1/logs`\n\nMax upload size is 100 MB. Chunked `partSize` is 4 MB. Direct multipart is preferred only for smaller bodies (clients often switch near 3.5 MB because of host body limits).\n\nLegacy `gsk_*` keys from the old GameStack branding still work.\n\nDashboard routes use your login cookie. If you are signed in, Try it out works without a key.\n\nLog filter DSL examples: `level:error`, `player:12`, `resource:ox_inventory`, `\"vehicle spawned\"`."},"servers":[{"url":"/","description":"This CDNForge host"}],"tags":[{"name":"Uploads","description":"CDN uploads from a game server or the dashboard"},{"name":"Files","description":"List, move, and delete stored files"},{"name":"Logs","description":"Ingest and query structured logs"},{"name":"Keys","description":"Create org-scoped API tokens (dashboard session)"},{"name":"Orgs","description":"Organizations and team members (dashboard session)"},{"name":"Auth","description":"Register, login, session"},{"name":"Public","description":"Unauthenticated endpoints"}],"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","bearerFormat":"cnf","description":"Scoped API token from Dashboard → API Keys (`cnf_*`; legacy `gsk_*` still accepted)."},"cookieAuth":{"type":"apiKey","in":"cookie","name":"cdnforge_session","description":"Set automatically when you log in to the dashboard."}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string"}}},"LogEvent":{"type":"object","required":["level","message"],"properties":{"level":{"type":"string","enum":["debug","info","warn","error"]},"message":{"type":"string"},"name":{"type":"string","description":"Log file name in the dashboard. Also accepts file or dataset."},"file":{"type":"string"},"dataset":{"type":"string"},"playerSource":{"type":"string","description":"Player id / source"},"metadata":{"type":"object","additionalProperties":true}}},"UploadResult":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"publicId":{"type":"string"},"size":{"type":"integer"},"mimeType":{"type":"string"},"originalName":{"type":"string"}}},"PresignRequest":{"type":"object","required":["filename","mimeType","size"],"properties":{"filename":{"type":"string"},"mimeType":{"type":"string","description":"MIME type. Do not send contentType."},"size":{"type":"integer","minimum":1,"maximum":104857600},"folder":{"type":"string"},"folderId":{"type":"string"},"metadata":{"type":"object","additionalProperties":true}}},"PresignResult":{"type":"object","properties":{"publicId":{"type":"string"},"uploadUrl":{"type":"string"},"mimeType":{"type":"string"},"originalName":{"type":"string"},"storageBucket":{"type":"string","description":"Present for direct R2/S3 presigns; may be omitted for worker upload URLs."}}},"CompletePresignRequest":{"type":"object","required":["publicId","mimeType","size"],"properties":{"publicId":{"type":"string","description":"Must be the publicId returned by presign."},"filename":{"type":"string"},"originalName":{"type":"string"},"mimeType":{"type":"string"},"size":{"type":"integer"},"storageBucket":{"type":"string"},"folder":{"type":"string"},"folderId":{"type":"string"},"metadata":{"type":"object","additionalProperties":true}}},"ChunkedInitRequest":{"type":"object","required":["filename","mimeType","size"],"properties":{"filename":{"type":"string"},"mimeType":{"type":"string"},"size":{"type":"integer","minimum":1,"maximum":104857600},"folder":{"type":"string"},"folderId":{"type":"string"},"metadata":{"type":"object","additionalProperties":true}}},"ChunkedInitResult":{"type":"object","properties":{"uploadId":{"type":"string","description":"Server-generated session id. Required for part and complete."},"publicId":{"type":"string"},"mimeType":{"type":"string"},"originalName":{"type":"string"},"storageBucket":{"type":"string"},"partSize":{"type":"integer","description":"Maximum bytes per part (4194304)."},"expiresAt":{"type":"string","format":"date-time"}}},"ChunkedCompleteRequest":{"type":"object","required":["uploadId"],"properties":{"uploadId":{"type":"string","description":"Only field used on complete. Session supplies publicId, mimeType, size, and storageBucket."}}},"ChunkedPartResult":{"type":"object","properties":{"ok":{"type":"boolean"},"partNumber":{"type":"integer"},"size":{"type":"integer"}}}}},"paths":{"/api/v1/upload":{"post":{"tags":["Uploads"],"summary":"Upload image, video, or audio","description":"Use an image, video, or audio key. Images are compressed to JPEG unless they are already small. For original PNG/WebP or zip files, use POST /api/v1/file.","security":[{"apiKey":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"},"image":{"type":"string","format":"binary"},"filename":{"type":"string"},"folder":{"type":"string","description":"Folder path, e.g. Screenshots"},"folderId":{"type":"string"},"metadata":{"type":"string","description":"JSON object as a string"}}}}}},"responses":{"200":{"description":"Uploaded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadResult"}}}},"401":{"description":"Unauthorized"}}}},"/api/v1/file":{"post":{"tags":["Uploads"],"summary":"Upload any file as-is","description":"Use a file key (cnf_fil_). Bytes are stored without image conversion.","security":[{"apiKey":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary"},"filename":{"type":"string"},"folder":{"type":"string"},"folderId":{"type":"string"},"metadata":{"type":"string"}}}}}},"responses":{"200":{"description":"Uploaded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadResult"}}}}}}},"/api/v1/upload/presign":{"post":{"tags":["Uploads"],"summary":"Presign a media upload","description":"Returns a short-lived uploadUrl and server-generated publicId. PUT bytes to uploadUrl, then call /api/v1/upload/complete. Body uses mimeType (not contentType).","security":[{"apiKey":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresignRequest"}}}},"responses":{"200":{"description":"Presigned","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresignResult"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Wrong key scope"},"413":{"description":"File too large (max 100 MB)"}}}},"/api/v1/upload/complete":{"post":{"tags":["Uploads"],"summary":"Complete a media presigned upload","description":"Creates the file record after a successful PUT to the presigned URL. publicId must come from presign.","security":[{"apiKey":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompletePresignRequest"}}}},"responses":{"200":{"description":"Saved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadResult"}}}},"400":{"description":"Upload missing in storage or invalid id"},"409":{"description":"Already saved"}}}},"/api/v1/upload/chunked/init":{"post":{"tags":["Uploads"],"summary":"Start a chunked media upload","description":"Creates an upload session. Use the returned uploadId for part and complete. partSize is 4194304 (4 MB). Sessions expire after about one hour by default.","security":[{"apiKey":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChunkedInitRequest"}}}},"responses":{"200":{"description":"Session created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChunkedInitResult"}}}},"413":{"description":"Declared size exceeds 100 MB"}}}},"/api/v1/upload/chunked/part":{"post":{"tags":["Uploads"],"summary":"Upload one media chunk","description":"Multipart form fields: uploadId, partNumber (starting at 1), chunk (binary, 1 byte–4 MB). Session is org-bound.","security":[{"apiKey":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["uploadId","partNumber","chunk"],"properties":{"uploadId":{"type":"string"},"partNumber":{"type":"integer","minimum":1},"chunk":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"Part stored","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChunkedPartResult"}}}},"400":{"description":"Invalid part or chunk size"},"404":{"description":"Unknown session"},"409":{"description":"Session already completed"},"410":{"description":"Session expired"},"413":{"description":"Part exceeds remaining expected size"}}}},"/api/v1/upload/chunked/complete":{"post":{"tags":["Uploads"],"summary":"Complete a chunked media upload","description":"Body is { uploadId } only. publicId, mimeType, size, and storageBucket come from the session.","security":[{"apiKey":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChunkedCompleteRequest"}}}},"responses":{"200":{"description":"Saved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadResult"}}}},"400":{"description":"Missing parts or size mismatch"},"404":{"description":"Unknown session"},"409":{"description":"Already completed or file exists"},"410":{"description":"Session expired"}}}},"/api/v1/file/presign":{"post":{"tags":["Uploads"],"summary":"Presign a generic file upload","description":"Same fields as media presign. Requires a file key (cnf_fil_) when using an API key.","security":[{"apiKey":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresignRequest"}}}},"responses":{"200":{"description":"Presigned","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresignResult"}}}},"403":{"description":"Non-file API key"}}}},"/api/v1/file/complete":{"post":{"tags":["Uploads"],"summary":"Complete a generic file presigned upload","security":[{"apiKey":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompletePresignRequest"}}}},"responses":{"200":{"description":"Saved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadResult"}}}}}}},"/api/v1/file/chunked/init":{"post":{"tags":["Uploads"],"summary":"Start a chunked generic file upload","description":"Requires cnf_fil_ when using an API key. Same session model as media chunked init.","security":[{"apiKey":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChunkedInitRequest"}}}},"responses":{"200":{"description":"Session created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChunkedInitResult"}}}},"403":{"description":"Non-file API key"}}}},"/api/v1/file/chunked/part":{"post":{"tags":["Uploads"],"summary":"Upload one generic file chunk","security":[{"apiKey":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["uploadId","partNumber","chunk"],"properties":{"uploadId":{"type":"string"},"partNumber":{"type":"integer","minimum":1},"chunk":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"Part stored","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChunkedPartResult"}}}}}}},"/api/v1/file/chunked/complete":{"post":{"tags":["Uploads"],"summary":"Complete a chunked generic file upload","description":"Body is { uploadId } only.","security":[{"apiKey":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChunkedCompleteRequest"}}}},"responses":{"200":{"description":"Saved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadResult"}}}}}}},"/api/v1/files":{"get":{"tags":["Files"],"summary":"List files and folders","security":[{"apiKey":[]},{"cookieAuth":[]}],"parameters":[{"name":"folderId","in":"query","schema":{"type":"string"}},{"name":"kind","in":"query","schema":{"type":"string","enum":["image","video","audio","other"]}},{"name":"q","in":"query","schema":{"type":"string"}},{"name":"from","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"visibility","in":"query","schema":{"type":"string","enum":["public","pending","hidden"]}},{"name":"limit","in":"query","schema":{"type":"integer","default":100}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"File listing"}}}},"/api/v1/files/{id}":{"get":{"tags":["Files"],"summary":"Get a file","description":"API keys may read files matching their scope (image/video/audio) or any file with a file key. Logs keys are rejected.","security":[{"apiKey":[]},{"cookieAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"File object under `file`"},"403":{"description":"Wrong key scope"},"404":{"description":"Not found"}}},"patch":{"tags":["Files"],"summary":"Update file metadata","description":"Dashboard session only. API keys receive 403. Supports folderId, originalName, visibility, exemptFromRetention, and metadata merges.","security":[{"cookieAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"folderId":{"type":"string","nullable":true},"originalName":{"type":"string"},"visibility":{"type":"string","enum":["public","pending","hidden"]},"exemptFromRetention":{"type":"boolean"},"metadata":{"type":"object","additionalProperties":true}}}}}},"responses":{"200":{"description":"Updated"},"403":{"description":"API key not allowed"}}},"delete":{"tags":["Files"],"summary":"Delete a file","description":"Dashboard session or a scoped API key that can access the file MIME type. Removes the DB row and stored object.","security":[{"apiKey":[]},{"cookieAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"403":{"description":"Wrong key scope"},"404":{"description":"Not found"}}}},"/api/v1/folders":{"get":{"tags":["Files"],"summary":"List folders","security":[{"apiKey":[]},{"cookieAuth":[]}],"parameters":[{"name":"parentId","in":"query","schema":{"type":"string"}},{"name":"all","in":"query","schema":{"type":"string","enum":["1"]}}],"responses":{"200":{"description":"Folders"}}},"post":{"tags":["Files"],"summary":"Create a folder","security":[{"apiKey":[]},{"cookieAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"parentId":{"type":"string","nullable":true}}}}}},"responses":{"200":{"description":"Created"}}}},"/api/v1/folders/{id}":{"delete":{"tags":["Files"],"summary":"Delete a folder","security":[{"apiKey":[]},{"cookieAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted"}}}},"/api/v1/logs":{"post":{"tags":["Logs"],"summary":"Ingest logs","description":"Send one JSON object, an array of events, or `{ \"logs\": [...] }`. Max 500 per request. Use a logs key.","security":[{"apiKey":[]}],"parameters":[{"name":"X-CDNForge-Dataset","in":"header","schema":{"type":"string"},"description":"Default log file name. Also accepts X-Fivemanage-Dataset."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/LogEvent"},{"type":"array","items":{"$ref":"#/components/schemas/LogEvent"}},{"type":"object","properties":{"logs":{"type":"array","items":{"$ref":"#/components/schemas/LogEvent"}}}}]},"examples":{"single":{"summary":"One event","value":{"name":"player-kills","level":"info","message":"Player eliminated","playerSource":"32","metadata":{"victim":"12"}}},"batch":{"summary":"Batch","value":[{"name":"match","level":"info","message":"round start"},{"name":"errors","level":"error","message":"player crashed"}]}}}}},"responses":{"200":{"description":"Stored"}}},"get":{"tags":["Logs"],"summary":"Query logs","security":[{"apiKey":[]},{"cookieAuth":[]}],"parameters":[{"name":"fileId","in":"query","schema":{"type":"string"}},{"name":"name","in":"query","schema":{"type":"string"},"description":"Log file name"},{"name":"file","in":"query","schema":{"type":"string"}},{"name":"level","in":"query","schema":{"type":"string","enum":["debug","info","warn","error"]}},{"name":"playerSource","in":"query","schema":{"type":"string"}},{"name":"from","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"q","in":"query","schema":{"type":"string"},"description":"Filter DSL, e.g. level:error player:12"},{"name":"limit","in":"query","schema":{"type":"integer","default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Matching events"}}}},"/api/v1/log-files":{"get":{"tags":["Logs"],"summary":"List log files","security":[{"apiKey":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"Log files"}}},"post":{"tags":["Logs"],"summary":"Create a log file","security":[{"apiKey":[]},{"cookieAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"}}}}}},"responses":{"200":{"description":"Created"}}}},"/api/v1/log-files/{id}":{"get":{"tags":["Logs"],"summary":"Get a log file","security":[{"apiKey":[]},{"cookieAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Log file"}}},"delete":{"tags":["Logs"],"summary":"Delete a log file and its events","security":[{"apiKey":[]},{"cookieAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted"}}}},"/api/v1/log-searches":{"get":{"tags":["Logs"],"summary":"List starred log searches","security":[{"cookieAuth":[]}],"responses":{"200":{"description":"Saved searches"}}},"post":{"tags":["Logs"],"summary":"Star a log search","security":[{"cookieAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"query":{"type":"string"},"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"},"logFileId":{"type":"string"},"columns":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"Saved"}}}},"/api/v1/log-searches/{id}":{"delete":{"tags":["Logs"],"summary":"Delete a starred search","security":[{"cookieAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted"}}}},"/api/keys":{"get":{"tags":["Keys"],"summary":"List API tokens","security":[{"cookieAuth":[]}],"responses":{"200":{"description":"Tokens (prefix only)"}}},"post":{"tags":["Keys"],"summary":"Create an API token","description":"The full token is returned once.","security":[{"cookieAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["scope"],"properties":{"name":{"type":"string"},"scope":{"type":"string","enum":["image","video","audio","file","logs"]}}}}}},"responses":{"200":{"description":"Created, includes token"}}}},"/api/keys/{id}":{"delete":{"tags":["Keys"],"summary":"Revoke a token","security":[{"cookieAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Revoked"}}}},"/api/orgs":{"get":{"tags":["Orgs"],"summary":"Current org and memberships","security":[{"cookieAuth":[]}],"responses":{"200":{"description":"Orgs"}}},"post":{"tags":["Orgs"],"summary":"Create an organization","security":[{"cookieAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"}}}}}},"responses":{"200":{"description":"Created"}}},"patch":{"tags":["Orgs"],"summary":"Rename the current organization","security":[{"cookieAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"}}}}}},"responses":{"200":{"description":"Updated"}}}},"/api/orgs/switch":{"post":{"tags":["Orgs"],"summary":"Switch current organization","security":[{"cookieAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["organizationId"],"properties":{"organizationId":{"type":"string"}}}}}},"responses":{"200":{"description":"Switched"}}}},"/api/orgs/members":{"get":{"tags":["Orgs"],"summary":"List members","security":[{"cookieAuth":[]}],"responses":{"200":{"description":"Members"}}},"post":{"tags":["Orgs"],"summary":"Add a member by email","description":"They must already have a CDNForge account.","security":[{"cookieAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string"},"role":{"type":"string","enum":["admin","member"]}}}}}},"responses":{"200":{"description":"Added"}}}},"/api/orgs/members/{id}":{"patch":{"tags":["Orgs"],"summary":"Change a member role","security":[{"cookieAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"role":{"type":"string","enum":["owner","admin","member"]}}}}}},"responses":{"200":{"description":"Updated"}}},"delete":{"tags":["Orgs"],"summary":"Remove a member","security":[{"cookieAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Removed"}}}},"/api/auth/register":{"post":{"tags":["Auth"],"summary":"Register","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["email","password","name"],"properties":{"email":{"type":"string"},"password":{"type":"string"},"name":{"type":"string"}}}}}},"responses":{"200":{"description":"Registered"}}}},"/api/auth/login":{"post":{"tags":["Auth"],"summary":"Log in","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string"},"password":{"type":"string"}}}}}},"responses":{"200":{"description":"Logged in"}}}},"/api/auth/logout":{"post":{"tags":["Auth"],"summary":"Log out","security":[{"cookieAuth":[]}],"responses":{"200":{"description":"Logged out"}}}},"/api/auth/me":{"get":{"tags":["Auth"],"summary":"Current user and org","security":[{"cookieAuth":[]}],"responses":{"200":{"description":"Session"}}}},"/api/dashboard/stats":{"get":{"tags":["Auth"],"summary":"Dashboard analytics","security":[{"cookieAuth":[]}],"parameters":[{"name":"range","in":"query","schema":{"type":"string","enum":["7","30","90"]}}],"responses":{"200":{"description":"Stats"}}}},"/api/public/stats":{"get":{"tags":["Public"],"summary":"Public platform counts","responses":{"200":{"description":"Counts"}}}}}}