# \[API\] Cleaner way to create a tag?

**URL:** https://meta.discourse.org/t/api-cleaner-way-to-create-a-tag/70526
**Category:** Development
**Tags:** rest-api
**Created:** [September 21, 2017, 4:52pm UTC](https://meta.discourse.org/t/api-cleaner-way-to-create-a-tag/70526 "2017-09-21T16:52:27Z")
**Posts on this page:** 17
**Page:** 1

<div class="post-metadata">

### Author: ![jack2](https://avatars.discourse-cdn.com/v4/letter/j/ac91a4/32.png) [@jack2](https://meta.discourse.org/u/jack2)
#### Post date: [September 21, 2017, 4:52pm UTC](https://meta.discourse.org/t/api-cleaner-way-to-create-a-tag/70526/1 "2017-09-21T16:52:28Z")

</div>

Right now, in order to create a tag with the API, I create a temporary topic with the new tag, then delete the temporary topic. Is there a cleaner way?

---

<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: [September 21, 2017, 6:22pm UTC](https://meta.discourse.org/t/api-cleaner-way-to-create-a-tag/70526/2 "2017-09-21T18:22:58Z")

</div>

I don’t know, but a slightly less painful solution would be to create a post in the staff category (where Assets for site design is) and just add the new tags there.

The reason is that you want to create a bunch of tags so that users can use them in the future, but your community doesn’t yet have posts with those tags?

---

<div class="post-metadata">

### Author: ![jack2](https://avatars.discourse-cdn.com/v4/letter/j/ac91a4/32.png) [@jack2](https://meta.discourse.org/u/jack2)
#### Post date: [September 21, 2017, 7:21pm UTC](https://meta.discourse.org/t/api-cleaner-way-to-create-a-tag/70526/3 "2017-09-21T19:21:05Z")

</div>

Thanks @pfaffman.

> [@pfaffman](#):
>
> I don’t know, but a slightly less painful solution would be to create a post in the staff category (where Assets for site design is) and just add the new tags there.

You mean manually adding the new tag? Or is it possible to use the “Update a single topic” API to add a tag to an existing topic? But in that case I would have to store the topic id, which is painful…

> [@pfaffman](#):
>
> The reason is that you want to create a bunch of tags so that users can use them in the future, but your community doesn’t yet have posts with those tags?

I guess this would be a legit use case. But mine is less legit: I use tags to store metadata (object ids from an external app).

---

<div class="post-metadata">

### Author: ![riking](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/riking/32/170938_2.png) [@riking](https://meta.discourse.org/u/riking)
#### Post date: [September 21, 2017, 7:27pm UTC](https://meta.discourse.org/t/api-cleaner-way-to-create-a-tag/70526/4 "2017-09-21T19:27:59Z")

</div>

> [@jack2](#):
>
> I guess this would be a legit use case. But mine is less legit: I use tags to store metadata (object ids from an external app).

Yeah, that’s not a good idea, especially if each tag is only used once.

You should either have a separate database mapping the external IDs to Discourse topic IDs, or write a plugin and use topic custom fields (this is a problem since there’s no existing mechanism to deliver these to the client, I think).

Another solution is to store the value in the post text.

---

<div class="post-metadata">

### Author: ![jack2](https://avatars.discourse-cdn.com/v4/letter/j/ac91a4/32.png) [@jack2](https://meta.discourse.org/u/jack2)
#### Post date: [September 21, 2017, 7:45pm UTC](https://meta.discourse.org/t/api-cleaner-way-to-create-a-tag/70526/5 "2017-09-21T19:45:27Z")

</div>

Since there is a legit use case, I believe adding a “new tag” API in the future would be a plus.

I can feel the danger of using tags the way I do. But as I need to display, in Discourse, a list of the topics that relate to a specific external object, the “tags.show” route seems the only way…

---

<div class="post-metadata">

### Author: ![riking](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/riking/32/170938_2.png) [@riking](https://meta.discourse.org/u/riking)
#### Post date: [September 21, 2017, 7:46pm UTC](https://meta.discourse.org/t/api-cleaner-way-to-create-a-tag/70526/6 "2017-09-21T19:46:47Z")

</div>

Well, what are the external objects? How many topics will one get? will a topic relate to multiple of these things?

You may be able to get away with using search.

---

<div class="post-metadata">

### Author: ![jack2](https://avatars.discourse-cdn.com/v4/letter/j/ac91a4/32.png) [@jack2](https://meta.discourse.org/u/jack2)
#### Post date: [September 21, 2017, 8:43pm UTC](https://meta.discourse.org/t/api-cleaner-way-to-create-a-tag/70526/7 "2017-09-21T20:43:35Z")

</div>

The external objects are document subsections. One topic relates to one and only one subsection. A minimum guess is: 100 documents x 100 subsections per document = 10,000 subsections = 10,000 tags in a single Discourse instance. I know this is dangerous, but since I’m in the prototype phase, tags are good enough for me.

Now I didn’t think about the search page before… I’ve just done some tests, but sadly, the results are not formatted like a topic list (with the ‘Replies’, ‘Views’ and ‘Activity’ columns). I guess a “topics only” checkbox that turns the result page into a standard Discourse topic list would be exactly what I need. 🙂

---

<div class="post-metadata">

### Author: ![riking](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/riking/32/170938_2.png) [@riking](https://meta.discourse.org/u/riking)
#### Post date: [September 21, 2017, 8:50pm UTC](https://meta.discourse.org/t/api-cleaner-way-to-create-a-tag/70526/8 "2017-09-21T20:50:52Z")

</div>

Consider not pre-creating that many topics - there’s often not much to discuss about the Bibliography. You can have a small service that takes a document & subsection ID and redirects you to either the existing topic or opens the composer pre-filled with the document link, subsection ID, etc.

```
title: Procedures for Smelling, section Keyboards
body: <https://link.to/document/1234#sec-26>

[write your text here]

lookup key: DISCUSS_1234_26

```

Then it polls /latest.json for new topics and checks them for the magic ID reference phrase I put in on the last line of the example.

---

<div class="post-metadata">

### Author: ![jack2](https://avatars.discourse-cdn.com/v4/letter/j/ac91a4/32.png) [@jack2](https://meta.discourse.org/u/jack2)
#### Post date: [September 21, 2017, 9:03pm UTC](https://meta.discourse.org/t/api-cleaner-way-to-create-a-tag/70526/9 "2017-09-21T21:03:40Z")

</div>

Yes, I already have something like this. I don’t create the subsection tags beforehand when a document is created. I’ve changed the “tag not found” page of a subsection so that it looks like an empty topic list with a “New Topic” button at the top. When user clicks the button, I create the tag on the fly using the API and open the composer pre-filled with the generated tag.

---

<div class="post-metadata">

### Author: ![syl](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/syl/32/98883_2.png) [@syl](https://meta.discourse.org/u/syl)
#### Post date: [November 23, 2019, 11:22pm UTC](https://meta.discourse.org/t/api-cleaner-way-to-create-a-tag/70526/10 "2019-11-23T23:22:23Z")

</div>

> [@jack2](#):
>
> Right now, in order to create a tag with the API, I create a temporary topic with the new tag, then delete the temporary topic. Is there a cleaner way?

Yes there is: create a **tag group** populated with the tag you want to create (see the API [here](https://docs.discourse.org/#tag/Tags/paths/~1tag_groups.json/post)).

---

<div class="post-metadata">

### Author: ![syl](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/syl/32/98883_2.png) [@syl](https://meta.discourse.org/u/syl)
#### Post date: [May 7, 2020, 2:18pm UTC](https://meta.discourse.org/t/api-cleaner-way-to-create-a-tag/70526/11 "2020-05-07T14:18:55Z")

</div>

The above method to create a tag with the API (by creating a tag group) has one drawback: it works only if you’re an admin.

---

<div class="post-metadata">

### Author: ![syl](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/syl/32/98883_2.png) [@syl](https://meta.discourse.org/u/syl)
#### Post date: [August 24, 2020, 6:52pm UTC](https://meta.discourse.org/t/api-cleaner-way-to-create-a-tag/70526/12 "2020-08-24T18:52:40Z")

</div>

And yet another way to create tags with the API (but still only for admins): the undocumented api `/tags/upload.json`, used by the `Upload Tags` menu. Use it like this:

```javascript
const tags = ['tag1', 'tag2']
const file = new Blob([tags.join('n')], { type: 'text/plain' })
const formData = new FormData()
formData.append('file', file)
$.ajax({
  type: 'POST',
  url: '/tags/upload.json',
  data: formData,
  contentType: false,
  processData: false
})

```

---

<div class="post-metadata">

### Author: ![SumOne](https://avatars.discourse-cdn.com/v4/letter/s/8e8cbc/32.png) [@SumOne](https://meta.discourse.org/u/SumOne)
#### Post date: [September 24, 2020, 4:57pm UTC](https://meta.discourse.org/t/api-cleaner-way-to-create-a-tag/70526/13 "2020-09-24T16:57:29Z")

</div>

If I plan to have 1000s of tags. Is it still a good idea to use this workaround, a group for each tag? Are tag groups as nimble as tags?

If they are then it solves my immediate problem. If not then I would try to avoid the duplication (of tag + tag group for just 1 tag).

---

<div class="post-metadata">

### Author: ![syl](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/syl/32/98883_2.png) [@syl](https://meta.discourse.org/u/syl)
#### Post date: [September 24, 2020, 8:51pm UTC](https://meta.discourse.org/t/api-cleaner-way-to-create-a-tag/70526/14 "2020-09-24T20:51:10Z")

</div>

> [@SumOne](#):
>
> Are tag groups as nimble as tags?

Sorry, I don’t know.

> [@SumOne](#):
>
> Is it still a good idea to use this workaround, a group for each tag?

I seem to remember that the API allows, in one operation, to create multiple tags in one group.

---

<div class="post-metadata">

### Author: ![SumOne](https://avatars.discourse-cdn.com/v4/letter/s/8e8cbc/32.png) [@SumOne](https://meta.discourse.org/u/SumOne)
#### Post date: [September 24, 2020, 9:15pm UTC](https://meta.discourse.org/t/api-cleaner-way-to-create-a-tag/70526/15 "2020-09-24T21:15:49Z")

</div>

Thanks. Yeah it allows us to create multiple tags in the same group but only on creation. We can update but for that I need to retreive the group, append it and then send it back. There’s no endpoint for appending.

About the second idea you suggested, the one with the /tags/upload.json endpoint.

I found the interface upload button. I created a csv that works fine there. But I can’t get it to work in Postman or in Golang (if you’re familiar I used csv.NewWriter).

Any ideas?

---

<div class="post-metadata">

### Author: ![syl](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/syl/32/98883_2.png) [@syl](https://meta.discourse.org/u/syl)
#### Post date: [September 25, 2020, 8:55am UTC](https://meta.discourse.org/t/api-cleaner-way-to-create-a-tag/70526/16 "2020-09-25T08:55:28Z")

</div>

> [@SumOne](#):
>
> But I can’t get it to work in Postman or in Golang.  
> Any ideas?

Sorry, I don’t know how to create and post a blob with those.

---

<div class="post-metadata">

### Author: ![SumOne](https://avatars.discourse-cdn.com/v4/letter/s/8e8cbc/32.png) [@SumOne](https://meta.discourse.org/u/SumOne)
#### Post date: [September 25, 2020, 4:21pm UTC](https://meta.discourse.org/t/api-cleaner-way-to-create-a-tag/70526/17 "2020-09-25T16:21:44Z")

</div>

Found out how to do it.

If anyone needs it, ping me. I’m not posting it here because it’s long and probably irrelevant to 99.99% of the community.
