Connect Webhook Guide

Set up a Webhook endpoint to receive article data from GroMach. Process published articles in your own backend system with full control over the data flow.

Last Updated: February 5, 2026

Overview

The Webhook integration allows you to receive article data from GroMach and process it in your own backend system. When you publish an article, GroMach sends a POST request to your configured endpoint with the article content.

Step 1: Set Up Your Webhook Endpoint

Create an HTTPS endpoint on your server to receive webhook requests. The endpoint must:

  • Accept POST requests: All webhook data is sent via POST
  • Use HTTPS: For security, only HTTPS URLs are supported
  • Return 2xx status: Return a success status code to confirm receipt

Step 2: Implement Signature Verification

GroMach signs all webhook requests using HMAC-SHA256. You should verify this signature to ensure requests are authentic.

Each request includes these headers:

  • x-webhook-signature: HMAC-SHA256 signature of the request body
  • x-webhook-timestamp: ISO 8601 timestamp of when the request was sent
  • Content-Type: application/json

Here's an example of signature verification in Node.js:

const crypto = require('crypto');

function verifySignature(payload, signature, secret) {
  const computedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature, 'hex'),
    Buffer.from(computedSignature, 'hex')
  );
}

// In your endpoint handler:
app.post('/webhook', (req, res) => {
  const signature = req.headers['x-webhook-signature'];
  const payload = JSON.stringify(req.body);

  if (!verifySignature(payload, signature, YOUR_SECRET_KEY)) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  // Process the webhook...
  res.json({ success: true });
});

Step 3: Webhook Payload Format

When an article is published, GroMach sends a payload with the following structure:

{
  "event_type": "publish_articles",
  "timestamp": "2024-01-15T10:30:00.000Z",
  "data": {
    "articles": [
      {
        "id": "article-uuid-123",
        "slug": "my-article-slug",
        "title": "Article Title",
        "excerpt": "Brief description of the article...",
        "content_format": "markdown",
        "content": "# Full article content in markdown...",
        "status": "published",
        "published_at": "2024-01-15T10:30:00.000Z",
        "author_name": "Admin",
        "cover_image": "https://example.com/image.jpg",
        "meta_title": "SEO Title",
        "meta_description": "SEO meta description",
        "tags": ["seo", "marketing"]
      }
    ]
  }
}

Article Fields Reference

  • id: Unique identifier for the article
  • slug: URL-friendly identifier for the article
  • title: Article title
  • excerpt: Brief description or summary
  • content_format: Either "markdown" or "html"
  • content: Full article content
  • status: Publication status (draft, published, archived)
  • published_at: ISO 8601 publication timestamp
  • author_name: Author display name
  • cover_image: URL of the cover image (if available)
  • meta_title: SEO title for search engines
  • meta_description: SEO meta description
  • tags: Array of tag strings

Step 4: Configure in GroMach

In the GroMach integrations page, fill in the following information:

  • Name (Optional): A friendly name to identify this webhook
  • Webhook URL: Your HTTPS endpoint URL (e.g., https://your-site.com/api/webhook)
  • Secret Key: A secret string used to sign requests (keep this secure!)
  • Publish Status: Choose whether articles are sent as "published" or "draft"

Important

Keep your Secret Key secure and never expose it in client-side code. Use environment variables to store it safely on your server.

Testing Your Webhook

Before creating the integration, you can test your webhook connection using the "Test Connection" button. GroMach will send a test request to verify your endpoint is properly configured.

Test Requirements

For the test to pass, your endpoint must:

  • 1. Verify the signature: Use the secret key to verify the X-Webhook-Signature header
  • 2. Return success response: Return a JSON response with { "success": true }

The test payload looks like:

{
  "event_type": "test",
  "timestamp": "2024-01-15T10:30:00.000Z",
  "data": {
    "message": "This is a test webhook from Gromach SEO",
    "integration_name": "My Webhook"
  }
}

Here's a complete example of how your test endpoint should handle the request:

const crypto = require('crypto');

app.post('/webhook', (req, res) => {
  const signature = req.headers['x-webhook-signature'];
  const payload = JSON.stringify(req.body);

  // Step 1: Verify the signature
  const computedSignature = crypto
    .createHmac('sha256', YOUR_SECRET_KEY)
    .update(payload)
    .digest('hex');

  const isValid = crypto.timingSafeEqual(
    Buffer.from(signature, 'hex'),
    Buffer.from(computedSignature, 'hex')
  );

  if (!isValid) {
    return res.status(401).json({
      success: false,
      error: 'Invalid signature'
    });
  }

  // Step 2: Process based on event type
  if (req.body.event_type === 'test') {
    // Test connection - just return success
    return res.json({ success: true });
  }

  if (req.body.event_type === 'publish_articles') {
    // Process articles...
    const articles = req.body.data.articles;
    // Save to your database, etc.
    return res.json({ success: true });
  }

  res.json({ success: true });
});

Why signature verification is required

Signature verification ensures that the webhook requests are genuinely from GroMach and haven't been tampered with. This is a security best practice that protects your endpoint from unauthorized requests.

Troubleshooting

Connection test fails

  • • Verify your endpoint URL is correct and uses HTTPS
  • • Ensure your server is accessible from the internet
  • • Check that your endpoint returns a 2xx status code

Signature verification fails

  • • Make sure you're using the exact Secret Key from GroMach
  • • Verify you're hashing the raw request body, not a parsed object
  • • Use timing-safe comparison to prevent timing attacks

Articles not appearing

  • • Check your server logs for any processing errors
  • • Verify the article status matches your expected workflow
  • • Ensure your database operations are completing successfully