Not long ago I faced a new challenge: how to add a new tag —in my case, “science fiction”— to every article, both in Spanish and in the other languages.
In other words, almost 3,000 articles that had to be:
- Analyzed to see which ones the tag actually suited.
- Given the tag in the corresponding language without deleting their other tags.
- Checked to make sure everything had gone well.
Creating the tag in each language was no mystery with the custom development I have in place. The problem was tagging only the old articles that should actually have it.
You could do it manually, of course, but after reviewing the content I ended up with a list of 12 articles in Spanish. That means that, since the site is translated into ten languages, I had to tag a total of 120 posts.
And searching for each entry in its language, opening it and adding the tag 120 times, one after another, was not something I fancied doing, frankly.
So it occurred to me that this was a pretty suitable task for Codex.
Besides, I wanted to use this fairly simple case as the basis for something much more general: apply changes to lots of articles automatically, but without letting the agent make changes on its own and go wild.
That is exactly what I explain in this tutorial.
Goal
Simple: add a specific tag to a closed list of WordPress posts.
Including the corresponding translation of that tag for each language version of the article, using Polylang, which is the multilingual plugin I use.
And we are not going to wing it; we will take a few precautions:
- We will work from a closed list of articles.
- We will first check what Codex is going to modify.
- We will not create new tags automatically.
- We will preserve every tag each post already has.
- We will run a simulation before writing anything.
- We will check WordPress again afterwards to verify the result.
Your case does not have to be exactly like mine. It is enough that you want to change something across a specific set of WordPress posts that would take you a while to do manually.
On the other hand, I use Codex, but you can follow the same process if you prefer Claude Code or Antigravity. The tool changes, the steps do not.
Step 1. Create the tag before you start
The first thing is to have the tag you want to apply already created in WordPress.
It is best to do this manually because I do not want Codex deciding how the site's taxonomy should be organized. We want it simply to locate something that already exists and assign it to specific posts.
In WordPress, as you know, you can do it from:
Posts > Tags
If your website has only one language, you have practically finished this step.
If you use Polylang (the Pro version or your own custom development on top, as in my case), also create the translations of the tag and check that they are correctly linked.
For example, in my case I had:
- Ciencia Ficción.
- Science Fiction.
- Science-fiction.
- Science-Fiction.
- Fantascienza.
- …
And so on.
WordPress stores them internally as different terms (tags), and each one will have its own ID. That will matter later.
A note here: I have a custom plugin that creates them automatically in every language, but you will probably have to create them manually, one by one for each language.
Once you have created them, you can ask Codex to locate them:
I want to add an existing tag to several WordPress posts.
The main tag is:
[TAG NAME]
For now, do not modify any data.
Locate the tag in WordPress and, if the site uses Polylang, all of its translations.
Return the following for each language:
– language;
– tag name;
– slug;
– term ID.
Do not create new tags.
If any translation is missing, there are duplicates or there is any ambiguity, stop and tell me.
The term ID is simply the number WordPress uses internally to identify that tag. The important thing is that Codex knows which ID corresponds to each language.
Step 2. Prepare a closed list of articles
Now we need to decide which posts we want to modify.
Here I recommend not giving the agent too much freedom.
We could ask it:
Find every article related to science fiction and tag them.
But then we would be mixing two very different tasks:
- Editorially deciding which content should carry the tag.
- Performing the same modification 20, 100 or 500 times in WordPress.
I prefer to separate the two so I can keep control of each step.
You can make the list manually if the number of articles is not very high.
You can also use ChatGPT or Codex to help you locate candidates.
In my case, since the volume was large, I gave it the three article sitemaps I have and asked ChatGPT to suggest candidates based on the URL.
However you do it, you should end up with a specific list of articles before modifying anything.
For example:
- Blade Runner: review and analysis.
- The best science fiction comics.
- Akira: manga and film.
- El Eternauta: series review.
- …
As I said, I ended up with 12 articles per language after removing a candidate or two that ChatGPT thought fitted but I did not.
Prompt to prepare the working set
Once you have the list, fire this at Codex:
I am going to provide you with a closed list of WordPress articles.
Work exclusively on these articles.
Do not add any other content even if you think it could also fit the tag.
List:
[PASTE THE TITLES OR URLS HERE]
For now, do not make any changes.
Locate each post and return:
– title;
– URL;
– post ID;
– status;
– language.
If any of them cannot be identified unambiguously, stop and flag it.
With this, we have now defined both ends of the operation:
- Which posts we want to tag
- Which tag we want to add.
Step 3. Configure Codex access to WordPress
To read certain WordPress properties and, above all, to modify posts, Codex needs to authenticate.
There are different ways to do it, some more secure than others. One fairly convenient option is to use a WordPress Application Password.
It is not your normal dashboard login password. It is an additional password created specifically so that an application can connect to WordPress through the REST API.
Just as you can create it, you can revoke it at any time without having to change your usual password.
You create it from:
Users > Profile > Application Passwords
Give it a name that lets you recognize it later, for example “Codex”.
WordPress will generate a password.
How to give the password to Codex
Do not put the password directly in the prompt
It could work, but sending your passwords to the cloud is not a good habit.
Ideally, store it locally as an environment variable or inside a .env file that is not uploaded to the repository, if you are working with Git.
For example, you could save a .env file containing just these three lines:
WP_URL=https://tudominio.com
WP_USERNAME=tu_usuario
WP_APP_PASSWORD=tu_application_password
Save it at C:UsersTU_USUARIO_WINDOWS.codex.env
And add .env to .gitignore so it is not uploaded.
The idea is that Codex can use the credentials without needing to display or copy them repeatedly.
Once you have created the corresponding file, you need to close Codex and open it again so it reads it.
Two important things:
- The WordPress username does not necessarily match the public name displayed as the author. Put the actual username in the file.
- The key WordPress generates contains spaces. Remove them when you save it in the .env. Otherwise it will not work.
Prompt for this part
After the previous step, give Codex this prompt:
Use the WordPress credentials available in the local environment variables.
Do not display, print or copy passwords, tokens or other secrets in the output.
Do not modify any content yet.
Only check that the required variables are available.
This way you will know whether it has picked them up correctly, an essential step before moving on.
Step 4. Check that Codex can connect
The next step is to check that the connection works.
The REST API is basically the interface through which Codex can ask WordPress things such as What tags does this post have? or Add this tag and save the article.
At this stage we only want to do the first. Ask it to make a read-only query:
Check authentication against the WordPress REST API.
Make GET requests only.
Confirm:
– that the connection works;
– which WordPress user is authenticated;
– that this user has permission to edit the posts we are going to work with.
If there is any authentication or permissions error, stop.
Do not make any write requests.
If everything is fine, we have access. If you receive a 401 error, you normally need to check the credentials.
Step 5. Locate the translations of each post
This step is only necessary if you have a multilingual.
If you use Polylang, we do not want Codex to find translations by comparing titles, because a title can change enormously between languages.
We want it to use the translation relationships WordPress/Polylang already has.
We start from each original article and locate its language versions.
The prompt
Starting exclusively from the posts in the approved list, locate their translations using the Polylang relationships.
Do not search for translations based on title similarity.
For each article return:
– original post;
– language;
– translated title;
– post ID;
– URL.
The website uses these languages:
[LANGUAGE LIST]
Each article should have:
[NUMBER OF VERSIONS]
versions in total.
If any translation is missing or you find an inconsistent relationship, stop and do not modify anything.
Here we have a very simple check that is worth doing.
If you have 25 articles × 5 languages = 125 posts Codex should find exactly 125.
If it finds 124, it should not continue.
Step 6. Run a complete dry run
Now we have enough information to build the real operation, but we are still not going to execute it.
First we will do a dry run, which is nothing more than a simulation of what would happen if we allowed the changes.
We want Codex to build a table linking post > language > corresponding tag > current status.
Prompt
Now run a complete dry run of the operation.
Do not make POST, PUT, PATCH or DELETE requests.
For each post included in the validated list:
1. Query its current tags.
2. Identify the language of the post.
3. Locate the translation of the new tag that corresponds exactly to that same language.
4. Get the term ID of that tag.
5. Check whether that term ID is already assigned to the post.
6. Calculate what the final tags array would look like after adding it, preserving all existing term IDs.
The relationship must always be:
post in language X → tag in language X → term ID of that tag.
Never assign the term ID of the Spanish tag to a post in another language, and never use a tag whose language does not exactly match the language of the post.
Return a table with:
– post ID;
– post language;
– title;
– current tags;
– name of the tag corresponding to that language;
– tag language;
– term ID that would need to be added;
– whether it is already present;
– expected final tags.
Explicitly check that the post language and tag language match in every case.
If you find any post for which you cannot unambiguously identify the tag in the same language, if a tag translation is missing, or if the post language and tag language do not match, stop and do not modify anything.
At the end indicate:
– total number of posts;
– posts that require modification;
– posts that already contain the tag;
– errors or inconsistencies.
Do not write anything yet.
This step has two advantages.
The first is obvious: we can see exactly what Codex intends to do.
The second is that we will discover posts that already have the tag.
There is no need to modify those articles again.
In my case there were 120 posts, but 2 were already correctly tagged (I had done that manually).
This is the point I would pay the most attention to.
Imagine an article already has these tags:
- Bitcoin.
- Investment.
- Tutorial.
And we want to add “Taxation”.
The result we obviously want is for the article to contain all four, not just Taxation.
It seems obvious, but when you work through the REST API you need to remember that the tags field represents the complete set of tags the post should have.
That is why Codex must first read the existing IDs, add the new one, and then send the complete set.
We do not want to replace; we want to add.
You can reinforce it with a specific prompt:
Before executing the changes, check this rule:
NEVER replace the post's current tags with only the new tag.
For each post:
1. Read the current array of term IDs.
2. Preserve all existing IDs.
3. Check whether the new term ID already exists.
4. If it does not exist, add it to the array.
5. Do not delete or modify any other term ID.
Show me any case where you cannot guarantee this operation.
Do not write yet.
If you are going to automate an operation like this, I would not skip this check.
Step 8. Revalidate everything immediately before modifying WordPress
We already have the dry run approved. We could execute it directly, but even so it costs very little to read WordPress again just before writing.
The reason is simple: the state of a post may have changed between one query and the next. Perhaps you edited it on different days, or someone else did. And we want to make sure Codex works on the current version.
Prompt
Revalidate immediately before executing the changes.
Query WordPress again and confirm:
– that all expected posts still exist;
– that the translation relationships have not changed;
– that the tag term IDs are still correct;
– that the current tags match the state you are about to modify.
If there is any difference compared with the dry run, stop.
If everything matches, tell me:
– total number of posts;
– modifications required;
– posts that are already correct.
Do not execute any changes yet until I authorize you.
This reduces the risk considerably.
Step 9. Execute the modification
If everything above is OK, now we can authorize writing.
At this point it is worth being very precise about what it may and may not change.
Prompt
I authorize execution of the changes.
Modify exclusively the posts included in the validated list.
For each post:
1. Read its current tags.
2. Identify the language of the post.
3. Use exclusively the translation of the new tag whose language exactly matches the language of that post.
4. Get the term ID of that tag.
5. Check whether that term ID is already present.
6. If it is not present, add it to the current tags array.
7. Preserve all other existing term IDs.
8. Save the complete resulting array.
The relationship must always be:
post in language X → tag in language X → term ID of that tag.
Never assign the term ID of the Spanish tag to a post in another language, and never use a tag whose language does not exactly match the language of the post.
If for any post you cannot unambiguously identify the tag in its same language, if a tag translation is missing, or if the post language and tag language do not match, do not modify that post and log the error.
DO NOT modify:
– title;
– content;
– excerpt;
– slug;
– categories;
– author;
– date;
– status;
– featured image;
– ACF fields;
– SEO;
– any other post data.
Do not modify posts outside the approved list.
Log for each operation:
– post ID;
– post language;
– name of the assigned tag;
– tag language;
– term ID added;
– tags before;
– tags after;
– WordPress response code;
– result.
If an operation fails, log the error and do not try to fix it by modifying other fields.
Now Codex will make the necessary requests against WordPress.
But we still have one check left.
Step 10. Read all the posts again
A successful API response means WordPress accepted the request.
But if we are working with dozens or hundreds of articles, it is worth checking the final state, rather than simply assuming everything went well.
So we run another round of read queries.
Prompt
Once the modifications are complete, perform an independent verification with new GET requests.
For each post in the list, check:
1. That it contains the term ID of the new tag corresponding to its language.
2. That it preserves all the term IDs it had before.
3. That no unexpected tag has been added.
4. That no post outside the list has been modified.
Return a final summary with:
– posts reviewed;
– modifications made;
– posts that were already correctly tagged;
– REST errors;
– previous tags lost;
– posts unexpectedly modified;
– final discrepancies.
Consider the task complete only if there are 0 discrepancies.
That closes the process.
Not only have we made the changes, we have also checked what was actually saved correctly in WordPress.
Conclusions
The first is that for a few posts it is probably still faster to do it manually. But scale changes quickly, especially with multilingual sites:
- 10 articles × 10 languages = 100 posts
- 30 articles × 10 languages = 300 posts
- 50 articles × 10 languages = 500 posts
At that point it is no longer just about saving clicks; above all, it is about reducing errors.
The idea I want you to take away, because I think it is genuinely useful, is that Codex does not freely decide and modify your WordPress:
- First it builds the system.
- Then it simulates.
- Then it revalidates.
- Only then does it write.
- And when it finishes, it checks everything again.
For large-scale editorial maintenance, that seems to me a much more sensible way to use agents such as Codex.
In fact, I already have another change clearly in mind. It affects more than 500 posts, and I had planned to do it manually with SQL.
After trying this approach, it is clear to me that it is much better and that the chances of error are reduced considerably.
This has been a one-way trip.
Frequently asked questions
What is the article about?
It explains how to use Codex (an AI agent) to add a new tag to a large set of multilingual WordPress articles in a controlled way and without errors.
Why not let Codex decide which articles to tag?
Because mixing the editorial decision with the technical execution is risky; it is better to separate the two tasks and work from a closed list of posts.
How does Codex connect to WordPress?
Through an Application Password (not the normal password), stored in a local .env file and never pasted directly into the prompt.
How are translations handled?
Codex must use Polylang's translation relationships, never compare titles, to avoid assigning tags in the wrong language.
What is the "dry run" and what is it for?
It is a prior simulation in which Codex shows what changes it would make (post → language → tag → term ID) without executing anything, allowing you to review before writing.
What is the main risk to avoid?
That Codex replaces the existing tags instead of adding the new one, which is why it must always read the current array and preserve it.
Why revalidate immediately before executing?
Because the state of the posts can change between queries (through your own or someone else's edits), and you need to work with up-to-date data.
What happens after executing the changes?
A final verification is carried out with new GET requests to confirm that everything was saved correctly and there are no discrepancies.
What is the main conclusion?
For a few articles it is faster to do it manually, but beyond a certain scale (hundreds of posts in several languages) this method greatly reduces the margin of error compared with doing it manually or via direct SQL.
What are the steps in the process?
- Prepare the translated tags (language, name, slug, term ID)
- Close the list of articles to modify
- Configure Codex access to WordPress;
- Check that Codex can connect (read-only)
- Locate the translations of each post via Polylang;
- Run a complete dry run
- Verify that existing tags will not be deleted
- Revalidate everything immediately before writing
- Execute the modification; 10) Read all posts again to confirm that everything is correct.
Why follow such a long process instead of executing directly?
Because each step adds a check that reduces the risk of errors at scale; simulating, revalidating and verifying costs little compared with correcting hundreds of incorrectly modified posts.
Can any step be skipped if the site is not multilingual?
Yes, step 5 (locating translations via Polylang) is only necessary on websites with multiple languages.

Leave a Reply