POSTs each scheduled post to it as JSON, and your code decides what publishing means — an article in your CMS, a row in a database, a message on a queue.
This page is the contract your endpoint has to satisfy. For the full request body, see Custom (webhook) in the help center.
Custom destinations are connected in the Ocoya app — Channels → Connect channel → Custom. There is no REST or MCP endpoint that connects one, so this page describes the endpoint you write, not one you call.
What Ocoya sends
APOST with a JSON body and Content-Type: application/json, plus any headers you configured on the channel.
What your endpoint must reply
Three things, all required. A publish missing any of them is recorded as failed.1. A 2xx status
Anything else is recorded as a failed publish, and the status and response body are shown on the post so you can see what your endpoint said.2. An id
Your own identifier for what you just created — a database row id, a CMS document id, whatever you would look the record up by. Ocoya stores it and sends it back to your delete URL, so this is what you delete by.
3. A url
The address you published to. It becomes the post’s View post link in Ocoya.
Both are read from this reply only. There is no callback to send them in afterwards, so an endpoint that queues the work has to know its id and address before it answers rather than after the work finishes.
2xx without them, Ocoya records the publish as failed and says so on the post. The content may well exist at your destination at that point — the message says as much, because republishing blindly would create a second copy.
Timing
Your endpoint has 30 seconds to respond. Acknowledge the request first and do the slow work afterwards, rather than the other way round. A redirect is followed rather than treated as a failure, as long as the address it points at passes the same checks the original did. The method is kept, so your endpoint still receives aPOST with the body. Three hops is the limit.
Deleting
If the channel has a delete URL, deleting a post in Ocoya sends apost.deleted request there carrying the id you returned when it published:
id is at the top level and on its own — the identifier you issued, with nothing to parse and no wrapper to reach through. The url you returned is not sent back: an endpoint deleting by its own id has no use for an address it already knows.
Answer any 2xx. If the post is already gone on your side, 404 or 410 is recorded as already deleted rather than as a failure. The post is deleted in Ocoya either way.
Related
Custom (webhook)
The full payload, headers, limits and common problems.