API Reference
Delivery Hub exposes REST APIs for cross-org synchronization and a portal API for client-facing dashboards. The sync endpoints are used internally by the sync engine, while the portal endpoints power the client portal experience.
Salesforce API Base URL
Replace your-org with your Salesforce org's My Domain. The delivery namespace prefix is the managed package namespace.
Authentication
All Public API calls require an X-Api-Key header with a valid API key from a Connected NetworkEntity record:
API keys are 64-character hex strings generated via DeliveryPublicApiService.generateApiKey(). All data is scoped to the authenticated NetworkEntity — you can only access WorkItems where ClientNetworkEntityId__c matches the entity. The Sync API uses opt-in API key validation for backward compatibility.
Portal API Base URL
Portal endpoints are served from the Cloud Nimbus web application. All portal endpoints require an X-Api-Key header for authentication. Endpoints that return entity-scoped data also require the X-Portal-User header to identify the requesting user and their entity context.
Portal Authentication
Portal API endpoints use API key authentication rather than OAuth:
| Header | Required | Description |
|---|---|---|
| X-Api-Key | Yes | API key for authenticating the request. |
| X-Portal-User | Yes | Portal user ID. Used to resolve the user's entity for data scoping. |
Portal Endpoints
GET/api/dashboard
Returns the portal dashboard scoped to the authenticated NetworkEntity. Includes active/completed/attention counts, phase distribution, recent completions, and recent activity.
GET/api/work-items
Returns work items for the authenticated entity. Optionally filter by status.
Parameters
| Param | Type | Description |
|---|---|---|
| status | String | active | completed | attention (optional) |
GET/api/work-items/{id}
Returns full detail for a single work item including comments (up to 200), file count, and ordered stages for a progress bar. Returns 403 if the work item belongs to a different entity.
POST/api/work-items
Creates a new work item request. Title is automatically prefixed with [Portal]. Created with stage Backlog, status New, and IsActive true.
Request Body
POST/api/work-items/{id}/comments
Adds a comment to a work item. Auto-tagged with Author "Portal User" and Source "Client". Returns 403 if the work item belongs to a different entity.
Request Body
GET/api/activity-feed
Returns a unified activity feed combining comments, hours logged, and field changes across work items for an entity.
Parameters
| Param | Type | Description |
|---|---|---|
| filterType | String | all | comments | hours | changes |
| pageOffset | Number | Pagination offset for results. |
| entityId | String | Network Entity ID to scope results. |
GET/api/conversations
Returns comments grouped by work item, providing a conversation-style view of discussions across the entity's work items.
Parameters
| Param | Type | Description |
|---|---|---|
| pageOffset | Number | Pagination offset for results. |
| entityId | String | Network Entity ID to scope results. |
GET/api/pending-approvals
Returns draft WorkLogs that are awaiting approval for the given entity.
Parameters
| Param | Type | Description |
|---|---|---|
| pageOffset | Number | Pagination offset for results. |
| entityId | String | Network Entity ID to scope results. |
GET/api/work-logs
Returns recent work logs (time entries) for the given entity.
Parameters
| Param | Type | Description |
|---|---|---|
| entityId | String | Network Entity ID to scope results. |
GET/api/files
Returns files attached to work items for an entity. Optionally filter to a specific work item.
Parameters
| Param | Type | Description |
|---|---|---|
| entityId | String | Network Entity ID to scope results. |
| workItemId | String | Optional. Filter files to a specific work item. |
GET/api/board-summary
Returns an AI-generated summary of the current board state for an entity, highlighting key activity and attention items.
Parameters
| Param | Type | Description |
|---|---|---|
| entityId | String | Network Entity ID to scope the summary. |
GET/api/documents
Returns documents and invoices associated with an entity.
Parameters
| Param | Type | Description |
|---|---|---|
| entityId | String | Network Entity ID to scope results. |
POST/api/approve-worklogs
Batch approves one or more draft work logs.
Request Body
| Field | Type | Description |
|---|---|---|
| workLogIds | String[] | Array of WorkLog record IDs to approve. |
POST/api/reject-worklogs
Batch rejects one or more draft work logs.
Request Body
| Field | Type | Description |
|---|---|---|
| workLogIds | String[] | Array of WorkLog record IDs to reject. |
POST/api/log-hours
Logs hours worked against a specific work item.
Request Body
| Field | Type | Description |
|---|---|---|
| workItemId | String | The WorkItem record ID to log hours against. |
| hours | Number | Number of hours worked (supports decimals). |
| workNotes | String | Description of work performed. |
| workDate | Date | The date the work was performed (YYYY-MM-DD). |
Sync Endpoints
POST/sync/{ObjectType}
Pushes changes from one org to another. The URL includes the object type (e.g., WorkItem__c, WorkItemComment__c, ContentVersion).
Headers
| Header | Required | Description |
|---|---|---|
| X-Api-Key | Optional | API key for opt-in validation. Must match a Connected NetworkEntity if sent. |
| X-Global-Source-Id | Optional | Original record ID for gateway-level echo suppression and multi-hop loop prevention. |
Request Payload
Response
Payload Fields
| Field | Type | Description |
|---|---|---|
| SourceId | String | Record ID in the sending org. Used for record resolution and bridge mapping. |
| TargetId | String | Known record ID in the receiving org (if previously synced). Used as direct fallback for resolution. |
| GlobalSourceId | String | Original record ID that initiated the sync chain. Carried forward across multi-hop topologies for loop prevention. |
| SenderOrgId | String | Salesforce Organization ID of the sending org. Used for auto-parenting to the correct NetworkEntity. |
| VendorPush | Boolean | Indicates this is a real-time vendor push (upstream), not a standard downstream sync. |
GET/sync/changes
Pull flow endpoint. Returns staged outbound SyncItems for a specific client entity. Items are marked as Synced after being returned. Used by the DeliveryHubPoller scheduled job for 15-minute polling.
Parameters
| Param | Type | Description |
|---|---|---|
| clientId | String | Required. NetworkEntity ID for data segregation. |
| since | ISO DateTime | Optional. Filter to items created after this datetime. Defaults to 1900-01-01. |
Response
Returns up to 200 items per request, ordered by CreatedDate ascending. Only returns items with StatusPk__c = "Staged" and DirectionPk__c = "Outbound".
Retry Logic
Failed sync items are retried up to 3 times. On each failure, RetryCountNumber__c is incremented and ErrorLogTxt__c is populated with error details.
- •Attempt 1: Immediate (via DeliverySyncItemProcessor queueable)
- •Attempt 2: Picked up on next scheduled poller run (15-minute intervals)
- •Attempt 3: Final automatic retry on next poller cycle
After 3 failed attempts, the sync item remains in Failed status for manual investigation via the Sync Retry Panel LWC on the admin home page. The DeliveryHubScheduler acts as a safety net, picking up any items that were missed.
Echo Suppression
When Org A pushes a change to Org B, the update in Org B triggers its own outbound sync trigger. Without echo suppression, this would create an infinite loop. Delivery Hub prevents this with 3 layers:
- Gateway-level (X-Global-Source-Id): HTTP header carries the original record ID. The receiving org checks for an existing outbound SyncItem with that GlobalSourceId and suppresses if matched.
- In-memory origin blocking: DeliverySyncItemIngestor registers the origin route in DeliverySyncEngine.blockedOrigins (static Set), preventing re-queuing within the same transaction.
- GlobalSourceId inheritance: When creating outbound SyncItems, the engine checks the ledger for an existing GlobalSourceId and carries it forward rather than replacing with the local ID. This enables multi-hop loop prevention across complex topologies (Org A → Org B → Org C).
Error Codes
| Code | Status | Description |
|---|---|---|
| 200 | OK | Sync processed successfully or echo suppressed. |
| 201 | Created | Resource created (POST work-items, comments, log-hours, submissions). |
| 400 | Bad Request | Missing body, blank required field, invalid parameters, or empty payload. |
| 401 | Unauthorized | Missing or invalid X-Api-Key header, or entity not in Connected status. |
| 403 | Forbidden | Work item belongs to a different NetworkEntity than the authenticated one. |
| 404 | Not Found | Unknown endpoint path or work item ID not found. |
| 500 | Server Error | Unexpected Apex exception. Check Sync Retry Panel for details. |
Related
- Architecture — data model and sync engine design
- CI/CD — automated testing for sync endpoints