Skip to content

Data retrieval

The data API is used to retrieve up-to-date data from Custobar. The set of returned results may be filtered using query parameters.

Note: To push data from Custobar directly to any HTTPS endpoint, you can use Datatargets.

Quick navigation: Customers | Events | Sales | Products | Pagination | Specifying fields | Ordering | Data format

Customers

Customer data can be retrieved using various filters to find specific customers or groups of customers.

Basic customer lookup

To retrieve a customer by their external_id, make a GET request to:

https://COMPANY.custobar.com/api/data/customers/?external_id=CUSTOMERID

The result is always a JSON object with a customers property, with all matching customers as a list:

json
{
    "customers": [
        {
            "external_id": "CUSTOMERID",
            "first_name": "Customer",
            "last_name": "Samplesson",
            "email": "customer@example.com",
            "can_email": true
        }
    ]
}

If there are no matching customers, the customers list will be empty. For external_id queries there are always either zero or one matching customers.

Fields that can be used as filters

You can filter customers using any of the following fields as query parameters. Multiple filters can be combined.

FieldDescriptionExample ValueExample Usage
external_idCustomer IDABC123?external_id=ABC123
emailEmail addressperson@example.org?email=person@example.org
phone_numberPhone number (country-prefixed format)+358101234567?phone_number=+358101234567
first_nameFirst nameJames?first_name=James
last_nameLast nameCarroll?last_name=Carroll
campaign_keyCampaign identifierCA-1?campaign_key=CA-1
can_emailEmail marketing permissiontrue / false?can_email=true
can_smsSMS marketing permissiontrue / false?can_sms=true
can_postPostal mail permissiontrue / false?can_post=true
can_pushPush notification permissiontrue / false?can_push=true
cityCity nameLondon?city=London
countryTwo-letter country code (ISO 3166-1 alpha-2)GB?country=GB
zip_codePostal codeOX15 3PW?zip_code=OX15+3PW
provinceProvince/state nameCalifornia?province=California

Filter examples

Single filter

Filter customers with email permission:

https://COMPANY.custobar.com/api/data/customers/?can_email=true

Multiple filters combined

Retrieve customers with last name Anderson who have email permission:

https://COMPANY.custobar.com/api/data/customers/?last_name=Anderson&can_email=true

Filter by campaign participation

Retrieve customers who participated in campaign CA-1:

https://COMPANY.custobar.com/api/data/customers/?campaign_key=CA-1

Combine with other filters to get customers with email permission who participated in the campaign:

https://COMPANY.custobar.com/api/data/customers/?campaign_key=CA-1&can_email=true

Filter by location

Retrieve customers from London, UK:

https://COMPANY.custobar.com/api/data/customers/?city=London&country=GB

Example response

json
{
    "customers": [
        {
            "external_id": "ABC123",
            "first_name": "James",
            "last_name": "Anderson",
            "email": "james.anderson@example.com",
            "phone_number": "+358101234567",
            "can_email": true,
            "can_sms": true,
            "city": "Helsinki",
            "country": "FI",
            "date_joined": "2024-01-15T10:30:00Z"
        }
    ]
}

Events

Event data can be retrieved using the events endpoint. Each event type must be queried separately.

Basic event lookup

To retrieve events of a specific type, make a GET request:

https://COMPANY.custobar.com/api/data/events/?type=MAIL_OPEN

For example, to access who has opened emails, you need to query MAIL_OPEN and MAIL_CLICK separately.

Fields that can be used as filters

You can filter events using any of the following fields as query parameters. Multiple filters can be combined.

FieldDescriptionExample ValueExample Usage
typeEvent type (see available types below)MAIL_OPEN?type=MAIL_OPEN
date.gteFilter events from this date onwards (greater than or equal)2026-02-01?date.gte=2026-02-01
date.lteFilter events up to this date (less than or equal)2026-02-28?date.lte=2026-02-28

Available event types

