Plan with AI

Get started →

Content Change Notifications

Overview

Subscribe to article, page, and document webhooks to trigger downstream workflows whenever content is created, updated, or deleted in Workvivo.

Workvivo is often the central hub for employee-facing content, but it rarely operates in isolation. Content changes in Workvivo frequently need to trigger actions in other systems: updating a search index, notifying a compliance team, syncing to an external CMS, logging changes for audit, or kicking off an approval workflow. Polling the API for changes is inefficient and introduces latency. Webhooks solve this by pushing event data to your systems the moment something happens.

Workvivo fires webhook events for the content lifecycle across articles, pages, documents, and document folders. When an article is published, your search platform can index it immediately. When a policy page is updated, your compliance system can flag it for review. When a document expires, your records management tool can archive it. Each webhook delivers the event action, the relevant resource payload, and delivery metadata. Resource payloads include fields such as content, creator, audience, and timestamps where they apply.

Value & Benefits

React to content changes without polling. Downstream systems can process supported event notifications as Workvivo delivers them.

Eliminate redundant API polling. Instead of repeatedly querying the API to detect changes, your systems only process events when something actually happens, reducing API usage and infrastructure load.

Power cross-platform content workflows. Use content events as triggers for external systems: search indexing, compliance review, translation pipelines, analytics ingestion, or notification routing.

Contribute to audit trails. Supported content lifecycle events can be captured and logged in your records management or compliance platform.

Build event-driven architectures. Decouple your systems from Workvivo's internal state by subscribing to the events you care about and processing them asynchronously in your own infrastructure.

Applications

Search index synchronisation. When articles or pages are published or updated, push the content to your enterprise search platform (Elasticsearch, Algolia, Coveo) so employees can find the latest information immediately.

Compliance and audit logging. Send relevant content lifecycle events to a compliance platform or SIEM, where your organisation can apply its required retention and immutability controls.

Translation pipeline triggers. When an article is published, automatically queue it for translation by sending the content to your translation management system, then use the API to push translated versions back as language variants.

Content expiry management. Subscribe to document.expired events to trigger renewal workflows, notifying document owners, creating review tasks, or archiving expired content in external systems.

Cross-platform content mirroring. Mirror Workvivo articles or pages to an external website, knowledge base, or partner portal by reacting to publish and update events in real time.

Analytics and engagement tracking. Feed content creation and publishing events into your analytics platform to track publishing velocity, content freshness, and authorship patterns across the organisation.

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.

Webhooks are configured in Admin > Platform > Webhook Settings. The user configuring webhooks must have the Developer role in Workvivo to access this page. Click Create Webhook to add a new endpoint.

When configuring a webhook, you select:

  • Webhook Name: A name that helps identify the 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 event checkboxes to listen for. New event types are not automatically subscribed to existing webhooks.
  • Content Scope: Send webhooks for only public content, or send webhooks for all content.

Webhook Payload Examples

Article Published Event

When an article is published, Workvivo sends a POST request to your configured URL.

{
    "action": "article.published",
    "article": {
        "id": 93,
        "user_alias": null,
        "external_id": 93,
        "slug": "--1",
        "title": "Welcome Aboard - Here's all you need to know!",
        "subtitle": null,
        "language_code": "en",
        "html_content": "<p>Key Contacts</p><p>The key point of contact for your onboarding is the HR Team...</p>",
        "secondary_image": null,
        "comments_count": 0,
        "reactions_count": 0,
        "global_audience": 0,
        "is_featured": 0,
        "has_acknowledgement": false,
        "image": {
            "mime_type": "image/jpeg",
            "url": "https://workvivo.com/img/users/primary-image.jpg",
            "width": 1667,
            "height": 688
        },
        "creator": {
            "id": 240,
            "external_id": "ja-001",
            "email": "ja@example.com",
            "name": "James Ashton",
            "first_name": "James",
            "last_name": "Ashton",
            "display_name": "James Ashton",
            "avatar_url": "https://workvivo.com/img/users/james-ashton.jpg",
            "job_title": "Marketing Executive"
        },
        "audience": {
            "is_global": false,
            "spaces": [{ "id": 5, "name": "HR & Onboarding" }],
            "teams": []
        },
        "language_variants": [
            {
                "title": "Welcome Aboard - Here's all you need to know!",
                "subtitle": null,
                "language_code": "en",
                "html_content": "<p>Key Contacts</p>..."
            }
        ],
        "published_at": "2026-06-17T09:00:00Z",
        "created_at": "2026-06-17T08:30:00Z",
        "updated_at": "2026-06-17T09:00:00Z",
        "permalink": "https://example.workvivo.com/news/93?source=api_permalink"
    },
    "meta": {
        "id": "4m32k5ykq5",
        "attempt": 1,
        "timestamp": 1781686800
    }
}

Page Updated Event

