Introduction
Welcome to the CycleSoftware API documentation
Documentation overview
- CycleSoftware API docs
- Warehouse API docs
- Supplier integration API docs
- Stock platform API docs
- TWSC API docs
API endpoints
Use the API endpoint hosts according to the country of your account;
Country code | API endpoint host |
---|---|
NL |
api.cyclesoftware.nl |
BE |
api.cyclesoftware.be |
FR |
api.cyclesoftware.fr |
other |
api.cyclesoftware.nl |
Requirements
To use the APIs you'll need API credentials. The API credentials are provided by CS or available in your account.
- You should access the API over HTTPS
- Where possible use Accept-encoding: gzip. For data api's this might be required.
Request/Response Format
The APIs consist of SOAP/WSDL webservices and JSON endpoints.
The default response format is JSON. Requests with a message-body use plain JSON to set or update resource attributes.
Successful requests will return a 200 OK
HTTP status.
Errors
Occasionally you might encounter errors when accessing the REST API. There are four possible types:
Error Code | Error Type |
---|---|
400 Bad Request |
Invalid request, e.g. using an unsupported HTTP method, or GET variable |
401 Unauthorized |
Authentication or permission error, e.g. incorrect credentials |
403 Forbidden |
Authentication or permission error |
404 Not Found |
Requests to resources that don't exist or are missing |
429 Too Many Requests |
API limit reached, see api limiting |
500 Internal Server Error |
Server error |
JSON error response
{
"error": true,
"error_message": "Unauthorized"
}
XML error response
<?xml version="1.0"?>
<result>
<error>1</error>
<error_message>Unauthorized</error_message>
</result>
SOAP error response
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>400</faultcode>
<faultstring>The problem description</faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Errors return both an appropriate HTTP status code and response object which contains a error
, and error_message
API Parameters
Almost all endpoints accept optional parameters which can be passed as an HTTP query string parameter,
e.g. GET /v1/endpoint?status=completed
. All parameters are documented along each endpoint.
API Pagination
For certain endpoints pagination is implemented. The mechanism differs per endpoint. But the default pagination mechanism is as follows:
JSON response
{
"error": false,
"error_message": null,
"data": [],
"pagination": {
"next_offset": 1000
}
}
GET /v1/endpoint?offset=1000
In the response the next_offset is suggested. You can pass the next offset in the offset
GET parameter.
API Types
Some general information about responses:
- Amounts could be specified in cents (which will be clear by the fieldname) or with decimal-strings
Scope | Description | Example |
---|---|---|
string |
An UTF-8 string of variadic length | Hello world! |
boolean |
Boolean true or false |
true |
integer |
64-bit signed integer | 1212 |
decimal |
Decimal number with 2 decimals e.g. 0.22 |
0.22 |
float |
A floating-point number with . used as the separator |
123.22 |
date |
Date in yyyy-mm-dd format |
2023-01-23 |
datetime |
Datetime in yyyy-mm-dd hh:mm:ss format |
2023-01-23 12:34:33 |
timestamp |
UNIX timestamp (seconds since Unix Epoch) | 1678348370 |
uuid |
UUID string | 20c5d026-68b3-11ec-90d6-0242ac120003 |
array |
List of sub types | [10,22] |
object |
An object | {"field": 1} |
API Limits
Since may 2022 api-limits are introduced. For endpoints that implement limits the following HTTP response headers are available.
If the limit is reached, the server will respond with an HTTP 429 - Too Many Requests
error.
The following HTTP headers are present in an limited endpoint response
HTTP Response header | Description |
---|---|
X-RateLimit-Minutely-Limit |
Contains the number of allowed requests per minute |
X-RateLimit-Minutely-Remaining |
Contains the number of remaining requests available within moving minutely interval |
X-RateLimit-Daily-Limit |
Contains the number of daily allowed requests |
X-RateLimit-Daily-Remaining |
Contains the number of daily remaining requests |
X-RateLimit-Daily-Reset |
Contains the UNIX timestamp when the daily limit is reset |
API Scopes
Scope | Description |
---|---|
common |
Access common data such as employees, enums, suppliers |
e-commerce |
Access e-commerce related endpoints (stock, order-creation, articledata) |
resources |
Access object resources such as customers , workshop-orders , repair-objects etc. |
stock-export |
Bulk export stock data |
sales-export |
Bulk export sales data |
rental |
Rental related information |
warehouse |
Warehouse related data |
platform |
Access authorized dealer-data for sales-platforms |
Authentication
CycleSoftware uses different authentication mechanisms.
HTTP Basic Authentication
The credentials consist of a username
, password
and api-key
. The username
and password
should be provided using the Basic HTTP authentication http header. The api-key is usage is documented per service.
SOAP/WSDL Authentication
The credentials consist of a username
, password
and api-key
. The username
and password
should be provided within the Authentication
element as documented per request. For dealer_id
the actual store id within the account or api-key can be provided.
Platform keys
Get list of associated stores
Authentication mechanism
- Basic HTTP Authentication
- IP filtering
- Scope(s):
platform
Properties
Property | Type | Description |
---|---|---|
error_message |
?string |
Error if occurred |
error |
boolean |
true if an error has occurred |
keys |
object[] |
List of entries |
keys[].key |
string |
The API key e.g. Ls6m1ZOgt5JbClmZZHAr8GNhk1qL4Dx0SB7hyyWf |
keys[].is_active |
boolean |
Whether the API access is enabled true |
keys[].store.store_id |
string |
CS store ID 1-1 |
keys[].store.store_gln |
string |
Global Location Number e.g. 8718288145482 |
keys[].store.store_name |
string |
Store name e.g. CycleSoftware Store |
keys[].store.store_address |
string |
Store address e.g. Raadhuisplein 1c |
keys[].store.store_postal_code |
string |
Postal code e.g. 5388GM |
keys[].store.store_city |
string |
City e.g. Nistelrode |
keys[].store.store_country_code |
string |
Country code e.g. NL |
keys[].store.store_phone_number |
string |
Phone number e.g. 0733030050 |
keys[].store.store_email |
string |
E-mail address.g. email1@example.nl |
keys[].store.store_coordinates |
float[] |
array with [latitude, longitude] |
keys[].store.store_meta_data |
object |
Meta data for this entry |
keys[].store.store_meta_data.drg_dealer_number |
string |
Dynamo Retail Group dealer number e.g. 999 |
Keys
Get a list of authentication keys
/api/v1/platform/authentication/keys.json
HTTP request
GET /api/v1/platform/authentication/keys.json HTTP/1.1
Host: api.cyclesoftware.nl
Authorization: Basic VXNlcm5hbWU6UGFzc3dvcmQ=
Accept-encoding: gzip
Accept: application/json
Content-type: application/json; charset=utf-8
HTTP Response
HTTP/1.1 200
Content-type: application/json; charset=utf-8
Content-length: 1626
{
"error_message": null,
"error": false,
"keys": [
{
"key": "Ls6m1ZOgt5JbClmZZHAr8GNhk1qL4Dx0SB7hyyWf",
"is_active": true,
"store": {
"store_id": "1-3",
"store_gln": "",
"store_name": "CycleSoftware",
"store_address": "Kievitsven 22Z",
"store_postal_code": "5249JJ",
"store_city": "Rosmalen",
"store_country_code": "NL",
"store_phone_number": "073 303 0050",
"store_email": "email1@example.nl",
"store_coordinates": [
0,
0
],
"store_meta_data": {
"drg_dealer_number": "999"
}
}
},
{
"key": "BLs6m1ZOgt5JbClmZZHAr8GNhk1qL4Dx0SB7hyyWf",
"is_active": false,
"store": {
"store_id": "1-1",
"store_gln": "8718288145482",
"store_name": "CycleSoftware",
"store_address": "Raadhuisplein 1c",
"store_postal_code": "5388GM",
"store_city": "Nistelrode",
"store_country_code": "NL",
"store_phone_number": "0733030050",
"store_email": "email1@example.nl",
"store_coordinates": [
51.701163,
5.5619904
],
"store_meta_data": {
"drg_dealer_number": "888"
}
}
}
]
}
Stock locator
Locate stock based on barcodes / article ids in associated accounts
Authentication mechanism
- Basic HTTP Authentication
- Scope(s):
platform
ore-commerce
Properties
Property | Type | Description |
---|---|---|
error_message |
?string |
Error message if occured |
error |
boolean |
true if error occured |
stores |
object[] |
Array of store objects |
stores[].store_id |
string |
Account ID in CS e.g. 5185-1 |
stores[].store_gln |
string |
GLN code 8718288145482 |
stores[].store_name |
string |
Company name e.g. CS-Unit test |
stores[].store_address |
string |
Company street e.g. Kievitsven 22 |
stores[].store_postal_code |
string |
Company postal code e.g. 5249JJ |
stores[].store_phone_number |
string |
Company phone number |
stores[].store_country_code |
string |
Company country code e.g. NL |
stores[].store_email |
string |
e.g. email5185@example.nl |
stores[].store_coordinates |
float[] |
array with [latitude, longitude] |
stock |
object[] |
List of stocked objects |
stock[].store_id |
string |
Account ID in CS e.g. 1-1 |
stock[].object_id |
integer |
ID of object in account 18696 |
stock[].barcode |
string |
Barcode of article 8717231204726 |
stock[].article_id |
string |
Article number e.g. 30015 |
stock[].brand_name |
string |
Brand name Gazelle |
stock[].is_demo |
boolean |
true if marked as demo bike |
Stores
Get a list of stores
/api/v1/stock-in-store-locator/stores.json
HTTP request
GET /api/v1/stock-in-store-locator/stores.json HTTP/1.1
Host: api.cyclesoftware.nl
Authorization: Basic VXNlcm5hbWU6UGFzc3dvcmQ=
Accept-encoding: gzip
Accept: application/json
Content-type: application/json; charset=utf-8
HTTP Response
HTTP/1.1 200
Content-type: application/json; charset=utf-8
Content-length: 998
{
"error_message": null,
"error": false,
"stores": [
{
"store_id": "1-1",
"store_gln": "8718288145482",
"store_name": "CycleSoftware",
"store_address": "Raadhuisplein 1c",
"store_postal_code": "5388GM",
"store_phone_number": "0733030050",
"store_country_code": "NL",
"store_email": "email1@example.nl",
"store_coordinates": [
51.701163,
5.5619904
]
},
{
"store_id": "5185-1",
"store_gln": "8718288145482",
"store_name": "CS-Unit test",
"store_address": "Kievitsven 22",
"store_postal_code": "5249JJ",
"store_phone_number": "",
"store_country_code": "NL",
"store_email": "email5185@example.nl",
"store_coordinates": [
51.7261667,
5.3978953
]
}
]
}
Stock in store locator
/api/v1/stock-in-store-locator/stock.json
HTTP request
POST /api/v1/stock-in-store-locator/stock.json HTTP/1.1
Host: api.cyclesoftware.nl
Authorization: Basic VXNlcm5hbWU6UGFzc3dvcmQ=
Accept-encoding: gzip
Accept: application/json
Content-type: application/json; charset=utf-8
Content-length: 65
[
{
"barcode": "8717144186799"
},
{
"barcode": "8717231204726"
}
]
HTTP Response
HTTP/1.1 200
Content-type: application/json; charset=utf-8
Content-length: 989
{
"error_message": null,
"error": false,
"stores": [
{
"store_id": "1-1",
"store_gln": "8718288145482",
"store_name": "CycleSoftware",
"store_address": "Raadhuisplein 1c",
"store_postal_code": "5388GM",
"store_phone_number": "0733030050",
"store_country_code": "NL",
"store_email": "email1@example.nl",
"store_coordinates": [
51.701163,
5.5619904
]
},
{
"store_id": "5185-1",
"store_gln": "8718288145482",
"store_name": "CS-Unit test",
"store_address": "Kievitsven 22",
"store_postal_code": "5249JJ",
"store_phone_number": "",
"store_country_code": "NL",
"store_email": "email5185@example.nl",
"store_coordinates": [
51.7261667,
5.3978953
]
}
],
"stock": [
{
"store_id": "5185-1",
"object_id": 144922,
"barcode": "8717144186799",
"article_id": "03505002",
"brand_name": "Sparta",
"is_demo": false
},
{
"store_id": "1-1",
"object_id": 18695,
"barcode": "8717231204726",
"article_id": "30015",
"brand_name": "Gazelle",
"is_demo": false
},
{
"store_id": "1-1",
"object_id": 18696,
"barcode": "8717231204726",
"article_id": "30015",
"brand_name": "Gazelle",
"is_demo": false
}
]
}
Leads
Create, read and cancel sales leads
Authentication mechanism
- Basic HTTP Authentication
- Scope(s):
platform
Properties
Field | Type | Description | Example value |
---|---|---|---|
error |
boolean |
true if an error occurred | false |
error_message |
?string |
Empty if no error | |
sales_lead.uuid |
string |
Unique identifier of the lead (null on creation) | 0c6b40a4-a217-11e8-92bb-005056a46320 |
sales_lead.store_id |
string |
The store identification format of [account]-[store] | 43831 |
sales_lead.type |
string |
Type of the lead (see type list) | information |
sales_lead.status |
string |
Status of the lead (see status list) | open |
sales_lead.title |
string |
Short title of lead description | Kieskeurig: proefrit Batavus Crescendo |
sales_lead.message |
string |
Message to the dealer about the lead | Een potientiele klant wil een proefrit maken |
sales_lead.costs_ex_vat_cents |
integer |
The costs that the platform charges to the dealer on acceptance of the lead | 1500 |
sales_lead.options.test_ride_requested |
boolean |
provide true if a test-ride is requested | false |
sales_lead.options.phone_call_requested |
boolean |
provide true if the dealer should call the customer | false |
sales_lead.options.finance_information_requested |
boolean |
provide true if the dealer should provide financial information | false |
sales_lead.options.insurance_information_requested |
boolean |
provide true if the dealer should provide insurance information | false |
sales_lead.object.description |
string |
Description of the object | Batavus Crescendo |
sales_lead.object.object_id |
integer |
Object id in stock dealer (can be retrieved in stock locator api) | 12212 |
sales_lead.object.article_number |
string |
Article number of the object | ART1 |
sales_lead.object.barcode |
string |
EAN barcode of the object | 877474749349 |
sales_lead.exchange_object.exchange_description |
string |
Description of the exchange object | |
sales_lead.exchange_object.exchange_remarks |
string |
Remarks about the exchange object | |
sales_lead.customer.customer_address_id |
?integer |
ID of the customer address (null on creation) | 91953 |
sales_lead.customer.address_type |
string |
lead null on creation | lead |
sales_lead.customer.customer_id |
integer |
Customer ID if address is linked to a customer null on creation) | 235240102 |
sales_lead.customer.is_business_address |
boolean |
true if address is for a company | false |
sales_lead.customer.company_name |
string |
The company name | |
sales_lead.customer.name |
string |
Name of the customer | Name 91953 |
sales_lead.customer.street |
string |
Street of the address | Slangenburg |
sales_lead.customer.house_number |
string |
Housenumber | 314 |
sales_lead.customer.house_number_postfix |
string |
Housenumber suffix | B |
sales_lead.customer.postal_code |
string |
Postalcode | 7423ZR |
sales_lead.customer.city |
string |
City | Deventer |
sales_lead.customer.country_code |
string |
Country code (ISO 3166) | NL |
sales_lead.customer.phone_number |
string |
Phonenumber | 06 38668303 |
sales_lead.customer.email |
string |
E-mail address | email91953@example.nl |
sales_lead.customer.notes |
string |
Extra information about the customer address | |
sales_lead.created_at |
datetime |
When the lead was created (null on creation) | 2020-04-14T06:33:26+02:00 |
sales_lead.modified_at |
datetime |
When the lead was last modified (null on creation) | 2020-04-14T06:33:26+02:00 |
Sales lead types
Possible values for sales_lead.type
Field | Description |
---|---|
information |
The customer would like to receive information |
sales_offer |
The customer would like to buy the object |
test_ride |
The customer would like to make a test-ride |
contact_request |
The customer would like to be contacted |
exchange |
The customer would like to exchange an object |
complaint |
The customer has a complaint |
other |
- |
Sales lead status
Possible values for sales_lead.status
Field | Description | Costs apply |
---|---|---|
open |
The dealer did not take any action on the lead | NO |
noticed |
The dealer has noticed the lead but did not accept or decline it | NO |
accepted |
The dealer has accepted the lead | YES |
declined |
The dealer has declined the lead | NO |
succeeded |
The dealer has successfully converted the lead | YES |
failed |
The dealer has not coverted the lead | YES |
cancelled |
The lead was cancelled | NO |
Create lead
Get a list of stores
/api/v1/leads/create.json
HTTP request
POST /api/v1/leads/create.json HTTP/1.1
Host: api.cyclesoftware.nl
Authorization: Basic VXNlcm5hbWU6UGFzc3dvcmQ=
Accept-encoding: gzip
Accept: application/json
Content-type: application/json; charset=utf-8
{
"store_id": "1-1",
"type": "test_ride",
"status": "open",
"title": "Kieskeurig: proefrit Batavus Crescendo",
"message": "NaamKlant wil een proefrit maken",
"costs_ex_vat_cents": 1500,
"options": {
"test_ride_requested": true,
"phone_call_requested": true,
"finance_information_requested": false,
"insurance_information_requested": false
},
"object": {
"description": "Batavus Crescendo",
"object_id": 11212,
"article_number": null,
"barcode": "877474749349"
},
"exchange_object": {
"exchange_description": null,
"exchange_remarks": null
},
"customer": {
"customer_address_id": null,
"address_type": "lead",
"customer_id": null,
"is_business_address": false,
"company_name": "",
"name": "NaamKlant",
"street": "Hoofdstraat",
"house_number": "10",
"house_number_postfix": "B",
"postal_code": "5238HL",
"city": "Berlicum",
"country_code": "NL",
"phone_number": "0612345678",
"email": "voorbeeld@host.nl",
"notes": "Bellen tussen 12.00-17.00"
}
}
HTTP Response
HTTP/1.1 200
Content-type: application/json; charset=utf-8
Content-length: 1357
{
"error": false,
"error_message": null,
"sales_lead": {
"uuid": "0c6b40a4-a217-11e8-92bb-005056a46320",
"store_id": "1-1",
"type": "information",
"status": "open",
"title": "Kieskeurig: proefrit",
"message": "Een potientiele klant wil een proefrit maken",
"costs_ex_vat_cents": 1500,
"options": {
"test_ride_requested": false,
"phone_call_requested": false,
"finance_information_requested": false,
"insurance_information_requested": false
},
"object": {
"description": "Batavus Crescendo",
"object_id": 12212,
"article_number": "ART1",
"barcode": "877474749349"
},
"exchange_object": {
"exchange_description": "",
"exchange_remarks": ""
},
"customer": {
"customer_address_id": 91953,
"address_type": "delivery_address",
"customer_id": 235240102,
"is_business_address": false,
"company_name": "",
"name": "Name 91953",
"street": "Slangenburg",
"house_number": "314",
"house_number_postfix": "",
"postal_code": "7423ZR",
"city": "Deventer",
"country_code": "NL",
"phone_number": "06 38668303",
"email": "email91953@example.nl",
"notes": ""
},
"created_at": "2020-04-14T06:33:26+02:00",
"modified_at": "2020-04-14T06:33:26+02:00"
}
}
Get lead
/api/v1/leads/:uuid.json
URI parameter | Type | Description |
---|---|---|
uuid |
uuid |
The UUID of the lead e.g. 0c6b40a4-a217-11e8-92bb-005056a46320 |
HTTP request
GET /api/v1/leads/0c6b40a4-a217-11e8-92bb-005056a46320.json HTTP/1.1
Host: api.cyclesoftware.nl
Authorization: Basic VXNlcm5hbWU6UGFzc3dvcmQ=
Accept-encoding: gzip
Accept: application/json
Content-type: application/json; charset=utf-8
Content-length: 65
HTTP Response
HTTP/1.1 200
Content-type: application/json; charset=utf-8
Content-length: 1357
{
"error": false,
"error_message": null,
"sales_lead": {
"uuid": "0c6b40a4-a217-11e8-92bb-005056a46320",
"store_id": "1-1",
"type": "information",
"status": "open",
"title": "Kieskeurig: proefrit",
"message": "Een potientiele klant wil een proefrit maken",
"costs_ex_vat_cents": 1500,
"options": {
"test_ride_requested": false,
"phone_call_requested": false,
"finance_information_requested": false,
"insurance_information_requested": false
},
"object": {
"description": "Batavus Crescendo",
"object_id": 12212,
"article_number": "ART1",
"barcode": "877474749349"
},
"exchange_object": {
"exchange_description": "",
"exchange_remarks": ""
},
"customer": {
"customer_address_id": 91953,
"address_type": "delivery_address",
"customer_id": 235240102,
"is_business_address": false,
"company_name": "",
"name": "Name 91953",
"street": "Slangenburg",
"house_number": "314",
"house_number_postfix": "",
"postal_code": "7423ZR",
"city": "Deventer",
"country_code": "NL",
"phone_number": "06 38668303",
"email": "email91953@example.nl",
"notes": ""
},
"created_at": "2020-04-14T06:33:26+02:00",
"modified_at": "2020-04-14T06:33:26+02:00"
}
}
Cancel lead
/api/v1/leads/:uuid/cancel.json
URI parameter | Type | Description |
---|---|---|
uuid |
uuid |
The UUID of the lead e.g. 0c6b40a4-a217-11e8-92bb-005056a46320 |
HTTP request
POST /api/v1/leads/0c6b40a4-a217-11e8-92bb-005056a46320/cancel.json HTTP/1.1
Host: api.cyclesoftware.nl
Authorization: Basic VXNlcm5hbWU6UGFzc3dvcmQ=
Accept-encoding: gzip
Accept: application/json
Content-type: application/json; charset=utf-8
HTTP Response
HTTP/1.1 200
Content-type: application/json; charset=utf-8
Content-length: 45
X-RateLimit-Minutely-Limit: 360
X-RateLimit-Minutely-Remaining: 59
X-RateLimit-Daily-Limit: 15000
X-RateLimit-Daily-Remaining: 14999
X-RateLimit-Daily-Reset: 1678230000
{
"error": false,
"error_message": null
}