Skip to content

API Reference

Every public name in cordless, with full signatures, defaults, and docstrings, generated straight from the installed package. For task-oriented guides and examples, see Commands, Components, Modals & Select Menus, Embeds, and the CLI Reference.

Cordless(public_key=None)
Cordless.command(name, description="No description provided.", options=None, defer=False,
dm_permission=True, default_member_permissions=None, nsfw=False,
ephemeral=False, guild_ids=None, user_installable=False,
name_localizations=None, description_localizations=None)

Register a slash command.

Parameter
name 1-32 lowercase letters, digits, - or _; validated at decoration time. Use parent/sub or parent/group/sub paths for subcommands
description Shown in Discord’s command picker
options List of option dicts (build with option()). When omitted, options are inferred from the handler’s typed parameters: str, int, float, bool, Literal[...] for fixed choices, and Optional[T] / T | None (unwrapped to T; a default value is what makes the option optional)
defer Respond via the worker Lambda
dm_permission Set False to hide the command in DMs
default_member_permissions Permission bitfield members need to see the command
nsfw Restrict to age-verified channels
ephemeral Only meaningful with defer=True: makes the loading state and final reply private. For non-deferred commands, use ctx.send(ephemeral=True) instead
guild_ids Scope this command to specific guilds instead of registering it globally
name_localizations {locale: name} dict for Discord’s per-locale command picker, e.g. {"es-ES": "comprar"}
description_localizations {locale: description} dict, same shape as name_localizations
await Cordless.send_message(channel_id, content=None, *, embeds=None, components=None, files=None)

Send a message as the bot. Requires DISCORD_BOT_TOKEN, callable from anywhere with no interaction to respond to, typically cron handlers. files is a list of (filename, bytes) tuples, same as ctx.send/ctx.edit.

await Cordless.edit_message(channel_id, message_id, content=None, *, embeds=None,
components=None, files=None)

Edit a message the bot previously sent. Requires DISCORD_BOT_TOKEN. files is a list of (filename, bytes) tuples, same as ctx.send/ctx.edit.

await Cordless.delete_message(channel_id, message_id)

Delete a message. Requires DISCORD_BOT_TOKEN.

await Cordless.execute_webhook(webhook_id, webhook_token=None, content=None, *, embeds=None,
components=None, files=None, username=None, avatar_url=None,
tts=False, allowed_mentions=None, wait=False, thread_id=None)

Send a message through a Discord webhook. No bot token required.

Pass a full webhook URL as webhook_id (leave webhook_token unset), or the id and token separately.

await Cordless.edit_webhook_message(webhook_id, webhook_token=None, message_id="@original",
content=None, *, embeds=None, components=None, files=None,
allowed_mentions=None)

Edit a message previously sent through a webhook. No bot token required.

await Cordless.delete_webhook_message(webhook_id, webhook_token=None, message_id="@original")

Delete a message previously sent through a webhook. No bot token required.

await Cordless.add_role(guild_id, user_id, role_id)

Grant a role to a guild member. Requires DISCORD_BOT_TOKEN.

await Cordless.remove_role(guild_id, user_id, role_id)

Remove a role from a guild member. Requires DISCORD_BOT_TOKEN.

await Cordless.create_webhook(channel_id, name, avatar=None)

Create a webhook in a channel. Requires DISCORD_BOT_TOKEN. Returns the webhook object, including the id/token pair execute_webhook needs.

await Cordless.get_channel_webhooks(channel_id)

List a channel’s webhooks. Requires DISCORD_BOT_TOKEN.

await Cordless.delete_webhook(webhook_id, webhook_token=None)

Delete a webhook. With webhook_token, authenticates with the webhook’s own token (no bot token needed); otherwise uses DISCORD_BOT_TOKEN.

Cordless.handler()

Returns the main Lambda entrypoint. Assign at module level in lambda_function.py: handler = bot.handler(). Wraps handle() plus keep-warm pings and @bot.cron dispatch.

Cordless.cron(schedule, name=None)

Register a scheduled handler; cordless deploy wires it to EventBridge.

schedule is an EventBridge expression, e.g. “rate(1 day)” or “cron(0 12 * * ? *)”. The handler takes no arguments.

Cordless.run_cron(name)

Run a registered @bot.cron handler by name, synchronously. Used by cordless cron NAME and the deployed EventBridge target; you don’t normally call this yourself.

Cordless.button(custom_id, defer=False)

Register a handler for a button click. Prefix matching applies: custom_id="shop" also matches "shop:item1:2", with the suffix segments landing on ctx.custom_id_args.

