How do I assign a topic via the API

Is there a way to assign via API? I don’t see it in the docs, but I would love to be surprised :slight_smile:

Edit: looks like I’ll be trying to reverse engineer it!

3 Likes

First of all, our goal is to have a stable API, it is a multi year effort to get there, but it is certainly a place we want to get.

In the meant time a reasonable 2025 trick you can use is lean on AI agents to figure this stuff out:

This shows how you can lean on our GitHub helper to answer the question!

4 Likes

Did you figure this out? If so, can you share your learning here?

1 Like

Hey!
Not yet! This project got bumped back for something more pressing, but I’ll be back on it next week :slight_smile:

4 Likes

@tobiaseigen this works for me using node js

var https = require(‘https’);

// Configuration
var CONFIG = {
apiUrl: ‘YOURDISCOURSEDOMAIN’,
apiKey: ‘YOURAPIKEY’,
apiUsername: ‘YOURAPIUSER’,
assignToUsername: ‘USERNAMETOASSIGNTO’  // Username to assign topics to
};

// Topic IDs to assign
var topicIds = [634]; //change with the topic id

function assignTopic(topicId, callback) {
var postData = JSON.stringify({
target_id: topicId,
target_type: ‘Topic’,
username: CONFIG.assignToUsername
});

var options = {
hostname: CONFIG.apiUrl,
port: 443,
path: ‘/assign/assign.json’,
method: ‘PUT’,
rejectUnauthorized: false,
headers: {
‘Api-Key’: CONFIG.apiKey,
‘Api-Username’: CONFIG.apiUsername,
‘Content-Type’: ‘application/json’,
‘Content-Length’: postData.length
}
};

var req = https.request(options, function(res) {
var data = ‘’;

res.on('data', function(chunk) {
  data += chunk;
});

res.on('end', function() {
  console.log('Status:', res.statusCode);
  console.log('Raw response:', data);
  try {
    var response = JSON.parse(data);
    if (res.statusCode === 200) {
      console.log('Topic ' + topicId + ' successfully assigned');
    } else {
      console.log('Topic ' + topicId + ' error:', response.errors || response.error_type || response);
    }
  } catch (e) {
    console.log('Parse error:', e.message);
  }
  if (callback) callback();
});

});

req.on(‘error’, function(e) {
console.error('Request error for topic ’ + topicId + ‘:’, e);
if (callback) callback();
});

req.write(postData);
req.end();
}

// Run sequentially
var index = 0;
function next() {
if (index < topicIds.length) {
assignTopic(topicIds[index], function() {
index++;
setTimeout(next, 500);
});
}
}

console.log(‘Assigning topics:’, topicIds.join(‘, ‘));
console.log(‘Assign to:’, CONFIG.assignToUsername);
console.log(’’);
next();
1 Like

The Discourse Assign exposes these API endpoints:

Assign (PUT /assign/assign.json)

Required parameters:

  • target_id - The topic or post ID
  • target_type - Either "Topic" or "Post"

Plus one of:

  • username - Username to assign to
  • group_name - Group name to assign to

Optional parameters:

  • note - Assignment note
  • status - Assignment status
  • should_notify - Send notifications (default: true)

Unassign (PUT /assign/unassign.json)

Required parameters:

  • target_id - The topic or post ID
  • target_type - Either "Topic" or "Post"

Examples (curl)

# Assign topic 123 to user "john"
curl -X PUT "https://your-discourse.com/assign/assign.json" \
  -H "Api-Key: YOUR_API_KEY" \
  -H "Api-Username: YOUR_USERNAME" \
  -H "Content-Type: application/json" \
  -d '{"target_id": 123, "target_type": "Topic", "username": "john"}'

# Assign to a group instead
curl -X PUT "https://your-discourse.com/assign/assign.json" \
  -H "Api-Key: YOUR_API_KEY" \
  -H "Api-Username: YOUR_USERNAME" \
  -H "Content-Type: application/json" \
  -d '{"target_id": 123, "target_type": "Topic", "group_name": "support-team"}'

Notes

  • The API user must have assign permissions (be in an assign-allowed group)
  • You can also assign individual posts using target_type: “Post” with the post ID

@opcourdis the Node.js example above looks correct! :+1:

2 Likes

Thanks for sharing nice to so see we can include all those parameters