How to programmatically retrieve the external_id for a topic

Hi all,

I need to retrieve the remote_id for a topic, programmatically. The backdrop - I am running a script on api.onPageChange that retrieves info on the current topic/category/group, then does an Ajax call to an external system for further entity-specific information.

I have an (ember?) api.onPageChange event running, and I seem to be able to get all the info I need except the remote_id value (I’m using the field name from the API).

What I have so far:

const topicController = api.container.lookup(“controller:topic”);
if (topicController) {
const thisTopic = topicController.get(“model”);
if (thisTopic) {
console.log(; // for example only … works perfectly.

… I can get various fields, all working wonderfully … I cannot find how to get the Remote ID, though (and I need it). I do know I can get it using a JSON call (adding .json to the current-page url) but that seems inefficient … or am I wrong, should I use that approach? Any other guidance?

Thanks in advance!

1 Like

Just to confirm, is remote_id the actual name of the field you are looking for? I’m not aware of that field being used by Discourse.


Gaah… apologies @simon (and thanks for checking out the question) … “external_id” is the correct name, as per the API.

I think I was actually checking for the correct name (external_id), but then misremembered it when writing up the question here … but I definitely do need to check. I can’t do so right now but I’ll revert here later today.

Thanks again, I appreciate it!

1 Like

Soo … I was mistakenly looking for the wrong field/value, not the correct (external_id) one. Sorry for time-wasting … if it’s any consolation, I wasted lots of my own first :frowning: :slight_smile:

The bad news is - I can’t find external_id anywhere in the Ember model. I’m not familiar with Ember so I’m just rooting around, really … I can find lots of other very useful Topic info, just, not external_id (I’ve logged the Topic model to the Console and I’ve been rummaging around).

Any pointers, @simon or anyone? Thanks again.

1 Like

external_id is a property of the SingleSignOnRecord model. It’s used to link a user to an external site when DiscourseConnect is used to log users into Discourse via an external site. If this is what you are trying to find, it’s not available on the Topic. As far as I know, Discourse only returns the external_id on the front end for the CurrentUser, so if you are trying to do something like get the external_id of the topic’s author, it could be tricky.

If you post some more details about what you are trying to accomplish, someone here might be able to help. There might be some easier ways of approaching the problem than what you are trying to do.

Not a problem. That’s what we’re here for :slight_smile:


Much thanks, all parts!

So, I expect to run multiple instances of Discourse, as well as an overarching (non-Discourse) admin/coordination system in the background. Topics will get added to Discourse in one of 2 ways - either by users via the usual Discourse topic-creation mechanism, or by the admin/coordination system via the API.

Where the topic is created via the API, it will typically represent a task or similar workflow item which will already have it’s own non-Discourse ID … lets call it the “External ID”.

Where the topic is created by the user within Discourse, we’ll use webhooks to trigger an Azure function to create a stub-like clone within the central system (so that the Discourse messages gets connected into a wider stream of content, tasks etc). Therefore, again, the Discourse Topic indirectly will have a unique “External ID” - which we propose to update the Topic with, via the API.

We have a bespoke Discourse theme component which, as each topic loads, will use Ajax to retrieve non-Discourse-centric information from the central system and to display this on the Topic screen.

While we could use the Discourse Topic ID to parameterise the Ajax call and find the matching data, its more efficient to use the “External ID” to do so (it’s just cleaner, multiple reasons - it avoids lookups etc).

We could easily store the “External ID” in a custom field - we already have one for other data - but we notice that the Topics API has an “external_id” field that looks exactly like what we need, and I’d prefer to use it for various reasons … it just makes this somewhat-pivotal field easier to incorporate in reports, exports, maybe future searches etc.

See the screengrab from the Discourse API Docs

I’m guessing this is a rather new field - most of the advice in the forum seems to relate to the User external_id field, which is not what I need right now. As mentioned above, I am retrieving the Ember model for the topic (within my custom theme component) and I can get just about all info about the topic through it … but not the external_id field.

(As above - I am getting the topic using this code, borrowed from somewhere on this site, no idea where at this stage:

        const topicController = api.container.lookup("controller:topic");
        if (topicController) {
            const thisTopic = topicController.get("model");      

So, the request - is the topic-specific external_id field buried in the model (“thisTopic”) somewhere, or am I misunderstanding these concepts and should I just use the custom field to store this external ID (I know I can get that approach to work, and how! … I just prefer the cleanliness and future-readiness of using the distinct external_id, if indeed its available).

Again, thanks for the help, I appreciate it!

1 Like

I’d never noticed that before. I was looking for something similar a few years ago for associating WordPress post ids with Discourse topics.

The topic’s external_id will only be returned as a property on the client if the topic has an external_id, so if the topic doesn’t have one, you won’t get a null value. This is working for me for topics that do have an external_id:

<script type="text/discourse-plugin" version="0.11.0">
api.onPageChange (() => {
    const c = api.container.lookup("controller:topic");
    if (c) {
        const m = c.get("model");
        if (m && m.hasOwnProperty('external_id')) {
        console.log("the external_id is ", m.external_id);

… and just like that, it goes from ‘impossible’ to ‘fabulous’ :slight_smile: … brilliant, that’s a game-changer for me. It hadn’t occurred to me that the model would be variable, but it makes total sense.

Thanks very kindly, @simon, including for the elegant code snippet!