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.
How sending works
Section titled “How sending works”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).
Enqueue a message
Section titled “Enqueue a message”Send a POST to /v1/telegram/messages.
-
Pick the account and recipient.
accountIdandtextare always required. Provide exactly one recipient identifier —contactId,username, ortelegramUserId.Field Type Required Notes accountIdinteger Yes Id of the Telegram account (owned by you) to send from. textstring Yes Message body. Maximum 4000 characters. contactIdinteger One of three CRM contact to message; the contact’s stored username / Telegram user id is used as the target. usernamestring One of three Recipient @username(leading@is stripped server-side).telegramUserIdinteger One of three Recipient’s numeric Telegram user id. runAtstring No Scheduled delivery time (UTC, ISO-8601). Omit or set to nullfor immediate dispatch. -
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}'const res = await fetch("https://api.crmsolid.com/v1/telegram/messages",{method: "POST",headers: {Authorization: "Bearer csk_live_...","Content-Type": "application/json",},body: JSON.stringify({accountId: 7,username: "john_doe",text: "Hi from Acme Inc.!",runAt: null,}),},);const job = await res.json();console.log(job.id, job.status); // -> 1024 "queued"import requestsres = requests.post("https://api.crmsolid.com/v1/telegram/messages",headers={"Authorization": "Bearer csk_live_..."},json={"accountId": 7,"username": "john_doe","text": "Hi from Acme Inc.!","runAt": None,},)job = res.json()print(job["id"], job["status"]) # -> 1024 "queued" -
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"}
Schedule for later
Section titled “Schedule for later”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"}Check delivery status
Section titled “Check delivery status”Poll GET /v1/telegram/messages/{id} with the job id from the enqueue response.
The status field moves through queued → sent, or to failed (in which case
lastError explains why).
curl https://api.crmsolid.com/v1/telegram/messages/1024 \ -H "Authorization: Bearer csk_live_..."const res = await fetch( "https://api.crmsolid.com/v1/telegram/messages/1024", { headers: { Authorization: "Bearer csk_live_..." } },);
const job = await res.json();console.log(job.status, job.lastError);import requests
res = requests.get( "https://api.crmsolid.com/v1/telegram/messages/1024", headers={"Authorization": "Bearer csk_live_..."},)
job = res.json()print(job["status"], job["lastError"])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}Poll until terminal
Section titled “Poll until terminal”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)); }}import timeimport requests
def wait_for_delivery(job_id): while True: res = requests.get( f"https://api.crmsolid.com/v1/telegram/messages/{job_id}", headers={"Authorization": "Bearer csk_live_..."}, ) job = res.json()
if job["status"] != "queued": return job # "sent" or "failed" time.sleep(5)Next steps
Section titled “Next steps”- 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.