Library / SDK
Cogmasters/concord avatar
Cogmasters/concord

concord: an asynchronous Discord API client in C

A Discord API wrapper library made in C

660 stars43 forksCMIT

At a glance

What is it?
concord is a C99 library that speaks the Discord API, described as a low-level translation of the official documentation into C code with minimal external dependencies. It generates much of its surface from templates, links against libcurl and nothing else, and its most recent tagged releases were withdrawn.
Who is it for?
Adopt concord if you are writing a Discord bot or tool in C, you want a low level API rather than a binding to a higher level client, and you can live with a project whose current work lives on a dev branch rather than on the default master.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 73 days ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A low level translation of the Discord docs

Concord is described as an asynchronous C99 Discord API library with minimal external dependencies, and as a low-level translation of the Discord official documentation to C code.

That second description is the most useful one for judging the design. Concord is not a convenience wrapper with a friendly object model and helpers for the common cases. It is the API surface itself, expressed in C, with a struct-based parameter convention and a function per endpoint. A developer who already knows the Discord documentation can read Concord's headers and recognise what is there, and a developer who does not will find no scaffolding to hide the endpoints.

The practical consequences follow from that choice. The library is written in C99, so it fits into an existing C project without dragging in a runtime, and it compiles on a wide set of Unix-like systems. Because the Discord API is largely websocket-driven, the library is asynchronous, and the event callbacks are the shape a bot is written around.

The licence is MIT, the documentation lives at cogmasters.github.io/concord, and the repository topics list api-client, api-rest, api-wrapper, discord, linux, windows and websockets, which matches the split between the REST calls, the gateway events and the websocket transport.

The work is on dev, and the newest tags were withdrawn

The README leads with a message that is unusual to see in a project of this age: Concord is not dead. Development has been happening in the dev branch, and the instruction is to check out that branch to access the latest version of the library.

That framing is the single most important piece of information for an adopter, because the default branch is master and the release history looks rough. The release list shows v3.0.1 on 2026-06-23 and v3.0.0 on 2026-06-12, and both of those release titles carry the word withdrawn. The last release before them is v2.4.0 from 2025-04-23.

So the picture is a project in transition. A v3 line was started, and the tagged artefacts for it were pulled back, and the active development is in a branch rather than in a release. The last push to the repository was on 2026-08-11.

For someone who wants a packaged dependency, that is an obstacle, because there is no clean recent tag to point a build at. For someone who intends to vendor or fork the library, it is less of a problem, since a branch can be cloned and built the same way a tag can.

The README also links migration guides for coming from v1, which tells you the API has changed shape at least twice already, and that a large rewrite is the likely reason for the withdrawn tags.

Two shapes of command handling, one event model

The examples show the two command styles the library supports, and the difference between them is instructive.

The first example is the newer slash command path, where a bot registers a guild application command on ready and answers interactions. The includes are minimal:

c
#include <string.h>
#include <concord/discord.h>

and the entry point shows the whole lifecycle in five lines:

c
int main(void) {
    struct discord *client = discord_init(BOT_TOKEN);
    discord_set_on_ready(client, &on_ready);
    discord_set_on_interaction_create(client, &on_interaction);
    discord_run(client);
}

discord_init takes the bot token and returns a client handle, the setters register callbacks, and discord_run blocks and drives the event loop. The interaction handler checks the event type against DISCORD_INTERACTION_APPLICATION_COMMAND, compares the command name, and replies with a struct of parameters and a callback data that carries the content.

The second example is the older message command path, where the handler is registered with discord_set_on_message_create and the message content is compared with strcmp. That handler has to opt into the message content intent explicitly, with discord_add_intents(client, DISCORD_GATEWAY_MESSAGE_CONTENT), because Discord gates that data behind an intent.

The slash command example carries a warning worth repeating: the code references GUILD_ID, which you have to define or replace with a real guild id, and the README suggests a #define GUILD_ID macro.

libcurl is the only dependency

The build instructions are short because there is one dependency, curl 7.56.1 or higher, and if you compile libcurl yourself you need to build it with SSL support.

On Linux, BSD and macOS the package name changes but the shape does not. The README lists the command for each distribution:

console
# apt update && apt install -y libcurl4-openssl-dev

with the equivalents given for Void Linux with xbps-install, Alpine with apk add curl-dev, FreeBSD with pkg install curl, and macOS with either Homebrew or MacPorts, where the macOS path also needs Xcode or at least the command line tools installed through xcode-select. Arch based systems are handled through the AUR, either by cloning concord-git and running makepkg, or with an AUR helper.

Windows is the awkward case and the README is explicit about it. You install Cygwin, and you have to make sure libcurl, gcc, make and git were selected during the Cygwin installer. Mingw64 and Msys2 are currently not supported, with a separate guide explaining why. Once Cygwin is in place you compile as you would on Unix.

The practical consequence is that a C project that already links libcurl can add Concord cheaply, while a project on a different TLS stack cannot.

Make, CFLAGS and the shared object case

Building from a clone is the documented path, and the Makefile at the top level drives everything:

console
$ git clone https://github.com/cogmasters/concord.git && cd concord
console
$ make

The Makefile exposes the whole structure of the project through its variables. SRC_DIR is src, INCLUDE_DIR is include, LIBDIR is lib, DOCS_DIR is docs, GENCODECS_DIR is gencodecs, CORE_DIR is core, EXAMPLES_DIR is examples and TEST_DIR is test, and the default target builds the static library. There is a shared target that compiles everything with position independent code, a shared_osx variant for macOS, a voice target, a debug target that switches to -O0 -g, and separate test and examples targets.

