Platform
Storage
Overview

Storage

Base URL: https://storage-api.pcampus.co
CDN: https://cdn.pcampus.co
Canonical API: /api-reference/storage — paths under /v1/* (bucket + key)

Overview

Storage คือ object storage service สำหรับเก็บและให้บริการ files ทุกประเภทที่ใช้ใน Pcampus ecosystem ตั้งแต่ brand assets ของ Content OS, creative files ของ Cockpit, ไปจนถึงไฟล์ที่ developer ลูกค้าอัพโหลดผ่าน app ของตัวเอง รองรับ CDN delivery เพื่อให้ผู้ใช้ได้รับไฟล์เร็ว

Who uses this

Personaใช้ทำอะไร
Internal serviceContent OS, Cockpit เรียก API เก็บ assets และดึง URL
Developer (ลูกค้า)อัพโหลดและให้บริการไฟล์ของ app ตัวเอง (user avatars, documents, etc.)
End userอัพโหลด profile picture, document ผ่าน app
Adminดู storage usage, จัดการ buckets

Key features

  • File upload — รองรับ direct upload (POST /v1/upload) และ presigned upload (POST /v1/presign) สำหรับ client-side
  • Bucket management — แยก bucket ตาม organization และ use case (public, private)
  • CDN delivery — public object serve ผ่าน https://cdn.pcampus.co/{bucket}/{key}
  • Image transformation — resize, crop, compress on-the-fly ผ่าน URL parameters (ดู API reference)
  • Access control — Public bucket (เข้าถึงผ่าน CDN ได้) vs. Private bucket (ต้อง auth หรือ download presign)
  • Usage tracking — ติดตาม storage used ต่อ org / bucket
  • Object identity — ระบุด้วย bucket + key (+ objectId ใน response)

User stories

Content OS (internal):

"เมื่อ brand manager อัพโหลด logo ต้องการเก็บใน storage แล้วได้ CDN URL กลับมาใช้แสดงผล"

→ Content OS เรียก POST /v1/upload → ได้ url (CDN) + objectId → เก็บใน Content OS DB → แสดงผลผ่าน CDN

Developer (ลูกค้า):

"ผมต้องการให้ user อัพโหลด profile picture โดยไม่ต้องส่งไฟล์ผ่าน backend ผม"

POST /v1/presign → ได้ uploadUrl + objectUrl → client PUT ตรงไป object store → ใช้ objectUrl เป็น public URL

Admin:

"ผมต้องการดู storage usage ของ org เพื่อตรวจสอบว่าใกล้ถึง limit แล้วหรือยัง"

→ Console → Storage → Usage dashboard → เห็น used / limit per bucket

How it works

Direct upload flow:

Presigned URL flow (client-side upload):

Data model

Objects are addressed by bucket + key. Responses may also include objectId for correlation — never expose raw internal storage_path to clients.

Integration

  • Content OS — เก็บ brand logos, images, content attachments
  • Cockpit — เก็บ campaign creative files
  • PIP — ทุก mutating call ผ่าน access check (storage.upload, storage.read) + Authorization: Bearer + x-tenant-id

Image transformation

Public images รองรับ transformation ผ่าน URL query params:

# Resize to 400x300
https://cdn.pcampus.co/{bucket}/{key}?w=400&h=300

# Crop (center) and compress
https://cdn.pcampus.co/{bucket}/{key}?w=400&h=300&fit=cover&q=80

# Convert format
https://cdn.pcampus.co/{bucket}/{key}?f=webp

รายละเอียดพารามิเตอร์: API reference → Image Transformation

API overview

MethodEndpointDescription
POST/v1/uploadUpload file directly (multipart; bucket, key, public)
POST/v1/presignPresigned URL for client PUT upload
GET/v1/objects/:bucket/:keyGet / redirect object (private requires auth)
POST/v1/presign/downloadPresigned download for private objects
DELETE/v1/objects/:bucket/:keyDelete object
GET/v1/bucketsList buckets for tenant
POST/v1/bucketsCreate bucket
DELETE/v1/buckets/:bucketNameDelete bucket (destructive — empties objects)

Full request/response shapes: API reference

Upload response

{
  "objectId": "obj_xxx",
  "bucket": "products",
  "key": "PROD-001/main.jpg",
  "url": "https://cdn.pcampus.co/products/PROD-001/main.jpg",
  "size": 204800,
  "mimeType": "image/jpeg",
  "public": true,
  "uploadedAt": "2026-07-15T10:00:00.000Z"
}
⚠️

Private bucket objects ต้องใช้ signed URL ที่มีอายุจำกัด หรือเรียก API ด้วย Bearer + tenant — อย่า expose storage_path โดยตรง

Storage

Base URL: https://storage-api.pcampus.co
CDN: https://cdn.pcampus.co
Canonical API: /api-reference/storage — paths under /v1/* (bucket + key)

Overview

Storage is the object storage service for storing and serving all file types used in the Pcampus ecosystem — from brand assets in Content OS and creative files in Cockpit, to files that customer developers upload through their own apps. It supports CDN delivery so end users receive files quickly.

Who uses this

PersonaWhat they do
Internal serviceContent OS, Cockpit call the API to store assets and retrieve URLs
Developer (customer)Upload and serve files for their own app (user avatars, documents, etc.)
End userUpload a profile picture or document via an app
AdminView storage usage, manage buckets

Key features

  • File upload — Direct upload (POST /v1/upload) and presigned upload (POST /v1/presign) for client-side
  • Bucket management — Buckets separated by organization and use case (public, private)
  • CDN delivery — Public objects served at https://cdn.pcampus.co/{bucket}/{key}
  • Image transformation — Resize, crop, and compress on-the-fly via URL parameters (see API reference)
  • Access control — Public buckets (CDN) vs. private buckets (auth or download presign)
  • Usage tracking — Track storage used per org / bucket
  • Object identity — Addressed by bucket + key (plus objectId in responses)

User stories

Content OS (internal):

"When a brand manager uploads a logo, I need it stored and a CDN URL returned for display."

→ Content OS calls POST /v1/upload → receives CDN url + objectId → stores it in the Content OS DB → renders via CDN

Developer (customer):

"I want users to upload profile pictures without the file passing through my backend."

POST /v1/presign → receive uploadUrl + objectUrl → client PUTs directly to the object store → use objectUrl as the public URL

Admin:

"I want to see an org's storage usage to check whether it's approaching the limit."

→ Console → Storage → Usage dashboard → see used / limit per bucket

How it works

Direct upload flow:

Presigned URL flow (client-side upload):

Data model

Objects are addressed by bucket + key. Responses may also include objectId for correlation — never expose raw internal storage_path to clients.

Integration

  • Content OS — Stores brand logos, images, and content attachments
  • Cockpit — Stores campaign creative files
  • PIP — Every mutating call goes through an access check (storage.upload, storage.read) with Authorization: Bearer + x-tenant-id

Image transformation

Public images support on-the-fly transformation via URL query params:

# Resize to 400x300
https://cdn.pcampus.co/{bucket}/{key}?w=400&h=300

# Crop (center) and compress
https://cdn.pcampus.co/{bucket}/{key}?w=400&h=300&fit=cover&q=80

# Convert format
https://cdn.pcampus.co/{bucket}/{key}?f=webp

Parameter details: API reference → Image Transformation

API overview

MethodEndpointDescription
POST/v1/uploadUpload file directly (multipart; bucket, key, public)
POST/v1/presignPresigned URL for client PUT upload
GET/v1/objects/:bucket/:keyGet / redirect object (private requires auth)
POST/v1/presign/downloadPresigned download for private objects
DELETE/v1/objects/:bucket/:keyDelete object
GET/v1/bucketsList buckets for tenant
POST/v1/bucketsCreate bucket
DELETE/v1/buckets/:bucketNameDelete bucket (destructive — empties objects)

Full request/response shapes: API reference

Upload response

{
  "objectId": "obj_xxx",
  "bucket": "products",
  "key": "PROD-001/main.jpg",
  "url": "https://cdn.pcampus.co/products/PROD-001/main.jpg",
  "size": 204800,
  "mimeType": "image/jpeg",
  "public": true,
  "uploadedAt": "2026-07-15T10:00:00.000Z"
}
⚠️

Private bucket objects require a time-limited signed URL or an authenticated API call — never expose storage_path directly.