The fix: send a full MIME type in media[].type"image/png", "image/jpeg", "video/mp4". Sending the category "image" returns 422: media.0.Invalid media format type. And media must always be present on publish — send media: [] for text-only posts.

Symptom

Creating a social post via the GHL API with status: "published" fails with 422 media.0.Invalid media format type, while the identical payload saved as a draft succeeds.

Why drafts lie to you

Draft posts do not validate media at all. A create-then-delete draft test accepts every malformed media variant, so drafts are useless for validating payloads. Only status: "published" runs validation.

The correct payload

{ "status": "published",
  "media": [ { "url": "https://...", "type": "image/png" } ] }

Publishing is async

The create call returns before the platform accepts the post. Status moves in_progress → published (or failed with an error). Poll /posts/list ~45 seconds later; do not trust the create response alone.

How we hit it

An automated content pipeline posting daily to LinkedIn through GHL: drafts validated in testing, then production publishes silently failed. The MIME fix plus post-publish polling made it reliable.

Related landmines

All GoHighLevel landmines

We build white-label automation on GoHighLevel for agencies. What we build →