Cordless.select(custom_id, defer=False)

Register a handler for a select menu. Prefix matching applies: custom_id="shop" also matches "shop:item1:2", with the suffix segments landing on ctx.custom_id_args. Selected values are on ctx.values.

Cordless.modal(custom_id, defer=False)

Register a handler for a modal submission. Prefix matching applies: custom_id="shop" also matches "shop:item1:2", with the suffix segments landing on ctx.custom_id_args. Submitted field values are on ctx.modal_values.

Cordless.user_command(name, dm_permission=True, guild_ids=None, user_installable=False,
name_localizations=None)

Register a User context menu command (right-click → Apps → name).

name_localizations is a {locale: name} dict, e.g. {"es-ES": "inspeccionar"}

  • context menu commands have no description, so there is no description_localizations.
Cordless.message_command(name, dm_permission=True, guild_ids=None, user_installable=False,
name_localizations=None)

Register a Message context menu command (right-click message → Apps → name).

name_localizations is a {locale: name} dict, e.g. {"es-ES": "inspeccionar"}

  • context menu commands have no description, so there is no description_localizations.
Cordless.autocomplete(cmd_name, option_name)

Handler for an option marked autocomplete=True. Return a list of strings (filtered against the typed value for you) or choice dicts (sent as-is).

Cordless.error(func)

Register the error handler, called as (ctx, exc). If it sends a response (or returns one), that becomes the interaction’s response; otherwise the exception propagates.

Cordless.guard(fn)

Attach a guard that runs before the handler. Guards reject by raising: a falsy return value is ignored, not treated as a rejection. Can be sync or async; runs for commands, buttons, selects, and modals alike.

Cordless.handle(event, context=None)

Process one raw Lambda event dict: verifies the signature and dispatches it to the right registered handler. Most bots use handler() instead, which wraps this plus keep-warm pings and @bot.cron dispatch, call this directly only if you’re building a custom Lambda entrypoint.

Cordless.load_extension(name: str)

Load a cog module by dotted path (e.g. ‘cogs.game’). Discovers all Cog instances defined in the module automatically. Alternatively, define a plain (non-async) setup(bot) for manual control.

Cordless.load_extensions(package: str)

Load all cog modules in a package (e.g. ‘cogs’). Files starting with ‘_’ are skipped.

Cordless.add_cog(cog)

Register all decorated handlers from a Cog instance.

Cordless.sync_commands(bot_token=None, client_id=None, client_secret=None, guild_id=None)

Push this bot’s registered commands to Discord.

Authenticate with a bot token, or with client_id + client_secret via OAuth2 client credentials (no bot user required). Run this from a deploy step, not from inside the Lambda handler, since it makes blocking network calls to Discord’s API.

Omit guild_id (the default) to sync each command to its own scope: global by default, or whichever guild(s) @bot.command(guild_ids=...) named, all in this one call. Pass guild_id to override every command’s own scope and push the full set to just that guild instead, for instant updates during development.

option(name, description="No description provided.", *, type="string", required=False,
autocomplete=False, choices=None, min_value=None, max_value=None, min_length=None,
max_length=None)

Build a Discord application command option dict, for @bot.command(options=[...]).

Parameter
type "string", "integer", "number", "boolean", "user", "channel", "role", "attachment"
required Default False, note this is the opposite default from inferred options, where a parameter without a default value is required
autocomplete Pair with @bot.autocomplete
choices List of {"name": label, "value": value} dicts; the user must pick one
min_value / max_value Bounds for integer/number options
min_length / max_length Length bounds for string options

Every handler receives one of these as ctx. Fields not applicable to the current interaction are None (or empty). Constructed by cordless itself, not something you instantiate directly.

Attribute
ctx.user The invoking User (resolved from the member in guilds, direct in DMs)
ctx.member Guild Member (roles, nick, permissions); None in DMs
ctx.guild_id / ctx.channel_id Where the interaction happened
ctx.channel Partial Channel
ctx.guild Partial Guild (None in DMs); only .id, .locale, .features are populated
ctx.message The Message the component sits on (component interactions)
ctx.locale The invoking user’s locale, e.g. "en-US"
ctx.options Dict of option name to value for the invoked (sub)command
ctx.attachments Dict of attachment id to Attachment for attachment options
ctx.resolved_users / ctx.resolved_members Dict of id to resolved User/Member, for UserSelect/MentionableSelect picks
ctx.resolved_roles Dict of id to resolved Role, for RoleSelect/MentionableSelect picks
ctx.resolved_channels Dict of id to resolved Channel, for ChannelSelect picks
ctx.custom_id The component/modal’s full custom_id
ctx.custom_id_args Suffix segments when a handler matched by prefix ("shop:item1" becomes ["item1"])
ctx.values Selected values/ids for select menus (always a list)
ctx.modal_values Dict of field custom_id to submitted value (modal submissions)
ctx.focused_value What the user has typed so far (autocomplete)
ctx.target_user / ctx.target_member Target User / Member of a user context menu command
ctx.target_message Target Message of a message context menu command
ctx.interaction_id / ctx.token The interaction’s id and token
ctx.interaction The full raw interaction payload, for anything not surfaced above

