Tulip Core API
Tulip exposes a set of APIs used for information retrieval and manipulation at a single-record level within Tulip Platform. These APIs are set of RESTful API services that allow additional operations to be performed on a running and operational Tulip Cloud backend. Tulip’s Core API can be used as a target behind any apps / modules the client wishes to build on their enterprise or public-facing apps.
While Tulip’s Bulk API is built for mass load, Tulip’s Core API allows granular single-record operations.
API Overview
Tulip Core API is a RESTful API for the Tulip Commerce Engine.
RESTful Design
The Tulip Core API is designed according to REST principles and design patterns. REST stands for Representational State Transfer, and relies on stateless, client-to-server, cacheable communications using the HTTP protocol.
REST is a very popular, flexible, and developer-friendly API architecture. Excellent tutorials and primers on using REST services are available for all languages.
JSON Data Format
JSON is expected and returned by all API responses.
Intended Uses
This API is intended primarily for server-to-server capabilities. It is robust and granular, making it perfect for tasks like synchronization and deep integration.
The Core API gives access to data based on routes, not users. As such, it is best designed for server-to-server usecases. It is not to be used directly from a client application that expects to respond to requests based on notions of “the current user” or “current customers”. An API key that has access to the customers route will be able to see all customers.
Reminder to not Expose Keys to Public
Although more detail about security and keys are discussed in the API Management documentation, remember to never access the Commerce Engine in a way that will expose or store keys in a client application. Websites should never use keys directly in their frontend to speak to the Tulip Core API, and mobile apps should never store authentication tokens in their binaries.
Funtionality
Read using GET
Reading entities is accomplished with GET. This includes reading single entities (GET /v2/catalog/products/<id>
) and listing all the entities (GET /v2/storeops/stores
).
The responses vary, and are documented in detail. Successful GETs always result in a 200 HTTP code.
Create using POST
Entities can be created with a POST action: ex.
POST /v2/crm/customers
The request body must be JSON-formatted data.
Create Response
A successful POST command responds with status code 201 and the created object will be returned in the body. Additionally, the response of a successful POST includes helpful HTTP header values:
Location
URL of the newly created entity
X-Tulip-Created
Internal ID of the created entity
Update using PUT
Entities can be updated with a PUT action: ex. PUT /v2/storeops/stores/12
PUT completely replaces the existing entity with the one provided in the request body. The PUT request must contain all required and updatable fields.
Update using PATCH and JSON-Patch
Updating a part of entity (ex. change the price of a product) can sometimes be done by sending a PATCH request. The body of that PATCH request must be a JSON-Patch document (RFC 6902, or the JSON-Patch reference).
By supporting JSON-Patch, we’re enabling “partial updates” via REST. This avoids having to send the whole object every time you want to make a change to it (like with PUT).
ex. The SKU of a product has changed in your catalog, and you want to update Commerce Engine. To set the sku
attribute of the product with ID 17 to “MDX-1234”, you send the following JSON body using: PATCH /v2/catalog/products/17
[
{"op": "replace", "path": "/sku", "value": "MDX-1234"}
]
Note the square brackets – the API is expects an array of JSON-Patch commands, so you can send multiple changes to a single product at once.
JSON-Patch Operations
Tulip supports many (but not all) JSON-Patch “op” parameters.
Operation (op) | Description | Required Fields |
---|---|---|
add | Adds a value to a field. Replaces the existing value if there’s only one. | path , value |
remove | Removes the field. | path |
replace | Explicitly replaces an existing value in a field. | path , value |
test | Evaluates whether a field has a specific value. If false, an exception is thrown and a 400 error occurs. | path , value |
JSON-Patch Path
The path
refers to name of the field in the model. You can update any field that you could set when creating a new object.
For example, the ProductCreate model includes these attributes:
ProductCreate {
name (string),
price (float),
status_id (integer),
upc (string),
sku (string),
product_url (string, optional)
}
To reference the SKU, the path value would be /sku
, while for product_url the path would be /product_url
.
More information about the path, op, and value parameters can be found on the JSON-Patch reference.
Patching Arrays
To update array values in entities, you can use replace
and add
operations. Here is an example:
[
{
"op": "add",
"path": "/images",
"value": ["http://tulip.io/wp-content/themes/Insperia-Tulip/images/logo.png"]
},
{
"op": "replace",
"path": "/category_ids",
"value": [1234, 3456]
}
]
Sending this document via PATCH /v2/catalog/products/17
will add the image to the list of current images
, and replace current category_ids
with the given categories.
Destroy using DELETE
There are very few DELETE routes in the API. Many entities cannot be deleted (this is by design).
Entities can be disabled, or invalidated, using a PUT or PATCH for the appropriate status_id
property.
Error Handling
Tulip Core API reports errors in a familiar way for developers with RESTful API experience. The HTTP status code indicates the type of error, and the response body has a readable description of the error, formatted as application/problem+json
.
Error Codes
The API responds with a standard HTTP response code when it encounters an error. In addition to the route-specific responses mentioned in the API docs (ex. 200 on success, 201 on create, etc.), these common responses can also appear for every call:
Code | Error | Description |
---|---|---|
401 | Unauthorized | The call was made either without a valid api_key , or the api_key was not authorized. |
403 | Forbidden | The request was authorized (the api_key was accepted), but the permission assigned to the api_key didn’t allow the action. Ex. Trying to create a new store, but your api_key doesn’t have the permission for creating new stores. |
404 | Not Found | The requested object could not be found. |
414 | Request URI Too Long | The request in the URL (https://host/request ) is longer than the maximum, which is 1024 by default. If your URL is that long, the application is likely trying to pass a POST parameter via GET, or you’re stuck in a redirection loop. Either way, it’s a measure to protect the API from mischief. |
429 | Too Many Requests | Your api_key is being throttled / rate-limited. See Rate Limiting for complete details. |
500 | Internal Server Error | Tulip encountered an error that was beyond the scope of normal error handling and reporting. The body of these errors should not be communicated to the user, as they often include technical details and messages useful for application developers. |
Error Response
Error responses will often include a body with clarifying information. The content type of the response body is application/problem+json
, and it looks like this:
{
"status": 401,
"title": "Unauthorized",
"detail": "The provided api_key is not authorized."
}
The fields status
(integer) and title
(string) are required. The field detail
(string) is optional.
For more information about application/problem+json
, see the IETF draft.
Metafields
Tulip Commerce Engine supports User Defined Attributes and Custom Objects for storing additional structured data for entities.
User Defined Attributes
User Defined Attributes are additional information for objects. Each attribute will have a key which acts as unique identifier, value which is the content of the attribute , type and description.
The data type of the value will be defined in the type
property.
There is a separate endpoints for each resource’s attributes to perform CRUD operations on its attributes.
Field | Type | Description | Required |
---|---|---|---|
key | string | Unique identifier of the attribute, underscore delimited notation | Y |
type | string | Type of the attribute value | Y |
value | mixed | Value of the attribute, with data type as described in the attribute field: type | Y |
description | string | Human-readable description for the attribute | N |
The type field will support any of these valid options:
boolean
integer
double
string
array
object
An example attribute object:
{
"key": "date_of_birth",
"type": "string",
"description": "Date of birth of the customer",
"value" : "1970-01-01"
}
Custom Objects
Custom Objects are custom additional key-value fields which are stored as JSON blobs in database.
Customer Custom Object Example
{
"customer_notes":"birthday coming up on Jan 1st",
"register_id": 888,
"credit_balance": 18.35,
"points" : 180
}
Unicode Support
This API supports Unicode encoding. To make sure incoming content is handled as UTF-8, send this header with your request:
Content-Type: application/json; charset=UTF-8
Encoding errors will generally return the 400 error code, with the error “Request body JSON couldn’t be parsed into an array.”
Date Formats
The date and time format that is used in the Core API format is configurable by Tulip.
By default the following format is used:
YYYY-MM-DDThh:mm:ss+hhmm (from UTC)
ex. 2016-04-25T15:53:09+0400