Wikimedia Developer Support

API query requires token in a GET request, but then produces error and asks to create a POST request

Hi,

I’ve a problem getting the correct token for these requests. The tokens can be aquired by API tokens module https://www.mediawiki.org/wiki/API:Tokens. This can be done employing Python, PHP or JavaScript. API modules (actions) are listed on the main page https://www.mediawiki.org/wiki/Wikibase/API.

According to documentation we make a request to order a token:

https://www.mediawiki.org/wiki/Special:ApiSandbox#action=query&format=json&meta=tokens

And we get response:

{
    "batchcomplete": "",
    "query": {
        "tokens": {
            "csrftoken": "ef0...95+\\"
        }
    }
}

If we perform Wikidata API request without token:

https://www.wikidata.org/w/api.php?action=wbcreateclaim&action=wbcreateclaim&entity=Q762&property=P7704&snaktype=value&value="agent/base/146741"

and we get following response:

{
    "error": {
        "code": "missingparam",
        "info": "The \"token\" parameter must be set.",
        "*": "See ... changes."
    },
    "servedby": "mw1404"
}

It requires a token. Therefore, the request for our goal with Wikidata API should be:

https://www.wikidata.org/w/api.php?action=wbcreateclaim&action=wbcreateclaim&entity=Q762&property=P7704&snaktype=value&value="agent/base/146741"&token=ef0...95+\\

The response is:

{
    "error": {
        "code": "mustpostparams",
        "info": "The following parameter was found in the query string, but must be in the POST body: token.",
        "*": "See ... changes."
    },
    "servedby": "mw1359"
}

When I created a POST request with token in body, I got an error again that token parameter is missing in URL.

How could I fix my quite simple GET request that it works?

Thanks

When I created a POST request with token in body, I got an error again that token parameter is missing in URL.

You probably made some mistake. (Note POST bodies should be application/x-www-form-urlencoded or multipart/form-data, not something like JSON.) But, you don’t show that part, so it’s impossible to tell.

Thanks. I’m using Talend API tester in Chrome to test this. After changing type of POST body, I’ve got new error that my csrf token is not valid. Can csrf token expire? Anyway I genereted fresh token from here:

https://www.mediawiki.org/wiki/Special:ApiSandbox#action=query&format=json&meta=tokens

using request URL: /w/api.php?action=query&format=json&meta=tokens

Then I created POST request using Content-Type " `application/x-www-form-urlencoded" and URL:

https://www.wikidata.org/w/api.php?action=wbcreateclaim&action=wbcreateclaim&entity=Q762&property=P7704&snaktype=value&value="agent/base/146741"&format=json

and body “token=ddade…ed259c5+\”

Response is:

{
    "error":{
        "code": "badtoken",
        "info": "Invalid CSRF token.",
        "*": "See https://www.wikidata.org/w/api.php for API usage. Subscribe to the mediawiki-api-announce mailing list at <https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce> for notice of API deprecations and breaking changes."
    },
    "servedby": "mw1288"
}

Should I generate token in a different way?

Thank you in advance

That seems fine, as long as the token is properly URL-encoded in the body.

May be you could provide a sample that works?

I’ve tried with different bodies: plain text e.g. “token=abc” and I tried to urlencode using Burp decoder the whole body “token=abc” or I encoded only “abc” part. In the first case with plain text I get error that csrf token is not valid, in other cases always that token parameter is missing:

{
    "error":{
        "code": "missingparam",
        "info": "The \"token\" parameter must be set.",
        "*": "See https://www.wikidata.org/w/api.php for API usage. Subscribe to the mediawiki-api-announce mailing list at <https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce> for notice of API deprecations and breaking changes."
    },
    "servedby": "mw1361"
}

Also that should actually work with GET request, not with POST? But then token parameter is generally not accepted, as I reported in my original message.

A valid POST body would look something like token=26ef6a7fc0a484190a94e9e962666e745edb6c55%2B%5C.

What I want is simply add an Europeana property P7704 with associated value “agent/base/146741” to a Wikidata entity e.g. Q762:
https://www.wikidata.org/w/api.php?action=wbcreateclaim&action=wbcreateclaim&entity=Q762&property=P7704&snaktype=value&value=“agent/base/146741”

I want to use Wikidata API or if that does not work QuickStatements or bots or something else. I tried all of these possibilities except the bots and nothing worked due to confusing documentation and missing samples. For instance GET request above requires a token. I registered accounts on mediawiki.org and order token. As far I understand from documentation I need “csrf” token. I get it using sandbox. If I do not use sandbox I get empty token in return. I can get “login” token both using sandbox and regular request. But I did not find information how to use it. I believe, I do not need it for my task. Anyway, when I try to add any token in GET request above to update Wikidata, it reports error: “The following parameter was found in the query string, but must be in the POST body: token.” When I switch to POST request for the same parameters and add token in the body URL encoded, then it reports “The “token” parameter must be set.” Above you will find related outputs.

In summary, after long search on the Web and looking into dozens of related pages, I cannot find example or information - how could I update entity property - which steps are required and which tokens and how I should use.

Regards,

Roman

As documented, the wbcreateclaim API only accepts POST requests. The method you described in

is the correct one. If it doesn’t work, the token is wrong; it’s stored in the session so you are probably making the two requests in a different session somehow.