Skip Navigation
November 20, 2018

Some applications use XML-RPC to edit WordPress sites. Most notably are the WordPress iPhone and BlackBerry applications.

Language custom fields

WPML allows controlling post and page languages via custom fields.

  • _wpml_language (R/W): The short ISO language code. For example, ‘en‘, ‘es‘, ‘fr‘, ‘de‘.
  • _wpml_trid (R/W): The translation group ID. Items with the same trid are considered as translations for one another.
  • _wpml_translations (R): A serialized array containing the translations for a post or page.

WPML adds the language custom fields to these XML-RPC calls:


  • metaWeblog.newPost or wp.newPage
  • metaWeblog.editPost or wp.editPage


  • wp.getPage
  • metaWeblog.getPost
  • metaWeblog.getRecentPosts

When a page/post is read, WPML sets the trid and language attributes. The actual values for these are stored in WPML’s translations table and the values are copied to the custom field when the RPC is called.

Please note: The “Reading” part of this feature is currently missing. We are working on it and will update you when it is ready.

When writing, WPML monitors for the presence of these custom fields and will update the translations table according to them.


1. Get language information


This will return a list of all available languages for the site. This list should be used to display languages and translation options for posts, pages, tags and categories.

Accepts one (optional) parameter: language code. Besides the English and native names, languages will be returned in this language as well.

1. Create a new page (or post)


In the application, include a drop-down window that allows selecting the language of the page.

Add the _wpml_language custom field to tell WPML the language of this new page.

2. Read a page from WordPress and display it (with translation controls)


This will return _wpml_language, _wpml_trid and _wpml_translations.

_wpml_translations needs to be unserialized. It will contain an array of language codes and the IDs of translations for this page. Any existing translation will be greater than zero. Languages with no translations will get an ID of zero.

The application can now display the language of the page and all existing translations and allow adding new translations or editing existing translations.

The trid value is kept, but doesn’t need to be displayed anywhere.

3. Add translation to a page


Include both _wpml_language and _wpml_trid. The trid value is the same as for the page we’re adding translation to. The language must be unique to the trid.


Two posts or pages cannot have the same trid and language values. All elements in the same trid must have unique languages.

If you edit an existing page or try to create a new page which causes the translation group to have two elements with the same number, the RPC will fail, returning an error.

For more information on WPML’s internals, have a look at the table structure.

Here is a PHP test code that you can modify to your needs:

XML RPC example

define('XMLRPC_REQUEST', true);

// Some browser-embedded clients send cookies. We don't want them.
$_COOKIE = array();

// A bug in PHP < 5.2.2 makes $HTTP_RAW_POST_DATA not set by default,
// but we can do it ourself.
if ( !isset( $HTTP_RAW_POST_DATA ) ) {
    $HTTP_RAW_POST_DATA = file_get_contents( 'php://input' );

// fix for mozBlog and other cases where '<?xml' isn't on the very first line
if ( isset($HTTP_RAW_POST_DATA) )

/** Include the bootstrap for setting up WordPress environment */
include( dirname( __FILE__ ) . '/wp-load.php' );

include_once(ABSPATH . 'wp-admin/includes/admin.php');
include_once(ABSPATH . WPINC . '/class-IXR.php');
include_once(ABSPATH . WPINC . '/class-wp-xmlrpc-server.php');

$client = new IXR_Client('');

$USER = 'admin';
$PASS = 'admin';

$content['title'] = 'Test title de '.mt_rand();
$content['categories'] = array("NewCategory","Nothing");
$content['description'] = '<p>Lorem ipsum dolor sit amet</p>';
$content['custom_fields'] = array( array('key' => '_wpml_language','value'=>'de'), array('key' => '_wpml_trid','value'=>'1234'));

if (!$client->query('wp.newPage','', $USER,$PASS, $content, true))
    die( 'Error while creating a new post' . $client->getErrorCode() ." : ". $client->getErrorMessage());
$ID =  $client->getResponse();

    $content['title'] = 'Test title en '.mt_rand();
    $content['categories'] = array("NewCategory","Nothing");
    $content['description'] = '<p>Lorem ipsum dolor sit amet</p>';
    $content['custom_fields'] = array( array('key' => '_wpml_language','value'=>'en'), array('key' => '_wpml_trid','value'=>'1234'));

    if (!$client->query('wp.newPage','', $USER,$PASS, $content, true))
        die( 'Error while creating a new post' . $client->getErrorCode() ." : ". $client->getErrorMessage());

4 Responses to “XML-RPC language interface”

  1. The XML-RPC implementation appears to be affected by this issue:

    The latest version of WPML does not seem to use the available register_meta() method to allow the modification of the protected _[meta_key] custom fields.

    The following quick hack will enable sending the custom field _wpml_language and _wpml_trid via XML-RPC. This does _NOT_ properly enforce permissions or perform any kind of sanitization.

    @@ -3,7 +3,8 @@
    class WPML_Translation_Management{

    function __construct(){
    – add_action(‘init’, array($this,’init’));
    + add_action(‘init’, array($this,’init’));
    + add_action(‘init’, array($this,’_register_meta’));

    function __destruct(){
    @@ -57,6 +58,19 @@


    + }
    + function _meta_sanitize_cb ( $meta_value, $meta_key, $meta_type ) {
    + return $meta_value;
    + }
    + function _meta_yes_you_can( $can, $key, $post_id, $user_id, $cap, $caps ) {
    + return true;
    + }
    + function _register_meta(){
    + register_meta( ‘post’, ‘_wpml_language’, array($this,’_meta_sanitize_cb’), array($this,’_meta_yes_you_can’));
    + register_meta( ‘post’, ‘_wpml_trid’, array($this,’_meta_sanitize_cb’), array($this,’_meta_yes_you_can’));

    function _no_wpml_warning(){

  2. Brand new WPML user here (only having used qTranslate in the past). I have a set of automation scripts used for wp development, production support on live sites, and managing content for larger content-heavy sites. They leverage both wp-cli and the XML-RPC API.

    They can spin up a WordPress on a bare LAMP server and completely build out a site from there with all plugins, pages + posts, menus, etc. They use XML-RPC to create all content pages on the target wordpress (currently in EN only) and I am interested in expanding them to work with WPML if/where possible.

    The documentation here seems old (2012… its 2017) and the interface incomplete. I have also found other posts with users having difficulties getting wpml to work when they are using the xmlrpc api.

    If I have a given page’s title+content in EN and I also have an FR translation for that page, what is the general process for creating that page via the API? It needs to be done properly so a user could be on the EN page, toggle to FR, and see the translated version. I am not clear on how to generate the trid and get it back such that my scripts would know it, so that they can set the ‘_wpml_trid’ value? Or can I arbitrarily set a value of my own (so long as its unique to the page I want translated and only used for translations of that page)?

    Is this process considered stable + supported come 2017, if there hasn’t been much activity since 2012?

    Beyond that, in terms of supporting tearing up a site from scratch entirely in an automated fashion… From plugin install, configuration (for EN + FR in my particular case, with ZH possible in future), to content generation, I’d love to get that fully worked into my automation scenario. Any resources or docs you have on this full case are also appreciated.

    • You’re right. This page is very old and may be outdated. I’m adding to our todo list to review and refresh it.

      In the meanwhile, can you please report this question in our technical support forum? Our supporters should be able to help you get this working.