DraftRank
All integration guides

// Integration guide

How to connect Custom Website

The universal destination. DraftRank sends each finished post as a JSON POST request to a URL you control, optionally signed so you can prove it came from us. What happens next is entirely your code — write to a database, commit a markdown file, trigger a rebuild, or forward it somewhere else.

About 15 minutes Advanced

Before you start

  • Somewhere to host an HTTP endpoint that accepts POST requests — any language or framework.
  • A publicly reachable HTTPS URL. Private and local addresses are rejected.
  • Somewhere for the post to go: a database, a content directory in your repository, or another API.

Step by step

  1. 1

    Create an endpoint that accepts POST

    Add a route to your site that reads a JSON body and returns a 2xx status. Anything other than 2xx is treated as a failed publish and the post is marked failed in DraftRank.

    POST https://yoursite.com/api/draftrank
  2. 2

    Generate a signing secret

    Strongly recommended. Create a long random string, keep a copy in your own environment configuration, and paste the same value into DraftRank.

    openssl rand -hex 32
  3. 3

    Verify the signature before trusting the body

    When a secret is set, DraftRank sends an Authorization bearer header and an HMAC-SHA256 signature of the exact raw body. Compare it against your own copy of the secret, using a constant-time comparison.

    Authorization: Bearer <secret>
    X-DraftRank-Signature: sha256=<hmac-sha256 of the raw body>

    Compute the HMAC over the raw request body exactly as received. Parsing the JSON first and re-serialising it changes the bytes and the signature will never match — this is the mistake that catches almost everyone.

  4. 4

    Read the payload

    The body carries the event name, the publish status, and a post object with everything DraftRank generated — both markdown and sanitised HTML, plus the SEO metadata.

    {
      "event": "post.publish",
      "published_at": "2026-08-14T09:30:00.000Z",
      "status": "publish",
      "featured": false,
      "post": {
        "id": "…",
        "title": "…",
        "slug": "…",
        "category": "…",
        "tags": ["…"],
        "meta_title": "…",
        "meta_description": "…",
        "primary_keyword": "…",
        "secondary_keywords": ["…"],
        "outline": […],
        "markdown": "# …",
        "html": "<h1>…</h1>",
        "cover_image_url": "https://…",
        "cta": { "title": "…", "description": "…", "button_label": "…" },
        "word_count": 1450,
        "reading_time_minutes": 7,
        "seo_score": 86,
        "sources": […]
      }
    }
  5. 5

    Store the post and answer

    Save it however your site works, then respond with any 2xx. If you return JSON containing a url, DraftRank records it and links to the live post from your dashboard.

    { "id": "your-post-id", "url": "https://yoursite.com/blog/the-slug" }
  6. 6

    Connect it in DraftRank

    Enter the webhook URL and the signing secret, then press Test & connect. The test sends a ping event rather than a post — any HTTP response counts as reachable, so a 404 from your route still passes the test but will fail on a real publish. Verify with a real post before relying on it.

    { "event": "ping", "sent_at": "2026-08-14T09:30:00.000Z" }

What goes in each field

These labels match the connect dialog exactly, so you can read this next to the form.

FieldWhat to enterExample
Webhook URLThe public HTTPS endpoint that receives the POST request.https://yoursite.com/api/draftrank
Signing secretoptionalOptional but strongly recommended. Sent as a bearer token and used to sign each request so you can verify it came from DraftRank.A long random string

If something goes wrong

Find the message DraftRank showed you. Each one has a specific cause.

yoursite.com isn't a reachable public address. Use your site's public URL.

Why: The URL resolves to a private or local network address, which DraftRank refuses to call as a protection against server-side request forgery.

Fix: Expose the endpoint on a public HTTPS URL. For local development, use a tunnel such as ngrok or Cloudflare Tunnel rather than localhost.

My signature check never matches

Why: The HMAC is being computed over a re-serialised body rather than the raw bytes received.

Fix: Read the raw body first and compute the HMAC on that exact string, then parse the JSON. In Next.js route handlers use await request.text(); in Express, express.raw() rather than express.json().

Webhook: HTTP 500 (or your framework's error)

Why: Your handler threw. DraftRank surfaces your response body, so whatever your endpoint returned is shown in the error.

Fix: Check your own server logs for that request. The error text in DraftRank is the first part of your response body, which usually points straight at the failing line.

The connection test passed but real publishes fail

Why: The test only sends a ping and treats any HTTP response as reachable, because a generic endpoint may legitimately reject an unknown event type.

Fix: Publish one post by hand and confirm it arrives before turning auto-publish on. That is the only real proof the integration works.

Requests time out

Why: DraftRank waits 25 seconds for a response.

Fix: Acknowledge quickly and do slow work afterwards — queue a background job, or return 202 and rebuild the site asynchronously rather than waiting for a full static build inside the request.

Custom Website FAQ

Which stacks does this cover?

Any of them. It is a plain HTTP POST, so Next.js, Astro, Hugo, Eleventy, Laravel, Django, Rails, a headless CMS such as Strapi or Sanity, or an automation tool such as Zapier, Make or n8n all work equally well.

Do I get markdown or HTML?

Both, in the same payload. Use markdown if you commit content files to a repository, and HTML if you are writing into a database or CMS field. The HTML is sanitised against a strict allowlist before it is sent — no scripts, no event handlers, no javascript: URLs.

Is the signing secret really necessary?

Your endpoint is a public URL that publishes content. Without a secret, anyone who guesses it can post to your site. With one, you can reject everything that does not carry a valid signature.

What happens if my endpoint is down?

The publish is recorded as failed with the error returned, and you can retry it from the post in DraftRank once your endpoint is healthy again.

Can I use this to reach a platform DraftRank does not support natively?

Yes, and it is the recommended route for anything not in the list — including Shopify stores that cannot obtain a permanent access token. Receive the JSON and call that platform's own API from your handler.

Ready to connect Custom Website?

Open your site in DraftRank, go to the Integrations tab, and follow the steps above.

Open DraftRank