Billing API
Base URL: https://billing-api.pcampus.co
Entitlements
GET /v1/orgs/:orgId/entitlements
Fetch the current plan and limits for an org — use this to enforce feature access in your app.
GET https://billing-api.pcampus.co/v1/orgs/org_xxx/entitlements
Authorization: Bearer <pip_api_key>Response:
{
"orgId": "org_xxx",
"plan": "starter",
"status": "active",
"currentPeriodEnd": "2026-08-15T00:00:00.000Z",
"entitlements": {
"pbcp": {
"enabled": true,
"eventsPerDay": 10000,
"contextRetentionDays": 90
},
"intelligence": {
"enabled": true,
"recommendationsPerDay": 1000
},
"connect": {
"enabled": true,
"channels": ["line", "facebook", "web"],
"agentSeats": 3
},
"notification": {
"enabled": true,
"sendsPerMonth": 5000
},
"mail": {
"enabled": true,
"sendsPerMonth": 2000
},
"storage": {
"enabled": true,
"storageGb": 10,
"bandwidthGbPerMonth": 50
},
"contentOs": {
"enabled": false
},
"pulse": {
"enabled": true
}
}
}Use this response to check feature access before rendering UI:
const { entitlements } = await getEntitlements(orgId)
if (!entitlements.contentOs.enabled) {
// show upgrade prompt
}Subscription
GET /v1/orgs/:orgId/subscription
GET https://billing-api.pcampus.co/v1/orgs/org_xxx/subscription
Authorization: Bearer <pip_api_key>Response:
{
"orgId": "org_xxx",
"plan": "starter",
"status": "active",
"stripeSubscriptionId": "sub_xxx",
"currentPeriodStart": "2026-07-15T00:00:00.000Z",
"currentPeriodEnd": "2026-08-15T00:00:00.000Z",
"cancelAtPeriodEnd": false,
"billingCycle": "monthly"
}POST /v1/orgs/:orgId/checkout
Create a Stripe Checkout session for upgrading a plan.
POST https://billing-api.pcampus.co/v1/orgs/org_xxx/checkout
Authorization: Bearer <pip_api_key>
{
"plan": "pro",
"billingCycle": "monthly",
"successUrl": "https://console.yourapp.co/billing?success=true",
"cancelUrl": "https://console.yourapp.co/billing"
}Response:
{
"checkoutUrl": "https://checkout.stripe.com/pay/cs_xxx",
"sessionId": "cs_xxx",
"expiresAt": "2026-07-15T10:30:00.000Z"
}Redirect the user to checkoutUrl — Stripe handles the payment.
POST /v1/orgs/:orgId/cancel
Cancel a subscription (cancel at period end).
POST https://billing-api.pcampus.co/v1/orgs/org_xxx/cancel
Authorization: Bearer <pip_api_key>
{ "reason": "too_expensive" }Usage
GET /v1/orgs/:orgId/usage
View current usage compared to plan limits.
GET https://billing-api.pcampus.co/v1/orgs/org_xxx/usage
Authorization: Bearer <pip_api_key>Response:
{
"orgId": "org_xxx",
"period": "2026-07-01T00:00:00.000Z / 2026-07-31T23:59:59.000Z",
"usage": {
"pbcp": { "eventsToday": 4523, "limitPerDay": 10000 },
"notification": { "sentThisMonth": 1842, "limitPerMonth": 5000 },
"mail": { "sentThisMonth": 430, "limitPerMonth": 2000 },
"storage": { "usedGb": 2.4, "limitGb": 10 }
}
}Invoices
GET /v1/orgs/:orgId/invoices
GET https://billing-api.pcampus.co/v1/orgs/org_xxx/invoices?limit=12
Authorization: Bearer <pip_api_key>Response:
{
"invoices": [
{
"invoiceId": "inv_xxx",
"amount": 99000,
"currency": "thb",
"status": "paid",
"paidAt": "2026-07-15T00:00:00.000Z",
"pdfUrl": "https://billing-api.pcampus.co/v1/invoices/inv_xxx/pdf"
}
]
}Error Responses
| Status | Code | When |
|---|---|---|
402 | PLAN_LIMIT_EXCEEDED | Usage has exceeded the plan quota |
403 | SERVICE_NOT_INCLUDED | This service is not included in the plan |
402 | PAYMENT_REQUIRED | Subscription has expired or payment failed |
Example:
{
"error": "PLAN_LIMIT_EXCEEDED",
"message": "Notification limit reached (5000/5000 this month). Upgrade to Pro for 20,000/month.",
"upgradeUrl": "https://console.pcampus.co/billing/upgrade"
}