.. index:: Advertisement .. _place_advertisement: Place Advertisement =================== Placing an advertisement using the Marktplaats API is at the moment only possible in free categories, unless you have a contract with Marktplaats, in which case advertisements are payed using an invoice. This example will show how to place an advertisement in a free category including images. In this example we use the *access_token* ``myaccesstoken`` to illustrate that in that place the *access_token* should be filled in. The full PHP example of which snippets are used in this guide can be found in this repository in the directory ``/phpexample``. Prerequisites ------------- You need to have an *access_token* which can be used to authenticate the request to the API. See :ref:`authentication` on how to get such a token. Step 1: Get the attributes for an category ------------------------------------------ Before we can place an advertisement, we need to now which in which category we will place the advertisement and which *attributes* we can use. *Attributes* are nothing more than *fields* in the JSON, but which are specific for the category the advertisement is placed in. For example, in a cars category, you can specify the *constructionYear* or the *model*, but these fields are not available in the books category. Some categories have mandatory fields. These fields have to be provided when creating a new advertisement. For example, in the cd players category, the condition attribute is mandatory. To get all the categories on Marktplaats we do a GET request on the endpoint /v1/categories: .. code-block:: http GET /v1/categories HTTP/1.1 Host: api.marktplaats.nl Authorization: Bearer myaccesstoken The response is a JSON object with all top level categories on Marktplaats: .. code-block:: json { "_links": { "self": { "href": "/v1/categories" }, "find": { "href": "/v1/categories{?categoryId}", "templated": true }, "describedby": { "href": "https://api.marktplaats.nl/docs/v1/categories.html" }, "curies": [ { "href": "https://api.marktplaats.nl/docs/v1/rels/{rel}.html", "templated": true, "name": "mp" } ] }, "_embedded": { "mp:category": [ { "_links": { "self": { "href": "/v1/categories/1" }, "up": { "href": "/v1/categories" } }, "_embedded": { "mp:category": [ { "_links": { "self": { "href": "/v1/categories/1/2" }, "up": { "href": "/v1/categories/1" }, "mp:category-attributes": { "href": "/v1/categories/1/2/attributes" } }, "categoryId": 2, "name": "Antiek | Bestek" }, ... } ] }, ... ] } } The result above is abbreviated, but the idea is clear. After we have determined which category we want to place the advertisement in, we can get the attributes for that category and use those to create the advertisement. For example, if we want to place an advertisement in the cd player category, we can get the attributes for that category by doing a GET request to ``/v1/categories/31/35/attributes`` .. code-block:: http GET /v1/categories/31/35/attributes HTTP/1.1 Host: api.marktplaats.nl Authorization: Bearer myaccesstoken The result will be a list of attributes, where each attribute has the following structure: .. code-block:: json { "key": "properties", "label": "Eigenschappen", "type": "LIST", "values": [ "Wisselaar", "Draagbaar", "Met radio" ], "mandatory": false, "searchable": true, "writable": true, "updateable": true } This attribute *properties* will be presented as *Eigenschappen* on the website, and it only accepts the values listed in the *values* array. If a different value is specified, an error will be produced. Furthermore, the attribute is not mandatory, it is possible to search on the attribute (on the website), it can be written (which means you can set it while placing an advertisement) and it can be updated (using a PUT or PATCH request on the advertisement). Step 2: Create the advertisement JSON ------------------------------------- Based on the data for the category we want to place an advertisement in, we can construct the json required to post an advertisement. To continue with the example of a CD player, the JSON for a minimal advertisement should look something like this: .. code-block:: json { "categoryId":35, "title":"Test cd player", "description":"This is an awesome cd-player", "condition":"Nieuw", "brand":"Sony", "properties":"Draagbaar", "delivery":"Ophalen", "priceModel":{ "modelType":"fixed", "askingPrice":3241 }, "location":{ "postcode":"1097DN" } } There are a couple of fields which are required, regardless of the category the advertisement is placed in: ``categoryId``, ``title``, ``description``, ``priceModel`` and ``location``. All the other fields are optional: ``condition``, ``brand``, ``properties`` and ``delivery`` are attributes of the category with id 35. Note that the ``properties`` attribute is of the type ``LIST``, and can also contain a array of values instead of a single value. The JSON should be send to the Marktplaats API using a ``POST`` request: .. code-block:: http POST /v1/advertisements HTTP/1.1 Host: api.marktplaats.nl Authorization: Bearer myaccesstoken Content-Type: application/json { "categoryId":35, "title":"Test cd player", "description":"This is an awesome cd-player", "condition":"Nieuw", "brand":"Sony", "properties":"Draagbaar", "delivery":"Ophalen", "priceModel":{ "modelType":"fixed", "askingPrice":3241 }, "location":{ "postcode":"1097DN" } } If we do this in PHP, and we have a form which is containing the field names matching the names of the API, it would look something like this: .. code-block:: PHP session_start(); $apiUrl = 'https://api.marktplaats.nl'; $accessToken = $_SESSION['access_token']; $l1id=$_GET['l1id']; $categoryId = $_POST['categoryId']; $adData = $_POST; $fixedPrice = $_POST['fixedPrice']; unset($adData['fixedPrice']); $adData['priceModel']['modelType'] = 'fixed'; $adData['priceModel']['askingPrice'] = intval($fixedPrice); $adData['location']['postcode'] = $adData['postcode']; unset($adData['postcode']); $adData['categoryId'] = intval($adData['categoryId']); $attributes = retrieveAttributes($apiUrl, $l1id, $categoryId, $accessToken); foreach($attributes->fields as $attribute) { if ($attribute->type == 'NUMERIC' && isset($adData[$attribute->key])) { $adData[$attribute->key] = intval($adData[$attribute->key]); } } $adJson = json_encode($adData); $url = $apiUrl . "/v1/advertisements?_links=false"; $jsonresult = apiCall($url, $adJson, $accessToken, 'POST'); Most code is needed to correct the type of numeric fields (like ``categoryId``). Note that the snippet above lacks any form of error handling. In any production usage of the API, errors should be handled. The API returns a common error document which contains both machine readable as well as human readable error messages. When the language is set correctly in the request, using the ``accept-language`` header, the messages are returned in the correct language. At the moment the only supported languages are Dutch and English. Step 3: Adding images --------------------- After successfully having created an advertisement, the first thing you will usually want to do, is attach images to your advertisement. To do this you do a ``POST`` request to the images endpoint. .. code-block:: http POST /v1/advertisements/m1000/images HTTP/1.1 Host: api.marktplaats.nl Authorization: Bearer myaccesstoken Content-Type: application/json { "urls": [ "http://www.marktplaats.nl/i/common/images/marktplaats-logo.png", "http://www.marktplaats.nl/i/common/images/mensen.jpg" ], "replaceAll": true } .. code-block:: http HTTP/1.1 202 Accepted Content-Type: application/json;charset=UTF-8 { "_links":{ "curies":[ { "href":"https://api.marktplaats.nl/docs/v1/rels/{rel}.html", "templated":true, "name":"mp" } ] }, "_embedded":{ "mp:advertisement-image":[ { "_links":{ "self":{ "href":"/v1/images/7" }, "mp:image-blob":{ "href":"/v1/images/7/{size}/blob", "templated":true }, "mp:image-meta":{ "href":"/v1/images/7/{size}/meta", "templated":true } }, "imageId":7, "status":"downloading" }, { "_links":{ "self":{ "href":"/v1/images/8" }, "mp:image-blob":{ "href":"/v1/images/8/{size}/blob", "templated":true }, "mp:image-meta":{ "href":"/v1/images/8/{size}/meta", "templated":true } }, "imageId":8, "status":"downloading" } ] } } Uploading images is an asynchronous process. You provide us with urls from where the images can be retrieved and we download the these images when there is capacity available. Usually this will be pretty quick. .. configuration-block:: .. code-block:: curl curl 'http://api.marktplaats.nl/v1/advertisements/m1000/images' \ -H 'Authorization: Bearer myaccesstoken' \ -H 'Content-Type: application/json' \ --data-binary $'{"urls": [ "http://www.marktplaats.nl/i/common/images/marktplaats-logo.png", "http://www.marktplaats.nl/i/common/images/mensen.jpg" ], "replaceAll": true}' .. code-block:: php array( 'http://www.marktplaats.nl/i/common/images/marktplaats-logo.png', 'http://www.marktplaats.nl/i/common/images/mensen.jpg' ), 'replaceAll' => true ); $ch = curl_init('http://api.marktplaats.nl/v1/advertisements/m1000/images'); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); var_dump( curl_exec($ch) ); curl_close($ch); Most of the time. This is all there is to it, and at this point you can continue with posting other ads or buying features. But if you want to make absolutely sure that images have finished downloading before continuing then you can poll the individual image resources by doing a ``GET`` request to the image endpoint. .. code-block:: http GET /v1/images/8 HTTP/1.1 Host: api.marktplaats.nl Authorization: Bearer myaccesstoken .. code-block:: http HTTP/1.1 200 OK Content-Type: application/json { "_links": { "curies": [ { "href": "https://api.marktplaats.nl/docs/v1/rels/{rel}.html", "name": "mp", "templated": true } ], "describedby": { "href": "https://api.marktplaats.nl/docs/v1/image.html" }, "mp:image-blob": { "href": "/v1/images/8/{size}/blob", "templated": true }, "mp:image-meta": { "href": "/v1/images/8/{size}/meta", "templated": true }, "self": { "href": "/v1/images/8" } }, "imageId": 8, "status": "available" } When the status field changes from ``downloading`` to ``available`` then the image has been successfully downloaded and attached to the advertisement .. configuration-block:: .. code-block:: curl curl 'http://api.marktplaats.nl/v1/images/8' \ -H 'Authorization: Bearer myaccesstoken' .. code-block:: php true ); $ch = curl_init('https://api.marktplaats.nl/v1/advertisements/m1000/features/topadvertentie/buy-feature'); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); var_dump( curl_exec($ch) ); curl_close($ch); Step 5: Updating the advertisement ---------------------------------- It is possible to change an advertisement after it has been created. However not all properties of an advertisement are updatable, even when these same properties where editable on creation. So be sure to look both at the advertisement `attributes documentation in the reference documentation `_ and at the category attributes (see step 1 of this guide) before attempting to update a property. Only attributes that are marked as updateable can be changed. An advertisement can be updated in two different ways. You can do a full update, by performing a ``PUT`` request, or a partial update, by doing a ``PATCH`` request against the advertisement endpoint Lets demonstrate a the former case first. .. code-block:: http PUT /v1/advertisements/m1000 HTTP/1.1 Host: api.marktplaats.nl Content-Type: application/json { "itemId": "m1000", "title": "Updated title", "description": "This is an awesome cd-player", "categoryId": 35, "priceModel": { "modelType": "fixed", "askingPrice": 3241 }, "location": { "postcode": "1097DN", "cityName": "Amsterdam" }, "seller": { "sellerId": 1, "sellerName": "Robin", "phoneNumber": "020-4167248", "acceptPaypal": false }, "showOnMap": false, "status": "online", "startDate": "2014-12-23T16:59:39Z", "closeDate": "2015-01-23T16:59:39Z", "condition": "Nieuw", "brand": "Sony", "properties": [ "Draagbaar" ], "delivery": "Ophalen" } .. configuration-block:: .. code-block:: curl curl 'https://api.marktplaats.nl/v1/advertisements/m1000' \ -X PUT -H 'Authorization: Bearer myaccesstoken' \ -H 'Content-Type: application/json' \ --data-binary $'{\n "itemId": "m1000",\n "title": "Test cd player",\n "description": "This is an awesome cd-player",\n "categoryId": 35,\n "priceModel": {\n "modelType": "fixed",\n "askingPrice": 3241\n },\n "location": {\n "postcode": "1097DN",\n "cityName": "Amsterdam"\n },\n "seller": {\n "sellerId": 1,\n "sellerName": "lalala",\n "phoneNumber": "",\n "acceptPaypal": false\n },\n "showOnMap": false,\n "status": "deactivated",\n "startDate": "2014-12-23T16:59:39Z",\n "closeDate": "2015-01-23T16:59:39Z",\n "condition": "Nieuw",\n "brand": "Sony",\n "properties": [\n "Draagbaar"\n ],\n "delivery": "Ophalen"\n}' .. code-block:: php 'm1000', 'title' => 'Test cd player', 'description' => 'This is an awesome cd-player', 'categoryId' => 35, 'priceModel' => array( 'modelType' => 'fixed', 'askingPrice' => 3241 ), 'location' => array( 'postcode' => '1097DN', 'cityName' => 'Amsterdam' ), 'seller' => array( 'sellerId' => 1, 'sellerName' => 'lalala', 'phoneNumber' => '', 'acceptPaypal' => false ), 'showOnMap' => false, 'status' => 'deactivated', 'startDate' => '2014-12-23T16:59:39Z', 'closeDate' => '2015-01-23T16:59:39Z', 'condition' => 'Nieuw', 'brand' => 'Sony', 'properties' => array( 'Draagbaar' ), 'delivery' => 'Ophalen' ); $ch = curl_init('https://api.marktplaats.nl/v1/advertisements/m1000'); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT'); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); var_dump( curl_exec($ch) ); curl_close($ch); In the above example we overwrote all the fields all at once. In some cases you may only want to update only one or two fields, leaving the rest unchanged. In that case you could perform a ``PATCH`` request instead. The body of this ``PATCH`` request should be a JSON Patch document. JSON Patch is a standard format for describing changes to a JSON document. A JSON Patch document is just a JSON file containing an array of patch operations. The patch operations supported by JSONPatch are “add”, “remove”, “replace”, “move”, “copy” and “test”. The operations are applied in order; if any of them fail then the whole patch operation should abort. Covering this standard in detail is outside of the scope of this document but there is `extensive documentation `_ on this format available online. Lets quickly take a look at what a request for updating just the title of an advertisement could look like. .. code-block:: http PATCH /v1/advertisements/m1000 HTTP/1.1 Host: api.marktplaats.nl Content-Type: application/json-patch+json [ {"op":"replace", "path":"/title", "value":"the new title"} ] .. configuration-block:: .. code-block:: curl curl 'https://api.marktplaats.nl/v1/advertisements/m1000' \ -X PATCH -H 'Authorization: Bearer myaccesstoken' \ -H 'Content-Type: application/json-patch+json' \ --data-binary $'[{"op":"replace", "path":"/title", "value":"the new title"}]' .. code-block:: php 'replace', 'path' => '/title', 'value' => 'the new title' ); $ch = curl_init('https://api.marktplaats.nl/v1/advertisements/m1000'); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH'); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); var_dump( curl_exec($ch) ); curl_close($ch); Step 6: Removing an advertisement --------------------------------- Removing an advertisement is straightforward. You simply do a ``DELETE`` request against the advertisement endpoint. No Request body is required .. code-block:: http DELETE /v1/advertisements/m1000 HTTP/1.1 Host: api.marktplaats.nl .. configuration-block:: .. code-block:: curl curl 'https://api.marktplaats.nl/v1/advertisements/m1000' \ -X DELETE -H 'Authorization: Bearer myaccesstoken' .. code-block:: php