Skip to main content

discordforge python library

Banner

A fully async Python SDK for the DiscordForge bot listing platform. Works with small bots and large sharded/auto-sharded bots equally.

Requirements

  • Python 3.11+
  • httpx >= 0.27

Installation

pip install discordforge

Quickstart

import os
import discord
from discordforge import ForgeClient, AutoPoster

bot = discord.Client(intents=discord.Intents.default())
forge = ForgeClient(os.environ["DISCORDFORGE_API_KEY"], bot_id=os.environ["BOT_ID"])

async def setup_hook():
    await forge.sync_from_discordpy(bot.tree, category="General")
    AutoPoster(forge, bot).start()

bot.setup_hook = setup_hook
bot.run(os.environ["BOT_TOKEN"])

AutoPoster posts your stats every 5 minutes automatically. It waits until all shards are ready before the first post, so counts are always accurate.

Want to post every 30 minutes instead? Pass interval=1800.0. Minimum is 300s (API limit).

AutoPoster(forge, bot, interval=1800.0).start()

Usage with discord.py

AutoPoster

poster = AutoPoster(forge, bot, interval=300.0)  # minimum 300s
poster.on("post", lambda stats: print(f"Posted {stats.server_count} servers"))
poster.on("error", lambda err: print(f"Error: {err}"))
poster.start()

Callbacks can be sync or async. The poster keeps running even if a post fails.

Manual stat posting

from discordforge import ForgeClient, BotStats

forge = ForgeClient("YOUR_API_KEY", bot_id="YOUR_BOT_ID")

@bot.event
async def on_ready():
    await forge.post_stats(BotStats(
        server_count=len(bot.guilds),
        shard_count=bot.shard_count,
        user_count=len(bot.users),
    ))

Check if a user voted

vote = await forge.check_vote("USER_DISCORD_ID")

if vote.has_voted:
    print(f"Voted at {vote.voted_at}, next vote available at {vote.next_vote_at}")
else:
    await ctx.send("You haven't voted yet! https://discordforge.org/bots/YOUR_BOT_ID")

Get your bot's public listing info

info = await forge.get_bot()
print(f"{info.name} has {info.vote_count} votes across {info.server_count} servers")

Sync slash commands

Pass your discord.py command tree and it maps commands automatically:

async def setup_hook():
    await bot.tree.sync()
    await forge.sync_from_discordpy(bot.tree, category="General")

Or pass a raw list if you want full control:

from discordforge import DiscordCommand

await forge.sync_commands([
    DiscordCommand(name="ping", description="Check bot latency"),
    DiscordCommand(name="help", description="Show help menu"),
])

Configuration

from discordforge import ForgeClient, ClientOptions

forge = ForgeClient(
    "YOUR_API_KEY",
    bot_id="YOUR_BOT_ID",
    options=ClientOptions(
        timeout=10.0,               # seconds per request
        retries=3,                  # retries on 5xx / network errors
        max_connections=10,         # httpx connection pool size
        max_keepalive_connections=5,
    ),
)

Error handling

from discordforge.errors import ForgeAPIError, ForgeRateLimitError, ForgeAuthError, ForgeNotFoundError

try:
    await forge.post_stats(BotStats(server_count=100))
except ForgeRateLimitError as e:
    print(f"Rate limited, retry in {e.retry_after}s")
except ForgeAuthError:
    print("Invalid API key")
except ForgeAPIError as e:
    print(f"API error {e.status}: {e}")
Exception When raised
ForgeRateLimitError 429 – backs off and retries automatically, only raises after all retries exhausted
ForgeAuthError 401 – invalid or missing API key
ForgeNotFoundError 404 – bot ID not found on DiscordForge
ForgeAPIError any other non-2xx response

AutoPoster reference

poster = AutoPoster(
    forge,                      # ForgeClient instance
    bot,                        # any discord client (discord.py, nextcord, py-cord, eris-style)
    interval=300.0,             # seconds between posts (minimum 300 – API rate limit)
    start_immediately=True,     # post as soon as ready fires
)

poster.on("post", callback)     # called after each successful post with BotStats
poster.on("error", callback)    # called on failure – poster keeps running

poster.start()                  # start the background task
poster.stop()                   # cancel the task (can restart with start())
poster.destroy()                # stop + clear all listeners
poster.is_running               # bool

Callbacks can be sync or async – both work:

async def on_post(stats):
    await log_channel.send(f"Posted {stats.server_count} servers")

def on_error(err):
    print(f"Error: {err}")

poster.on("post", on_post)
poster.on("error", on_error)

Types reference

Type Fields
BotStats server_count, shard_count, user_count, voice_connections
VoteMetadata has_voted, voted_at, next_vote_at
BotInfo id, name, vote_count, server_count
DiscordCommand name, description, type, options
CustomCommand name, description, usage, category

Examples

The examples/ folder has ready-to-run scripts covering every API feature:

File What it shows
post_stats.py Post server/shard/user counts
check_vote.py Check if a user voted in the last 8h
get_bot.py Fetch your bot's public listing info
sync_commands.py Sync commands using DiscordCommand or CustomCommand
sync_commands_discordpy.py Auto-sync directly from bot.tree
autoposter.py AutoPoster with post/error callbacks
vote_reward.py Full vote reward flow with role assignment
error_handling.py Catching all error types
bot.py Complete bot with all slash commands and AutoPoster

All examples use environment variables for credentials – copy and set these before running:

export DISCORDFORGE_API_KEY="your_api_key"
export BOT_ID="your_bot_discord_id"
export BOT_TOKEN="your_bot_token"       # discord.py examples only
export VOTER_ROLE_ID="role_id"          # vote_reward.py only

Running tests

pip install -e ".[dev]"
pytest tests/ -v

License

MIT

Metadata

Release files for discordforge 1.0.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for discordforge 1.0.5
File Size Uploaded
discordforge-1.0.5.tar.gz 19.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for discordforge 1.0.5
File Interpreter ABI Platform
discordforge-1.0.5-py3-none-any.whl Python 3 none any Details

Total release size: 31.8 kB

Release files / discordforge-1.0.5.tar.gz

Download URL discordforge-1.0.5.tar.gz
Size 19.3 kB
Tags Source
SHA-256 checksum
How to use checksums
cda39a3eefc39e15e6f46471db09bd72273e219e78f4c7b6470c77e6236d9793
BLAKE2b-256 checksum
How to use checksums
0689532140b87ccb0e38363d762571cfa8e03e7890bd371c14668c10da24bbc4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 1, 2026.

Transparency log

Release files / discordforge-1.0.5-py3-none-any.whl

Download URL discordforge-1.0.5-py3-none-any.whl
Size 12.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c2bf6e5cd5f7f37b0ea8fca90b1c342ee2caa1966a8d556759f4d5868f487966
BLAKE2b-256 checksum
How to use checksums
c88fa357196a046a3f7691e21cb0eadfd6304e3a10d62b85f1272b3301340b43
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 1, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.5 This release

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page