Event TypeDescription
MAIL_OPENEmail open
MAIL_CLICKEmail click
BASKET_ADDProduct added to basket
BROWSEBrowsing data from website/app
AUTOMATED_CAMPAIGNCustomer has received an automated campaign
MAIL_DEFERREDEmail delivery has been temporarily blocked
MAIL_UNSUBSCRIBECustomer has unsubscribed from newsletter
MAIL_BLOCKEDCustomer's email sending has been completely blocked

Filter examples

Filter by event type

Retrieve all email open events:

https://COMPANY.custobar.com/api/data/events/?type=MAIL_OPEN

Filter by date range

Retrieve all email open events from February 2026:

https://COMPANY.custobar.com/api/data/events/?type=MAIL_OPEN&date.gte=2026-02-01&date.lte=2026-02-28

Filter events from a specific date onwards

Retrieve all browsing events from February 1st, 2026 onwards:

https://COMPANY.custobar.com/api/data/events/?type=BROWSE&date.gte=2026-02-01

Filter events up to a specific date

Retrieve all basket additions up to January 31st, 2026:

https://COMPANY.custobar.com/api/data/events/?type=BASKET_ADD&date.lte=2026-01-31

Example response

json
{
    "events": [
        {
            "type": "MAIL_OPEN",
            "date": "2026-02-01T12:30:00Z",
            "customer_id": "23132",
            "email": "customer@example.com"
        }
    ]
}

Sales

Sales data can be retrieved using the sales endpoint. A sale represents a single line item (row) in a transaction with a customer.

Basic sales lookup

To retrieve sales for a specific customer, make a GET request:

https://COMPANY.custobar.com/api/data/sales/?sale_customer_id=A501

Fields that can be used as filters

You can filter sales using any of the following fields as query parameters. Multiple filters can be combined.

Transaction-level filters

FieldDescriptionExample ValueExample Usage
sale_external_idUnique identifier for the entire transaction1000?sale_external_id=1000
sale_dateDate of the sale2017-12-01?sale_date=2017-12-01
sale_customer_idCustomer external_idA501?sale_customer_id=A501
sale_phone_numberCustomer phone number+358101234567?sale_phone_number=+358101234567
sale_emailCustomer email addresscustomer@example.com?sale_email=customer@example.com
sale_shop_idShop external_id where purchase was made1?sale_shop_id=1
sale_payment_methodPayment method identifierCredit Card?sale_payment_method=Credit+Card
sale_stateSale stateCOMPLETE?sale_state=COMPLETE

Sale-row-level filters

FieldDescriptionExample ValueExample Usage
external_idUnique identifier of sale row1000-1?external_id=1000-1
product_idProduct external_idSKU0435?product_id=SKU0435
product_skuProduct SKU identifierSKU-123456?product_sku=SKU-123456

Available sale states

Sale StateDescription
NEWNew sale
PENDING_PAYMENTPayment pending
PROCESSINGBeing processed
COMPLETECompleted sale
CANCELLEDCancelled sale (not included in statistics)
CLOSEDClosed sale (not included in statistics)
HOLDEDOn hold

Filter examples

Filter by customer

Retrieve all sales for a specific customer:

https://COMPANY.custobar.com/api/data/sales/?sale_customer_id=A501

Filter by transaction

Retrieve all sale rows for a specific transaction:

https://COMPANY.custobar.com/api/data/sales/?sale_external_id=1000

Filter by date

Retrieve sales from a specific date:

https://COMPANY.custobar.com/api/data/sales/?sale_date=2017-12-01

Filter by product

Retrieve all sales containing a specific product:

https://COMPANY.custobar.com/api/data/sales/?product_id=SKU0435

Filter by shop and state

Retrieve completed sales from a specific shop:

https://COMPANY.custobar.com/api/data/sales/?sale_shop_id=1&sale_state=COMPLETE

Filter by payment method

Retrieve sales paid with credit card:

