REST API · Votway

SMM panel API: orders and automation

Place orders from your own scripts and services. Create a key in Settings → API.

Authentication

Pass your API key in the header for catalog, balance, transactions, and orders.

X-API-Key: vw_your_key
Base URLhttps://votway.com/api/v1
Request example
POST /api/v1/orders
{
  "service_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "link": "https://t.me/channel",
  "quantity": 1000
}

Platforms and services

Platforms and categories first, then services. Orders use the service id (service_id). Check order_type: default — link and quantity; subscription — username plus extra.min/max/posts or a fixed link+quantity pack; autoclick — channel or chat_id; traffic — link, volume, and interval extras.

MethodPathAuthDescription
GET/catalog/platformsX-API-KeyStore platforms (Telegram, VK, …). Platform id is not sent when creating an order
GET/catalog/categoriesX-API-KeyCategories. Use platform and id with GET /catalog/services?category_id=
GET/catalog/services?category_id=X-API-KeyServices: id, order_type, min/max, price. Prices include the key owner's discounts
GET/catalog/services/{service_id}X-API-KeyOne service — take service_id from here for the order
POST/catalog/calculateX-API-KeyQuote: { service_id, quantity } → amount, currency

Account

MethodPathAuthDescription
GET/profile/balanceX-API-KeyCurrent balance (RUB)
GET/transactionsX-API-KeyTransaction history
GET/transactions/{transaction_id}X-API-KeySingle transaction

Orders

Cancel with POST /cancel when allow_user_cancel. Pause and resume with /stop and /start when can_stop / can_start. Edit autoclick and traffic with PATCH when can_edit. Poll GET for status; there is no webhook. refill is 501 for now.

MethodPathAuthDescription
POST/ordersX-API-KeyCreate an order: service_id, link/quantity or extra based on the service order_type
GET/ordersX-API-KeyList (limit≤300, offset, search, platform, status_group, order_type)
GET/orders/{order_id}X-API-KeyStatus, progress, can_stop/can_start/can_edit flags, child tasks
POST/orders/{order_id}/cancelX-API-KeyCancel when allow_user_cancel. Returns order, refund_amount, balance
POST/orders/{order_id}/stopX-API-KeyPause autoclick, traffic, or autopost when can_stop
POST/orders/{order_id}/startX-API-KeyResume when can_start
PATCH/orders/{order_id}X-API-KeyEdit autoclick/traffic when can_edit: clicks, interval, geo, source

Autoclick: channels

Private Telegram: add the bot as an admin, get connect-code and publish the code in a post in the channel itself → channels (chat_id) → POST /orders with chat_id. For a public channel, enter @username and use check-channel. MAX: connect-link → channels → order with platform=max and chat_id.

MethodPathAuthDescription
POST/orders/autoclick/check-channelX-API-KeyCheck a channel: service_id plus channel or chat_id
POST/orders/autoclick/telegram/connect-codeX-API-KeyPermanent personal code to publish in a post in a private Telegram channel
POST/orders/autoclick/telegram/channelsX-API-KeyConnected Telegram channels (optional refresh, chat_id)
POST/orders/autoclick/max/connect-linkX-API-KeyPersonal MAX connection link
POST/orders/autoclick/max/channelsX-API-KeyConnected MAX channels (optional refresh, chat_id)

Telegram · MAX

Autopost API

Connect Telegram and MAX from your service: link accounts, check channels, order subscriptions and manage publications.

Open Autopost methods in Swagger

Your customers: client_ref

Choose a permanent customer identifier such as customer_42: 1–64 ASCII letters, digits, hyphens or underscores. Linked accounts, channels and orders are isolated by client_ref within your account. Create the client with PUT before linking an account.

The reserved value self refers to your own resources, including the dashboard. Keys belonging to the same owner access the same clients within their scopes. Replacing a key does not require recreating clients.

Your key and shared balance

Create a personal key in the dashboard under Settings → API. Send X-API-Key from your server. Do not send an Authorization header alongside it or expose the key in your customers’ browsers. All orders are charged to the key owner’s balance in RUB.

