Integrations

Receive Meeeters drafts on your own site

For custom sites (Next.js, Node, PHP, anything). Meeeters POSTs your AI drafts to a URL you own, signed so you can verify it is really us. Five minutes, copy-paste below. On WordPress? You do not need this page: use the WordPress connector instead.

How it works, in three steps

1. In your Meeeters dashboard, Settings → Connect your site → Webhook: paste your endpoint URL and click Generate to create the signing secret. 2. Store that same secret in your site's environment variables and deploy one of the endpoints below. 3. Click Connect: Meeeters sends a signed ping, and from then on every draft you approve arrives as JSON at your URL.

What we send

Payload (POST, application/json)
// Header: X-Meeeters-Signature = HMAC-SHA256(body, your secret), hex

// Connection test:
{ "event": "ping", "source": "meeeters.com" }

// Draft:
{
  "event": "article.draft",
  "title": "3D Product Visualization Services for Swiss Brands",
  "meta_description": "…max 155 chars…",
  "lang": "fr",
  "markdown": "# Title\n\nFull article in markdown…"
}

Next.js (App Router)

app/api/meeeters/route.ts
import crypto from "node:crypto";

const SECRET = process.env.MEEETERS_WEBHOOK_SECRET || "";

export async function POST(req: Request) {
  const body = await req.text();
  const sig = req.headers.get("x-meeeters-signature") || "";
  const expected = crypto.createHmac("sha256", SECRET).update(body).digest("hex");
  const ok = sig.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
  if (!ok) return new Response("invalid signature", { status: 401 });

  const data = JSON.parse(body);
  if (data.event === "ping") return Response.json({ ok: true });

  // data = { event: "article.draft", title, meta_description, lang, markdown }
  // Save it as a draft wherever your content lives, for example:
  // await db.drafts.insert({ title: data.title, lang: data.lang, md: data.markdown });
  return Response.json({ ok: true });
}

Node / Express

server.js
const crypto = require("crypto");
const express = require("express");
const app = express();
const SECRET = process.env.MEEETERS_WEBHOOK_SECRET || "";

app.post("/api/meeeters", express.text({ type: "*/*" }), (req, res) => {
  const expected = crypto.createHmac("sha256", SECRET).update(req.body).digest("hex");
  const sig = req.get("x-meeeters-signature") || "";
  if (sig.length !== expected.length ||
      !crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
    return res.status(401).send("invalid signature");
  }
  const data = JSON.parse(req.body);
  if (data.event === "ping") return res.json({ ok: true });
  // TODO: store { title, meta_description, lang, markdown } as a draft
  res.json({ ok: true });
});

PHP

meeeters-webhook.php
<?php
$secret = getenv("MEEETERS_WEBHOOK_SECRET");
$body = file_get_contents("php://input");
$sig = $_SERVER["HTTP_X_MEEETERS_SIGNATURE"] ?? "";
if (!hash_equals(hash_hmac("sha256", $body, $secret), $sig)) {
  http_response_code(401); exit("invalid signature");
}
$data = json_decode($body, true);
if (($data["event"] ?? "") === "ping") { echo json_encode(["ok" => true]); exit; }
// TODO: enregistrer le brouillon ($data["title"], $data["lang"], $data["markdown"])
echo json_encode(["ok" => true]);

Multilingual sites

Every draft carries a lang field (the primary language detected by your Meeeters audit). Route it to the right locale of your site, and let your usual translation pipeline handle the other languages, exactly like the rest of your content.

Frequently asked questions

Quick answers to the questions people ask most about this topic.

?
Where does the signing secret come from?

You invent it. Click Generate in the Meeeters connect card, then store the same value in your endpoint's environment variables. It is a shared secret: Meeeters signs every request with it, your endpoint verifies the signature.

?
What if my site runs WordPress?

Skip the webhook entirely. Use the WordPress connector: create an application password in your WP profile, paste it in Meeeters, done. Drafts land directly in your wp-admin.

?
Is anything published automatically?

No. Meeeters only sends drafts. Your endpoint decides what to do with them, and the recommended pattern is to store them as drafts for review.

?
What happens if my endpoint is down?

The send fails and the member sees an error in the dashboard, nothing is lost: the draft stays in Meeeters and can be re-sent or copied manually.

?
Does the webhook give Meeeters access to my site or my code?

No. A webhook is one-way delivery: Meeeters POSTs a JSON payload to your URL and that is all. It cannot read your database, your code, your dashboard or anything else on your site. The only code with any power is the endpoint you wrote yourself, and it does exactly what you programmed, nothing more.

?
Can Meeeters access my GitHub repository?

Never. Meeeters only sees what everyone sees: your public site. A third-party tool cannot reach a private repository unless you explicitly install it there, and Meeeters does not ask for that. Publishing works through credentials you choose to share (a CMS token) or through this webhook, where your own code stays in full control.

?
How do I fix an article after it was sent?

The content lives on your site, so you edit it there like any other content, nothing is locked. You can also edit the draft in Meeeters and re-send it: if your endpoint matches incoming drafts by title or slug and replaces the existing entry, corrections apply cleanly.

Open Settings and connect →