Developer Docs

Attach an OmniEditor receiver to your blog.

OmniEditor POSTs a finished article as JSON to an endpoint you control. Build a receiver in PHP, Node, or Python, validate the key, create the post, and return its public URL. Then share your endpoint + key + auth type with the OmniEditor team.

Overview

  1. 01Build a receiver endpoint on your blog that accepts a JSON POST request.
  2. 02Choose an auth method — an API Key sent in the X-API-Key header, or a Bearer token.
  3. 03Create or update the post in your CMS, then return the post’s public URL.
  4. 04Share your endpoint URL, key, and auth type with the OmniEditor team using the form below.

Authentication

Pick one method, configure your receiver to check it, and share the same secret and auth type back to the team.

X-API-Key Header

Send the key in a custom header.

X-API-Key: omni_8f3c2a1b9e7d

Bearer Token

Send the token in the standard Authorization header.

Authorization: Bearer omni_8f3c2a1b9e7d

Request payload

OmniEditor sends a JSON POST to your endpoint. action is "publish" for new posts or "update" for existing ones (then include remote_id).

{ "action": "publish", "external_id": "art_8f3c2a", "remote_id": null, "article": { "title": "How Signal Tracking Shapes Weekly SEO Strategy", "slug": "signal-tracking-seo-strategy", "excerpt": "Why market signals deserve a seat in your editorial calendar.", "body_html": "<h2>...</h2><p>...</p>", "meta_description": "Use market signals to plan weekly SEO content.", "category": "SEO", "tags": ["seo", "content", "research"], "sources": ["https://example.com/source"], "featured_image_url": "https://cdn.../cover.png", "cta_text": "Request Access", "cta_url": "https://omni-editor.com/#pricing" } }

Payload shape

{
  "action": "publish" | "update",
  "external_id": "<article id>",
  "remote_id": "<remote id if updating>",
  "article": {
    "title", "slug", "excerpt",
    "body_html", "meta_description",
    "category", "tags", "sources",
    "featured_image_url", "cta_text", "cta_url"
  }
}

Receiver examples

Drop-in receivers that authenticate the request, upsert the post, and always return the public URL. Switch languages below.

<?php
// OmniEditor receiver — always returns the post public URL.
header('Content-Type: application/json');

// 1. Authenticate. Pick one method, store the secret server-side,
//    and share the same value + auth type with the OmniEditor team.
$apiKey = getenv('OMNI_API_KEY');

$xKey   = $_SERVER['HTTP_X_API_KEY'] ?? '';
$bearer = preg_replace('/^Bearer\s+/i', '', $_SERVER['HTTP_AUTHORIZATION'] ?? '');

if ($xKey !== $apiKey && $bearer !== $apiKey) {
  http_response_code(401);
  echo json_encode(['success' => false, 'error' => 'Unauthorized']);
  exit;
}

// 2. Read the article payload.
$payload = json_decode(file_get_contents('php://input'), true);
$article = $payload['article'];
$action  = $payload['action'];          // "publish" | "update"
$slug    = $article['slug'];

// 3. Create or update the post in your CMS (replace with your logic).
$postId = upsert_post($article, $payload['remote_id'] ?? null);

// 4. ALWAYS return the public URL so OmniEditor can confirm delivery.
$url = 'https://yourblog.com/' . $slug;

echo json_encode([
  'success'   => true,
  'remote_id' => (string) $postId,
  'url'       => $url,
]);

function upsert_post($article, $remoteId) {
  /* ...your CMS insert / update... */
  return $remoteId ?? uniqid();
}

The receiver must return the post’s public URL whenever the post is reachable — that’s how OmniEditor confirms delivery.

Response

Respond with JSON. Include url (the public post URL) and remote_id (your internal post id, so later updates target the same post).

{ "success": true, "remote_id": "12345", "url": "https://yourblog.com/signal-tracking-seo-strategy" }

On a bad key, return { "success": false, "error": "Unauthorized" } with a 401 status.

Share your destination

Once your receiver is live, send your endpoint URL, auth type, and API key back to the OmniEditor team. We’ll wire it up and start delivering articles.

Share your destination

Payload your receiver will get:

{
  "action": "publish" | "update",
  "external_id": "<article id>",
  "remote_id": "<remote id if updating>",
  "article": {
    "title", "slug", "excerpt",
    "body_html", "meta_description",
    "category", "tags", "sources",
    "featured_image_url", "cta_text", "cta_url"
  }
}

Respond with { success: true, remote_id, url }

Don’t have a receiver yet?

Request access and we’ll help you get wired up.

Black ink forming precise geometric shapes in water

Your next issue is waiting

Build an audience with something worth reading.