Skip to content
Open app

Send a Telegram message

This guide shows how to enqueue an outbound Telegram message and then poll for its delivery status via the Public API.

All requests go to the base URL https://api.crmsolid.com and must include your API key as a bearer token. New here? Start with the Quickstart and Authentication guides.

Sends are asynchronous. When you call the API, the message is written to a queue and the endpoint returns immediately with a job in the queued state. A background job worker on the server picks up queued jobs and dispatches them through Telegram, respecting rate limits and flood-wait backoff. You then poll the job to see when it transitions to sent (or failed).

Send a POST to /v1/telegram/messages.

  1. Pick the account and recipient. accountId and text are always required. Provide exactly one recipient identifier — contactId, username, or telegramUserId.

    FieldTypeRequiredNotes
    accountIdintegerYesId of the Telegram account (owned by you) to send from.
    textstringYesMessage body. Maximum 4000 characters.
    contactIdintegerOne of threeCRM contact to message; the contact’s stored username / Telegram user id is used as the target.
    usernamestringOne of threeRecipient @username (leading @ is stripped server-side).
    telegramUserIdintegerOne of threeRecipient’s numeric Telegram user id.
    runAtstringNoScheduled delivery time (UTC, ISO-8601). Omit or set to null for immediate dispatch.
  2. Send the request.

    Terminal window
    curl -X POST https://api.crmsolid.com/v1/telegram/messages \
    -H "Authorization: Bearer csk_live_..." \
    -H "Content-Type: application/json" \
    -d '{
    "accountId": 7,
    "username": "john_doe",
    "text": "Hi from Acme Inc.!",
    "runAt": null
    }'
  3. Read the response. A successful enqueue returns 202 Accepted with the queued job. Save the id — you’ll use it to check status.

    {
    "id": 1024,
    "accountId": 7,
    "status": "queued",
    "runAt": "2024-05-01T08:00:00Z",
    "createdAt": "2024-04-30T18:00:00Z"
    }

To schedule a send instead of dispatching immediately, set runAt to a UTC ISO-8601 timestamp:

{
"accountId": 7,
"username": "john_doe",
"text": "Reminder: your trial ends tomorrow.",
"runAt": "2024-05-01T08:00:00Z"
}

Poll GET /v1/telegram/messages/{id} with the job id from the enqueue response. The status field moves through queuedsent, or to failed (in which case lastError explains why).

Terminal window
curl https://api.crmsolid.com/v1/telegram/messages/1024 \
-H "Authorization: Bearer csk_live_..."

The detail response includes updatedAt and lastError:

{
"id": 1024,
"accountId": 7,
"status": "sent",
"runAt": "2024-05-01T08:00:00Z",
"createdAt": "2024-04-30T18:00:00Z",
"updatedAt": "2024-05-01T08:00:05Z",
"lastError": null
}

Keep polling until status is no longer queued. Use a sensible interval and backoff — the worker processes the queue on a short cycle, not instantly.

async function waitForDelivery(jobId) {
while (true) {
const res = await fetch(
`https://api.crmsolid.com/v1/telegram/messages/${jobId}`,
{ headers: { Authorization: "Bearer csk_live_..." } },
);
const job = await res.json();
if (job.status !== "queued") return job; // "sent" or "failed"
await new Promise((r) => setTimeout(r, 5000));
}
}
  • Need a recipient first? See Sync contacts to create one and pass its id as contactId.
  • Browse every field, scope, and error code in the full API reference.