User, Member, Message, Channel, and Attachment are thin wrappers around Discord’s raw object, not dicts. Every field Discord sends is available as an attribute, e.g. ctx.user.username. Fields not on the underlying payload raise AttributeError rather than silently returning None.

await Context.send(msg=None, *, content=None, ephemeral=False, embeds=None, components=None,
files=None, allowed_mentions=None)

Send the response. msg and content are interchangeable (positional vs keyword). files is a list of (filename, bytes) tuples. In a deferred handler, send edits the loading message instead of creating a new one.

await Context.followup(msg=None, *, content=None, ephemeral=False, embeds=None, components=None,
files=None, allowed_mentions=None)

Manual replica of what decorator defer=True sends automatically: same shape as send. You normally don’t call this yourself, it’s what send/edit fall through to in worker mode.

await Context.send_followup(msg=None, *, content=None, ephemeral=False, embeds=None,
components=None, allowed_mentions=None)

Deferred handlers only: post an additional, separate message (doesn’t touch the original loading message).

await Context.delete_original()

Deferred handlers only: delete the original loading message.

await Context.edit(msg=None, *, content=None, embeds=None, components=None, files=None,
allowed_mentions=None)

Update the message the component sits on (buttons/selects). No ephemeral: a message’s visibility can’t change after creation.

await Context.defer(ephemeral=False)

Loading state, for commands/modals. You don’t normally call this yourself; decorator defer=True handles the ack and runs your handler on the worker.

await Context.defer_edit()

Defer a component interaction: tells Discord we’ll update this message async (type 6).

await Context.send_modal(modal)

Show a Modal. Must be the first response; you can’t defer, then open a modal.

await Context.respond_autocomplete(choices)

The manual piece underneath an @bot.autocomplete handler’s returned list. You don’t normally call this yourself.

Cog()

Group related handlers. Decorate functions with @cog.command, @cog.button, etc.

Cog.command(name, description="No description provided.", options=None, defer=False,
dm_permission=True, default_member_permissions=None, nsfw=False, ephemeral=False,
guild_ids=None, user_installable=False, name_localizations=None,
description_localizations=None)

Same parameters as Cordless.command. Handlers registered here take effect once the cog is passed to bot.add_cog(cog).

Cog.button(custom_id, defer=False)

Same as Cordless.button.

Cog.select(custom_id, defer=False)

Same as Cordless.select.

Cog.modal(custom_id, defer=False)

Same as Cordless.modal.

Cog.autocomplete(cmd_name, option_name)

Same as Cordless.autocomplete.

Cog.user_command(name, dm_permission=True, guild_ids=None, user_installable=False,
name_localizations=None)

Same as Cordless.user_command.

Cog.message_command(name, dm_permission=True, guild_ids=None, user_installable=False,
name_localizations=None)

Same as Cordless.message_command.

ActionRow(components)

Wraps up to 5 buttons or 1 select.

Button(label=None, custom_id=None, style=1, url=None, emoji=None, disabled=False, sku_id=None)

style is a ButtonStyle. emoji is a partial emoji dict, e.g. {"name": "👋"} or {"id": "1234", "name": "custom"}.

Button.style values: PRIMARY (1), SECONDARY (2), SUCCESS (3), DANGER (4), LINK (5, takes url instead of custom_id), PREMIUM (6, takes only sku_id).

Constant Value
PRIMARY 1
SECONDARY 2
SUCCESS 3
DANGER 4
LINK 5
PREMIUM 6
ChannelSelect(custom_id, channel_types=None, placeholder=None, min_values=1, max_values=1,
disabled=False)

A select menu populated with the guild’s channels, resolved by Discord. channel_types is a list of Discord channel type ints, e.g. [0, 2] for text + voice.

MentionableSelect(custom_id, placeholder=None, min_values=1, max_values=1, disabled=False)

A select menu populated with both members and roles, resolved by Discord.

Modal(custom_id, title, *components)

Takes up to 5 TextInputs (each wrapped in its own row automatically).

