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

1

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.

2

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.

3

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.

4

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.

5

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

FieldTypeRequiredDescription
textstringyes*Post text (up to 4096 for TG, 4000 for Max, 15895 for VK)
entitiesarraynoIN-payload formatting in Telegram Bot API format (offset/length/type)
mediaarrayyes*Images/videos/audio (HTTPS URLs, up to 10 items)
buttonsarraynoURL buttons (rows × columns)
is_advertisementboolnoAdvertisement marker
ad_pause_minutesintnoAuto-pause duration for the target after publication (0-1440)
external_idstringnoUnique ID for idempotency
metadataobjectnoCustom 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

  1. Sign up for Crosslybot (Pro+ plan for webhook input)
  2. Create a webhook endpoint, copy the Bearer token
  3. Attach to a project with TG/VK/Max targets
  4. Test via sandbox: POST /v1/sandbox/test
  5. Integrate into your code

Webhook input is available on Pro, Maxi and Business plans.

Free plan

Ready to try?

Connect the bot in 2 minutes. Free plan — no cards, no signup.

More about the bot →