The Pro Import API allows you to manage your Blocket ads programmatically. This document describes how to create, update and delete ads, by invoking a REST API. It also describes how to get information about the state of your ads.
The Pro Import API should only be used for managing ads on Blocket and Bytbil, not for powering websites or similar. API users must keep a record of ads in their own system. Any changes made directly in Blocket Admin will not be reflected when retrieving the ad via the API. The API only exposes data that was created or updated through the API itself. For consistency and data integrity, all ad modifications should preferably be performed via the API.
Are you migrating from legacy file imports? Pay attention to the chapter on migration.
For recent changes and new features, see the Changelog.
The API documentation is available at the following URLs:
| Service | URL |
|---|---|
| Swagger | https://api.blocket.se/pro-import-api/docs/swagger-ui/ |
| ReDoc | https://api.blocket.se/pro-import-api/docs/redoc/ |
There is no separate test environment. All API integrations must be developed and tested directly in the production environment.
To avoid publishing test ads on the marketplaces, you can set visible: false when creating ads. These ads will:
There is also a /v4/{vehicle_type}/validate endpoint that can be used to validate input data without saving anything.
The API allows you to create, update, renew and delete ads. After making a request it will be processed asynchronously, and you will be able to check the progress and result by looking at the action logs associated with the ad, and the final state of the ad.
The common procedure to create an ad is as follows:
If everything went well, the response from the HTTP GET will contain info on all state transitions performed during the workflow execution (logs field), as well as a Blocket ad ID (blocket_ad_id) for the newly created Blocket ad and Bytbil ad ID (offer_id) for registered vehicles.
Important: The
blocket_ad_idfield is assigned asynchronously after the ad has been published on Blocket. It will benullimmediately after POST β this is expected behavior. Poll viaGET /v4/ad/{source_id}until the log showspublish | doneandblocket_ad_idis populated. Typical latency is seconds to minutes depending on current load.
All actions made on the ad while processing it will have their own state. By inspecting the ad logs you can track each action and its state. All actions start with the state processing and transition into done when completed. If there was an error while processing, the action will end up in state error.
The ad itself will have a state indicating if the ad was created or deleted. While this means that the ad was successfully created in the API, there could be more information in the ad logs which could indicate that there was an issue with a specific action.
| Name | Type | Description |
|---|---|---|
create |
string | Action for creating the ad within the API |
update |
string | Action for updating the ad |
bump |
string | Action for renewing the ad on marketplaces |
boost |
string | Action for activating Pole Position on the ad |
handle_media |
string | Action for handling media on the ad (uploading images, removing previous images etc) |
publish |
string | Action for publishing the ad on marketplaces |
delete |
string | Action for removing the ad |
unpublish |
string | Action for unpublishing the ad on marketplaces |
| Name | Type | Description |
|---|---|---|
processing |
string | Ad action is being processed |
done |
string | Ad action completed successfully |
error |
string | There were error(s) while processing the action |
Each entry in the log array has the following fields:
| Field | Type | Description |
|---|---|---|
request_id |
string (UUID) | Groups all actions performed during a single API request |
created |
string (ISO 8601) | Timestamp when the log entry was created |
action |
string | One of the ad actions listed above (e.g. create, publish) |
state |
string | One of processing, done, or error |
external_message |
string / object | Human-readable status message or error details |
Example value (after a successful create + publish flow):
[
{"request_id": "a1b2c3d4-...", "created": "2025-01-15T10:00:00Z", "action": "create", "state": "processing", "external_message": "Processing"},
{"request_id": "a1b2c3d4-...", "created": "2025-01-15T10:00:00Z", "action": "create", "state": "done", "external_message": "Ad created"},
{"request_id": "a1b2c3d4-...", "created": "2025-01-15T10:00:01Z", "action": "handle_media", "state": "processing", "external_message": "Processing"},
{"request_id": "a1b2c3d4-...", "created": "2025-01-15T10:00:02Z", "action": "handle_media", "state": "done", "external_message": "Images uploaded"},
{"request_id": "a1b2c3d4-...", "created": "2025-01-15T10:00:03Z", "action": "publish", "state": "processing", "external_message": "Publishing in progress."},
{"request_id": "a1b2c3d4-...", "created": "2025-01-15T10:00:05Z", "action": "publish", "state": "done", "external_message": "Ad published"}
]
Tip: To check if an ad has been fully published, poll
GET /v4/{vehicle_type}/{source_id}and look for a log entry withaction: publishandstate: done. Therequest_idfield lets you correlate which actions belong to the same API call. For ads with a long action history, useGET /v4/ad/{source_id}/log?request_id={request_id}to retrieve only the log entries for a specific request.
Ad states
| Name | Type | Description |
|---|---|---|
created |
string | Ad is created. Note: the ad may not be visible on the marketplace if visible=false is set or a marketplace error occurred β check log messages for details. |
deleted |
string | Ad is deleted (soft delete β the ad is unpublished from all marketplaces but remains retrievable via GET) |
Note: The
statefield is updated asynchronously by the background worker. After aDELETErequest, the state will remaincreateduntil the worker has finished processing. Poll viaGETand check for a log entry withaction: deleteandstate: doneβ at that point the ad's state will bedeleted. See the DELETE endpoint section for details.Deletion is a soft delete. The ad is unpublished from all marketplaces, but the ad data is retained in the API and can still be retrieved via
GET /v4/ad/{source_id}orGET /v4/{vehicle_type}/{source_id}.
All invocations to the API require a JWT token sent as a X-Auth-Token request header. You can get one from customer support by contacting butikssupport@blocket.se. The token contains one of two scope types:
dealer_code β Grants access to a single dealer. The dealer_code field can be omitted from the request body β it is inferred from the token.dealer_group β Grants access to all dealers within a group. A dealer group contains one or more dealer codes. When creating an ad (POST), you must include dealer_code in the request body to specify which dealer the ad belongs to. For updates and deletes, the dealer_code is read from the existing ad.| Status | Meaning | When |
|---|---|---|
200 |
OK | GET, PUT, PATCH, DELETE succeeded |
201 |
Created | POST succeeded β ad created and queued for processing |
400 |
Bad Request | Validation error β see error format below |
401 |
Unauthorized | Missing or invalid X-Auth-Token header |
403 |
Forbidden | Token is valid but lacks required scope for the endpoint |
404 |
Not Found | Ad with the given source_id does not exist or does not belong to your dealer |
When a request fails validation, the API returns HTTP 400 with a JSON object. Each key is a field name, and each value is an array of error messages for that field:
{
"title": ["This field is required."],
"contact": ["This field is required."]
}
Nested field errors (e.g. category_fields) include the full path:
{
"category_fields": {
"registration_number": ["This field is required."],
"brand": ["\"invalid_brand\" is not a valid choice."]
}
}
Non-field errors (e.g. business logic violations) use a string array under a single key:
["Ad has been deleted, cannot update"]
Authentication errors (401) return:
{"detail": "Invalid token: <error details>"}
/v4/{vehicle_type}/) β Current version, recommended for new integrations. Supports all vehicle categories including full field support for Moped, Camper, Caravan, Trailer, Boats and Agriculture./v3/ad) β Legacy version, still fully supported. New features are V4-only.API base URL V3: https://api.blocket.se/pro-import-api/v3/
API base URL V4: https://api.blocket.se/pro-import-api/v4/
It is possible to renew a Blocket ad. This invocation is asynchronous and requires no JSON body. A renewal of an ad will make it appear as new β first in the listing (charges apply).
GET /v4/ad/{source_id}/bump
initiates a renewal of a Blocket adFor registered vehicles, you can choose to exclude either Blocket or Bytbil by passing exclude_bytbil=true or exclude_blocket=true.
It is also possible to activate Pole Position on an ad. This will make the ad appear first in the search result. If several ads with Pole Position match the end user's search filter, only one is shown. Pole Position lasts for 3 days. Charges apply.
GET /v4/ad/{source_id}/pole_position
activates Pole Position on an adPrerequisites: The ad must be visible (visible=true). Pole Position is only available for registered vehicle categories (Blocket only).
Note: All generic
/v4/ad/endpoints (GET, DELETE, bump, pole_position, retry) are also available on the typed endpoints (/v4/{vehicle_type}/). For POST, PUT and PATCH you must use the typed endpoints.
The POST, PUT, PATCH and DELETE API invocations are asynchronous. This means you will get a prompt response, but the operation will be executed afterwards. The only synchronous operation is the GET invocation (except /bump and /pole_position).
Use this endpoint to create an ad. The creation will happen asynchronously and you will need to check the status/result of the operation with a GET request.
Refer to the OpenAPI documentation for more detailed information about all fields.
| Name | Type | In | Required | Description |
|---|---|---|---|---|
id |
string (UUID) | Response | β | Internal ad ID |
source_id |
string | Both | Yes | Client's reference ID. See source_id section. |
dealer_code |
string | Both | Depends | The dealer_code for which to create the ad. Required if auth scope is dealer_group, not needed if auth scope is dealer_code. |
category_id |
int | Both | Yes | See category_id section |
state |
string | Response | β | Ad state: created or deleted. Updated asynchronously β see Ad States section. |
title |
string | Both | Depends | Ad title. Required for: boat, truck, bus, construction, and agriculture categories. Must not be sent for: car, transport, motorcycle, moped, snowmobile, ATV, camper, caravan, and trailer β the title is generated automatically, and including it will return a 400 error. |
body |
string | Both | No | Ad body text |
visible |
boolean | Both | No | Default=true. Set to false to prevent the ad from being published on marketplaces. |
price |
array of objects | Both | No | See price section |
image_urls |
array of strings | Request | No | See image_urls section |
image_refs |
array of objects | Response | β | Processed image references. Each object contains url (original URL), cdn_url (CDN URL where the image is served), id (internal image reference ID), and checksum. |
url |
string | Both | No | URL to page at the seller's website with more info about the ad. |
video_url |
string | Both | No | URL to Youtube or Vimeo video that is shown on the ad page. |
location |
object | Both | No | See location section. |
contact |
object | Both | Depends | See contact section. Required for: boat, truck, bus, construction, and agriculture categories. Must not be sent for: car, transport, motorcycle, moped, snowmobile, ATV, camper, caravan, and trailer β including it will return a 400 error. |
category_fields |
object | Both | Yes | Vehicle-specific attributes (e.g. registration_number, brand, fuel, mileage). These fields are displayed on the ad page on blocket.se and enable filtering in search results. The available fields vary by vehicle type β see the Category Reference or the Swagger UI for full field specifications per category. |
dont_publish_on_failed_images |
boolean | Both | No | Default=false. Set to true if you don't want to publish the ad if any of the images have an error. |
product_declaration |
string | Both | No | URL to a hosted "varudeklaration" in PDF format. |
blocket_ad_id |
string | Response | β | Blocket marketplace ad ID. Assigned asynchronously after publish. |
offer_id |
string | Response | β | Bytbil/Offer API ID. Only present for registered vehicle categories. |
api_version |
string | Response | β | API version used to create the ad (v3 or v4) |
created |
string (ISO 8601) | Response | β | Timestamp when the ad was created |
updated |
string (ISO 8601) | Response | β | Timestamp when the ad was last updated |
log |
array of objects | Response | β | Action log entries (when included via query parameter). See Action Log section. |
source_idYour ID for the ad. Each ad must have a unique source_id, since it is used to create, update, get and delete the ad.
We recommend using a UUID here to ensure uniqueness.
Important: Once a
source_idhas been used for a dealer, it cannot be reused β even after the ad is deleted. This is because deleted ads are retained in the system (soft delete). Use UUIDs to avoid collisions.
category_id| ID | Path / Name | API version |
|---|---|---|
1020 |
Vehicles > Cars | V3, V4 |
1021 |
Vehicles > Vans | V3, V4 |
1045 |
Vehicles > Trailer | V3, V4 |
1060 |
Vehicles > Boats | V4 |
1063 |
Vehicles > Boats > Inflatable / RIB Boat | V3 |
1064 |
Vehicles > Boats > Dinghy / Rowboat | V3 |
1065 |
Vehicles > Boats > Kayak / Canoe | V3 |
1066 |
Vehicles > Boats > Jet Ski | V3 |
1067 |
Vehicles > Boats > Other | V3 |
1101 |
Vehicles > Caravan | V3, V4 |
1102 |
Vehicles > Motorhome | V3, V4 |
1121 |
Vehicles > Mopeds & A-Tractors > Mopeds | V3, V4 |
1122 |
Vehicles > Mopeds & A-Tractors > A-Tractors | V3, V4 |
1140 |
Vehicles > Motorcycle | V3, V4 |
1143 |
Vehicles > ATV | V3, V4 |
1180 |
Vehicles > Snowmobile | V3, V4 |
1221 |
Vehicles > Trucks, Machinery & Construction > Truck & Bus | V3 |
1222 |
Vehicles > Forestry & Agricultural Machinery > Agricultural Machinery | V3 |
1223 |
Vehicles > Trucks, Machinery & Construction > Construction Machinery | V3 |
1224 |
Vehicles > Trucks, Machinery & Construction > Truck & Material Handling | V3 |
1225 |
Vehicles > Forestry & Agricultural Machinery > Forestry Machinery | V3 |
1226 |
Vehicles > Forestry & Agricultural Machinery > Ground Care Machinery | V3 |
1227 |
Vehicles > Forestry & Agricultural Machinery > Agriculture Thresher | V4 |
1228 |
Vehicles > Forestry & Agricultural Machinery > Agriculture Tractor | V4 |
1229 |
Vehicles > Forestry & Agricultural Machinery > Agriculture Tools | V4 |
1321 |
Vehicles > Trucks, Machinery & Construction > Bus | V4 |
1322 |
Vehicles > Trucks, Machinery & Construction > Truck | V4 |
1323 |
Vehicles > Trucks, Machinery & Construction > Construction | V4 |
For V4-only categories, see the Category Reference for full field specifications and examples.
priceArray of objects representing prices for the ad. For registered vehicles, you can also send in price as leasing. Please see the OpenAPI documentation for details.
| Type | Description |
|---|---|
list |
Regular list price |
reduced |
Reduced/sale price (not allowed on POST, only on PUT/PATCH) |
leasing |
Leasing price (only supported by registered vehicle categories) |
Example value:
[{"type": "list", "amount": 7000, "currency": "SEK"}]
image_urlsArray of strings containing URLs to images for the ad. Accepted formats are JPG and PNG. The sort order of the images is the order of the list. Every time you want to update images, you need to send the complete list and it will replace the previous list. Already uploaded images that match an existing checksum will be internally reused.
Example value:
[
"https://cdn.example.com/image1.jpg",
"https://cdn.example.com/image2.jpg"
]
locationObject with location parameters. If omitted or set to null, the ad's location defaults to your dealer's address configured in Blocket Admin. The API response will show location: null but the published ad will use the dealer's location.
There are three alternatives for setting ad location:
| Parameter name | Type | Required | Description |
|---|---|---|---|
latitude + longitude |
string | No | Decimal coordinates. Both must be provided together. Works for all categories. |
zipcode |
string | No | Zip/postal code without spaces. Works for all categories. |
lkf |
string | No | Swedish area code (LKF). See lkf section. Only works for non-registered vehicle categories (boats, agriculture, etc.). Not supported for registered vehicles (car, motorcycle, etc.). |
Example value:
{"latitude": 59.53485752244251, "longitude": 16.71093897174057}
lkfLKF is a Swedish abbreviation for "lΓ€n, kommun, fΓΆrsamling" (region, municipality, parish), and is a four or six digit area code (LK vs full LKF). Either the four or six digit version of the LKF can be used, where the latter increases location accuracy further and is particularly relevant to increase accuracy for ads located in Stockholm, GΓΆteborg and MalmΓΆ. For example, the LK and full LKF for Vaksala in the city of Uppsala is:
LK code: 0380
LKF code: 038004
Where the LK code 0380 refers to the greater Uppsala-area and the six digit LKF code 038004 refers to Vaksala specifically. A complete list of LKF codes can be found here.
Please note that Blocket does not show exact coordinates, but resolves to a predefined geographical area.
contactObject with contact information. Will override store information. Required for: boat, truck, bus, construction, and agriculture categories. Must not be sent for: car, transport, motorcycle, moped, snowmobile, ATV, camper, caravan, and trailer β including it will return a 400 error.
| Parameter name | Type | Required | Description |
|---|---|---|---|
name |
string | No | Seller's name |
phone |
string | No | Phone number (digits only, optionally prefixed with +, 8β16 characters) |
email |
string | Yes | Email address |
Example value:
{"name": "Sir Henry Williamsworth III", "phone": "0700000000", "email": "email@example.com"}
category_fieldsEvery vehicle type has its own set of category_fields that describe the vehicle's attributes β for example registration_number, brand, model, fuel, mileage and body_type for cars, or brand, model_year, powertrain, physics and equipments for boats. These fields are required when creating a V4 ad and are what makes the ad searchable and filterable on blocket.se.
The available fields vary by vehicle type. See the Category Reference for full field specifications and examples per category.
Tip: For the most up-to-date field definitions and valid enum values, open
POST /v4/{vehicle_type}(e.g.POST /v4/car) in the Swagger UI and click the Schema tab next to "Example Value". This shows exact field names, types, required/optional status and all accepted values for each category.
Use this endpoint to list your ad-requests and see progress/result of previous POST/PUT/DELETE operations. Each POST/PUT/DELETE on a certain source_id will appear as an individual entry. Log messages can be included with the help of the include field but only the last 100 messages will be provided. To get older log messages β see the endpoint for getting ad logs.
| Name | Type | Description |
|---|---|---|
id |
Filter | Internal ad ID (UUID) |
state |
Filter | Values available: created, deleted |
source_id |
Filter | Client's reference ID (exact match) |
source_id__in |
Filter | Comma separated list of source IDs to include |
source_id__icontains |
Filter | Case-insensitive partial match on source ID |
dealer_code |
Filter | Customer identifier |
category_id |
Filter | Category ID (exact match) |
category_id__in |
Filter | Comma separated list of category IDs to include |
search |
Filter | Case-insensitive text search across the title and body fields |
blocket_ad_id |
Filter | Ad ID on Blocket |
blocket_ad_id__in |
Filter | Comma separated list of Blocket ad IDs to include |
registration_number |
Filter | Registration number of the vehicle (case-insensitive). Only works for registered vehicles. |
created__gt |
Filter | Format: YYYY-MM-DD HH:MM:SS |
created__gte |
Filter | Format: YYYY-MM-DD HH:MM:SS |
created__lt |
Filter | Format: YYYY-MM-DD HH:MM:SS |
created__lte |
Filter | Format: YYYY-MM-DD HH:MM:SS |
updated__gt |
Filter | Format: YYYY-MM-DD HH:MM:SS |
updated__gte |
Filter | Format: YYYY-MM-DD HH:MM:SS |
updated__lt |
Filter | Format: YYYY-MM-DD HH:MM:SS |
updated__lte |
Filter | Format: YYYY-MM-DD HH:MM:SS |
limit |
Setting | Limit results |
offset |
Setting | Offset results |
ordering |
Setting | Values available: -created, created, -updated, updated, -source_id, source_id |
fields |
Setting | Comma separated fields to include in response |
include |
Setting | Comma separated fields to include other than the defaults. Fields excluded by default in this endpoint are: log. Note: only the 100 latest log messages are included. To view more messages use /v4/ad/{source_id}/log endpoint. |
GET /v4/ad?state=deleted
GET /v4/boat?state=created&ordering=-created&limit=10
GET /v4/ad?source_id__in=uuid-1,uuid-2,uuid-3&include=log
GET /v4/car?created__gte=2025-01-01 00:00:00&ordering=-created
Look up a specific ad based on source ID. Only includes the last 100 log messages.
Look up all log messages for an ad. This endpoint provides a paginated list of all log messages for an ad.
| Name | Type | Description |
|---|---|---|
action |
Filter | Values available: create update bump boost delete handle_media publish unpublish |
state |
Filter | Values available: processing done error |
request_id |
Filter | Filter by request ID (UUID) to see only log entries from a specific API call |
limit |
Setting | Limit results |
offset |
Setting | Offset results |
ordering |
Setting | Values available: -created created |
Use this endpoint to update an ad. Same signature as ad creation except for source_id which is provided in the path instead of the body. The ads contents will be updated but it will not appear as new. To renew an ad β see /v4/ad/{source_id}/bump endpoint.
Important β merge semantics: Both PUT and PATCH use deep merge semantics. This differs from the HTTP standard where PUT replaces the entire resource. In this API, fields not included in the request body are preserved, not cleared. Nested objects such as
category_fieldsare also merged recursively.This means PUT and PATCH are functionally equivalent β both perform a partial update. To clear a field, explicitly set it to
null(for nullable fields).
You can use the PUT method to revive a deleted ad in unregistered vehicle categories (excluding registered vehicles such as cars and vans).
Use this endpoint to update part of an ad. Same signature as ad creation except for source_id which is provided in the path instead of the body. The ads contents will be updated but it will not appear as new. To renew an ad β see /v4/ad/{source_id}/bump endpoint.
Note: PATCH uses the same deep merge behavior as PUT β see the PUT section above for details.
You can use the PATCH method to revive a deleted ad in unregistered vehicle categories (excluding registered vehicles such as cars and vans).
Request to delete an ad. Like all write operations, deletion is asynchronous β the endpoint returns immediately while the actual deletion is processed in the background.
The response returns the ad with state: "created". This is expected. The state transitions to "deleted" once the background worker has unpublished the ad from all marketplaces. To confirm deletion, poll GET /v4/ad/{source_id} and look for a log entry with action: delete and state: done.
Calling this endpoint will make the ad appear as new again. Charges apply.
Prerequisites: The ad must be visible (visible=true). The dealer must have bump permissions for at least one marketplace.
Calling this endpoint will make the ad appear first in the search result. If several ads with pole position match the end user's search filter, only one is shown. Pole position lasts for 3 days. More information here. Charges apply.
Prerequisites: The ad must be visible (visible=true) and must not already have an active Pole Position. Only available for registered vehicle categories (Blocket only).
Valid values for fields like body_type, brand and fuel are listed directly in the Swagger UI schema for each category. Open POST /v4/{vehicle_type} (e.g. POST /v4/car), click Schema, and expand category_fields to see the accepted enum values.
You can also discover attributes and their valid values programmatically:
GET /v4/vehicles/{vehicle_type}/attributes
Returns a list of queryable attributes for the given vehicle type. Each entry has an id and a human-readable name:
[
{"id": "body_type", "name": "Body Type"},
{"id": "brand", "name": "Brand"},
{"id": "powertrain.fuel", "name": "Powertrain Fuel"}
]
To retrieve the allowed values for a specific attribute:
GET /v4/vehicles/{vehicle_type}/{attribute}
Returns a list of valid values, each with an id (slug) and name:
[
{"id": "volvo", "name": "Volvo"},
{"id": "bmw", "name": "BMW"}
]
For example, to list all valid brands for boats: GET /v4/vehicles/boat/brand
For cars, you can also look up models for a specific brand:
GET /v4/vehicles/car/models?brand={brand}
Use
/v4/{vehicle_type}/for new integrations. All V3 endpoints (/v3/ad) remain fully supported.
| Method | Path | Description |
|---|---|---|
GET |
/v4/ad |
List ads (returns both V3 and V4 ads) |
GET |
/v4/ad/{source_id} |
Get specific ad |
DELETE |
/v4/ad/{source_id} |
Delete ad |
GET |
/v4/ad/{source_id}/log |
Get ad logs |
GET |
/v4/ad/{source_id}/bump |
Renew an ad |
GET |
/v4/ad/{source_id}/pole_position |
Set pole position on an ad |
GET |
/v4/ad/{source_id}/retry |
Re-queue ad for processing |
| Method | Path | Description |
|---|---|---|
GET |
/v4/vehicles/{vehicle_type}/attributes |
List available attributes for a vehicle type |
GET |
/v4/vehicles/{vehicle_type}/{attribute} |
Get valid values for an attribute |
{vehicle_type} e.g. car, boat, truck, etc.)| Method | Path | Description |
|---|---|---|
POST |
/v4/{vehicle_type} |
Create new ad |
GET |
/v4/{vehicle_type} |
List ads for category |
POST |
/v4/{vehicle_type}/validate |
Validate payload without saving |
GET |
/v4/{vehicle_type}/{source_id} |
Get specific ad |
PUT |
/v4/{vehicle_type}/{source_id} |
Full update |
PATCH |
/v4/{vehicle_type}/{source_id} |
Partial update |
DELETE |
/v4/{vehicle_type}/{source_id} |
Delete ad |
POST |
/v4/{vehicle_type}/{source_id}/migrate |
Migrate V3 ad to V4 (see Migrating V3 ads to V4) |
Available vehicle types: car, transport, motorcycle, moped, snowmobile, atv, camper, caravan, trailer, boat, agriculture-thresher, agriculture-tractor, agriculture-tools, bus, truck, construction
If you have existing V3 ads, V4 endpoints handle them as follows. Some categories changed schema between V3 and V4 (e.g. Moped, Camper, Boats, Agriculture, Truck & Bus) β these require explicit migration before they can be updated via V4.
| Operation | Compatible (Car, MC, etc.) | Incompatible (Moped, Camper, Boats, etc.) |
|---|---|---|
| GET | Works | Works |
| DELETE | Works | Works |
| PUT / PATCH | Auto-converts to V4 | Blocked β use /v4/{vehicle_type}/{source_id}/migrate first |
Migration is automatic β simply update the ad via a V4 endpoint and it will be converted to V4.
You have two options:
Option A: Use the typed migration endpoint (recommended)
POST /v4/{vehicle_type}/{source_id}/migrate converts the ad in-place. The ad ID, source ID and history are preserved. Requires a complete V4 payload with all required category_fields. Do not include category_id in the request body β it is determined by the endpoint URL.
Available migration endpoints:
| V3 Category | Endpoint | Target V4 category |
|---|---|---|
| Moped (1121) | POST /v4/moped/{source_id}/migrate |
1121 |
| Camper (1102) | POST /v4/camper/{source_id}/migrate |
1102 |
| Caravan (1101) | POST /v4/caravan/{source_id}/migrate |
1101 |
| Trailer (1045) | POST /v4/trailer/{source_id}/migrate |
1045 |
| Boats (1061β1067) | POST /v4/boat/{source_id}/migrate |
1060 (unified) |
| Agriculture Tools (1225, 1226) | POST /v4/agriculture-tools/{source_id}/migrate |
1229 (unified) |
| Agriculture (1222) β Thresher | POST /v4/agriculture-thresher/{source_id}/migrate |
1227 |
| Agriculture (1222) β Tractor | POST /v4/agriculture-tractor/{source_id}/migrate |
1228 |
| Truck & Bus (1221) β Bus | POST /v4/bus/{source_id}/migrate |
1321 |
| Truck & Bus (1221) β Truck | POST /v4/truck/{source_id}/migrate |
1322 |
| Construction (1223) | POST /v4/construction/{source_id}/migrate |
1323 |
Note: For categories that were split in V4 (Agriculture 1222 β Thresher/Tractor, Truck & Bus 1221 β Bus/Truck), choose the endpoint that matches the target category. If a V3 ad was created in the wrong category (e.g. a tractor listed as a thresher), it cannot be corrected via migration β you must delete the ad and create a new one in the correct category.
Option B: DELETE + POST
Delete the V3 ad and create a new V4 ad with a new source_id. The internal ad ID and history will also be new.
We recommend a gradual migration: start using /v4/{vehicle_type}/ for new ads, keep existing V3 ads unchanged, and migrate them at your convenience. V3 endpoints remain fully supported β there is no deadline to migrate.
Do I need to migrate all ads at once? No. V3 ads continue to work. Migrate at your own pace.
Can I still use V3 endpoints? Yes. V3 endpoints remain available. New features will be V4-only.
Can I read V3 ads using V4 endpoints?
Yes. GET /v4/ad returns both V3 and V4 ads.
Do I need to change my authentication? No. The same API token works for both V3 and V4.
The Import-API is very different from the legacy file imports where you send a file via FTP with the entire stock and wait for that file to be imported. The imports via FTP require you to send all the stock information on every update, and images are sent separately either as raw image files or via URLs in json-files.
The API is a modern replacement to the previous file imports via FTP which is now being deprecated.
When migrating to the API, all existing ads currently managed in Blocket Admin must be re-submitted to the API using POST requests. This is necessary to establish the source_id relationship between the API-managed ad and the corresponding ad in Blocket Admin. Matching is based on licence plate, including Q based licence plates allocated automatically when the ad was created manually in Blocket Admin.
During this initial migration, you are also required to provide a list of image URLs via the image_urls field. Below follows a short recap and caveats you need to be aware of when migrating from legacy file imports or building a new integration.
Source ID
As described in the documentation above, every ad needs a source_id, this is your identifier when updating or deleting the ad after creation. The source_id needs to be unique within the customer it belongs to. The source_id can be any string of choice.
Images
As described in the documentation above, images are sent as a list of URLs in the ad payload under the field named image_urls. The images will be downloaded by the API when creating or updating the ad. There is no possibility to upload raw image files to the API, you need to provide URLs to your own publicly accessible image storage or CDN.
All data submitted through the API will overwrite the existing data in Blocket Admin. Unlike the previous file import system, there is no concept of import locks β any ad data submitted via the API is considered the source of truth.
Any changes made directly in Blocket Admin will not be reflected when retrieving the ad via the API. The API only exposes data that was created or updated through the API itself. For consistency and data integrity, all ad modifications should preferably be performed via the API.
Once the migration to the API is complete, the legacy file import functionality will be shut down.