The include and library search paths are the part that causes trouble on systems that keep libcurl outside the default locations, and the README gives the pattern:

console
$ CFLAGS=-I<some_path> LDFLAGS=-L<some_path> make

with concrete variants for FreeBSD, for macOS with MacPorts, for a self-compiled libcurl on macOS, and for Cygwin where POSIX threading needs both -pthread and -lpthread.

There is one more case that catches people out. If you intend to link Concord into a shared object, or link it as a shared object into another one, you need to compile it with CFLAGS="-fpic" make, which is why the Makefile keeps a separate SOFLAGS variable.

Installation is the standard install and uninstall pair, placing headers and the static library under the PREFIX, which defaults to /usr/local.

gencodecs is where the API surface comes from

The repository layout explains the low-level translation claim better than any documentation could. There is a gencodecs/ directory, a templates/ directory, a scripts/ directory and a core/ directory, alongside the hand written parts in src/ and include/.

The Makefile's docs target runs the gencodecs headers rule, and the build order makes the dependency explicit: the core is compiled first, then gencodecs, then src, each with the CFLAGS of the chosen target. In other words, the API layer is generated before the library that uses it, and the generated headers are installed alongside the hand written ones, since the install rule copies INCLUDE_DIR, CORE_DIR and GENCODECS_DIR headers into the destination.

That is a coherent design for a library whose scope is the whole API surface, and it explains the templates/ and scripts/ directories. The trade-off is that the generated code is not the place to look for the meaning of an endpoint, and the docs are Doxygen based, with a Doxyfile at the top level and a doxygen-awesome-css directory for the stylesheet.

The rest of the top level is a familiar set of project files: .clang-format for the style, KNOWN_BUGS.md, SECURITY.md, AUTHORS, a config.json, a .gitmodules file, a .vscode directory, and a licenses/ directory for the third party code. The examples/ directory is the best catalogue of what the library can do, with one file per topic, among them audit-log.c, ban.c, cache.c, channel.c, components.c, embed.c, emoji.c, fetch-messages.c, guild-template.c, invite.c, pin.c, presence.c, reaction.c, shell.c, slash-commands.c, slash-commands2.c, spam.c and timers.c, plus a ping-pong.c that is the minimum viable bot.

Wide platform support with one known gap

The supported operating systems are listed with their minimum versions: GNU/Linux 4.x, FreeBSD 12, NetBSD 8.1, Windows 7 through Cygwin, GNU/Hurd 0.9 and Mac OS X 10.9.

That list is a genuine advantage for a library of this kind, since a bot that has to run on a variety of hosts is otherwise stuck with either a language runtime or a binary that only works on one platform. The C99 requirement keeps the code portable in practice.

The known gap is endianness, and the README states it directly: big-endian processors running certain operating systems, such as SPARC Solaris, PowerPC AIX, System Z z/OS or Linux, and MIPS IRIX, are not supported, because there are a few issues that prevent some of the logic from working correctly on big-endian systems. The README adds that this will be fixed soon, which is a statement about intent rather than a schedule.

For most deployments that is academic, but for anyone running on a big-endian host, such as certain enterprise mainframes, it is the deciding fact, and KNOWN_BUGS.md at the top of the repository is where the current state of such issues is recorded.

Combined with the dev branch situation, the picture for a new adopter is a library that is broad, portable and light on dependencies, but that has to be consumed with attention to which branch and which tag you actually build against.

Editorial conclusion

Adopt concord if you are writing a Discord bot or tool in C, you want a low level API rather than a binding to a higher level client, and you can live with a project whose current work lives on a dev branch rather than on the default master. Skip it if you want a maintained package manager release, since the v3.0.0 and v3.0.1 tags are marked withdrawn and the last published release before those is v2.4.0 from 2025-04-23, and note that Windows support means Cygwin, since MinGW64 and MSYS2 are not supported. Before you build, install libcurl 7.56.1 or newer, read KNOWN_BUGS.md, and check the dev branch if you need the newest features. The last push was on 2026-08-11.

Frequently asked questions

What does concord need to build a Discord bot in C?

The only dependency is curl 7.56.1 or higher, and the library itself is built with make after cloning the repository. On Windows you need Cygwin with libcurl, gcc, make and git, and MinGW64 and MSYS2 are not supported.

Is concord still maintained?

The README says development has been happening in the dev branch and tells users to check that branch out for the latest version. The last push was on 2026-08-11, and the v3.0.0 and v3.0.1 release entries are both marked withdrawn, with v2.4.0 from 2025-04-23 the last release before them.

How do I register a slash command with concord?

The README example registers the command in the on_ready handler with discord_create_guild_application_command, using a real guild id in place of GUILD_ID, and answers it in the interaction handler with discord_create_interaction_response when the interaction type is DISCORD_INTERACTION_APPLICATION_COMMAND.

How do I link concord into a shared library?

The README says that if you want to link Concord into a shared object, or link it as a shared object into another shared object, you need to compile it with CFLAGS="-fpic" make. The Makefile keeps a separate SOFLAGS variable for that case.

Official sources

  1. Cogmasters/concord on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/cogmasters-concord.svg)](https://hysenlabs.com/projects/cogmasters-concord)

Was this useful?