https://COMPANY.custobar.com/api/data/sales/?sale_payment_method=Credit+Card

Multiple filters combined

Retrieve completed sales for a customer from a specific shop:

https://COMPANY.custobar.com/api/data/sales/?sale_customer_id=A501&sale_shop_id=1&sale_state=COMPLETE

Example response

json
{
    "sales": [
        {
            "sale_external_id": "1000",
            "sale_customer_id": "A501",
            "sale_date": "2017-12-01T13:11:23Z",
            "sale_shop_id": "1",
            "sale_payment_method": "Credit Card",
            "sale_total": 5160,
            "external_id": "1000-1",
            "product_id": "SKU0435",
            "unit_price": 1200,
            "quantity": 1,
            "total": 1200
        }
    ]
}

Products

Product data can be retrieved using various filters to find specific products or groups of products.

Basic product lookup

To retrieve a product by its external_id, make a GET request to:

https://COMPANY.custobar.com/api/data/products/?external_id=1619490226

The result is always a JSON object with a products property, with all matching products as a list:

json
{
    "products": [
        {
            "external_id": "1619490226",
            "title": "Alice in Wonderland",
            "brand": "Lewis Carroll",
            "category": "Children's Books",
            "price": 1200,
            "visible": true
        }
    ]
}

If there are no matching products, the products list will be empty. For external_id queries there are always either zero or one matching products.

Fields that can be used as filters

You can filter products using any of the following fields as query parameters. Multiple filters can be combined.

FieldDescriptionExample ValueExample Usage
external_idProduct identifier1619490226?external_id=1619490226
skuProduct SKU identifierSKU-123456?sku=SKU-123456
eanInternational Article Number5901234123457?ean=5901234123457
titleProduct nameAlice in Wonderland?title=Alice+in+Wonderland
brandBrand nameLewis Carroll?brand=Lewis+Carroll
categoryCategory nameChildren's Books?category=Children%27s+Books
category_idCategory identifier1619?category_id=1619
typeProduct typePaperback?type=Paperback
vendorPublisher or manufacturerPenguin Books?vendor=Penguin+Books
shop_idShop identifierBAKER-STREET?shop_id=BAKER-STREET
visibleProduct visibility statustrue / false?visible=true
in_stockGeneral stock availabilitytrue / false?in_stock=true
languageLanguage code (ISO 639-1)en?language=en
stock.shop_idFilter by stock at specific shopBAKER-STREET?stock.shop_id=BAKER-STREET
stock.quantity.gteMinimum stock quantity10?stock.quantity.gte=10
stock.quantity.lteMaximum stock quantity50?stock.quantity.lte=50

Filter examples

Single filter

Filter products in a specific category:

https://COMPANY.custobar.com/api/data/products/?category=Children's Books

Filter by brand

Retrieve all products from a specific brand:

https://COMPANY.custobar.com/api/data/products/?brand=Lewis Carroll

Filter by type

Retrieve all products of a specific type:

https://COMPANY.custobar.com/api/data/products/?type=Paperback

Filter by visibility

Retrieve only visible (active) products:

https://COMPANY.custobar.com/api/data/products/?visible=true

Filter by stock availability

Retrieve products that are in stock:

https://COMPANY.custobar.com/api/data/products/?in_stock=true

Filter by shop

Retrieve products available in a specific shop:

https://COMPANY.custobar.com/api/data/products/?shop_id=BAKER-STREET

Filter by stock at specific location

Retrieve products that have stock at a specific shop:

https://COMPANY.custobar.com/api/data/products/?stock.shop_id=BAKER-STREET

Filter by stock quantity

Retrieve products with at least 10 items in stock:

https://COMPANY.custobar.com/api/data/products/?stock.quantity.gte=10

Retrieve products with stock between 10 and 50 items:

https://COMPANY.custobar.com/api/data/products/?stock.quantity.gte=10&stock.quantity.lte=50

Filter by stock at specific shop with quantity

