CMS integrations
Custom Integration
GrowGanic POSTs each finished article to a URL you control, signed and retried, so anything that can receive a request can be your destination.
A primary destination. Your article lives here and the canonical URL points at it, so this is the site Google credits. About 5 minutes.
#What connecting does
Every article GrowGanic finishes is POSTed as JSON to the endpoint you name. What happens after that is yours: a Next.js or Express app, Payload, Strapi, Directus, an internal tool, a Make, Zapier or n8n scenario, anything that can accept a request.
This is a primary destination, so articles delivered here carry the canonical URL. It is the right choice for a custom build with no traditional CMS behind it, which is the largest group of people who end up on this page.
The full payload schema, the signature algorithm, a worked verification handler and the retry table are on the webhook reference page. This page covers the connection itself.
#Before you start
- An endpoint reachable over https that answers a POST. It must be a public address: private, loopback, link-local and cloud metadata addresses are refused, and GrowGanic never follows a redirect, because a redirect is a way to send your payload somewhere you did not name.
#Connect
Set it up
- Paste the URL your endpoint listens on (Zapier, Make, or your own service) into the Endpoint URL field.
- Set a Signing Secret if your endpoint verifies signatures. We'll send
X-GrowGanic-Signature: t=<unix>,v1=<hmac>(Stripe-style) for replay-safe verification. - Each delivery includes
X-GrowGanic-Delivery-Id(unique per attempt) andX-GrowGanic-Event(publish | update | delete | test). Use the articleId in the body as your idempotency key. - We retry 5xx and 408 up to 3 times with exponential backoff, and honor
Retry-Afteron 429. Permanent 4xx (401, 403) marks your connection inactive so you see a 'Reconnect needed' badge.
What you paste
| Field | Required | Where to find it |
|---|---|---|
| Endpoint URL | Yes | Wherever your app listens. It has to be the final address: we do not follow redirects, and a redirect is reported as an error naming the destination so you can paste that instead. |
| Signing secret | Optional | Yours to invent. Leave it blank unless your endpoint verifies signatures. Set it and every delivery carries an HMAC header you can check. |
| Public article URL pattern | Optional | Under Advanced settings. The address each article ends up at on your site, with {slug} standing in for the slug. |
If it will not connect
- Public article URL pattern, under Advanced settings: if your app serves each article at a predictable address, give us the pattern, for example
https://your-app.com/blog/{slug}. It has to be https and it has to contain{slug}. - It is used for exactly one thing. When your endpoint accepts an article and its response never reaches us, we read that page, confirm your copy is really there, and record the delivery instead of sending the article a second time. Leave the pattern empty and that one case stays unresolved forever.
- Route shortens the slug? Write
{slug:50}and we cut the slug to that many characters before building the address, so a receiver that truncates still matches.
#Permissions we ask for
Every permission below is used by a call GrowGanic actually makes. We ask for nothing we do not use.
| Permission | Used for | Why |
|---|---|---|
| None | Nothing | GrowGanic holds no credential for your system and can read nothing from it. The connection is outbound only: we POST to the address you gave us. The optional signing secret is not access, it is a way for you to prove a request came from us. |
GrowGanic holds no key to your system and can read nothing from it. The only thing it ever fetches is the public article page, never any API of yours, and only in the one situation described under Publishing behaviour, and only when you have given it a URL pattern to read.
#What we write
| Field | What goes in it |
|---|---|
| event | article.publish, article.update or article.delete. |
| articleId | A stable id. Use it as your idempotency key. |
| article.title, .slug, .contentHtml, .excerpt | The article itself. |
| article.metaTitle, .metaDescription | The meta fields. |
| article.featuredImageUrl | The hero image address. |
| article.canonicalUrl | The canonical URL for this article. |
| X-GrowGanic-Signature | t=<unix>,v1=<hmac>, Stripe-style, when you set a signing secret. The timestamp is inside the signed payload, so a captured request cannot be replayed later. |
| X-GrowGanic-Delivery-Id and X-GrowGanic-Event | Unique per attempt, and the event name, so a log line is enough to tell two deliveries apart. |
Fields your setup does not have are skipped rather than guessed at, and the article publishes with the ones it does have.
The hero image
The hero is sent as a URL served from our CDN. Nothing is uploaded to you, because we have no idea what your storage looks like.
If you want it hosted on your side, download it from that URL when you receive the article. The address is stable.
To have GrowGanic record that your copy carries the right image, answer with the v6 confirmation shape described on the webhook reference page. Anything else is treated as unproven and the image is re-sent next time, which costs you nothing.
#Publishing behaviour
A create is sent EXACTLY ONCE. It is never blind-retried, because your receiver can commit an article and then lose its own response, and a retry would give you two copies of the same article. Updates and deletes do carry a bounded retry.
Retries on update and delete: three attempts with backoff, on 408 and 5xx and on network errors. A 429 honours your Retry-After once. A permanent 4xx switches the connection off so you see a Reconnect badge rather than silence.
The public article URL pattern exists for exactly one case: your endpoint accepted an article and its answer never reached us. Then we read that page, confirm your copy is really there, and record the delivery instead of sending it a second time. Leave the pattern empty and that one case stays unresolved forever.
Draft mode is not offered here, because we cannot know what your receiver does with a draft flag and will not promise on its behalf.
If this destination is ever unreachable, the article is not held. It publishes to your GrowGanic blog and moves here on its own once the connection is healthy again. GrowGanic never holds a finished article back waiting for you.
#Disconnect
Disconnecting stops the deliveries. Articles your endpoint already received are yours and nothing is recalled.
There is no credential to revoke on your side. If you want deliveries to stop immediately without touching GrowGanic, take the endpoint down: the failures switch the connection off on their own.
Open Integrations in GrowGanic, find this destination and click Disconnect. The stored credential is deleted from our database in the same step, not marked inactive. Articles already published stay exactly where they are, and they are yours.
#Troubleshooting
| What you see | Why | Fix |
|---|---|---|
| Your webhook URL redirected. | The address you gave forwards somewhere else, and we never send a payload on to a host you did not name. | Paste the final destination URL, which the message names for you. |
| Your webhook endpoint did not respond within 30 seconds. | The server is down, slow, or sitting behind a long redirect chain. | Answer fast and do the work afterwards. Accept the POST, queue it, return 200. |
| Could not reach your webhook URL. | DNS, TLS or the host being offline. | Try a curl to the same address from a terminal. If that fails, it is not us. |
| Your webhook receiver rejected the request with 401 or 403. | The signature check failed, or the endpoint does not allow POST from us. | Check the signing secret matches on both sides and that your handler accepts POST. The body of your own response is quoted back to you in the error. |
| The public article URL pattern is refused. | It has to be an https address containing {slug}. | Write it like https://your-app.com/blog/{slug}. If your route shortens the slug, write {slug:50} and we cut it to that length before building the address. |
Still stuck? Email [email protected] and tell us the sentence you are seeing. Or read the other destinations.