← All posts
Tutorial

Telegram Group Join Requests: Build a Reliable Approval Queue

A reliable Telegram group approval queue should not depend on push events alone. List pending requests on a schedule, treat each returned request id as the member identifier for moderation, and submit explicit approve or reject actions. A group.join_request webhook can refresh the queue quickly, but polling remains the source of truth because that push signal is best-effort.

Key takeaways

  • Telegram’s official Bot API can expose chat_join_request updates when the bot is an administrator with the can_invite_users right.
  • In UnifyPort, enable approval with group_id and enabled: true, then list the pending queue with the same group_id.
  • Use the returned item id values as member_ids when approving or rejecting requests.
  • Treat group.join_request as a low-latency hint. Always reconcile by listing pending requests.
  • Keep a human decision step unless your acceptance policy is narrow, explicit, and auditable.

Choose the identity model before writing the queue

There are two sensible starting points.

If a bot identity is acceptable, Telegram’s official Bot API already defines ChatJoinRequest, approveChatJoinRequest, and declineChatJoinRequest. The bot must be an administrator and needs the can_invite_users administrator right. This is the best fit when the group is intentionally bot-managed and Telegram-only.

If moderation must operate through an existing Telegram account or share an integration style with other messaging work, a connected UnifyPort messaging account gives you group actions through one API. Before choosing, review the difference between an API ID/API hash and a BotFather token in Telegram API credentials explained.

Do not mix these models accidentally. A bot token represents a bot; an API ID and hash identify a Telegram client application; a connected messaging account represents the account your UnifyPort calls act through.

Build the Telegram group join-request approval queue

1. Turn on approval mode

The group must require approval before a pending queue can exist. Call the documented approval-mode route with the connected account ID, target group_id, and a boolean enabled value:

curl -X POST \
  "https://api.unifyport.ai/v1/accounts/<ACCOUNT_ID>/groups/join-approval-mode" \
  -H "X-Api-Key: <YOUR_API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "group_id": "group_example",
    "enabled": true
  }'

The action requires administrator permission in the group. Keep this configuration operation separate from the recurring moderation worker; the worker should not toggle group policy every time it runs. See Set group join approval mode for the current request contract.

2. Poll the pending list as the source of truth

Request the pending queue by passing group_id as a query parameter:

curl \
  "https://api.unifyport.ai/v1/accounts/<ACCOUNT_ID>/groups/join-requests?group_id=group_example" \
  -H "X-Api-Key: <YOUR_API_KEY>"

Store only the moderation state your application needs: the returned request ID, the target group, the decision state, who made the decision, and your local timestamp. Do not assume a webhook was delivered before an item appears in this response.

The important field transition is simple: an item returned by List group join requests has an id; that value becomes an entry in member_ids for the update call. Do not substitute a display name or a guessed Telegram identifier.

3. Make the decision explicit

A useful queue has at least four local states:

Local stateMeaningNext action
pendingPresent upstream, not reviewedShow to a moderator
approvedModerator acceptedSend approve
rejectedModerator declinedSend reject
staleNo longer present when reconciledClose without another action

Your policy may consider answers collected outside Telegram, an allowlist, or a manual review. Label those as your application rules; they are not Telegram or UnifyPort fields. Avoid automatic acceptance based only on an untrusted profile name or bio.

4. Approve or reject in batches

Submit one or more returned IDs with the target group and an explicit action:

curl -X POST \
  "https://api.unifyport.ai/v1/accounts/<ACCOUNT_ID>/groups/join-requests/update" \
  -H "X-Api-Key: <YOUR_API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "group_id": "group_example",
    "action": "approve",
    "member_ids": ["member_example", "member_other"]
  }'

For rejected requests, send the same shape with "action": "reject". The route requires group administrator permission. Read Approve or reject join requests before implementing retries or batch sizing.

After any update, list the queue again. This closes the gap between your local UI and the current upstream state, especially when two moderators act at nearly the same time.

5. Use group.join_request to wake the worker, not replace it

Subscribe your webhook endpoint to group.join_request if you want the moderation UI to refresh quickly. The documented event indicates that someone requested access to a group with approval enabled, but delivery is best-effort. Its safest role is therefore:

  1. receive the event;
  2. verify and acknowledge the webhook;
  3. enqueue a refresh for the affected moderation flow;
  4. call the list endpoint;
  5. render decisions from the returned pending list.

This is the same reliability principle used for other signed event pipelines: push reduces latency, reconciliation restores truth. If you are implementing the receiver, pair the webhook event reference with the HMAC replay-protection guide.

Keep membership events separate from join requests

A join request is not yet a membership change. Do not mark someone as a member when group.join_request arrives. Approve the request, reconcile, and then process later group membership changes through their own event path.

That distinction also prevents duplicate audit entries: “requested access,” “moderator approved,” and “member added” are three different facts. For the post-approval side, see the guide to Telegram community added and removed events.

Production checklist

  • Confirm the connected identity has administrator permission.
  • Keep X-Api-Key in server-side secret storage.
  • Enable approval mode once as an administrative action.
  • Poll the pending list even when no webhook has arrived.
  • Use only returned request id values in member_ids.
  • Record moderator identity and decision reason in your own audit log.
  • Re-list after every approve or reject operation.
  • Verify webhook signatures before using an event as a refresh hint.
  • Never treat a join-request event as proof that membership changed.

Limitations and trade-offs

Use Telegram’s official Bot API when a bot administrator is the intended identity and the workflow is Telegram-only. It is direct, officially documented, and has dedicated approve and decline methods.

Use UnifyPort’s unofficial interface when an existing account identity or a shared API pattern is the more important requirement. You still need group administrator permission, a clear moderation policy, secure API-key handling, and reconciliation. The interface does not decide whom your group should trust, and best-effort event delivery means your system must retain a polling path.

FAQ

Can a Telegram bot approve group join requests?

Yes. Telegram’s official Bot API provides approval and decline methods. The bot must be a group administrator with the can_invite_users right.

Should I process only the group.join_request webhook?

No. Use it as a fast notification, then list pending requests. The UnifyPort reference states that this push signal is best-effort and polling is the reliable source.

Which identifier goes into member_ids?

Use the id from each item returned by the list-group-join-requests endpoint. Do not derive it from a display name.

Can I approve several requests in one call?

Yes. The update route accepts one or more values in member_ids and an action of approve or reject.

What should happen after an approval call?

List pending requests again, update your local queue, and keep later membership-change events separate from the original request.

Next step

Start with the List group join requests API reference, then implement the approval-mode and update routes around that reconciliation loop.

Sources

Checked on August 24, 2026:

UnifyPort API

Turn messaging integration into a stable product pipeline.

Start by sending through one API, then bring every inbound message back into your business system with standard events.