Key scopes: catalog:read for the catalog and capabilities; autopost:read for reads; autopost:write for changes. Creating, renewing and cancelling orders also requires orders:write. GET /profile/balance requires balance:read.

From connection to the first publication

  1. Choose a service

    Get the service_id of an autopost service from the catalog. Call GET /autopost/capabilities?service_id=… for publication modes, available AI models and limits.

  2. Create a client

    PUT /autopost/clients/customer_42 with a name or an empty object creates the client context. Repeating PUT updates it.

  3. Confirm the account in the bot

    POST link-sessions returns a deep_link. Give it to your customer and poll GET link-sessions with the returned id until status=linked. If expired, create a new session. For MAX, set platform=max.

  4. Check the channel and choose sources

    Grant the bot the required permissions, then call channels/check. Look for permissions=ready and can_order=true. Save the response UUID id as channel_id. GET sources with service_id returns available sources; you can also provide your own HTTPS source URLs.

  5. Create an order

    Send service_id, channel_id, external_order_id, months and settings. Choose a schedule or timer. max_amount caps the charge; the example’s 1500.00 is an illustrative cap, not a service price.

  6. Wait for the result

    202 means the command was accepted. Poll the Location URL at the Retry-After interval until succeeded or failed. Use subscription_id from a successful operation to read the subscription, settings and queue. Read error if the operation failed.

Request examples

Paths are relative to the API domain. Replace the key, UUIDs, URLs, identifiers and spending cap with your values. The UUIDs below are illustrative. Use one Idempotency-Key per command.

1. Create a client and link an account

After POST, open the returned deep_link in the relevant messenger. Use the session id for GET. The user must confirm the link in the bot.

PUT /api/v1/autopost/clients/customer_42
X-API-Key: vw_your_key
Content-Type: application/json

{
  "name": "Customer 42"
}

POST /api/v1/autopost/clients/customer_42/link-sessions
X-API-Key: vw_your_key
Idempotency-Key: link-customer42-001
Content-Type: application/json

{
  "service_id": "11111111-1111-4111-8111-111111111111",
  "platform": "telegram"
}

GET /api/v1/autopost/clients/customer_42/link-sessions/{id}
X-API-Key: vw_your_key
2. Connect a channel and list sources

Use the channel UUID returned by the check as channel_id and catalog source UUIDs as source_ids. Messenger chat_id values cannot replace these UUIDs.

POST /api/v1/autopost/clients/customer_42/channels/check
X-API-Key: vw_your_key
Idempotency-Key: check-customer42-001
Content-Type: application/json

{
  "service_id": "11111111-1111-4111-8111-111111111111",
  "platform": "telegram",
  "target": "https://t.me/your_channel"
}

GET /api/v1/autopost/clients/customer_42/sources?service_id=11111111-1111-4111-8111-111111111111&kind=catalog
X-API-Key: vw_your_key
3. Order a subscription with a schedule

This example uses new and old publications, every Monday at 09:00 and within 17:00–19:00 Moscow time. Add slots to days for other weekdays.

POST /api/v1/autopost/clients/customer_42/orders
X-API-Key: vw_your_key
Idempotency-Key: order-customer42-001
Content-Type: application/json

{
  "service_id": "11111111-1111-4111-8111-111111111111",
  "channel_id": "22222222-2222-4222-8222-222222222222",
  "external_order_id": "order-2026-001",
  "months": 1,
  "max_amount": "1500.00",
  "settings": {
    "source_selection": {
      "type": "catalog",
      "source_ids": [
        "33333333-3333-4333-8333-333333333333"
      ]
    },
    "queue_mode": "new_and_old",
    "publication": {
      "mode": "schedule",
      "timezone": "Europe/Moscow",
      "days": {
        "1": [
          {
            "at": "09:00"
          },
          {
            "from": "17:00",
            "to": "19:00"
          }
        ]
      }
    }
  }
}
4. Check the operation, order and queue

