Developer Docs
A REST API for scripts and CI pipelines. An MCP endpoint for AI assistants — publish from Cursor, VS Code, and Claude Desktop without leaving your editor.
Quick start
Create an account
Sign up free. API key access is available on the Solo plan.
Generate an API key
Dashboard → API Keys → Create. Keys are prefixed omv_ and shown once.
Configure channels
Add credentials for your target platforms — Bluesky, dev.to, Mastodon, GitHub, etc.
Use the REST API from any HTTP client, CI pipeline, or server-side script.
Base URL: https://api.omnivocal.io/api/v1
All API requests require a Bearer token. Generate keys in the dashboard under API Keys (requires Solo plan). The key is shown only once — store it in your CI secrets.
Authorization: Bearer omv_YOUR_API_KEY
All errors return a JSON body with an error string and a standard HTTP status code.
| Status | Meaning |
|---|---|
| 400 | Bad request — validation error, invalid JSON |
| 401 | Missing or invalid API key |
| 403 | Plan limit reached or action not permitted |
| 404 | Resource not found |
| 413 | Payload too large (asset uploads) |
| 500 | Internal server error |
Publish content to one or more configured channels. Supports immediate publishing, future scheduling via publish_at, and Telegram approval flows.
| Field | Type | Req | Description |
|---|---|---|---|
| content.title | string | ✓ | Post title |
| content.body | string | ✓ | Post body — Markdown by default |
| content.body_format | markdown | html | Default: markdown | |
| content.media_urls | string[] | Image URLs. Free: max 1. Solo: max 4. Use upload_asset to host them. | |
| content.tags | string[] | Tags for blog platforms (dev.to max 4) | |
| content.canonical_url | string | Original URL when cross-posting — improves SEO | |
| targets[].channel | string | ✓ | github bluesky devto hashnode mastodon ghost slack discord brevo beehiiv threads telegram |
| targets[].publish_at | ISO 8601 | Schedule for later — omit for immediate | |
| options.require_approval | boolean | Send to Telegram for human approval first |
Example
curl -X POST https://api.omnivocal.io/api/v1/broadcast \
-H "Authorization: Bearer omv_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": {
"title": "Shipping v2.0",
"body": "## What is new\n\nFaster. More reliable.",
"tags": ["release"],
"canonical_url": "https://myblog.com/v2"
},
"targets": [
{ "channel": "bluesky" },
{ "channel": "devto" },
{ "channel": "slack" },
{ "channel": "github" }
]
}' Response — 201
{
"id": "01J...",
"status": "published",
"targets": [
{ "channel": "bluesky", "status": "success", "url": "https://bsky.app/..." },
{ "channel": "devto", "status": "success", "url": "https://dev.to/..." },
{ "channel": "slack", "status": "success" },
{ "channel": "github", "status": "success", "url": "https://github.com/..." }
]
}
Per-channel secrets. Encrypted at rest — secrets are never returned in GET responses.
Supported channels: github bluesky devto hashnode mastodon ghost slack discord brevo beehiiv threads telegram
/api/v1/credentials — list configured channels /api/v1/credentials/:channel — upsert credentials | Channel | Required fields |
|---|---|
| github | token (PAT), default_repo (owner/repo) |
| bluesky | identifier (handle), password (app password) |
| devto | api_key |
| hashnode | access_token, publication_id |
| mastodon | instance_url, access_token |
| ghost | url, admin_api_key |
| slack | webhook_url |
| discord | webhook_url |
| brevo | api_key, list_ids, sender_name, sender_email |
| telegram | bot_token, chat_id and/or publish_chat_id |
curl -X PUT https://api.omnivocal.io/api/v1/credentials/bluesky \
-H "Authorization: Bearer omv_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "identifier": "you.bsky.social", "password": "xxxx-xxxx-xxxx-xxxx" }' /api/v1/credentials/:channel — remove a channel Broadcast records with per-channel delivery statuses.
/api/v1/posts List posts, newest first. Query params: page (default 1), per_page (default 20, max 100).
/api/v1/posts/:id Single post with all target statuses and URLs.
/api/v1/posts/:id Delete a post record. Returns 403 if the post is already published — OmniVocal does not retract from external platforms.
Upload images and video to the OmniVocal CDN (Cloudflare R2). Returns a permanent public URL to use in broadcast as content.media_urls.
| Plan | Images | Video |
|---|---|---|
| Free | JPG, PNG, GIF, WebP — max 5 MB | Not available |
| Solo | JPG, PNG, GIF, WebP — max 10 MB | MP4, MOV, WebM — max 100 MB |
multipart/form-data (recommended)
curl -X POST https://api.omnivocal.io/api/v1/assets \ -H "Authorization: Bearer omv_YOUR_API_KEY" \ -F "file=@/path/to/screenshot.png"
Raw body — for large video / streaming
curl -X POST https://api.omnivocal.io/api/v1/assets \ -H "Authorization: Bearer omv_YOUR_API_KEY" \ -H "X-Filename: demo.mp4" \ -H "Content-Type: video/mp4" \ --data-binary @demo.mp4
Response — 201
{"url": "https://api.omnivocal.io/assets/usr_abc/screenshot-1743600000.png"}
OmniVocal exposes a Streamable HTTP MCP endpoint. Add it to your IDE to publish, commit files, and upload assets without leaving your AI assistant.
Endpoint: https://api.omnivocal.io/mcp
The same Bearer token auth applies. See the IDE Setup page in your dashboard for Cursor / VS Code / Claude Desktop config snippets.
The endpoint supports tools/list and tools/call via JSON-RPC 2.0 POST.
list_credentials no parameters Returns the channels you have configured. Always call this first — AI must not assume what channels are available before calling broadcast_post.
broadcast_post Publish content to one or more channels. Supports scheduling and Telegram approval.
| Parameter | Type | Req | Description |
|---|---|---|---|
| content.title | string | ✓ | Post title |
| content.body | string | ✓ | Markdown body. Inline images via  are fine. |
| content.body_format | markdown | html | Default: markdown | |
| content.media_urls | string[] | CDN URLs. Use upload_asset to host them first. | |
| content.tags | string[] | Tags for blog platforms | |
| content.canonical_url | string | Original URL for cross-post SEO | |
| targets[].channel | string | ✓ | From list_credentials output |
| targets[].publish_at | ISO 8601 | Schedule; omit for immediate | |
| options.require_approval | boolean | Route through Telegram first |
github_commit Create or update a file in a GitHub repository using your configured GitHub credentials.
| Parameter | Type | Req | Description |
|---|---|---|---|
| repo | string | ✓ | owner/repo |
| path | string | ✓ | File path, e.g. posts/2026-04-02.md |
| content | string | ✓ | Full file content |
| message | string | Commit message. Auto-generated if omitted. | |
| branch | string | Target branch. Default: main |
upload_asset Upload an image or video to the OmniVocal CDN. Returns a URL to use in broadcast_post as media_urls. Free: images max 5 MB. Solo: images 10 MB + video 100 MB.
| Parameter | Type | Req | Description |
|---|---|---|---|
| filename | string | ✓ | e.g. screenshot.png |
| data | string | ✓ | Base64-encoded file content |
| mime_type | string | ✓ | e.g. image/png, video/mp4 |
Start free — API key access is included in the Solo plan.