# Grant a custom badge through the API

**URL:** https://meta.discourse.org/t/grant-a-custom-badge-through-the-api/103270
**Category:** Integrations
**Tags:** rest-api, how-to
**Created:** [December 2, 2018, 1:40am UTC](https://meta.discourse.org/t/grant-a-custom-badge-through-the-api/103270 "2018-12-02T01:40:40Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![Discourse](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/discourse/32/148734_2.png) [@Discourse](https://meta.discourse.org/u/Discourse)
#### Post date: [December 2, 2018, 1:40am UTC](https://meta.discourse.org/t/grant-a-custom-badge-through-the-api/103270/1 "2018-12-02T01:40:40Z")

</div>

Custom badges that you have created on your forum can be granted through the API. This is a great way to award badges without having to use custom badge SQL.

To grant a badge through the API, you need to know the username of the user that you wish to grant the badge to, and the ID (or name) of the badge you wish to grant. You also need to make sure you have generated an API key from your site’s Admin \> API \> Keys section (`/admin/api/keys`).

### Finding the Badge ID

You can get the Badge ID from the badge’s URL. Go to your Admin/Badges section and then click on the badge that you wish to grant. The URL will look something like this: `https://forum.example.com/admin/badges/102`. The last number in the URL is the badge ID.

### Making the API call

To test an API call, you can try granting a badge using curl or [Postman](https://www.getpostman.com/). Here is how I grant a badge from my computer’s terminal with curl.

First, to make things easier, set an `api_key` variable:

```plaintext
 api_key=yourapikey

```

Then to grant a badge with the ID of 102 to the user `bobby`:

```plaintext
curl -X POST "https://forum.example.com/user_badges" \
-H "Api-Key: $api_key" \
-H "Api-Username: system" \
-F "username=bobby" \
-F "badge_id=102" \
-F "reason=https://forum.example.com/t/whats-the-best-photo-youve-ever-taken/160/2"

```

Instead of `badge_id`, you can also use `badge_name` to identify the badge by its name:

```plaintext
-F "badge_name=My Custom Badge"

```

The `reason` parameter is optional. If you supply it, it must be set to the URL of a topic or a post on your site.

You should get a JSON response with details about the badge and when it was granted.

---

<div class="post-metadata">

### Author: ![jtbayly](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jtbayly/32/119510_2.png) [@jtbayly](https://meta.discourse.org/u/jtbayly)
#### Post date: [June 2, 2019, 8:19pm UTC](https://meta.discourse.org/t/grant-a-custom-badge-through-the-api/103270/8 "2019-06-02T20:19:18Z")

</div>

Has anybody added a badge (or flair) via Zapier to Discourse API like outlined here?

> [@Trigger a Zapier task with Discourse Webhooks](https://meta.discourse.org/t/discourse-webhooks-and-zapier/56753):
>
> Want to use Discourse Webhooks to trigger a task via [Zapier](https://zapier.com)? Let’s get started! bulb Tip: Zapier now has an [official Discourse integration](https://zapier.com/apps/discourse/integrations) with built-in triggers and actions (e.g. “New Post”, “Create Post”). For common use cases, this is simpler than configuring generic webhooks manually. The guide below covers the manual webhook approach, which gives you more flexibility and access to all Discourse event types. Zapier requires a trigger and an action. In this howto the trigger…

Also, seems like a great candidate for an action via the [official integration](https://meta.discourse.org/t/put-in-a-vote-for-discourse-in-zapier-apps/21858/34), @HAWK.

---

<div class="post-metadata">

### Author: ![mattdm](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mattdm/32/216484_2.png) [@mattdm](https://meta.discourse.org/u/mattdm)
#### Post date: [December 19, 2021, 8:37pm UTC](https://meta.discourse.org/t/grant-a-custom-badge-through-the-api/103270/9 "2021-12-19T20:37:38Z")

</div>

See also [Create a custom badge with an image through the API](https://meta.discourse.org/t/how-to-create-a-custom-badge-with-an-image-through-the-api/210616), which shows how to upload, and also has another example of granting the badge (in python).

---

<div class="post-metadata">

### Author: ![smileBeda](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/smilebeda/32/272497_2.png) [@smileBeda](https://meta.discourse.org/u/smileBeda)
#### Post date: [January 16, 2023, 11:53am UTC](https://meta.discourse.org/t/grant-a-custom-badge-through-the-api/103270/10 "2023-01-16T11:53:14Z")

</div>

What is the reason this method is not described in the API Docs at [https://docs.discourse.org/](https://docs.discourse.org/)?

I couldn’t find this there.

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [January 16, 2023, 9:16pm UTC](https://meta.discourse.org/t/grant-a-custom-badge-through-the-api/103270/11 "2023-01-16T21:16:18Z")

</div>

> [@smileBeda](#):
>
> What is the reason this method is not described in the API Docs at [https://docs.discourse.org/](https://docs.discourse.org/)?

Because it doesn’t seem to be anyone’s job to keep those docs complete or up to date and some kind soul posted these instructions here. Generally, the documentation for the API is [Reverse engineer the Discourse API](https://meta.discourse.org/t/reverse-engineer-the-discourse-api/20576) and looking at the source.

---

<div class="post-metadata">

### Author: ![sunjam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sunjam/32/175682_2.png) [@sunjam](https://meta.discourse.org/u/sunjam)
#### Post date: [November 17, 2023, 7:31pm UTC](https://meta.discourse.org/t/grant-a-custom-badge-through-the-api/103270/12 "2023-11-17T19:31:34Z")

</div>

Nice, so there is no way to automate such badge giving via API?

Example, someone who receives 5,000 likes on their replies is granted a badge.

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [November 17, 2023, 7:40pm UTC](https://meta.discourse.org/t/grant-a-custom-badge-through-the-api/103270/13 "2023-11-17T19:40:22Z")

</div>

> [@sunjam](#):
>
> someone who receives 5,000 likes on their replies is granted a badge.

If you’re self-hosted, or on Enterprise, you want to [Enable Badge SQL](https://meta.discourse.org/t/enable-badge-sql/47894).

---

<div class="post-metadata">

### Author: ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)
#### Post date: [November 17, 2023, 8:05pm UTC](https://meta.discourse.org/t/grant-a-custom-badge-through-the-api/103270/14 "2023-11-17T20:05:08Z")

</div>

> [@sunjam](#):
>
> someone who receives 5,000 likes on their replies is granted a badge.

If you can’t enable badge SQL, it would be technically possible to automate this, but it would be a two step process. First, make an API request to run a [Data Explorer](https://meta.discourse.org/t/32566?silent=true) query that returns the usernames of users who meet your criteria who have not yet been granted the badge: [Run Data Explorer queries with the Discourse API](https://meta.discourse.org/t/run-data-explorer-queries-with-the-discourse-api/120063). Then, use the usernames returned by that query to grant the badge via the API.

This feels kind of inefficient though. As far as I can tell, there isn’t a route that can be used to grant a badge to multiple users with a single API call, so depending on how many users qualify for the badge, you could end up making a lot of API requests.

Ultimately, this feels like the kind of thing that could be handled by the Automation plugin. There could be a recurring trigger that runs a [Data Explorer](https://meta.discourse.org/t/32566?silent=true) query with a given query ID. Based on the fields returned by the query, the results could be used to trigger various scripts. For example, if a `username` field was returned by the query, it could be used to run scripts that awarded badges, added users to groups, etc.

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [November 17, 2023, 11:43pm UTC](https://meta.discourse.org/t/grant-a-custom-badge-through-the-api/103270/15 "2023-11-17T23:43:21Z")

</div>

> [@simon](#):
>
> There could be a recurring trigger that runs a [Data Explorer](https://meta.discourse.org/t/32566) query with a given query ID

Won’t the have the same problems that caused the badge sql to get disabled in the first place?

---

<div class="post-metadata">

### Author: ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)
#### Post date: [November 18, 2023, 12:58am UTC](https://meta.discourse.org/t/grant-a-custom-badge-through-the-api/103270/16 "2023-11-18T00:58:34Z")

</div>

I don’t think so. [Data Explorer](https://meta.discourse.org/t/32566?silent=true) queries are run in a transaction block that times out after 10 seconds. I think the point of that is to avoid the kind of issue that badge queries can trigger. If things weren’t configured that way, an inefficient [Data Explorer](https://meta.discourse.org/t/32566?silent=true) query could crash the site.

Thinking about that now, I wonder if custom badge sql could have the same kind of safeguard.
