oqimDocs
API referenceConsole

Start here

  • Introduction
  • Getting started

Guides

  • Telegram accounts
  • Recipients
  • Campaigns
  • Scheduling
  • Webhooks
  • AI writing assistant

AI Seller

  • AI Seller
  • Channels
  • Live inbox
  • Past conversations and privacy
  • Business insights

API

  • Authentication
  • API reference
  • SDK
  • Errors
  • Rate limits

Trust and operations

  • Security
  • Compliance
  • Administration
Docs / Getting started

Start here

  • Introduction
  • Getting started

Guides

  • Telegram accounts
  • Recipients
  • Campaigns
  • Scheduling
  • Webhooks
  • AI writing assistant

AI Seller

  • AI Seller
  • Channels
  • Live inbox
  • Past conversations and privacy
  • Business insights

API

  • Authentication
  • API reference
  • SDK
  • Errors
  • Rate limits

Trust and operations

  • Security
  • Compliance
  • Administration

Getting started

A campaign goes through nine steps, from connecting an account to watching it deliver. This page walks through them in the console, then shows how to run Oqim on your machine with Docker Compose and the Telegram simulator.

Before you start#

  • You need a role that can do each step. Owners and Admins can do all of them. Managers can do every step except connecting accounts. Operators can launch, pause and resume campaigns but not create them. See roles and permissions.
  • An Owner or Admin must accept the acceptable-use policy in Settings → Policy. Until then, connecting accounts and launching campaigns fail with policy_not_accepted.
  • Every person you message needs a recorded basis for contact: they opted in, authorized contact, or already have a relationship with you. Oqim won't send to anyone else.

The nine steps#

  1. 1

    Connect a Telegram account

    In Accounts → Connect account, enter the phone number of an account your organization owns. Type the login code Telegram sends to that account, then its two-step verification password if it has one. The new account starts at the platform's default pace: 150 messages a day, at least 8 seconds apart. See Telegram accounts.

  2. 2

    Import recipients

    In Recipients → Import, upload a CSV with a Telegram ID or username per row and each person's consent status. The dry run reports invalid rows, duplicates, and people who are suppressed or opted out, before anything is saved. Commit when the report looks right. See Recipients.

  3. 3

    Create a campaign

    In Campaigns → New campaign, name it and choose the audience: any mix of lists, tags and individual recipients. Opted-out and suppressed people are left out automatically, and so are people with unknown consent unless your platform allows them.

  4. 4

    Write the message

    Up to 4,096 characters, or 1,024 when you attach a photo, document or video. Use formatting such as **bold** and variables such as {{first_name|there}}, and include {{opt_out_url}} so people can stop your messages. The preview renders the message for real recipients in your audience. See writing messages.

  5. 5

    Select accounts

    Choose which connected accounts send this campaign. Recipients are spread across them and each account keeps its own daily limit and interval, so adding accounts shortens delivery without making any single account send faster.

  6. 6

    Schedule

    Set the campaign's time zone, an optional start and end, the daily sending window and the weekdays it may send on. Windows can cross midnight. See Scheduling.

  7. 7

    Review

    Oqim runs the pre-launch checks: organization status, your permission, the policy, the accounts, the audience, message length, variables, the opt-out link, the schedule, your plan's quota and whether delivery fits before the end time. A failed check blocks launch; a warning doesn't. See pre-launch validation.

  8. 8

    Launch

    Launching runs the checks again, freezes the message and moves the campaign to SCHEDULED. When its start time has passed and its window is open, the scheduler moves it to RUNNING and sending begins.

  9. 9

    Monitor

    The campaign page shows delivery progress, a lane per account with each send, and every failure with its reason. Pause and resume whenever you need to. To follow along from your own systems, subscribe a webhook to campaign.* and message.* events.

Run Oqim locally#

The repository's Docker Compose file runs Postgres, Redis, the API, the scheduler, a worker and the web console. You need Docker with Compose v2. From the repository root:

Terminal
cp .env.example .env

# Prints APP_KEY, SESSION_KEY and INTERNAL_TOKEN: paste them into .env
docker compose run --rm --no-deps worker oqimctl gen-keys

docker compose up --build

Open http://localhost:3000 and create an organization, or load the demo tenant and create your platform administrator in a second terminal:

Terminal
# Demo organization "Silk Road Events": sign in as demo@oqim.dev / oqim-demo-2026
docker compose exec worker oqimctl seed-demo

docker compose exec worker oqimctl create-admin -email you@example.com -password 'a-long-passphrase'

The console forwards /api/v1 to the API, so the browser and your scripts use the same origin; its OpenAPI spec is at http://localhost:3000/docs/openapi.json. The admin console is at /admin and asks you to set up two-factor authentication on the first visit.

ServiceOn your machineWhat it does
weblocalhost:3000Console, admin console (/admin) and these docs (/docs)
apilocalhost:8087REST API (8080 inside the Compose network)
worker—Sends messages and holds Telegram sessions; its gateway on 8090 is internal only
scheduler—Starts and ends campaigns and hands each account its next message
postgreslocalhost:5447Primary database
redislocalhost:6397Queues, rate limits and live events

docker compose --profile monitoring up adds Prometheus on 9090 and Grafana on 3001. To work on the code with hot reload instead, run ./scripts/dev.sh backend (databases in Docker, Go services on the host, API on 8087) and ./scripts/dev.sh web.

Note

oqimctl seed-demo is for local development: its accounts carry simulator sessions, and its running campaign keeps sending while the worker runs with the simulator. Don't run it against production.

Simulator mode#

With TELEGRAM_DRIVER=simulator, the default, nothing reaches Telegram. The worker answers with the same error values Telegram uses, so cooldowns, restrictions and re-authentication go through the production code paths. Pacing is never simulated: the scheduler paces accounts exactly as it does in production. The console shows Simulator mode in its sidebar.

InputSimulated behavior
Any phone numberSign-in works. The login code is always 12345; anything else is PHONE_CODE_INVALID.
Phone number ending in 00Two-step verification is on; the password is password (hint: pw).
Phone number ending in 13The number is banned: sign-in fails with PHONE_NUMBER_BANNED.
Connected account whose number or display name ends in 13Restricted with PEER_FLOOD after 25 sends, so you can rehearse the restriction flow. The demo organization's Expo Desk 13 is one.
Username starting with privacyThe recipient's privacy settings refuse the message (USER_PRIVACY_RESTRICTED). Unreachable.
Username starting with blockedThe recipient blocked the account (USER_IS_BLOCKED). Unreachable.
Username starting with ghostNo such user (USERNAME_NOT_OCCUPIED). Unreachable.
Any other recipient93% delivered. The rest: privacy restrictions (4%), short FLOOD_WAITs of 3 to 20 seconds (2%) and timeouts (1%). Half of the timeouts happen after delivery, so the retry exercises duplicate protection.

Switching to real Telegram

TELEGRAM_DRIVER=mtproto sends real messages from real accounts. It needs TELEGRAM_APP_ID and TELEGRAM_APP_HASH from the platform operator's own application at my.telegram.org. Read Compliance first.

Next steps#

  • Automate imports and launches with the API, authenticated with an API key. The TypeScript SDK wraps it, and the OpenAPI 3.1 spec works with client generators and tools such as Postman.
  • Receive delivery results in your own systems with webhooks.
  • Running Oqim for others? Read Administration and Security.
PreviousIntroductionNext Telegram accounts