REST API for sending posts to Telegram, VK and Max from your backend
One webhook, three platforms. Bearer token, JSON, REST.
How to set up
Get a Bearer token
In Crosslybot create a webhook input in the Channels section. Bearer token (format crossly_live_<random>) is shown ONCE — save it in your service's environment variables.
Attach the webhook to a project
Create a cross-posting project, set the webhook as source, add target channels (Telegram, VK, Max or any combination). Configure AI, filters, signatures.
Implement sending from your code
POST to `https://wh.crosslybot.com/v1/webhooks/{endpoint_id}`. Headers: Authorization: Bearer <token>, Content-Type: application/json, Idempotency-Key: <uuid>. Body — JSON with text, media, entities, buttons, is_advertisement fields.
Handle the response
200 — post accepted and queued. 202 — post was already accepted (by Idempotency-Key). 4xx — validation error (details in JSON). 5xx — internal error, retry with exponential backoff.
Use sandbox for testing
POST `/v1/sandbox/test` validates payload without real publishing. Returns would_create_post + list of errors and warnings. Perfect for CI/CD smoke tests.
Features
Simple authentication
Bearer in Authorization header (simplifies integration with any SDK or script). Token rotation is instant.
Idempotency-Key out of the box
Stripe-style standard: pass Idempotency-Key (or external_id in payload) — repeated request with the same ID returns cached result. Safe retries.
Accepts Telegram Bot API entities (IN)
Incoming webhook accepts entities in Telegram Bot API format: type (bold, italic, code, text_link etc.), offset, length. If you already have code for sending to Telegram — it works with Crosslybot with almost no changes. Outgoing webhook delivers text + text_html (no entities).
crossly_live_/test_ prefixes
Test tokens have crossly_test_ prefix — easy to grep in logs. Live tokens: crossly_live_. No environment confusion.
FAQ
Where's the OpenAPI documentation?
OpenAPI 3 spec is available at https://wh.crosslybot.com/openapi.json (Phase 6 plans public Swagger UI on /docs). Already now you can inspect the payload schema via the sandbox tester.
What are the RPS limits?
Depends on the plan. Pro: burst 1/5 seconds + 300 requests/hour. Maxi: 1/2s + 1000/hour. Business: 1/1s + 5000/hour. On repeated violations the endpoint is temporarily paused with an owner notification — cleared from UI or via support.
Does the API support batch sending of multiple posts?
Not in MVP, one post per request. Batch endpoint (multiple posts per request) is on the roadmap. For now, send in a loop — the sequential queue guarantees order.
How to use the webhook from Python / Node.js / PHP?
Any HTTP client: requests (Python), node-fetch / axios (Node.js), Guzzle (PHP), standard libraries in Java/Go/Rust. Minimal example: POST with JSON, Authorization header — every language supports this. Examples will be in OpenAPI docs.
Does the webhook accept iframe/HTML embeds?
No. Webhook accepts only structured payload: text + entities + media[]. HTML parsing and rendering is the source's job (e.g. AI agent converts HTML to plain-text + entities before sending).
Crosslybot provides a simple REST API for developers: instead of integrating with three different APIs (Telegram Bot API, VK API, Max API) — one webhook URL and one Bearer token. One JSON request — post publishes to all configured platforms.
The API is designed for developer experience: incoming format accepts Telegram entities (offset/length/type) — reuse your TG code with minimal changes. Outgoing format delivers text + text_html — pick whatever fits your target. Standard HTTP codes, Idempotency-Key like Stripe, token prefixes like GitHub.
Minimal example (cURL)
curl -X POST https://wh.crosslybot.com/v1/webhooks/{endpoint_id} \
-H "Authorization: Bearer crossly_live_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 8f4a-1234-..." \
-d '{
"text": "Hello from API!",
"entities": [
{"type": "bold", "offset": 0, "length": 5}
],
"media": [
{"type": "photo", "url": "https://cdn.example.com/img.jpg"}
]
}'
Response — 200 OK + created post ID. Crosslybot processes the payload, runs it through AI/filters/signature and publishes to all project targets.
Payload structure
| Field | Type | Required | Description |
|---|---|---|---|
text | string | yes* | Post text (up to 4096 for TG, 4000 for Max, 15895 for VK) |
entities | array | no | IN-payload formatting in Telegram Bot API format (offset/length/type) |
media | array | yes* | Images/videos/audio (HTTPS URLs, up to 10 items) |
buttons | array | no | URL buttons (rows × columns) |
is_advertisement | bool | no | Advertisement marker |
ad_pause_minutes | int | no | Auto-pause duration for the target after publication (0-1440) |
external_id | string | no | Unique ID for idempotency |
metadata | object | no | Custom user data |
*at least one of text/media/buttons.
API response
{
"ok": true,
"id": "post_abc123",
"trace_id": "tr_...",
"queued_targets": 3
}
On validation error (4xx) — list of specific issues:
{
"ok": false,
"errors": [
"media[0]: type 'document' not supported",
"entity[2]: offset+length exceeds text length"
]
}
What sets Crosslybot REST API apart
- Three-platform unification: TG, VK, Max via one payload
- Bearer token — simple integration with LLM agents and no-code tools
- Idempotency-Key — safe retries, Stripe-style
- Accepts Telegram entities (IN) — most existing TG code is reusable. Outgoing webhook delivers text + text_html for any receiver platform.
- Built-in AI processing: translations, filters, replacements, signature
Getting started
- Sign up for Crosslybot (Pro+ plan for webhook input)
- Create a webhook endpoint, copy the Bearer token
- Attach to a project with TG/VK/Max targets
- Test via sandbox: POST /v1/sandbox/test
- Integrate into your code
Webhook input is available on Pro, Maxi and Business plans.
Ready to try?
Connect the bot in 2 minutes. Free plan — no cards, no signup.