Compliance Archiving & Data Retention
Overview
Stream all Workvivo content events to a third-party archiving platform in real time to meet regulatory and legal hold requirements.
Regulated industries, such as financial services, healthcare, government, legal are required to capture, retain, and produce employee communications and content on demand. When Workvivo is the primary employee experience platform, all content flowing through it (articles, updates, comments, documents, kudos) falls within the scope of these obligations. Manually exporting and archiving this data is impractical and leaves gaps that regulators will find.
Workvivo webhooks provide event notifications for supported content lifecycle changes. By subscribing to the relevant content-bearing events with the all content scope, organisations can send available event data to an archiving platform, including events for content in private and hidden spaces. The archiving platform remains responsible for retention controls, immutability, and evidentiary requirements.
This approach can support ongoing retention and legal-hold workflows when the subscribed events and their payloads contain the data required by the organisation's retention policy.
Value & Benefits
Meet regulatory retention requirements. Capture all employee communications and content in real time, satisfying obligations under regulations such as FINRA, MiFID II, HIPAA, and GDPR data retention mandates.
Support legal hold and e-discovery workflows. Send available content lifecycle event data to an archive that applies the organisation's legal-hold and retention policies.
Eliminate manual export processes. Content flows to your archiving platform automatically as events occur - no scheduled exports, no missed content, no human intervention required.
Capture relevant lifecycle changes. Subscribe to the available creation, update, publication, archival, and deletion events required by your retention policy.
Cover content types in a single integration. A single webhook endpoint can receive events for articles, pages, updates, documents, chat messages, comments, kudos, badges, and events - providing broad coverage from one integration point.
Applications
Financial services communications archiving. Capture all employee posts, articles, chat messages, and comments to meet FINRA Rule 17a-4 or MiFID II record-keeping requirements for electronic communications.
Legal hold preservation. Route relevant event data to an archive where content can be retained under your organisation's legal-hold policy.
Healthcare compliance. Archive all internal communications to support HIPAA audit trails and demonstrate that sensitive information was communicated appropriately within the organisation.
Content lifecycle auditing. Record supported lifecycle events and their available metadata for internal governance and audit workflows.
Cross-platform archiving consolidation. Feed Workvivo events into the same archiving platform (Smarsh, Global Relay, Veritas, Proofpoint) that captures your email, Slack, and Teams communications - providing a unified compliance archive.
Data retention policy enforcement. Use event timestamps and content metadata to apply retention schedules programmatically - flagging content that has exceeded its retention period or triggering automated deletion workflows.
Technical Details
Webhook Configuration
See Webhooks Fundamentals for endpoint registration, request verification, retries, idempotency, and out-of-order delivery. This use case focuses on the events and processing specific to this workflow.
To capture all content for archiving, configure a webhook in Admin > Platform > Webhook Settings. The user configuring webhooks must have the Developer role in Workvivo to access this page. Click Create Webhook and select:
- Webhook Name: A name that helps identify the archiving webhook later.
- Webhook URL: The HTTPS endpoint that will receive POST requests.
- Authentication: No Authentication or OAuth 2.0. OAuth 2.0 adds Login URL, Client ID, Client Secret, and optional custom form parameters for the token request.
- Custom Headers: Optional headers to include with each webhook request
- Subscribed Events: The content-bearing event checkboxes you need to archive. New event types are not automatically subscribed to existing webhooks.
- Content Scope: Select Send webhooks for all content to capture content from public, private, and hidden spaces.
Important: The "all content" scope includes content from private and hidden spaces, teams, and other limited audiences. Chat webhooks are never considered public, so you must use the all content scope to receive chat events. Ensure your archiving platform meets appropriate security and access control standards before enabling this scope.
Webhook Payload Examples
Chat Message Created
{
"action": "chat.message.created",
"message": {
"id": 12201456460,
"text": "Hello",
"files": [
{
"url": "https://example.com/image.jpg"
}
],
"parent": {
"message": {
"id": 12199318351
}
}
},
"channel": {
"url": "sendbird_group_channel_623970305_7453eed4dbe657ba1b4dd3f137b3bb80291b5c7a"
},
"sender": {
"id": 1,
"name": "John Doe"
},
"meta": {
"id": "4m32k5ykq5",
"attempt": 1,
"timestamp": 1725887565
}
}
Update Created
{
"action": "update.created",
"update": {
"id": 22,
"legacy_system_id": "ext-22",
"text": "I'm delighted to introduce you to our brand new interns who have started this week - make sure you stop by and say hello if you see them!",
"html": "<p>I'm delighted to introduce you to our brand new interns who have started this week...</p>",
"created_at": "2026-06-17T09:00:00Z",
"audience": {
"type": "Space",
"spaces": [{ "id": 108, "name": "New Hires" }]
},
"creator": {
"id": 250,
"external_id": null,
"email": "rj@example.com",
"name": "Rebecca Jones",
"job_title": "Senior Communications Specialist"
},
"gallery": [
{ "url": "https://example.com/img/updates/example-update.jpg" }
],
"attachments": []
},
"meta": {
"id": "7x91p2abc3",
"attempt": 1,
"timestamp": 1781686800
}
}
Comment Created
{
"action": "comment.created",
"comment": {
"comment_id": 93,
"comment_external_id": null,
"comment_parent_id": null,
"has_replies": false,
"item_type": "article",
"item_id": 6,
"text": "Wowee, what great content.",
"html": "<p>Wowee, what great content.</p>",
"creator": {
"id": 240,
"external_id": "ja-001",
"email": "ja@example.com",
"name": "James Ashton",
"job_title": "Marketing Executive"
},
"created_at": "2026-06-17T14:04:20Z",
"updated_at": "2026-06-17T14:04:20Z"
},
"meta": {
"id": "9k42m8xyz1",
"attempt": 1,
"timestamp": 1750172660
}
}
Webhook Delivery Behaviour
- Timeouts: Workvivo has a 5-second connection timeout and a 5-second response timeout. Your endpoint must connect and respond within these windows.
- Retries: If your endpoint does not return a 2xx response, Workvivo retries up to 4 additional times (5 total attempts) with exponential delay between retries.
- Ordering: Events may arrive out of order. Use the resource's
created_at/updated_attimestamps and themeta.timestampfor sequencing in your archive. - Idempotency: Use the
meta.idfield to deduplicate retried deliveries - the sameidis used across all retry attempts for a given event. - OAuth authentication: If OAuth 2.0 is configured, Workvivo retrieves an access token from your Login URL and sends it as an
Authorization: Bearer ...header in addition to the standard webhook headers.
JavaScript Integration Example
Receive Workvivo content events and pass each event to your compliance archive. The storage functions are placeholders for your archiving platform or database.
import express from 'express';
import { archiveEvent, hasArchivedEvent } from './archive.js';
const app = express();
app.use(express.json());
app.post('/webhooks/compliance', async (request, response) => {
const payload = request.body;
const eventId = payload.meta?.id;
if (!payload.action || !eventId) {
return response
.status(400)
.json({ error: 'Missing action or meta.id' });
}
// meta.id remains the same when Workvivo retries a delivery.
if (await hasArchivedEvent(eventId)) {
return response.status(200).json({ status: 'already_archived' });
}
await archiveEvent({
eventId,
action: payload.action,
occurredAt: payload.meta.timestamp,
payload,
});
return response.status(200).json({ status: 'archived' });
});
app.listen(3000);
export async function hasArchivedEvent(eventId) {
// Check your archive or deduplication store for this Workvivo event ID.
return false;
}
export async function archiveEvent(event) {
// Store the complete event in your compliance archiving platform.
}