{
    "action": "page.updated",
    "page": {
        "id": 42,
        "parent_id": null,
        "external_id": null,
        "external_parent_id": null,
        "title": "Welcome to the Knowledge Base (Updated)",
        "slug": "welcome-to-the-knowledge-base",
        "subtitle": "Your guide to getting started",
        "space_id": 5,
        "language_code": "en",
        "html_content": "<p>Key Resources</p><p>This space contains all the key information you need to get started...</p>",
        "is_draft": false,
        "is_standalone": false,
        "is_sidebar_enabled": true,
        "hide_title_and_subtitle": false,
        "featured_image": {
            "mime_type": "image/jpeg",
            "url": "https://example.com/img/pages/hero.jpg",
            "width": 1200,
            "height": 630
        },
        "audience": {
            "is_global": false,
            "spaces": [{ "id": 5, "name": "HR & Onboarding" }],
            "teams": []
        },
        "language_variants": [
            {
                "title": "Welcome to the Knowledge Base (Updated)",
                "subtitle": "Your guide to getting started",
                "language_code": "en",
                "html_content": "<p>Key Resources</p>..."
            }
        ],
        "created_at": "2026-03-18T10:00:00Z",
        "updated_at": "2026-06-17T11:30:00Z",
        "permalink": "https://yourcompany.workvivo.com/spaces/5/pages/welcome-to-the-knowledge-base"
    },
    "meta": {
        "id": "7x91p2abc3",
        "attempt": 1,
        "timestamp": 1781695800
    }
}

Document Expired Event

{
    "action": "document.expired",
    "document": {
        "id": 1042,
        "label": "Employee Handbook 2024 (Revised)",
        "description": "Updated to reflect the new remote work policy.",
        "is_featured": false,
        "creator": {
            "id": 55,
            "external_id": "HR-001",
            "email": "jane.smith@example.com",
            "name": "Jane Smith",
            "first_name": "Jane",
            "last_name": "Smith",
            "display_name": "Jane Smith",
            "avatar_url": "https://cdn.workvivo.com/avatars/55.jpg",
            "job_title": "HR Manager"
        },
        "audience": {
            "is_global": true,
            "spaces": [],
            "teams": []
        },
        "document": {
            "content_id": 204,
            "content_type": "file",
            "url": "https://cdn.workvivo.com/files/employee-handbook-2024-revised.pdf"
        },
        "icon_url": null,
        "created_at": "2024-03-15T09:00:00Z",
        "updated_at": "2024-06-10T14:32:00Z",
        "expiry_date": "2025-03-15T09:00:00Z"
    },
    "meta": {
        "id": "9k42m8xyz1",
        "attempt": 1,
        "timestamp": 1742029200
    }
}

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: Webhooks may not always arrive in the order they were triggered. For example, you may receive article.published before article.created for the same article.
  • Idempotency: Use the meta.id field to deduplicate retried deliveries - the same id is 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 content lifecycle events and route them to the relevant downstream operation. The example keeps Workvivo event handling concrete while leaving search, compliance, and notification implementations to your systems.

import express from 'express';
import {
    hasProcessedEvent,
    indexContent,
    markEventProcessed,
    notifyDocumentOwner,
    recordAuditEvent,
    removeContent,
} from './downstream.js';

const app = express();
app.use(express.json());

app.post('/webhooks/content', async (request, response) => {
    const payload = request.body;
    const action = payload.action ?? '';
    const eventId = payload.meta?.id;

    if (!action || !eventId) {
        return response
            .status(400)
            .json({ error: 'Missing action or meta.id' });
    }

    if (await hasProcessedEvent(eventId)) {
        return response.status(200).json({ status: 'already_processed' });
    }

    if (action.startsWith('article.')) {
        await handleContentEvent('article', action, payload.article);
    } else if (action.startsWith('page.')) {
        await handleContentEvent('page', action, payload.page);
    } else if (action.startsWith('document.folder.')) {
        await handleContentEvent('document_folder', action, payload.folder);
    } else if (action.startsWith('document.')) {
        await handleContentEvent('document', action, payload.document);

        if (action === 'document.expired') {
            await notifyDocumentOwner(payload.document);
        }
    }

    await recordAuditEvent(payload);
    await markEventProcessed(eventId);

    return response.status(200).json({ status: 'processed' });
});

async function handleContentEvent(contentType, action, resource) {
    if (!resource) {
        return;
    }

    if (action.endsWith('.deleted') || action.endsWith('.archived')) {
        await removeContent(contentType, resource.id);
    } else if (
        action.endsWith('.created') ||
        action.endsWith('.updated') ||
        action.endsWith('.published')
    ) {
        await indexContent(contentType, resource);
    }
}

app.listen(3000);
export async function hasProcessedEvent(eventId) {
    // Check your persistent deduplication store.
    return false;
}

export async function markEventProcessed(eventId) {
    // Record the Workvivo event ID after successful processing.
}

export async function indexContent(contentType, resource) {
    // Add or update the resource in your search or content platform.
}

export async function removeContent(contentType, resourceId) {
    // Remove the resource from your downstream platform.
}

export async function notifyDocumentOwner(document) {
    // Notify the owner that their document has expired.
}

export async function recordAuditEvent(payload) {
    // Store the event in your audit or compliance system.
}