RoleSelect(custom_id, placeholder=None, min_values=1, max_values=1, disabled=False)

A select menu populated with the guild’s roles, resolved by Discord.

SelectOption(label, value, description=None, emoji=None, default=False)

One option in a StringSelect. default=True pre-selects it.

StringSelect(custom_id, options, placeholder=None, min_values=1, max_values=1, disabled=False)

A select menu with a fixed list of SelectOptions.

TextInput(custom_id, label, style=1, min_length=None, max_length=None, required=True, value=None,
placeholder=None)

A field inside a Modal. value pre-fills it.

TextInput.style values: SHORT (1) or PARAGRAPH (2).

Constant Value
SHORT 1
PARAGRAPH 2
UserSelect(custom_id, placeholder=None, min_values=1, max_values=1, disabled=False)

A select menu populated with the guild’s members, resolved by Discord.

Embed(title=None, description=None, color=None, url=None, timestamp=None)

color is an integer (0x5865F2); timestamp accepts a datetime or ISO 8601 string. All setters return the embed, so calls chain: Embed(title="Hi").set_footer("a footer").add_field("name", "value").

Embed.set_footer(text, icon_url=None)

Sets the embed’s footer text and optional icon. Returns self.

Embed.set_image(url)

Sets the embed’s large image. Returns self.

Embed.set_thumbnail(url)

Sets the embed’s small corner thumbnail. Returns self.

Embed.set_author(name, url=None, icon_url=None)

Sets the embed’s author line, with an optional link and icon. Returns self.

Embed.add_field(name, value, inline=False)

Appends an EmbedField. Returns self.

EmbedField(name, value, inline=False)

What Embed.add_field creates; you rarely construct it directly.

Attachment(data)

A file attached to a command’s attachment option, e.g. ctx.attachments[att_id]. .id, .filename, .url, .size, .content_type, and any other field Discord sends are available as attributes.

Channel(data)

A partial Discord channel, e.g. ctx.channel. .id, .name, .type, and any other field Discord sends are available as attributes.

Member(data)

A guild member, e.g. ctx.member (None in DMs). .nick, .roles, .permissions, and any other field Discord sends are available as attributes.

Message(data)

A Discord message, e.g. ctx.message (the message a component sits on). .id, .content, .embeds, and any other field Discord sends are available as attributes.

Permissions(raw=0, **flags)

A Discord permission bitfield. Read one off an incoming member or role, e.g. ctx.member.permissions.manage_guild, or build one to send, e.g. default_member_permissions=Permissions(manage_guild=True).

raw is the starting value (Discord sends this as a string of a big int, e.g. off ctx.member.permissions or ctx.role.permissions). Keyword args set or clear individual named bits on top of that, e.g. Permissions(manage_guild=True, kick_members=True).

Role(data)

A Discord role, e.g. ctx.resolved_roles[role_id] from a RoleSelect or MentionableSelect pick. .id, .name, .color, .permissions, and any other field Discord sends are available as attributes.

User(data)

A Discord user, e.g. ctx.user. .id, .username, .global_name, .bot, and any other field Discord sends are available as attributes - not modeled explicitly here, since they’re resolved dynamically off the raw payload by DiscordObject.__getattr__.

Container(components, accent_color=None, spoiler=False)

Components v2 layout block. accent_color is an integer color for the left-edge bar.

File(url, spoiler=False)

Components v2 layout block: a file attached to this message. url must be an "attachment://filename" reference, matching a file uploaded alongside this message.

MediaGallery(*items)

Components v2 layout block: a gallery of images/videos. items are dicts, e.g. {"media": {"url": "..."}}.

Section(*components, accessory=None)

Components v2 layout block. Holds up to 3 TextDisplays with an optional Thumbnail or Button accessory.

Separator(divider=True, spacing=1)

Components v2 layout block: visual spacing between other blocks. spacing is 1 (small) or 2 (large).

TextDisplay(content)

Components v2 layout block: a block of markdown text.

Thumbnail(url, description=None, spoiler=False)

Components v2 layout block: a small image, typically used as a Section’s accessory.

Base exception for all cordless errors.

Raised when a request fails Discord’s Ed25519 signature verification.

Raised when outgoing message content exceeds Discord’s character limit.

Raised when a handler never calls ctx.send/edit/defer nor returns a response.

Raised by a guard function when the interaction is not permitted.

Raised when an interaction references a custom_id with no registered handler.

Raised when an interaction references a command with no registered handler.

Raised when a select menu interaction has no registered handler.

Raised when a modal submission has no registered handler.

Raised when an interaction type is not handled by the router.