Le canal Custom ne publie sur aucun réseau. Il envoie chaque publication programmée, en JSON, à une URL dont vous êtes propriétaire, et la suite dépend de votre code.

Utilisez-le pour un CMS auquel Ocoya ne se connecte pas, un générateur de site statique, une file de relecture interne, ou tout ce que vous préférez construire plutôt qu’attendre.

Connecter un endpoint

La boîte de dialogue Connect a custom destination avec les champs Name, Publish URL et Delete URL (facultatif) à gauche, un panneau gris à droite intitulé What your endpoint should reply montrant un extrait JSON renvoyant une url, et un bouton Connect destination

Le formulaire de connexion. Le panneau à côté des champs est le contrat de réponse — un code 2xx, et l’adresse vers laquelle faire le lien.

1

Ouvrir Channels

Sélectionnez Channels dans la barre latérale gauche, puis Connect channel.

2

Choisir Custom

Choisissez Custom dans le panneau Add a connection.

3

Lui donner un nom

Donnez-lui un nom que vous reconnaîtrez dans la liste des canaux, par exemple Mon blog. Ce n’est qu’une étiquette.

4

Saisir votre URL de publication

L’URL complète, schéma compris — https://example.com/hooks/content. Elle doit être accessible depuis les serveurs d’Ocoya : une adresse sur votre propre machine ou dans un réseau privé ne fonctionnera pas.

Si votre site redirige — example.com vers www.example.com, ou http vers https — les deux formes fonctionnent. Ocoya suit la redirection après avoir vérifié la nouvelle adresse comme il a vérifié la première.

5

Facultatif : ajouter une URL de suppression

Sous Advanced options. Une seconde adresse, utilisée quand une publication est supprimée dans Ocoya — https://example.com/hooks/content/delete. Laissez-la vide et la suppression d’une publication dans Ocoya la laisse là où elle a été publiée.

Ce doit être une URL différente de la précédente. Votre endpoint de publication crée quelque chose avec POST ; si la suppression arrivait au même endroit, elle créerait une seconde copie sur tout récepteur qui ne vérifie pas le nom de l’événement.

6

Facultatif : ajouter des en-têtes

Également sous Advanced options. La plupart des endpoints veulent savoir que la requête vient de vous avant de l’accepter — ajoutez Authorization avec la valeur Bearer your-token, ou l’en-tête que vérifie votre récepteur. Chacun est envoyé avec chaque requête — vers les deux URL.

Sans en-tête d’autorisation, l’URL est le seul identifiant — quiconque la découvre peut publier sur votre endpoint. Ajoutez-en un, ou au minimum utilisez un chemin long et impossible à deviner.

Les valeurs des en-têtes sont stockées comme des identifiants et ne sont jamais renvoyées au navigateur : le formulaire de connexion affiche donc une section Headers vide, même pour une destination qui en a. Reconnecter la même URL remplace tout l’ensemble — saisissez de nouveau chaque en-tête que vous voulez conserver.

Ce que reçoit votre endpoint

Un POST avec Content-Type: application/json. Il contient ce dont un blog a besoin, et rien d’autre :

{
  "event": "post.published",
  "publishedAt": "2026-09-17T09:00:00.000Z",
  "post": {
    "id": "clx…",
    "title": "Three labels, one warmer palette",
    "caption": "Testing a softer set of creams…",
    "image": "https://…/image.jpg"
  }
}
ChampCe que c’est
post.idL’identifiant Ocoya de cette publication. Il reste identique si une livraison est retentée : utilisez-le comme clé pour mettre à jour plutôt que de publier une seconde copie
post.titleLe titre, ou null s’il n’y en avait pas
post.captionLe corps, exactement tel qu’il a été rédigé. En Markdown si vous avez écrit en Markdown
post.imageLa première image de la publication, sous forme d’URL à récupérer — téléchargez-la, ne la liez pas en direct. null s’il n’y en a pas. Les vidéos ne sont pas envoyées
post.optionsLes champs d’article, quand la publication en a. Listés ci-dessous

Contenu de post.options

Seul un article en a — un article rédigé par une campagne de blog. Une publication faite à la main n’en a aucun, et options est tout simplement omis. Considérez chaque champ comme facultatif.