Retrieve products at Baker Street location with at least 5 items in stock:

https://COMPANY.custobar.com/api/data/products/?stock.shop_id=BAKER-STREET&stock.quantity.gte=5

Multiple filters combined

Retrieve visible paperback books in a specific category:

https://COMPANY.custobar.com/api/data/products/?category=Children's Books&type=Paperback&visible=true

Combine brand and stock filters:

https://COMPANY.custobar.com/api/data/products/?brand=Lewis Carroll&in_stock=true

Retrieve in-stock products from a specific category at a specific location:

https://COMPANY.custobar.com/api/data/products/?category=Children's Books&stock.shop_id=BAKER-STREET&stock.quantity.gte=1

Example response

json
{
    "products": [
        {
            "external_id": "1619490226",
            "title": "Alice in Wonderland",
            "brand": "Lewis Carroll",
            "category": "Children's Books",
            "category_id": "1619",
            "type": "Paperback",
            "price": 1200,
            "sale_price": 1050,
            "url": "https://www.example.com/product/1619490226",
            "image": "https://www.example.com/images/1619490226.png",
            "visible": true,
            "in_stock": true,
            "shop_id": "BAKER-STREET",
            "stock": [
                {"shop_id": "BAKER-STREET", "quantity": 40},
                {"shop_id": "CANNON-STREET", "quantity": 17}
            ]
        }
    ]
}

Pagination

By default, the data api returns maximum of 100 results. You can specify a custom maximum result set size using the limit parameter, for example

https://COMPANY.custobar.com/api/data/customers/?can_email=true&limit=1000

returns up to 1,000 customers with email permission turned on.

However, the maximum value for limit parameter is 10000 (100000 if using CSV, see format below). If there are more results that the limit allows, they can be delivered using multiple requests. In case there are more results available, the response includes additional next_url field. The next chunk of results may be retrieved from this url. To retrieve results, you must keep requesting more results until the last response contains no next_url field. Here is an example in Python, retrieving all customers in chunks of 1000:

python
import requests
import time

api_token = 'APIXXX...'  # replace this with actual api token
headers = {'Authorization': f'Token {api_token}'}
url = 'https://COMPANY.custobar.com/api/data/customers/?limit=1000'
customers = []

while url:
    reply = requests.get(url, headers=headers).json()
    customers.extend(reply['customers'])
    url = reply.get('next_url')

    time.sleep(1)  # Wait for a second to make sure we don't try to fetch too quickly

The next_url field is also available as the HTTP header field X-Custobar-Next-Url in the HTTP response. This is useful when using CSV format, as there is no place for the next url in the response data.

Specifying the returned fields

By default, the data api returns all data associated with matching results. If you are only interested in certain data fields, you can specify them as a comma-separated list with fields query parameters:

https://COMPANY.custobar.com/api/data/customers/?external_id=CUSTOMERID&fields=email,can_email

external_id is always included, so this will return

json
{
    "customers": [
        {
            "external_id": "CUSTOMERID",
            "email": "customer@example.com",
            "can_email": true
        }
    ]
}

Note that if a record does not have a particular data field, it is not included in the result, even if the field was specified in fields parameter.

Specifying the order

Result order can be chosen using order query parameter. To order in descending order, prefix property name with a dash ('-'). For example, to retrieve customers sorted by their email address domain first, then descending (from z to a) by email address for all customers with same domain, use:

https://COMPANY.custobar.com/api/data/customers/?order=email_domain,-email

Data format

By default, the data api returns the matching results as JSON. However, by specifying format parameter, the results can be formatted as CSV (comma-separated list).

https://COMPANY.custobar.com/api/data/customers/?can_email=True&format=csv

retrieves a CSV of all customers with email permission.

If fields parameter is not specified, the returned CSV contains columns for all potential properties in the data, many of which may not be in use in the particular set of data. Thus it is good practice to specify fields when requesting data in CSV.