The first lines show response headers; the rest are requests. Wait for the operation’s final status, then use its order_id and subscription_id. pending and reconciling mean the command is still in progress.

HTTP/1.1 202 Accepted
Location: /api/v1/autopost/clients/customer_42/operations/{id}
Retry-After: 2

GET /api/v1/autopost/clients/customer_42/operations/{id}
X-API-Key: vw_your_key

GET /api/v1/autopost/clients/customer_42/orders/{order_id}
X-API-Key: vw_your_key

GET /api/v1/autopost/clients/customer_42/subscriptions/{subscription_id}/queue
X-API-Key: vw_your_key
5. Switch a subscription to a timer

Read the subscription first. Send its ETag as If-Match, including quotes; 1 is only an example. PATCH returns 202: wait for the operation to finish, then check applied_settings_revision.

GET /api/v1/autopost/clients/customer_42/subscriptions/{id}
X-API-Key: vw_your_key

HTTP/1.1 200 OK
ETag: "1"

PATCH /api/v1/autopost/clients/customer_42/subscriptions/{id}/settings
X-API-Key: vw_your_key
If-Match: "1"
Content-Type: application/json

{
  "publication": {
    "mode": "ad_timer",
    "interval_min": 30,
    "interval_max": 60
  }
}
Custom sources and publication signatures

Use this as the settings object when ordering, or as a settings PATCH body. Send source_selection together with source_signature_settings for new sources. Each signature override key is a custom source URL or a catalog source UUID. This example queues only new publications.

{
  "source_selection": {
    "type": "custom",
    "urls": [
      "https://t.me/your_source"
    ]
  },
  "queue_mode": "new",
  "publication": {
    "mode": "ad_timer",
    "interval_min": 30,
    "interval_max": 60
  },
  "signature_settings": {
    "mode": "append",
    "text": "Our channel",
    "url": "https://t.me/your_channel"
  },
  "source_signature_settings": {
    "https://t.me/your_source": {
      "mode": "replace",
      "url": "https://t.me/your_channel"
    }
  }
}

Integration rules

Retrying requests
Every POST requires Idempotency-Key: 1–128 ASCII letters, digits or . _ : -. After a timeout, retry the same URL with the same key and body. A different body with the same key returns 409 idempotency_conflict. Use a new key for a new command. PUT and DELETE do not require this header.
Your order reference and spending cap
external_order_id is required for each order and renewal: 1–128 ASCII letters, digits or . _ : -. It is unique within client_ref. Repeating the same parameters returns the original operation; different parameters cause external_order_conflict. max_amount is a string with two decimal places; a higher price causes price_changed.
Updating settings
PATCH requires If-Match from GET subscription. A missing header returns 428; an outdated version returns 412. Read the settings again and reconcile your changes. Send each changed section in full; omitted sections are preserved. null is not accepted. Also check the subscription’s actions.
Sources and AI
Choose one source_selection type: catalog with source_ids, or custom with urls. Custom sources support HTTPS URLs on t.me, telegram.me and max.ru. Prompts, models and individual AI settings are managed by an administrator. Do not send ai_settings or source_settings when creating an order or updating settings, even as empty objects: the request will be rejected. The plan's AI processing uses the saved settings.
Linked signatures
signature_settings.mode: off disables the feature, remove deletes a detected signature, replace replaces it only when found, and append always adds yours. text is the clickable label (defaults to the channel name), url is the destination or invitation (required for private channels). Detection covers a separate short final line linking to a Telegram/MAX channel. source_signature_settings fully overrides settings for a source; mode: off disables the shared rule. Changes affect unsent posts and do not bypass other ad filters.
Schedule and timer
schedule requires timezone and days. Weekdays: 1 is Monday, 7 is Sunday. Each slot has at or a from/to range in HH:MM format; dates keys use YYYY-MM-DD. ad_timer intervals are in minutes, defaulting to 30–60. queue_mode defaults to new_and_old; new selects only new publications.
Subscriptions and the queue
The subscription list defaults to active and paused; status=all includes other states. publish-next sends the next queued post. delivery_unknown means one post's delivery is unconfirmed: it is not retried and does not block subsequent publications. Use summary and empty_reason to diagnose an empty queue. Check can_cancel before cancelling, and refunded_amount on the order for refunds.
Lists and status polling
Lists return data and next_cursor. Pass the cursor unchanged with the same filters until it is null. limit is 1–100, default 50. Webhooks are not available in this release: poll statuses with GET.
Autopost errors
Errors contain an error object with code, message, request_id, retryable and fields. 401: key; 403: insufficient scopes; 402: balance; 404: resource unavailable in this context; 409: conflict; 422: invalid fields. For 429, follow Retry-After; for 503, retry after a delay with the same key. Save X-Request-ID for support.
Request limits
Limits apply both per key and across its owner’s account. Creating link sessions and checking channels have separate limits. Extra keys do not increase the owner’s total limit; the API returns 429 when a limit is reached.
All 25 Autopost operations