ChampTypeCe que c’est
markdownModebooleantrue quand post.caption est en Markdown. À afficher en conséquence
slugstringUn slug compatible avec les URL, dérivé du titre — why-your-content-is-not-converting. À vous de l’utiliser ou de l’ignorer
excerptstringUn résumé d’une ou deux phrases, pour une carte ou un flux
seoTitlestringJusqu’à 70 caractères, pour <title>
seoDescriptionstringJusqu’à 200 caractères, pour <meta name="description">
tagsstring[]Les tags de l’article. Généralement un seul
readingMinutesnumberCalculé à partir du corps final

Un article arrive sous cette forme :

{
  "event": "post.published",
  "publishedAt": "2026-09-22T09:00:00.000Z",
  "post": {
    "id": "clx…",
    "title": "Why your content is not converting",
    "caption": "You're posting every day and still refreshing an empty inbox.\n\n## The three pillars\n\n- A clear offer, repeated\n- One place to send people\n",
    "image": "https://…/cover.png",
    "options": {
      "markdownMode": true,
      "slug": "why-your-content-is-not-converting",
      "excerpt": "Volume is rarely the problem. Nothing you publish asks anybody to do anything.",
      "seoTitle": "Why your content is not converting",
      "seoDescription": "Volume is rarely the problem. Here is the system that fixes it.",
      "tags": ["content-marketing"],
      "readingMinutes": 7
    }
  }
}

post.caption est en Markdown quand markdownMode vaut true. La publier sans l’interpréter affiche ## The three pillars sur votre site tel quel — exactement comme c’est écrit.

Il vous faut quelque chose qui n’est pas là ? Dites-le-nous. Les champs sont ajoutés quand un récepteur en a besoin, plutôt qu’envoyés au cas où.

Supprimer une publication

Supprimer une publication dans Ocoya la supprime sur les réseaux où elle a été publiée. Une destination personnalisée est votre système : Ocoya ne peut donc que l’en informer — ce qu’il fait par un POST vers l’URL de suppression, si vous en avez fourni une.

Le corps est de nouveau la publication publiée, avec trois ajouts : le nom de l’événement, les horodatages et — le seul champ dont vous avez besoin — l’id que votre endpoint a renvoyé lors de la publication.

{
  "event": "post.deleted",
  "id": "9f2c1a",
  "publishedAt": "2026-09-22T09:00:00.000Z",
  "deletedAt": "2026-09-28T14:12:00.000Z",
  "post": {
    "id": "clx…",
    "title": "Why your content is not converting",
    "caption": "…",
    "image": null,
    "options": { "slug": "why-your-content-is-not-converting" }
  }
}

Supprimez par id — l’identifiant que votre endpoint a renvoyé lors de la publication, rendu tel quel au premier niveau pour qu’il n’y ait rien à extraire d’une adresse. L’url que vous avez renvoyée n’est pas envoyée : un endpoint qui supprime avec son propre id n’a aucun besoin d’une adresse qu’il connaît déjà.

Sans URL de suppression configurée, rien n’est envoyé. La publication est supprimée dans Ocoya et le canal signale que sa copie est toujours en ligne, plutôt que de ne rien faire en silence.

Répondez par n’importe quel code 2xx, comme pour une publication. Si la publication a déjà disparu de votre côté, répondez 404 ou 410 et Ocoya l’enregistre comme déjà supprimée plutôt que comme un échec. Toute autre réponse est signalée sur la publication, et la publication est de toute façon supprimée dans Ocoya : une destination qui refuse n’est jamais une raison de conserver une publication que vous avez demandé de supprimer.

Ce qu’Ocoya attend en retour

Répondez avec n’importe quel statut 2xx. Tout le reste est enregistré comme une publication échouée, et le statut ainsi que le corps de la réponse s’affichent sur la publication pour que vous voyiez ce que votre endpoint a répondu.

Renvoyer un id et une url

Votre endpoint doit répondre avec les deux, en JSON :

{
  "id": "9f2c1a",
  "url": "https://yourblog.com/post"
}
ChampCe que c’estCe qu’Ocoya en fait
idVotre propre identifiant pour ce que vous venez de créer — un id de ligne, un id de documentLe renvoie à votre URL de suppression sous le nom id. C’est par lui que vous supprimez.
urlL’adresse à laquelle vous avez publiéDevient le lien View post de la publication

