Globals & Advanced API Patterns
Complete reference for Payload CMS Globals and advanced API usage patterns.
📌 Note: In all code examples below, replace
{org-name}with your organization's subdomain. For example:eeda,kinexion, ormy-company.
Globals Overview
Globals are singleton documents that store site-wide or system-wide configuration. Unlike collections which contain multiple documents, globals contain a single document per slug.
Accessing Globals
All globals are accessed via the /globals/{slug} endpoint:
GET /globals/{slug}
POST /globals/{slug}
SiteSettings Global
Endpoint: /globals/site-settings
Get Site Settings
curl https://{org-name}.api.picoshealth.com/v1/globals/site-settings
Response:
{
"id": "site-settings-global",
"siteName": "Picos Health",
"siteDescription": "Healthcare delivered with care and efficiency",
"supportEmail": "support@picoshealth.com",
"contactPhone": "1-800-PICOS-01",
"businessHours": {
"monday": "9:00 AM - 5:00 PM",
"tuesday": "9:00 AM - 5:00 PM",
"wednesday": "9:00 AM - 5:00 PM",
"thursday": "9:00 AM - 5:00 PM",
"friday": "9:00 AM - 5:00 PM",
"saturday": "Closed",
"sunday": "Closed"
},
"socialLinks": {
"facebook": "https://facebook.com/picoshealth",
"twitter": "https://twitter.com/picoshealth",
"linkedin": "https://linkedin.com/company/picos-health"
},
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-20T10:00:00Z"
}
Update Site Settings
curl -X POST https://{org-name}.api.picoshealth.com/v1/globals/site-settings \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"siteName": "Picos Health v2",
"supportEmail": "help@picoshealth.com"
}'
JavaScript Example
// Fetch and cache site settings
let cachedSettings = null;
const getSiteSettings = async (token) => {
if (cachedSettings) return cachedSettings;
const response = await fetch('https://{org-name}.api.picoshealth.com/v1/globals/site-settings', {
headers: { 'Authorization': `Bearer ${token}` },
});
cachedSettings = await response.json();
// Cache for 1 hour
setTimeout(() => { cachedSettings = null; }, 60 * 60 * 1000);
return cachedSettings;
};
OrganizationSettings Global
Endpoint: /globals/organization-settings
Get Organization Settings
curl https://{org-name}.api.picoshealth.com/v1/globals/organization-settings
Response:
{
"id": "org-settings-global",
"organizationName": "Picos Health Inc",
"tier": "enterprise",
"supportEmail": "admin@picoshealth.com",
"apiKey": "[REDACTED]",
"maxUsers": 1000,
"maxProducts": 50000,
"networkSummary": {
"totalUsers": 243,
"totalOrders": 1542,
"totalRevenue": 125430.50,
"activePatients": 187,
"activeProviders": 42
},
"features": {
"advancedReporting": true,
"customBranding": true,
"apiAccess": true,
"webhooks": true,
"sso": false
},
"updatedAt": "2024-01-20T15:30:00Z"
}
Update Organization Settings
const updateOrgSettings = async (token, updates) => {
const response = await fetch('https://{org-name}.api.picoshealth.com/v1/globals/organization-settings', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(updates),
});
return response.json();
};
// Usage
await updateOrgSettings(token, {
organizationName: 'Picos Health Updated',
supportEmail: 'newemail@picoshealth.com',
});
MessageSettings Global
Endpoint: /globals/message-settings
Configure Messaging
curl -X POST https://{org-name}.api.picoshealth.com/v1/globals/message-settings \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"emailNotifications": true,
"smsNotifications": false,
"pushNotifications": true,
"defaultTemplate": "order-notification",
"retentionDays": 90,
"archiveAfterDays": 365
}'
Response:
{
"id": "msg-settings-global",
"emailNotifications": true,
"smsNotifications": false,
"pushNotifications": true,
"defaultTemplate": "order-notification",
"retentionDays": 90,
"archiveAfterDays": 365,
"updatedAt": "2024-01-20T16:00:00Z"
}
Wallet Global
Endpoint: /globals/wallet
Get Wallet Configuration
curl https://{org-name}.api.picoshealth.com/v1/globals/wallet
Response:
{
"id": "wallet-global",
"autoChargeEnabled": true,
"minimumBalance": 50,
"autoChargeAmount": 200,
"autoChargeThreshold": 25,
"currencies": ["USD", "EUR", "GBP"],
"processingFee": {
"type": "percent",
"value": 2.9
},
"autoChargeSchedule": "weekly",
"maxAutoChargePerMonth": 5,
"updatedAt": "2024-01-20T10:30:00Z"
}
Update Wallet Settings
const updateWalletSettings = async (token) => {
const response = await fetch('https://{org-name}.api.picoshealth.com/v1/globals/wallet', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
autoChargeEnabled: true,
minimumBalance: 100,
autoChargeAmount: 500,
}),
});
return response.json();
};
GlobalOrgDashboard
Endpoint: /globals/organization
Get Organization Dashboard Config
curl https://{org-name}.api.picoshealth.com/v1/globals/organization
Response:
{
"id": "org-dashboard-global",
"dashboardTitle": "Organization Overview",
"refreshInterval": 300,
"widgets": [
{
"id": "total-orders",
"title": "Total Orders",
"type": "metric",
"metric": "count",
"collection": "orders"
},
{
"id": "revenue-trend",
"title": "Revenue Trend",
"type": "chart",
"chartType": "line"
},
{
"id": "active-users",
"title": "Active Users",
"type": "metric"
}
],
"summary": {
"totalOrders": 1542,
"totalRevenue": 125430.50,
"activeMembers": 243,
"growthRate": "12.5%"
},
"updatedAt": "2024-01-20T12:00:00Z"
}
HCPCSFinder Global
Endpoint: /globals/hcpcs-finder
Search HCPCS Codes
// Get HCPCS index for searching
const getHCPCSIndex = async (token) => {
const response = await fetch('https://{org-name}.api.picoshealth.com/v1/globals/hcpcs-finder', {
headers: { 'Authorization': `Bearer ${token}` },
});
return response.json();
};
// Usage
const hcpcsData = await getHCPCSIndex(token);
console.log('Total HCPCS Codes:', hcpcsData.codeCount);
console.log('Last Updated:', hcpcsData.lastUpdated);
Response:
{
"id": "hcpcs-finder-global",
"codeCount": 67500,
"lastUpdated": "2024-01-15T00:00:00Z",
"searchIndex": {
"E0663": {
"description": "Compression garment, hand, each",
"category": "Medical Supplies",
"status": "active"
},
"E0666": {
"description": "Compression garment, foot",
"category": "Medical Supplies",
"status": "active"
}
}
}
SKUFinder Global
Endpoint: /globals/sku-finder
Access SKU Index
const getSKUIndex = async (token) => {
const response = await fetch('https://{org-name}.api.picoshealth.com/v1/globals/sku-finder', {
headers: { 'Authorization': `Bearer ${token}` },
});
return response.json();
};
Response:
{
"id": "sku-finder-global",
"lastUpdated": "2024-01-20T10:00:00Z",
"totalSKUs": 5200,
"searchIndex": {
"CS-MED-001": {
"productName": "Compression Socks",
"manufacturer": "CompressionCare",
"productId": "prod-uuid-1"
}
}
}
Advanced API Patterns
Batch Operations
// Batch create multiple users
const batchCreateUsers = async (token, users) => {
const promises = users.map(user =>
fetch('https://{org-name}.api.picoshealth.com/v1/users', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(user),
}).then(r => r.json())
);
return Promise.all(promises);
};
// Usage
const newUsers = [
{ email: 'user1@example.com', firstName: 'John', lastName: 'Doe', role: 'patient' },
{ email: 'user2@example.com', firstName: 'Jane', lastName: 'Smith', role: 'provider' },
{ email: 'user3@example.com', firstName: 'Bob', lastName: 'Johnson', role: 'patient' },
];
const results = await batchCreateUsers(token, newUsers);
console.log('Created users:', results);
Pagination Helpers
// Fetch all results with automatic pagination
const fetchAll = async (url, headers, limit = 100) => {
let allDocs = [];
let page = 1;
let hasMore = true;
while (hasMore) {
const response = await fetch(`${url}?limit=${limit}&page=${page}`, { headers });
const data = await response.json();
allDocs = allDocs.concat(data.docs);
hasMore = page < data.totalPages;
page++;
}
return allDocs;
};
// Usage
const allProducts = await fetchAll(
'https://{org-name}.api.picoshealth.com/v1/products',
{ 'Authorization': `Bearer ${token}` }
);
console.log('Total products:', allProducts.length);
Streaming Responses
// Stream large result sets
const streamResults = async (url, headers, onData) => {
const response = await fetch(url, { headers });
const reader = response.body.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const text = new TextDecoder().decode(value);
const data = JSON.parse(text);
onData(data);
}
};
// Usage
await streamResults(
'https://{org-name}.api.picoshealth.com/v1/orders?limit=1000',
{ 'Authorization': `Bearer ${token}` },
(order) => console.log('Processing order:', order.id)
);
Caching Requests
// Simple in-memory cache with TTL
class CachedAPI {
constructor(ttl = 60000) {
this.cache = new Map();
this.ttl = ttl;
}
async fetch(url, options) {
const cacheKey = `${options?.method || 'GET'}:${url}`;
// Check cache for GET requests
if (!options?.method || options.method === 'GET') {
if (this.cache.has(cacheKey)) {
const { data, timestamp } = this.cache.get(cacheKey);
if (Date.now() - timestamp < this.ttl) {
return data;
}
}
}
// Make request
const response = await fetch(url, options);
const data = await response.json();
// Cache GET responses
if (!options?.method || options.method === 'GET') {
this.cache.set(cacheKey, { data, timestamp: Date.now() });
}
return data;
}
invalidate(pattern) {
for (const key of this.cache.keys()) {
if (key.includes(pattern)) {
this.cache.delete(key);
}
}
}
}
// Usage
const api = new CachedAPI(60000); // 60 second TTL
const products = await api.fetch('https://api.picoshealth.com/v1/products', {
headers: { 'Authorization': `Bearer ${token}` },
});
// Invalidate related cache after creating new product
api.invalidate('/products');
Error Recovery with Circuit Breaker
class CircuitBreaker {
constructor(failureThreshold = 5, resetTimeout = 60000) {
this.failureCount = 0;
this.failureThreshold = failureThreshold;
this.resetTimeout = resetTimeout;
this.state = 'CLOSED'; // CLOSED, OPEN, HALF_OPEN
this.nextAttempt = Date.now();
}
async execute(fn) {
if (this.state === 'OPEN') {
if (Date.now() < this.nextAttempt) {
throw new Error('Circuit breaker is OPEN');
}
this.state = 'HALF_OPEN';
}
try {
const result = await fn();
this.onSuccess();
return result;
} catch (error) {
this.onFailure();
throw error;
}
}
onSuccess() {
this.failureCount = 0;
this.state = 'CLOSED';
}
onFailure() {
this.failureCount++;
if (this.failureCount >= this.failureThreshold) {
this.state = 'OPEN';
this.nextAttempt = Date.now() + this.resetTimeout;
}
}
}
// Usage
const breaker = new CircuitBreaker(5, 60000);
try {
const users = await breaker.execute(() =>
fetch('https://api.picoshealth.com/v1/users').then(r => r.json())
);
} catch (error) {
console.error('Service unavailable:', error.message);
}
Request Queuing and Rate Limiting
class RateLimitedQueue {
constructor(maxRequests = 100, windowMs = 60000) {
this.maxRequests = maxRequests;
this.windowMs = windowMs;
this.requests = [];
this.queue = [];
}
async add(fn) {
return new Promise((resolve, reject) => {
this.queue.push({ fn, resolve, reject });
this.process();
});
}
async process() {
if (this.queue.length === 0) return;
const now = Date.now();
this.requests = this.requests.filter(time => now - time < this.windowMs);
if (this.requests.length >= this.maxRequests) {
// Wait before trying again
setTimeout(() => this.process(), 100);
return;
}
const { fn, resolve, reject } = this.queue.shift();
this.requests.push(now);
try {
const result = await fn();
resolve(result);
} catch (error) {
reject(error);
}
// Process next item
if (this.queue.length > 0) {
setTimeout(() => this.process(), 0);
}
}
}
// Usage
const queue = new RateLimitedQueue(100, 60000); // 100 requests per minute
// Add requests to queue
queue.add(() => fetch('https://api.picoshealth.com/v1/users').then(r => r.json()));
queue.add(() => fetch('https://api.picoshealth.com/v1/products').then(r => r.json()));
Data Aggregation
// Aggregate data across multiple endpoints
const aggregateData = async (token) => {
const [users, orders, products] = await Promise.all([
fetch('https://api.picoshealth.com/v1/users?limit=1', {
headers: { 'Authorization': `Bearer ${token}` },
}).then(r => r.json()),
fetch('https://api.picoshealth.com/v1/orders?limit=1', {
headers: { 'Authorization': `Bearer ${token}` },
}).then(r => r.json()),
fetch('https://api.picoshealth.com/v1/products?limit=1', {
headers: { 'Authorization': `Bearer ${token}` },
}).then(r => r.json()),
]);
return {
totalUsers: users.totalDocs,
totalOrders: orders.totalDocs,
totalProducts: products.totalDocs,
avgOrderValue: orders.docs.length > 0
? orders.docs.reduce((sum, o) => sum + o.total, 0) / orders.docs.length
: 0,
};
};
Webhook Processing
// Handle incoming webhooks
const handleWebhook = (event) => {
const { collection, operation, doc } = event;
switch (`${collection}:${operation}`) {
case 'orders:create':
console.log('New order created:', doc.id);
// Send confirmation email
break;
case 'orders:update':
if (doc.status === 'shipped') {
console.log('Order shipped:', doc.id);
// Send tracking notification
}
break;
case 'users:create':
console.log('New user registered:', doc.email);
// Send welcome email
break;
default:
console.log('Unhandled webhook:', event);
}
};
Testing API Endpoints
Using cURL
# Get all users
curl https://api.picoshealth.com/v1/users \
-H "Authorization: Bearer YOUR_TOKEN"
# Create a user
curl -X POST https://api.picoshealth.com/v1/users \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","password":"pass123","role":"patient"}'
# Update a user
curl -X PATCH https://api.picoshealth.com/v1/users/USER_ID \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"role":"provider"}'
# Delete a user
curl -X DELETE https://api.picoshealth.com/v1/users/USER_ID \
-H "Authorization: Bearer YOUR_TOKEN"
Using Postman
- Set up environment variable:
api_token= your JWT token - Create requests with URL:
https://api.picoshealth.com/v1/users - Add header:
Authorization: Bearer {{api_token}} - Use pre-request scripts for data generation
- Use tests to verify responses
Using Jest/Vitest
describe('Users API', () => {
const baseUrl = 'https://api.picoshealth.com';
const token = process.env.API_TOKEN;
it('should fetch all users', async () => {
const response = await fetch(`${baseUrl}/users`, {
headers: { 'Authorization': `Bearer ${token}` },
});
expect(response.status).toBe(200);
const data = await response.json();
expect(Array.isArray(data.docs)).toBe(true);
});
it('should create a new user', async () => {
const response = await fetch(`${baseUrl}/users`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: `test-${Date.now()}@example.com`,
password: 'TestPass123!',
role: 'patient',
}),
});
expect(response.status).toBe(201);
const data = await response.json();
expect(data.email).toBeDefined();
});
});
Performance Optimization Tips
Use
depthparameter wisely - Only expand relationships when neededGET /orders/id?depth=2 // Include related documents GET /orders/id?depth=0 // Just IDsFilter early - Use
whereclauses server-sideGET /products?where={"status":{"equals":"published"}} // ✓ GoodPaginate large datasets - Never fetch all at once
GET /orders?limit=50&page=1Cache aggressively - Global data changes infrequently
// Cache for 1 hourUse bulk operations - Batch multiple operations
Promise.all([...]) // Parallel requestsMonitor rate limits - Implement backoff strategies
// Exponential backoff
Security Best Practices
Never commit tokens - Use environment variables
Authorization: Bearer ${process.env.API_TOKEN}Validate all inputs - Server validates, but validate client-side too
if (!email.includes('@')) throw new Error('Invalid email');Use HTTPS in production - Always encrypt in transit
https://api.picoshealth.com/v1Rotate tokens regularly - Implement token refresh
refreshToken() // Every hour or as neededAudit API access - Log all requests and responses
Authorization: Bearer TOKEN Method: POST Endpoint: /api/orders Status: 201 Timestamp: 2024-01-20T14:30:00Z