Prefix the paths below with /api/v1. See Swagger for exact parameters, required fields, key scopes and response schemas. capabilities, accounts, channels and sources require service_id; deleting an account or channel also requires service_id in the query.

  • GET
    /autopost/capabilities

    Service modes, platforms, AI models and limits

  • GET
    /autopost/clients

    Integration clients

  • PUT
    /autopost/clients/{client_ref}

    Create a client or update its name

  • GET
    /autopost/clients/{client_ref}

    Get a client

  • POST
    /autopost/clients/{client_ref}/link-sessions

    Create a linking session

  • GET
    /autopost/clients/{client_ref}/link-sessions/{id}

    Check account confirmation

  • GET
    /autopost/clients/{client_ref}/accounts

    Linked accounts

  • DELETE
    /autopost/clients/{client_ref}/accounts/{id}

    Unlink an account

  • GET
    /autopost/clients/{client_ref}/channels

    Channels and their availability for orders

  • POST
    /autopost/clients/{client_ref}/channels/check

    Connect a channel and check permissions

  • DELETE
    /autopost/clients/{client_ref}/channels/{id}

    Disconnect an unused channel

  • GET
    /autopost/clients/{client_ref}/sources

    Catalog and custom sources

  • POST
    /autopost/clients/{client_ref}/orders

    Create an order; returns an operation

  • GET
    /autopost/clients/{client_ref}/orders

    List orders or find one by external_order_id

  • GET
    /autopost/clients/{client_ref}/orders/{id}

    Order status, charge and subscription

  • POST
    /autopost/clients/{client_ref}/orders/{id}/cancel

    Cancel an order when can_cancel allows

  • GET
    /autopost/clients/{client_ref}/subscriptions

    Subscriptions; defaults to active and paused

  • GET
    /autopost/clients/{client_ref}/subscriptions/{id}

    State, settings, ETag and available actions

  • PATCH
    /autopost/clients/{client_ref}/subscriptions/{id}/settings

    Update settings using If-Match

  • POST
    /autopost/clients/{client_ref}/subscriptions/{id}/pause

    Pause publications

  • POST
    /autopost/clients/{client_ref}/subscriptions/{id}/resume

    Resume publications

  • POST
    /autopost/clients/{client_ref}/subscriptions/{id}/publish-next

    Send the next queued post

  • POST
    /autopost/clients/{client_ref}/subscriptions/{id}/renewals

    Renew a subscription

  • GET
    /autopost/clients/{client_ref}/subscriptions/{id}/queue

    Publications and queue diagnostics

  • GET
    /autopost/clients/{client_ref}/operations/{id}

    Check command execution

This release supports source selection, schedules, timers and publication signatures. AI prompts are editable only by an administrator. Separate source management, schedule template APIs and webhooks are not part of this contract yet.

Swagger

Interactive reference: every method, request and response fields, and example bodies. Try requests with your API key.

Errors and limits

Catalog and general order methods return errors with detail. The Autopost API uses the error object described above. 401 — missing or invalid key. 429 — wait and retry. POST /orders/{id}/refill returns 501. Balance top-up is not available with an API key.