Les deux sont obligatoires. Un 2xx sans eux est enregistré comme une publication échouée, et le message l’indique sur la publication — y compris que le contenu existe peut-être déjà à votre destination, de sorte que republier à l’aveugle créerait une seconde copie.

url est la seule clé lue pour l’adresse — permalink était accepté comme synonyme dans les versions précédentes et ne l’est plus.

Renvoyez les deux dans la même réponse. Ocoya les lit une seule fois, quand votre endpoint répond ; il n’y a pas de callback pour les envoyer ensuite, donc un endpoint qui met le travail en file d’attente doit connaître son id et son adresse finale avant de répondre, pas après.

Votre endpoint dispose de 30 secondes pour répondre. Faites le travail lent après avoir répondu plutôt qu’avant : accusez réception de la requête, puis traitez-la.

Une redirection est suivie plutôt que traitée comme un échec, tant que l’adresse visée passe la même vérification que l’originale — accessible publiquement, et épinglée sur ce vers quoi elle se résout. La méthode est conservée : votre endpoint reçoit donc toujours un POST avec le corps. La limite est de trois sauts.

Limites

Titre300 caractères
Corps200 000 caractères
Médias20 éléments
Délai d’attente30 secondes
En-têtesJusqu’à 10, valeurs de 2 000 caractères

Aucun fournisseur ne se trouve derrière un webhook, il n’y a donc rien de réel à valider : vous possédez la partie réceptrice et décidez de ce qu’elle accepte. Ce sont des garde-fous plutôt que des limites : assez larges pour un long article avec ses médias, assez étroits pour qu’une génération qui s’emballe soit arrêtée dans le composer plutôt qu’à votre endpoint.

Problèmes fréquents

“A destination URL must start with http:// or https://.” L’URL n’a pas de schéma. Ajoutez-le.

“”Content-Type” is set by Ocoya and cannot be overridden.” Quelques en-têtes décrivent la requête elle-même au lieu de l’authentifier — les en-têtes de contenu, Host, Connection, Transfer-Encoding. Ocoya les définit, vos propres en-têtes ne peuvent donc pas les remplacer.

“”…” is not a valid header name.” Un nom d’en-tête est composé de lettres, de chiffres et de tirets. Un espace ou deux-points dans le champ du nom signifie généralement que toute la ligne Name: value y a été collée — le nom va dans le champ de gauche, la valeur dans celui de droite.

“That is not a valid URL.” L’adresse n’a pas pu être analysée. Vérifiez les fautes de frappe et les espaces parasites.

“Your endpoint could not be reached. Check the URL is correct and publicly accessible.” Le DNS n’a pas résolu l’adresse ou la connexion a été refusée. Un endpoint sur localhost ou sur un réseau privé n’est pas accessible depuis Ocoya.

“Your endpoint answered 200 but did not return id or url.” La requête a atteint votre endpoint et il l’a acceptée, mais la réponse ne contenait pas l’un des champs obligatoires, ou les deux. Ocoya l’enregistre comme une publication échouée car, sans id, il n’y aura rien à utiliser pour supprimer plus tard.

Notez que le contenu existe peut-être déjà à votre destination — l’endpoint a bien répondu avec succès. Vérifiez avant de republier, sinon vous aurez deux copies.

“This destination has no delete endpoint.” Une publication a été supprimée dans Ocoya et ce canal n’a pas d’URL de suppression : rien n’a été envoyé et la copie à votre destination est toujours là. Reconnectez la destination avec une URL de suppression pour changer cela.

“Your endpoint did not respond in time.” Il a mis plus de 30 secondes. Accusez réception d’abord, traitez ensuite.

“Your endpoint redirected to https://…” La redirection est sortie de l’adresse que vous avez donnée — un autre hôte ou un autre schéma qu’Ocoya n’a pas pu revérifier, ou une adresse qui se résolvait vers un réseau privé. Utilisez l’adresse qui répond directement. Une redirection qui reste sur une adresse publiquement accessible est suivie pour vous, jusqu’à trois sauts.

“Your endpoint returned 500: …” Votre code a levé une erreur. Le détail après le statut est ce que votre endpoint a renvoyé, tronqué.

À lire aussi