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 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:

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:

{
  "_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

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:

{
 "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:

{
  "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:

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:

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.

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
}
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.

  • 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}'
    
  • PHP
    <?php
    
    $header = array(
      'Content-type: application/json',
      'Authorization: Bearer myaccesstoken'
    );
    
    $data = array(
        'urls' => 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.

GET /v1/images/8 HTTP/1.1
Host: api.marktplaats.nl
Authorization: Bearer myaccesstoken
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

  • CURL
    curl 'http://api.marktplaats.nl/v1/images/8' \
     -H 'Authorization: Bearer myaccesstoken'
    
  • PHP
    <?php
    
    $header = array(
        'Content-type: application/json',
        'Authorization: Bearer myaccesstoken'
    );
    
    $ch = curl_init('http://api.marktplaats.nl/v1/advertisements/m1000/images');
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    
    var_dump( curl_exec($ch) );
    
    curl_close($ch);
    

Step 4: Buying features

Immediately after successfully creating an advertisement it becomes possible to purchase features that make your advertisement stand out.

To get all list of all features that can be bought for an advertisement we do a GET request on the features endpoint

GET /v1/advertisements/m1000/features HTTP/1.1
Host: api.marktplaats.nl
Authorization: Bearer myaccesstoken

The response is a JSON object that lists all possible features for an advertisement

HTTP/1.1 200 OK
Content-Type: application/json

{
  "_links": {
    "self": {
      "href": "/v1/advertisements/m1000/features"
    },
    "curies": [
      {
        "href": "https://api.marktplaats.nl/docs/v1/rels/{rel}.html",
        "templated": true,
        "name": "mp"
      }
    ]
  },
  "_embedded": {
    "mp:advertisement-feature": [
      {
        "_links": {
          "self": {
            "href": "/v1/advertisements/m1000/features/fotoknaller"
          },
          "mp:buy-advertisement-feature": {
            "href": "/v1/advertisements/m1000/features/fotoknaller/buy-feature"
          }
        },
        "name": "fotoknaller",
        "price": 500,
        "available": true,
        "active": false
      },
      {
        "_links": {
          "self": {
            "href": "/v1/advertisements/m1000/features/url"
          }
        },
        "name": "url",
        "price": 900,
        "available": false,
        "active": true
      },
      {
        "_links": {
          "self": {
            "href": "/v1/advertisements/m1000/features/dagtopper"
          },
          "mp:buy-advertisement-feature": {
            "href": "/v1/advertisements/m1000/features/dagtopper/buy-feature"
          }
        },
        "name": "dagtopper",
        "price": 151,
        "available": true,
        "active": false
      },
      {
        "_links": {
          "self": {
            "href": "/v1/advertisements/m1000/features/omhoogplaatsen"
          },
          "mp:buy-advertisement-feature": {
            "href": "/v1/advertisements/m1000/features/omhoogplaatsen/buy-feature"
          }
        },
        "name": "omhoogplaatsen",
        "price": 130,
        "available": true,
        "active": false
      },
      {
        "_links": {
          "self": {
            "href": "/v1/advertisements/m1000/features/topadvertentie"
          },
          "mp:buy-advertisement-feature": {
            "href": "/v1/advertisements/m1000/features/topadvertentie/buy-feature"
          }
        },
        "name": "topadvertentie",
        "price": 1100,
        "available": true,
        "active": false
      },
      {
        "_links": {
          "self": {
            "href": "/v1/advertisements/m1000/features/videoopvaller"
          }
        },
        "name": "videoopvaller",
        "price": 105,
        "available": false,
        "active": false
      },
      {
        "_links": {
          "self": {
            "href": "/v1/advertisements/m1000/features/blikvanger"
          },
          "mp:buy-advertisement-feature": {
            "href": "/v1/advertisements/m1000/features/blikvanger/buy-feature"
          }
        },
        "name": "blikvanger",
        "price": 4500,
        "available": true,
        "active": false
      }
    ]
  }
}

If the available field of an embedded feature is set to true, this feature is available for purchase. If we look at the example output above you can see that the topadvertentie feature is available but the url feature is not. In this case the url feature is unavailable because it has already been bought. We know this because the active field is set to true.

It is worth noting that the prices (in cents) are the prices that users of the marktplaats website would pay. In many cases other arrangements have been made with api partners and these arrangements are not reflected in the price

Let’s continue and buy the topadvertentie. To do this we we do a POST request to the features endpoint

POST /v1/advertisements/m1000/features/topadvertentie/buy-feature HTTP/1.1
Host: api.marktplaats.nl
Content-Type: application/json

{
    "pay": true
}

If the call is successful then an order will be returned and the feature is now active. It might however still take a few minutes before all of the features that you have bought are visible on the website

  • CURL
    curl 'https://api.marktplaats.nl/v1/advertisements/m1000/features/topadvertentie/buy-feature' \
     -H 'Authorization: Bearer myaccesstoken' \
     -H 'Content-Type: application/json' \
     --data-binary '{ "pay":true }'
    
  • PHP
    <?php
    
    $header = array(
        'Content-type: application/json',
        'Authorization: Bearer myaccesstoken'
    );
    
    $data = array(
        'pay' => 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.

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"
}
  • 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}'
    
  • PHP
    <?php
    
    $header = array(
        'Content-type: application/json',
        'Authorization: Bearer myaccesstoken'
    );
    
    $data = array(
        'itemId' => '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.

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"}
]
  • 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"}]'
    
  • PHP
    <?php
    
    $header = array(
        'Content-type: application/json',
        'Authorization: Bearer myaccesstoken'
    );
    
    $data = array(
        'op' => '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

DELETE /v1/advertisements/m1000 HTTP/1.1
Host: api.marktplaats.nl
  • CURL
    curl 'https://api.marktplaats.nl/v1/advertisements/m1000' \
     -X DELETE -H 'Authorization: Bearer myaccesstoken'
    
  • PHP
    <?php
    
    $header = array(
        'Authorization: Bearer myaccesstoken'
    );
    
    $ch = curl_init('https://api.marktplaats.nl/v1/advertisements/m1000');
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    
    var_dump( curl_exec($ch) );
    
    curl_close($ch);
    

This concludes the placing an advertisement section of this guide. We’ve showed you how to place an advertisement, attach images, purchase features, update an advertisement and finally how to remove your advertisement. In the next section we will describe how