The Sell API is accessed from the domain. All data is sent and received in the JSON format and all API requests require authentication.



  • https:// - the API is served ONLY over secure HTTP
  • - the API's endpoint domain.
  • api-version - the api version identifier e.g. v2.
  • resource - the service-slug's api endpoint e.g. contacts.

All requests to the API must be made over SSL (https:// not http://).

HTTP Verbs

HEADQuery HTTP headers
GETRetrieve resources
POSTCreates resources or execute custom actions
PUTPartial update of resources
DELETEDelete resources

Query Parameters


There are many cases where you need to load data related to the resource being requested. Rather than requiring you to hit the API repeatedly, we allow related data to be returned and loaded alongside the original resource on demand, which improves performance.

One or more resources can be included by using our standard includes parameter. The ?includes query parameter will take a comma-separated list of one or more resources related to the primary resource and return those resources as well.

Consult an endpoint's parameter description in order to verify which related resources are supported.

For example, to retrieve a contact with the id of "2" and information about that contact's associated organization, use:

curl -X GET \     -u "$YOUR_API_KEY:"     -H "Accept: application/json"


Record relationships in Sell can be complex. It's not uncommon to see URLs 5 or 6 levels deep. Usually, we don't need to include the levels above once we have the primary key for the level we are interested in.

We made it as simple as possible for you to use the API by putting optional states and attributes behind the HTTP question mark. For more information, see the example below.

Consult an endpoint's parameters description to check which properties are filterable for that endpoint.

To retrieve contacts within the same organization, with id "1", and living in the same city - NY

curl -X GET"NY" \     -u "$YOUR_API_KEY:" \     -H "Accept: application/json"

IDs filter

You can control which individual resources that are returned during the request by appending the standard ids query parameter to the collection URL. The ?ids query parameter takes a comma-separated list of unique identifiers.

To retrieve contacts with IDs "1", "2" and "3"

curl -X GET,2,3 \     -u "$YOUR_API_KEY:" \     -H "Accept: application/json"

Custom Fields filter

In addition to standard attributes, we support custom fields filtering. In order to use it, you need set the custom field to as Filterable in the custom field settings. Keep in mind, only of the following custom field types are supported: "Single Line Text", "Number", "Dropdown" or "Multi Select".

To retrieve a contact by a filterable custom field called sku set to "SKU1", use:

curl -X GET[sku]=SKU1 \     -u "$YOUR_API_KEY:" \     -H "Accept: application/json"


You can control the maximum number of records that are returned using the standard per_page query parameter. To choose a page, use the standard page query parameter.

The default page is always the first one. Page numbering is 1-based and omitting the ?page parameter will return the first page.

The default limit is 25 and maximum number that can be returned is 100.

curl -X GET \     -u "$YOUR_API_KEY:" \     -H "Accept: application/json"


You can control in what order, according to one criteria, how to sort resource collections using the standard query parameter sort_by.

The ?sort_by query parameter takes a field name to sort by.

The default sort order is ascending. If you want to change the sort order to ascending, append an :asc to the field (or append a :desc to explicitly specify descending).

Consult an endpoint's parameters description in order to check what properties are sortable.

For example, to get a list of contacts within the same organization and sort it by first_name in descending order, use:

curl -X GET \     -u "$YOUR_API_KEY:" \     -H "Accept: application/json"

Custom Fields sort option

In addition to standard attributes, we support custom fields sorting. In order to use it, you need set the custom field to as Filterable in the custom field settings. Keep in mind, only of the following custom field types are supported: "Single Line Text", "Number" or "Dropdown".

The following query shows how to sort by a custom field sku: ?sort_by=custom_fields:sku:desc.

Breaking down the query in more detail, sort_by operator instructs to use sorting, the custom_fields:sku part tells us to sort by a custom field sku, and the remaining element desc specify that we want to sort in descending order.

To sort contacts by a filterable custom field called sku in descending order, use:

curl -X GET \     -u "$YOUR_API_KEY:" \     -H "Accept: application/json"


Content Negotiation

When you want a response in JSON, you will need to specify this. This is done via the Accept header, and setting the header's value to application/json.

Accept: application/json

When you use the JSON format, you should specify that you are sending a JSON request in the header. This is done by setting the Content-Type header to application/json. This ensures that your request is interpreted correctly by our servers.

Content-Type: application/json

Language Negotiation

HTTP has built-in support for language negotiation through the standard Accept-Language header. Accept-Language works in the same way content negotiation works: by utilising the Accept pattern. The header utilizes Language Tags, where any two-letter primary-tag is an ISO-639 language abbreviation and any two-letter initial subtag is an ISO-3166 country code.

If your request has no Accept-Language, the Sell API will return a representation with all human-readable text in your default language (which can be changed via dashboard).

Accept-Language: da, en-gb;1=0.8, en;q=0.7

User Agent

All API requests must include a valid User-Agent header. Requests with no User-Agent header will be rejected with 400 Bad Request and the error code invalid_user_agent will be included in the response payload.

User-Agent: ClientName/1.0


All JSON requests must specify the object type that the payload is carrying within the data field. In addition, you can include an object's type within the meta/type attribute. The type field is mandatory unless the documentation for a given endpoint says otherwise.

Use an envelope to include additional fields in your request, such as metadata, pagination information, etc. Another reason for the envelope is that some clients don't allow easy access to HTTP headers, and JSONP requests have no access to HTTP headers at all.

{  "data": {    "content": "your note content",    "resource_id": 1,    "resource_type": "note"  },  "meta": {    "type": "note" // mandatory  }}

Date and Time

Date and time formats can cause a lot of confusion and interoperability issues. To overcome this, we use the industry-adopted standard, ISO 8601. Even though we internally store all the timestamps using the UTC timezone, we don't make any assumptions about the timezone you supply.

Section 3.7 Mutual agreement of the ISO 8601 standard states that we are free to define our own representations as long as we do not interfere with the representations defined in the standard. On occasion you may want to specify an expiration time and set it to forever. Thanks to the loose standard we can mutually agree upon 9999-12-31T00:00:00Z to indicate forever.

Here's a glimpse of our Date-Time syntax, where timezone-offset set to Z indicates UTC timezone:


Custom Fields

You can assign any number of custom fields to any single Lead, Contact or Deal. Each custom field is a key-value pair assigned to the custom_fields object field.

Custom fields must be defined in Sell before they can be assigned. See Creating and managing custom fields in Sell in Zendesk help.

Most custom field values are strings, with the following exceptions:

  • Address values are nested objects, as defined in the Address documentation.
  • List values must match exactly the drop-down choice in Settings. Any other values will be ignored.
  • Multi Select values are arrays. Their elements must match exactly the drop-down choice in Settings. Any other values will be ignored.

The API returns custom fields in the custom_fields object in the API response. The custom_fields object only lists the fields that have a value assigned to them. If no value has been assigned to a field, the field is omitted from the custom_fields object. The field won't be listed with a null or empty value.

{  "data": {    // other fields skipped for readability
    "custom_fields": {      "website": "",      "correspondence": {        "line1": "1060 W. Addison",        "city": "Chicago",        "postal_code": "60613",        "state": "IL",        "country": "United States"      },      "league": "MLB",      "sports": ["baseball", "football", "soccer", "hockey"]    },    "created_at": "2014-08-27T16:32:56Z",    "updated_at": "2014-08-27T17:32:56Z"  },  "meta": {    "type": "deal"  }}

If no values have been assigned to any of the custom fields:

{  "data": {    // other fields skipped for readability
    "custom_fields": {},    "created_at": "2014-08-27T16:32:56Z",    "updated_at": "2014-08-27T17:32:56Z"  },  "meta": {    "type": "deal"  }}


You can assign any number of tags to any single Lead, Contact or Deal. Tags are listed within the tags array field.

Tags don't need to exist to be assigned - they can be created while creating a record. You can check them later via Tags API.

In order to modify tags on an object, you need to supply the entire set. tags are replaced every time they are used in a request which modifies a resource.

{  "data": {    // other fields skipped for readability
    "tags":[      "important",      "retailer"    ],    "created_at": "2014-08-27T16:32:56Z",    "updated_at": "2014-08-27T17:32:56Z"  },  "meta": {    "type": "deal"  }}