NAV

Introduction

The Booqable API is a RESTful JSON API as such is designed to have predictable, resource-oriented URLs and to use HTTP response codes to indicate API errors. We use standard HTTP features, like HTTP authentication and HTTP verbs, which can be understood by off-the-shelf HTTP clients.

Endpoint

All API requests need to be directed to the correct company-specific endpoint. The format is as follows:

https://{company_slug}.booqable.com/api/boomerang/

Response types

The Booqable API supports two response types jsonapi and json.

By default, the API returns jsonapi responses. These responses are designed to return graph data more efficiently and also include links to related resources.

You can, however, also request data in nested structure by appending .json to the path of each request.

A typical JSON API response:

GET /api/boomerang/orders?include=customer
{
  "data": [
    {
      "id": "54808378-a247-4715-89f6-0a8da2e7ad62",
      "type": "orders",
      "attributes": {
        "starts_at": "2021-11-12T15:00:00+00:00",
        "stops_at": "2021-11-13T15:00:00+00:00"
      },
      "relationships": {
        "customer": {
          "links": {
            "related": "api/boomerang/customers/24e54970-7473-49a9-a71a-8c07eb97e510"
          },
          "data": {
            "type": "customers",
            "id": "24e54970-7473-49a9-a71a-8c07eb97e510"
          }
        }
      }
    }
  ],
  "included": [
    {
      "id": "24e54970-7473-49a9-a71a-8c07eb97e510",
      "type": "customers",
      "attributes": {
        "name": "John Doe"
      },
      "relationships": {
        "properties": {
          "links": {
            "related": "api/boomerang/properties?filter[owner_id]=24e54970-7473-49a9-a71a-8c07eb97e510&filter[owner_type]=Customer"
          }
        }
      }
    }
  ],
  "links": {
    "self": "api/boomerang/orders?fields%5Bcustomer%5D=name&fields%5Borders%5D=starts_at%2Cstops_at&include=customer&page%5Bnumber%5D=1&page%5Bsize%5D=25",
    "first": "api/boomerang/orders?fields%5Bcustomer%5D=name&fields%5Borders%5D=starts_at%2Cstops_at&include=customer&page%5Bnumber%5D=1&page%5Bsize%5D=25",
    "last": "api/boomerang/orders?fields%5Bcustomer%5D=name&fields%5Borders%5D=starts_at%2Cstops_at&include=customer&page%5Bnumber%5D=1&page%5Bsize%5D=25"
  },
  "meta": {}
}

A JSON response:

GET /api/boomerang/orders.json?include=customer
{
  "data": [
    {
      "id": "30d35575-c8d1-4f5c-b4c6-cc0abc32c6ed",
      "starts_at": "2021-11-12T15:15:00+00:00",
      "stops_at": "2021-11-13T15:15:00+00:00",
      "customer": {
        "id": "92ec8fee-423e-4f7e-8565-3e6028a0f437",
        "name": "John Doe"
      }
    }
  ]
}

Fields

For every resource, fields can be written, read, filtered, sorted, and aggregated. The behavior of fields is described for each resource.

On every request, you can specify fields to be returned in the response. Note that you can also specify fields of included resources.

Including specific fields can be done like this:

?fields[orders]=starts_at,stops_at&fields[plannings]=reserved_from,reserved_till

Filtering

Collections returned in list requests can be filtered on specific fields; filters support the following operators:

Type Operators
String eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
Uuid eq, not_eq
Enum eq, not_eq
Integer eq, not_eq, gt, gte, lt, lte
Integer eq, not_eq, gt, gte, lt, lte
Big Decimal eq, not_eq, gt, gte, lt, lte
Float eq, not_eq, gt, gte, lt, lte
Boolean eq
Date eq, not_eq, gt, gte, lt, lte
DateTime eq, not_eq, gt, gte, lt, lte
Hash eq
Array eq

How to filter a request:

/api/boomerang/orders?filter[starts_at][gte]=1980-11-16T09:00:00+00:00&filter[starts_at][lte]=1990-11-16T09:00:00+00:00&filter[status]=reserved

Includes

The Booqable API consists of many resources related to each other. Therefore the API supports loading associated resources in a single request. Use the dot-syntax to deeply nest includes.

Including associated data:

GET api/boomerang/orders?include=customer,customer.properties
  {
  "data": {
    "id": "f2afdb0e-55bd-4993-b9c2-4f04b569419d",
    "type": "orders",
    "attributes": {
      "starts_at": "2021-11-12T16:00:00+00:00",
      "stops_at": "2021-11-13T16:00:00+00:00"
    },
    "relationships": {
      "customer": {
        "links": {
          "related": "api/boomerang/customers/404021af-c889-4d72-9296-481640f4c750"
        },
        "data": {
          "type": "customers",
          "id": "404021af-c889-4d72-9296-481640f4c750"
        }
      },
    }
  },
  "included": [
    {
      "id": "404021af-c889-4d72-9296-481640f4c750",
      "type": "customers",
      "attributes": {
        "name": "John Doe"
      },
      "relationships": {
        "properties": {
          "links": {
            "related": "api/boomerang/properties?filter[owner_id]=404021af-c889-4d72-9296-481640f4c750&filter[owner_type]=Customer"
          },
          "data": [
            {
              "type": "properties",
              "id": "9625bd15-732e-4301-8c1c-f5b3e03c1bed"
            }
          ]
        },
      }
    },
    {
      "id": "9625bd15-732e-4301-8c1c-f5b3e03c1bed",
      "type": "properties",
      "attributes": {
        "name": "Phone",
        "value": "+31600000000"
      },
      "relationships": {
        "owner": {
          "links": {
            "related": "api/boomerang/customers/404021af-c889-4d72-9296-481640f4c750"
          }
        }
      }
    }
  ],
  "meta": {}
}

Stats

Results from list requests can be aggregated by providing stats. These stats are always computed over the unpaginated filtered collection. The following aggregations are supported: count, count_each, average, sum, maximum, minimum. You can supply multiple types for each field.

Example of how to request stats:

?stats[to_be_paid_in_cents][]=sum&stats[grand_total_in_cents][]=average&stats[grand_total_in_cents][]=sum&stats[total]=count&stats[payment_status]=count
"meta": {
  "stats": {
    "to_be_paid_in_cents": {
      "sum": 79000
    },
    "grand_total_in_cents": {
      "average": 25000,
      "sum": 1198000
    },
    "total": {
      "count": 237
    },
    "payment_status": {
      "count": {
        "payment_due": 161,
        "paid": 51,
        "partially_paid": 13,
        "overpaid": 11,
        "process_deposit": 1
      }
    }
  }
}

Sideposting

Due to the nature of actions in the API, the API does not support official JSON API compliant side posting. Instead, actions are designed in a way that related resources are managed automatically.

There are a few exceptions though, in these cases, resources can be created or associated by setting:

When side posting is supported, it will be mentioned in the resource-specific documentation.

The following resources support advanced searching with POST requests:

With advanced search you can make logical filter groups with and/or operators. The example on the right yields:

(starts_at >= date AND starts_at <= date) OR (stops_at >= date AND stops_at <= date)

{
  "filter": {
    "conditions": {
      "operator": "or",
      "attributes": [
        {
          "operator": "and",
          "attributes": [
            {
              "starts_at": {
                "gte": "2022-04-27T12:54:37Z"
              }
            },
            {
              "starts_at": {
                "lte": "2022-04-30T12:54:37Z"
              }
            }
          ]
        },
        {
          "operator": "and",
          "attributes": [
            {
              "stops_at": {
                "gte": "2022-04-27T12:54:37Z"
              }
            },
            {
              "stops_at": {
                "lte": "2022-04-30T12:54:37Z"
              }
            }
          ]
        }
      ]
    }
  }
}

Authentication

To interact with the Booqable API, first, you have to have a means of authentification, here's how to setup authentication.

Access Token

  1. Go to your account settings page {company-name-here}.booqable.com/employees/current
  2. Name your new token
  3. Click "Create new authentication method"

You can manage your Access Tokens from your account. You can have multiple Access Tokens active at one time.

Example of an authorized request

curl --request GET \
  --url 'https://example.booqable.com/api/boomerang/customers' \
  --header 'Authorization: Bearer 9bcabeaa827810ad6383d2e15feab2d0c7d039093e22fdd955f11fe83437a32a'

You authenticate to the Booqable API by providing on of your Access Tokens in the request.

Request signing

Single-Use Tokens to sign requests are generated on the client and can only be used once for one particular request. The Booqable API supports the following signing algorithms:

  1. Go to your account settings page {company-name-here}.booqable.com/employees/current
  2. Name your new authentication method
  3. Insert your public key (for ES256 and RS256 only)
  4. Click "Create new authentication method"

You can manage your authentication methods from your account. You can have multiple authentication methods active at one time.

Signing a request (in Ruby, other languages should work like this as well)

# To prevent tampering with the request (making a DELETE from a GET, or posting different params with
# the same signature) we include all request data in the data value.  Note that we generate a SHA256 from it.
request_method = 'POST'

# Encoded request params
fullpath = '/api/boomerang/orders/?filter%5Bcreated_at%5D%5Bgte%5D%3D1231232131132'

# Base64 encoded SHA256 body
body = '{"note":"Let me in!"}'
encoded_body = Base64.strict_encode64(::OpenSSL::Digest::SHA256.new(body).digest)

# Compute data value
data = Base64.strict_encode64(
  ::OpenSSL::Digest::SHA256.new([request_method, fullpath, encoded_body].join('.').join('.')).digest
)

# Generate a unique request identifier (can be anything unique)
uuid = Digest::UUID.uuid_v4

# We define the authentication method id (which you have obtained in a previous step) and kind in the header
headers = { kid: authentication_method_id, kind: 'single_use' }
payload = {
  iss: 'http://company-name.booqable.com',
  sub: employee_id,
  aud: company_id,
  exp: (Time.current + 10.minutes).to_i, # Can not exceed 10 minutes
  iat: Time.current.to_i,
  jti: "#{uuid}.#{data}"
}

# Note that with HS256 you don't have to supply a public key but a secret is generated for you.
token = JWT.encode payload, private_key, 'ES256', headers
token #=> eyJraWQiOiIwZTJkM2I2YS00OTU0LTQyZTItYTAyNS1kYjMzODE1ZDU2YzUiLCJraW5kIjoic2luZ2xlX3VzZSIsImFsZyI6IkVTMjU2In0.eyJpc3MiOiJodHRwOi8vY29tcGFueS1uYW1lLmJvb3FhYmxlLmNvbSIsInN1YiI6IjVlMWViZmFmLWM5YmEtNDMyOC1hM2U1LThlNzNmZGQ1NGNiOSIsImF1ZCI6IjE4ZGI4YTE0LThhYzctNDE1OS05NmJkLTMxMzI0NmRhYTExMCIsImV4cCI6MTYzNTk0ODk3MiwiaWF0IjoxNjM1OTQ4MzcyLCJqdGkiOiJmMTNkZjNlOC0zMWNjLTQxYTUtOWVlNy1mZjgzMTdmNWQ0Y2EuVUU5VFZDNHZQMlpwYkhSbGNpVTFRbU55WldGMFpXUmZZWFFsTlVRbE5VSm5kR1VsTlVRbE0wUXhNak14TWpNeU1UTXhNVE15TGpWemNGcEhSak5IZFdVeVoycFZRVVZ3ZUhsVll6VTVVbTlIZW5sb2NHMXNWbVo0WlVGNVRrSlZUazA5In0.7S2eI3R6meFPPgZ5iyZQOsTDBHRCihKozKMjvIrNHeYoEsxzKltQhGjb2rnfSlpGrCL38-ub-FTs5EXP39rJfw

The algorithm to generate the data value in the payload looks like this:

Base64(
  SHA256(
    [
      request_method,
      encoded_request_fullpath_with_paramaters,
      Base64(
        SHA256(request_body)
      )
    ].join('.')
  )
)

Example of an authorized request

curl --request GET \
  --url 'https://example.booqable.com/api/boomerang/customers' \
  --header 'Authorization: Bearer eyJraWQiOiIwZTJkM2I2YS00OTU0LTQyZTItYTAyNS1kYjMzODE1ZDU2YzUiLCJraW5kIjoic2luZ2xlX3VzZSIsImFsZyI6IkVTMjU2In0.eyJpc3MiOiJodHRwOi8vY29tcGFueS1uYW1lLmJvb3FhYmxlLmNvbSIsInN1YiI6IjVlMWViZmFmLWM5YmEtNDMyOC1hM2U1LThlNzNmZGQ1NGNiOSIsImF1ZCI6IjE4ZGI4YTE0LThhYzctNDE1OS05NmJkLTMxMzI0NmRhYTExMCIsImV4cCI6MTYzNTk0ODk3MiwiaWF0IjoxNjM1OTQ4MzcyLCJqdGkiOiJmMTNkZjNlOC0zMWNjLTQxYTUtOWVlNy1mZjgzMTdmNWQ0Y2EuVUU5VFZDNHZQMlpwYkhSbGNpVTFRbU55WldGMFpXUmZZWFFsTlVRbE5VSm5kR1VsTlVRbE0wUXhNak14TWpNeU1UTXhNVE15TGpWemNGcEhSak5IZFdVeVoycFZRVVZ3ZUhsVll6VTVVbTlIZW5sb2NHMXNWbVo0WlVGNVRrSlZUazA5In0.7S2eI3R6meFPPgZ5iyZQOsTDBHRCihKozKMjvIrNHeYoEsxzKltQhGjb2rnfSlpGrCL38-ub-FTs5EXP39rJfw

You authenticate to the Booqable API by signing the request.

Errors

The Booqable API uses the following error codes:

Error Code Meaning
400 Bad Request -- Your request is invalid.
401 Unauthorized -- You are not authenticated.
403 Forbidden -- The resource requested is hidden for administrators only.
404 Not Found -- The specified resource could not be found.
405 Method Not Allowed -- You tried to access a resource with an invalid method.
406 Not Acceptable -- You requested a format that isn't json.
410 Gone -- The resource requested has been removed from our servers.
418 I'm a teapot.
422 Unprocessible Entity -- Something wen't wrong saving your data.
429 Too Many Requests -- You're doing too many requests! Slow down!
500 Internal Server Error -- We had a problem with our server. Try again later.
503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.

Resources

Authentication methods

Authentication methods define ways to authenticate with the API. They are always scoped to the currently signed-in employee.

See Authentication for more information on authenticating with the API.

Relationships

Name Description
company Company required
The company this authentication method belongs to.
employee Employee required
The employee this authentication method belongs to.

Check matching attributes under Fields to see which relations can be written.
Check each individual operation to see which relations can be included as a sideload.

Fields

Name Description
algorithm enum
Algorithm used for signing.
One of: ES256, RS256, HS256.
company_id uuid readonly
The company this authentication method belongs to.
created_at datetime readonly
When this authentication method was created.
employee_id uuid readonly
The employee this authentication method belongs to.
id uuid readonly
Primary key.
key string extra
Key that is being used for authentication strategy. Because this key is supposed to be kept secret (depending on kind), its value is only returned when explicitly requested.
kind enum
Kind of strategy used for authentication.
One of: token, single_use, oauth.
name string
Name of the key (for identification by user).

List authentication methods

How to fetch a list of authentication methods:

  curl --get 'https://example.booqable.com/api/boomerang/authentication_methods'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "63e16d3e-a24d-4137-8fc5-dc94f18a5068",
        "type": "authentication_methods",
        "attributes": {
          "created_at": "2019-09-26T20:08:02.000000+00:00",
          "updated_at": "2019-09-26T20:08:02.000000+00:00",
          "name": "Segment integration",
          "kind": "single_use",
          "algorithm": "ES256",
          "employee_id": "ca0083cb-ea69-4e2b-8270-e691e0599f5e",
          "company_id": "b5c213f3-bf74-40ee-825d-3fd6219fc0a0"
        },
        "relationships": {}
      }
    ],
    "meta": {}
  }

HTTP Request

GET /api/boomerang/authentication_methods

Request params

This request accepts the following parameters:

Name Description
extra_fields[] array
List of comma separated fields to include in addition to the default fields. ?extra_fields[authentication_methods]=key
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[authentication_methods]=created_at,name,kind
filter hash
The filters to apply ?filter[attribute][eq]=value
meta hash
Metadata to send along. ?meta[total][]=count
page[number] string
The page to request.
page[size] string
The amount of items per page.
sort string
How to sort the data. ?sort=attribute1,-attribute2

Filters

This request can be filtered on:

Name Description
algorithm enum
eq
company_id uuid
eq, not_eq
created_at datetime
eq, not_eq, gt, gte, lt, lte
employee_id uuid
eq, not_eq
id uuid
eq, not_eq
kind enum
eq
name string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match

Meta

Results can be aggregated on:

Name Description
total array
count

Includes

This request does not accept any includes

Fetch an authentication method

How to fetch an authentication method:

  curl --get 'https://example.booqable.com/api/boomerang/authentication_methods/874482c4-c602-4605-8e8f-bdd68bc4e0fe'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": {
      "id": "874482c4-c602-4605-8e8f-bdd68bc4e0fe",
      "type": "authentication_methods",
      "attributes": {
        "created_at": "2014-12-11T10:59:01.000000+00:00",
        "updated_at": "2014-12-11T10:59:01.000000+00:00",
        "name": "Segment integration",
        "kind": "single_use",
        "algorithm": "ES256",
        "key": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEEDRq3Sua6NyUU0WusNISEcchCLBL\nShY0rPpRLfU+Y96OcMiSWaKazYmQDKq4zyIVLlnGiHjv4lwEfhe3Psr39A==\n-----END PUBLIC KEY-----\n",
        "employee_id": "24cc151b-daa4-48f0-8535-f63d7ec20fe7",
        "company_id": "84e60c43-023a-4c37-809c-a941cbac102a"
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

GET /api/boomerang/authentication_methods/{id}

Request params

This request accepts the following parameters:

Name Description
extra_fields[] array
List of comma separated fields to include in addition to the default fields. ?extra_fields[authentication_methods]=key
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[authentication_methods]=created_at,name,kind

Includes

This request does not accept any includes

Create an authentication method

How to create a token authentication method:

  curl --request POST
       --url 'https://example.booqable.com/api/boomerang/authentication_methods'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "type": "authentication_methods",
           "attributes": {
             "name": "Segment integration"
           }
         }
       }'

A 201 status response looks like this:

  {
    "data": {
      "id": "220c0989-a7b1-4962-884e-01ee74df46dc",
      "type": "authentication_methods",
      "attributes": {
        "created_at": "2027-11-18T02:17:01.000000+00:00",
        "updated_at": "2027-11-18T02:17:01.000000+00:00",
        "name": "Segment integration",
        "kind": "token",
        "algorithm": null,
        "key": "821465b1c39ad8d8584eee99c158868d986e7291281dfbedf3855cc9142c197a",
        "employee_id": "d6313cd4-52d0-4f71-87e9-0a5fbd855b19",
        "company_id": "d79aa57f-76cb-483a-8e40-c25404c26a5d"
      },
      "relationships": {}
    },
    "meta": {}
  }

How to create a single_use authentication method (with ES256 strategy):

  curl --request POST
       --url 'https://example.booqable.com/api/boomerang/authentication_methods'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "type": "authentication_methods",
           "attributes": {
             "name": "Segment integration",
             "key": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEEDRq3Sua6NyUU0WusNISEcchCLBL\nShY0rPpRLfU+Y96OcMiSWaKazYmQDKq4zyIVLlnGiHjv4lwEfhe3Psr39A==\n-----END PUBLIC KEY-----\n",
             "kind": "single_use",
             "algorithm": "ES256"
           }
         }
       }'

A 201 status response looks like this:

  {
    "data": {
      "id": "e53a56a3-0f4e-4bd6-8bab-dad967b320b3",
      "type": "authentication_methods",
      "attributes": {
        "created_at": "2021-04-10T18:40:01.000000+00:00",
        "updated_at": "2021-04-10T18:40:01.000000+00:00",
        "name": "Segment integration",
        "kind": "single_use",
        "algorithm": "ES256",
        "key": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEEDRq3Sua6NyUU0WusNISEcchCLBL\nShY0rPpRLfU+Y96OcMiSWaKazYmQDKq4zyIVLlnGiHjv4lwEfhe3Psr39A==\n-----END PUBLIC KEY-----\n",
        "employee_id": "75a59189-d0d6-4668-8c8b-83903cf22d08",
        "company_id": "031ece0d-d2c2-4b5a-86ac-e2eb24560de5"
      },
      "relationships": {}
    },
    "meta": {}
  }

How to create a single_use authentication method (with RS256 strategy):

  curl --request POST
       --url 'https://example.booqable.com/api/boomerang/authentication_methods'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "type": "authentication_methods",
           "attributes": {
             "name": "Segment integration",
             "key": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtRuZD4X3MhIz1ntbxpkp\njVFUTdH7mspUNXmE0bcQ3bJrgWYZmtPm64+lpo7KWqQIL28dhtNAjImJmzcr04ve\nRAxxyQT0f0uwe3zUBEqaxKim1aCJV60c71cPKJVfhXElnjhMkBW6ftIEgf7J4bwe\n7kPCK/NfdiOuFlMjfaY+5WmaA1lAZ/SSetwglSaHPPQKaix3LW4ocHtHUd7OBKNC\nIU/DO3baUDAkymF7ZCnMaf3F9Le9sGSpgUA8Fof69rH1EdagQFmIkftflj/IlJiC\nPDEoc1x7b4opEuGp287S+DsRRgr6vzVZi4CPQcJJsG+07jZQN5K3wboBlx8LW2jT\nfQIDAQAB\n-----END PUBLIC KEY-----\n",
             "kind": "single_use",
             "algorithm": "RS256"
           }
         }
       }'

A 201 status response looks like this:

  {
    "data": {
      "id": "f8a49c93-c272-4014-82f7-aaee9e656a32",
      "type": "authentication_methods",
      "attributes": {
        "created_at": "2014-10-08T04:38:01.000000+00:00",
        "updated_at": "2014-10-08T04:38:01.000000+00:00",
        "name": "Segment integration",
        "kind": "single_use",
        "algorithm": "RS256",
        "key": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtRuZD4X3MhIz1ntbxpkp\njVFUTdH7mspUNXmE0bcQ3bJrgWYZmtPm64+lpo7KWqQIL28dhtNAjImJmzcr04ve\nRAxxyQT0f0uwe3zUBEqaxKim1aCJV60c71cPKJVfhXElnjhMkBW6ftIEgf7J4bwe\n7kPCK/NfdiOuFlMjfaY+5WmaA1lAZ/SSetwglSaHPPQKaix3LW4ocHtHUd7OBKNC\nIU/DO3baUDAkymF7ZCnMaf3F9Le9sGSpgUA8Fof69rH1EdagQFmIkftflj/IlJiC\nPDEoc1x7b4opEuGp287S+DsRRgr6vzVZi4CPQcJJsG+07jZQN5K3wboBlx8LW2jT\nfQIDAQAB\n-----END PUBLIC KEY-----\n",
        "employee_id": "bc3373ee-ee17-4d83-8c01-3b200bf8bdb3",
        "company_id": "faf47d6b-8d0b-4ac5-8892-c0590faa0054"
      },
      "relationships": {}
    },
    "meta": {}
  }

How to create a single_use authentication method (with HS256 strategy):

  curl --request POST
       --url 'https://example.booqable.com/api/boomerang/authentication_methods'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "type": "authentication_methods",
           "attributes": {
             "name": "Segment integration",
             "kind": "single_use",
             "algorithm": "HS256"
           }
         }
       }'

A 201 status response looks like this:

  {
    "data": {
      "id": "29c57921-3618-445f-89ac-84463b0ae952",
      "type": "authentication_methods",
      "attributes": {
        "created_at": "2028-10-03T00:29:01.000000+00:00",
        "updated_at": "2028-10-03T00:29:01.000000+00:00",
        "name": "Segment integration",
        "kind": "single_use",
        "algorithm": "HS256",
        "key": "cb991b0f11304f313a1487b2cb22a067eb4b03da8499bd2f833df79d83045110",
        "employee_id": "777ef44e-2bce-40e3-85dc-63792f9f0c22",
        "company_id": "61df6c42-088c-4fa3-8860-b75b9c114770"
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

POST /api/boomerang/authentication_methods

Request params

This request accepts the following parameters:

Name Description
extra_fields[] array
List of comma separated fields to include in addition to the default fields. ?extra_fields[authentication_methods]=key
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[authentication_methods]=created_at,name,kind
include string
List of comma seperated relationships to sideload. ?include=employee,company

Request body

This request accepts the following body:

Name Description
data[attributes][algorithm] enum
Algorithm used for signing.
One of: ES256, RS256, HS256.
data[attributes][key] string
Key that is being used for authentication strategy. Because this key is supposed to be kept secret (depending on kind), its value is only returned when explicitly requested.
data[attributes][kind] enum
Kind of strategy used for authentication.
One of: token, single_use, oauth.
data[attributes][name] string
Name of the key (for identification by user).

Includes

This request accepts the following includes:

employee

company

Delete an authentication method

How to delete an authentication method:

  curl --request DELETE
       --url 'https://example.booqable.com/api/boomerang/authentication_methods/ef2b6529-43ac-4e66-8ab9-bd2950729b50'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": {
      "id": "ef2b6529-43ac-4e66-8ab9-bd2950729b50",
      "type": "authentication_methods",
      "attributes": {
        "created_at": "2021-11-06T06:35:01.000000+00:00",
        "updated_at": "2021-11-06T06:35:01.000000+00:00",
        "name": "Segment integration",
        "kind": "single_use",
        "algorithm": "ES256",
        "key": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEEDRq3Sua6NyUU0WusNISEcchCLBL\nShY0rPpRLfU+Y96OcMiSWaKazYmQDKq4zyIVLlnGiHjv4lwEfhe3Psr39A==\n-----END PUBLIC KEY-----\n",
        "employee_id": "792a5596-9c55-46ab-8317-6c0651512e04",
        "company_id": "5da72e2c-3b67-4d80-88c1-6e96acba5c58"
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

DELETE /api/boomerang/authentication_methods/{id}

Request params

This request accepts the following parameters:

Name Description
extra_fields[] array
List of comma separated fields to include in addition to the default fields. ?extra_fields[authentication_methods]=key
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[authentication_methods]=created_at,name,kind

Includes

This request does not accept any includes

Barcodes

You can assign Barcodes to Product (variations), individually tracked StockItems, and Customers (for use on a customer card, for example).

An QR code is always generated for each Order. This QR code can be included in emails for speedy pickup and printed on packing slips for easier logistics.

Barcodes cannot be added to ProductGroups. Instead Barcodes can be added to individual Products within the ProductGroup. This is also true when a ProductGroup does not have variations enabled. In that case a Barcode is added to the single Product in the group.

Supported formats

Booqable supports the following barcode formats:

Note that when using URLs as numbers, it's advised to base64 encode the number before filtering.

Relationships

Name Description
owner Customer, Product, Order, Stock item required
The resource pointed to by this Barcode.

Check matching attributes under Fields to see which relations can be written.
Check each individual operation to see which relations can be included as a sideload.

Fields

Name Description
barcode_type enum
Barcode format. See resource description above for pros/cons of each format.
One of: code39, code93, code128, ean8, ean13, qr_code.
created_at datetime readonly
When the resource was created.
id uuid readonly
Primary key.
image_url string readonly
A link to an image of the Barcode.
number string
The barcode data, can be a number, code or url. Leave blank to let Booqable create one. When using a URL, it's advised to base64 encode the number before filtering.
owner_id uuid readonly-after-create
The resource pointed to by this Barcode.
owner_type enum readonly-after-create
The resource type of the owner.
One of: customers, products, orders, stock_items.
updated_at datetime readonly
When the resource was last updated.

List barcodes

How to fetch a list of barcodes:

  curl --get 'https://example.booqable.com/api/boomerang/barcodes'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "c3fbfdf6-d756-4d88-89c7-974df32dc31f",
        "type": "barcodes",
        "attributes": {
          "created_at": "2026-11-20T19:16:00.000000+00:00",
          "updated_at": "2026-11-20T19:16:00.000000+00:00",
          "number": "http://bqbl.it/c3fbfdf6-d756-4d88-89c7-974df32dc31f",
          "barcode_type": "qr_code",
          "image_url": "http://company-name-14.lvh.me:/barcodes/c3fbfdf6-d756-4d88-89c7-974df32dc31f/image",
          "owner_id": "2318a321-06f9-4303-8d23-b46cfb189aeb",
          "owner_type": "customers"
        },
        "relationships": {}
      }
    ],
    "meta": {}
  }

How to find an owner by a barcode number:

  curl --get 'https://example.booqable.com/api/boomerang/barcodes'
       --header 'content-type: application/json'
       --data-urlencode 'filter[number]=http://bqbl.it/9882a0de-d425-4c34-8a53-f65dd35dd375'
       --data-urlencode 'include=owner'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "9882a0de-d425-4c34-8a53-f65dd35dd375",
        "type": "barcodes",
        "attributes": {
          "created_at": "2021-09-12T13:49:00.000000+00:00",
          "updated_at": "2021-09-12T13:49:00.000000+00:00",
          "number": "http://bqbl.it/9882a0de-d425-4c34-8a53-f65dd35dd375",
          "barcode_type": "qr_code",
          "image_url": "http://company-name-15.lvh.me:/barcodes/9882a0de-d425-4c34-8a53-f65dd35dd375/image",
          "owner_id": "48f38dad-4082-4377-8d28-c793e2d1c814",
          "owner_type": "customers"
        },
        "relationships": {
          "owner": {
            "data": {
              "type": "customers",
              "id": "48f38dad-4082-4377-8d28-c793e2d1c814"
            }
          }
        }
      }
    ],
    "included": [
      {
        "id": "48f38dad-4082-4377-8d28-c793e2d1c814",
        "type": "customers",
        "attributes": {
          "created_at": "2021-09-12T13:49:00.000000+00:00",
          "updated_at": "2021-09-12T13:49:00.000000+00:00",
          "archived": false,
          "archived_at": null,
          "number": 1,
          "name": "John Doe",
          "email": "[email protected]",
          "deposit_type": "default",
          "deposit_value": 0.0,
          "discount_percentage": 0.0,
          "legal_type": "person",
          "email_marketing_consented": false,
          "email_marketing_consent_updated_at": null,
          "properties": {},
          "tag_list": [],
          "merge_suggestion_customer_id": null,
          "tax_region_id": null
        },
        "relationships": {}
      }
    ],
    "meta": {}
  }

How to find an owner by a barcode number containing a url:

  curl --get 'https://example.booqable.com/api/boomerang/barcodes'
       --header 'content-type: application/json'
       --data-urlencode 'filter[number]=aHR0cDovL2JxYmwuaXQvMWRmNGY4YzAtNzU5Zi00OWNkLTkxZWYtZjQ1ODkwMTNlMDEz'
       --data-urlencode 'include=owner'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "78a5e268-fca0-450a-855f-49f29ef29ef3",
        "type": "barcodes",
        "attributes": {
          "created_at": "2023-09-26T19:48:00.000000+00:00",
          "updated_at": "2023-09-26T19:48:00.000000+00:00",
          "number": "http://bqbl.it/78a5e268-fca0-450a-855f-49f29ef29ef3",
          "barcode_type": "qr_code",
          "image_url": "http://company-name-16.lvh.me:/barcodes/78a5e268-fca0-450a-855f-49f29ef29ef3/image",
          "owner_id": "ab6232e0-b056-4bf8-8bc7-99c41f2782de",
          "owner_type": "customers"
        },
        "relationships": {
          "owner": {
            "data": {
              "type": "customers",
              "id": "ab6232e0-b056-4bf8-8bc7-99c41f2782de"
            }
          }
        }
      }
    ],
    "included": [
      {
        "id": "ab6232e0-b056-4bf8-8bc7-99c41f2782de",
        "type": "customers",
        "attributes": {
          "created_at": "2023-09-26T19:48:00.000000+00:00",
          "updated_at": "2023-09-26T19:48:00.000000+00:00",
          "archived": false,
          "archived_at": null,
          "number": 2,
          "name": "John Doe",
          "email": "[email protected]",
          "deposit_type": "default",
          "deposit_value": 0.0,
          "discount_percentage": 0.0,
          "legal_type": "person",
          "email_marketing_consented": false,
          "email_marketing_consent_updated_at": null,
          "properties": {},
          "tag_list": [],
          "merge_suggestion_customer_id": null,
          "tax_region_id": null
        },
        "relationships": {}
      }
    ],
    "meta": {}
  }

HTTP Request

GET /api/boomerang/barcodes

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[barcodes]=created_at,updated_at,number
filter hash
The filters to apply ?filter[attribute][eq]=value
include string
List of comma seperated relationships to sideload. ?include=owner
meta hash
Metadata to send along. ?meta[total][]=count
page[number] string
The page to request.
page[size] string
The amount of items per page.
sort string
How to sort the data. ?sort=attribute1,-attribute2

Filters

This request can be filtered on:

Name Description
barcode_type enum
eq
created_at datetime
eq, not_eq, gt, gte, lt, lte
id uuid
eq, not_eq
number string
eq
owner_id uuid
eq, not_eq
owner_type enum
eq, not_eq
updated_at datetime
eq, not_eq, gt, gte, lt, lte

Meta

Results can be aggregated on:

Name Description
total array
count

Includes

This request accepts the following includes:

owner => photo

product => photo

Fetch a barcode

How to fetch a barcode:

  curl --get 'https://example.booqable.com/api/boomerang/barcodes/60d46666-056c-4072-8fd0-cae57d7a90ff'
       --header 'content-type: application/json'
       --data-urlencode 'include=owner'

A 200 status response looks like this:

  {
    "data": {
      "id": "60d46666-056c-4072-8fd0-cae57d7a90ff",
      "type": "barcodes",
      "attributes": {
        "created_at": "2023-11-26T10:01:03.000000+00:00",
        "updated_at": "2023-11-26T10:01:03.000000+00:00",
        "number": "http://bqbl.it/60d46666-056c-4072-8fd0-cae57d7a90ff",
        "barcode_type": "qr_code",
        "image_url": "http://company-name-17.lvh.me:/barcodes/60d46666-056c-4072-8fd0-cae57d7a90ff/image",
        "owner_id": "9a08fa5a-eddb-4502-8e1e-60dbd303cb58",
        "owner_type": "customers"
      },
      "relationships": {
        "owner": {
          "data": {
            "type": "customers",
            "id": "9a08fa5a-eddb-4502-8e1e-60dbd303cb58"
          }
        }
      }
    },
    "included": [
      {
        "id": "9a08fa5a-eddb-4502-8e1e-60dbd303cb58",
        "type": "customers",
        "attributes": {
          "created_at": "2023-11-26T10:01:03.000000+00:00",
          "updated_at": "2023-11-26T10:01:03.000000+00:00",
          "archived": false,
          "archived_at": null,
          "number": 1,
          "name": "John Doe",
          "email": "[email protected]",
          "deposit_type": "default",
          "deposit_value": 0.0,
          "discount_percentage": 0.0,
          "legal_type": "person",
          "email_marketing_consented": false,
          "email_marketing_consent_updated_at": null,
          "properties": {},
          "tag_list": [],
          "merge_suggestion_customer_id": null,
          "tax_region_id": null
        },
        "relationships": {}
      }
    ],
    "meta": {}
  }

HTTP Request

GET /api/boomerang/barcodes/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[barcodes]=created_at,updated_at,number
include string
List of comma seperated relationships to sideload. ?include=owner

Includes

This request accepts the following includes:

owner => photo

product => photo

Create a barcode

How to create a barcode:

  curl --request POST
       --url 'https://example.booqable.com/api/boomerang/barcodes'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "type": "barcodes",
           "attributes": {
             "barcode_type": "qr_code",
             "owner_id": "9d177e60-f890-4d0a-8dc6-44d61d8cca22",
             "owner_type": "customers"
           }
         }
       }'

A 201 status response looks like this:

  {
    "data": {
      "id": "954b9fd3-271d-4ab4-8a7e-87e89b15c0a0",
      "type": "barcodes",
      "attributes": {
        "created_at": "2019-09-24T03:44:00.000000+00:00",
        "updated_at": "2019-09-24T03:44:00.000000+00:00",
        "number": "http://bqbl.it/954b9fd3-271d-4ab4-8a7e-87e89b15c0a0",
        "barcode_type": "qr_code",
        "image_url": "http://company-name-18.lvh.me:/barcodes/954b9fd3-271d-4ab4-8a7e-87e89b15c0a0/image",
        "owner_id": "9d177e60-f890-4d0a-8dc6-44d61d8cca22",
        "owner_type": "customers"
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

POST /api/boomerang/barcodes

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[barcodes]=created_at,updated_at,number
include string
List of comma seperated relationships to sideload. ?include=owner

Request body

This request accepts the following body:

Name Description
data[attributes][barcode_type] enum
Barcode format. See resource description above for pros/cons of each format.
One of: code39, code93, code128, ean8, ean13, qr_code.
data[attributes][number] string
The barcode data, can be a number, code or url. Leave blank to let Booqable create one. When using a URL, it's advised to base64 encode the number before filtering.
data[attributes][owner_id] uuid
The resource pointed to by this Barcode.
data[attributes][owner_type] enum
The resource type of the owner.
One of: customers, products, orders, stock_items.

Includes

This request accepts the following includes:

owner => photo

product => photo

Update a barcode

How to update a barcode:

  curl --request PUT
       --url 'https://example.booqable.com/api/boomerang/barcodes/d4f58d8f-2318-44f4-8097-9dbe2a9ddaf2'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "id": "d4f58d8f-2318-44f4-8097-9dbe2a9ddaf2",
           "type": "barcodes",
           "attributes": {
             "number": "https://myfancysite.com"
           }
         }
       }'

A 200 status response looks like this:

  {
    "data": {
      "id": "d4f58d8f-2318-44f4-8097-9dbe2a9ddaf2",
      "type": "barcodes",
      "attributes": {
        "created_at": "2021-10-11T03:09:01.000000+00:00",
        "updated_at": "2021-10-11T03:09:01.000000+00:00",
        "number": "https://myfancysite.com",
        "barcode_type": "qr_code",
        "image_url": "http://company-name-19.lvh.me:/barcodes/d4f58d8f-2318-44f4-8097-9dbe2a9ddaf2/image",
        "owner_id": "a8f4104c-a6da-44d0-8505-a590b71bb780",
        "owner_type": "customers"
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

PUT /api/boomerang/barcodes/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[barcodes]=created_at,updated_at,number
include string
List of comma seperated relationships to sideload. ?include=owner

Request body

This request accepts the following body:

Name Description
data[attributes][barcode_type] enum
Barcode format. See resource description above for pros/cons of each format.
One of: code39, code93, code128, ean8, ean13, qr_code.
data[attributes][number] string
The barcode data, can be a number, code or url. Leave blank to let Booqable create one. When using a URL, it's advised to base64 encode the number before filtering.
data[attributes][owner_id] uuid
The resource pointed to by this Barcode.
data[attributes][owner_type] enum
The resource type of the owner.
One of: customers, products, orders, stock_items.

Includes

This request accepts the following includes:

owner => photo

product => photo

Destroy a barcode

How to delete a barcode:

  curl --request DELETE
       --url 'https://example.booqable.com/api/boomerang/barcodes/ac988a7e-ebdc-45af-8638-9783aeb4594e'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": {
      "id": "ac988a7e-ebdc-45af-8638-9783aeb4594e",
      "type": "barcodes",
      "attributes": {
        "created_at": "2023-03-27T06:20:00.000000+00:00",
        "updated_at": "2023-03-27T06:20:00.000000+00:00",
        "number": "http://bqbl.it/ac988a7e-ebdc-45af-8638-9783aeb4594e",
        "barcode_type": "qr_code",
        "image_url": "http://company-name-20.lvh.me:/barcodes/ac988a7e-ebdc-45af-8638-9783aeb4594e/image",
        "owner_id": "20fbc832-70a9-45dd-84fd-848ee269b502",
        "owner_type": "customers"
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

DELETE /api/boomerang/barcodes/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[barcodes]=created_at,updated_at,number
include string
List of comma seperated relationships to sideload. ?include=owner

Includes

This request accepts the following includes:

owner => photo

product => photo

Bundles

Bundles allow for a single product to be made up of multiple other products. This makes it possible to offer customers a set of products that logically go together as a single package, for a single price, and with a combined availability.

Bundles are composed from BundleItems, which describe which products are included, how many of them, and the discount for each product.

There are two types of bundles:

Relationships

Name Description
bundle_items Bundle items hasmany
The bundle items that make up this bundle.
inventory_levels Inventory levels hasmany
Availability of this bundle. Because bundles do not exist on a physical level (they are a collection of products), the returned availability will be the maximum number of bundles that can be made from the available products (bundle availability is restricted by the least available product).
photo Photo optional
Primary photo of this bundle.
photos Photos hasmany
All photos of this bundle. The primary photo must be selected from this set.
tax_category Tax category optional
Tax category for tax calculations. When present, this tax category overrides the tax category of the individual products.

Check matching attributes under Fields to see which relations can be written.
Check each individual operation to see which relations can be included as a sideload.

Fields

Name Description
archived boolean readonly
Whether the bundle is archived.
archived_at datetime readonly nullable
When the bundle was archived.
bundle_items_attributes array writeonly
Writing to this attribute allows to create or update bundle items at the same time as the bundle itself.
created_at datetime readonly
When the resource was created.
description string nullable
Description used in the online store.
discountable boolean
Whether discounts should be applied to items in this bundle.
excerpt string nullable
Excerpt used in the online store.
extra_information string nullable
Extra information about the bundle, shown on orders and documents.
id uuid readonly
Primary key.
name string
Name of the bundle.
photo_base64 string writeonly
Base64 encoded photo, use this field to store a main photo.
photo_id uuid readonly nullable
Primary photo of this bundle.
photo_url string readonly
Main photo url.
product_type enum readonly
Always bundle. This attribute exists because bundles are a kind of Item.
Always bundle
remote_photo_url string writeonly
Url to an image on the web.
seo_description string nullable
SEO meta description tag.
seo_title string nullable
SEO title tag.
show_in_store boolean
Whether to show this item in the online.
slug string
Slug of the bundle.
sorting_weight integer
Defines sort order in the online store, the lower the weight - the higher it shows up in lists.
tag_list array
List of tags.
tax_category_id uuid nullable
Tax category for tax calculations. When present, this tax category overrides the tax category of the individual products.
taxable boolean
Whether this bundle is taxable.
type string readonly
Always bundles. This attribute exists because bundles are a kind of Item.
updated_at datetime readonly
When the resource was last updated.

List bundles

How to fetch a list of bundles:

  curl --get 'https://example.booqable.com/api/boomerang/bundles'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "18ffd1b4-8468-4bad-82c1-1e7f370f600f",
        "type": "bundles",
        "attributes": {
          "created_at": "2020-11-21T17:08:01.000000+00:00",
          "updated_at": "2020-11-21T17:08:01.000000+00:00",
          "archived": false,
          "archived_at": null,
          "type": "bundles",
          "name": "iPad Bundle",
          "slug": "ipad-bundle",
          "product_type": "bundle",
          "extra_information": null,
          "photo_url": null,
          "description": null,
          "excerpt": null,
          "show_in_store": true,
          "sorting_weight": 0,
          "discountable": true,
          "taxable": true,
          "seo_title": null,
          "seo_description": null,
          "tag_list": [],
          "photo_id": null,
          "tax_category_id": null
        },
        "relationships": {}
      }
    ],
    "meta": {}
  }

HTTP Request

GET /api/boomerang/bundles

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[bundles]=created_at,updated_at,archived
filter hash
The filters to apply ?filter[attribute][eq]=value
include string
List of comma seperated relationships to sideload. ?include=photo,inventory_levels
meta hash
Metadata to send along. ?meta[total][]=count
page[number] string
The page to request.
page[size] string
The amount of items per page.
sort string
How to sort the data. ?sort=attribute1,-attribute2

Filters

This request can be filtered on:

Name Description
archived boolean
eq
archived_at datetime
eq, not_eq, gt, gte, lt, lte
created_at datetime
eq, not_eq, gt, gte, lt, lte
description string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
discountable boolean
eq
excerpt string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
extra_information string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
id uuid
eq, not_eq
name string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
photo_id uuid
eq, not_eq
product_type enum
eq
q string
eq
seo_description string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
seo_title string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
show_in_store boolean
eq
slug string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
sorting_weight integer
eq, not_eq, gt, gte, lt, lte
tag_list string
eq
tax_category_id uuid
eq, not_eq
taxable boolean
eq
type string
eq, not_eq
updated_at datetime
eq, not_eq, gt, gte, lt, lte

Meta

Results can be aggregated on:

Name Description
archived array
count
discountable array
count
product_type array
count
show_in_store array
count
tag_list array
count
tax_category_id array
count
taxable array
count
total array
count

Includes

This request accepts the following includes:

photo

inventory_levels

Search bundles

Use advanced search to make logical filter groups with and/or operators.

How to search for bundles:

  curl --request POST
       --url 'https://example.booqable.com/api/boomerang/bundles/search'
       --header 'content-type: application/json'
       --data '{
         "fields": {
           "bundles": "id"
         },
         "filter": {
           "conditions": {
             "operator": "or",
             "attributes": [
               {
                 "operator": "and",
                 "attributes": [
                   {
                     "discountable": true
                   },
                   {
                     "taxable": true
                   }
                 ]
               },
               {
                 "operator": "and",
                 "attributes": [
                   {
                     "show_in_store": true
                   },
                   {
                     "taxable": true
                   }
                 ]
               }
             ]
           }
         }
       }'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "ea409533-a730-4d13-8149-036b51248925"
      },
      {
        "id": "16552c0c-85c9-4d79-81d8-862b15da8a16"
      },
      {
        "id": "714cbc42-5133-4ee2-8945-1fb6391bfbc8"
      }
    ]
  }

HTTP Request

POST api/boomerang/bundles/search

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[bundles]=created_at,updated_at,archived
filter hash
The filters to apply ?filter[attribute][eq]=value
include string
List of comma seperated relationships to sideload. ?include=photo,inventory_levels
meta hash
Metadata to send along. ?meta[total][]=count
page[number] string
The page to request.
page[size] string
The amount of items per page.
sort string
How to sort the data. ?sort=attribute1,-attribute2

Filters

This request can be filtered on:

Name Description
archived boolean
eq
archived_at datetime
eq, not_eq, gt, gte, lt, lte
created_at datetime
eq, not_eq, gt, gte, lt, lte
description string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
discountable boolean
eq
excerpt string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
extra_information string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
id uuid
eq, not_eq
name string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
photo_id uuid
eq, not_eq
product_type enum
eq
q string
eq
seo_description string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
seo_title string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
show_in_store boolean
eq
slug string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
sorting_weight integer
eq, not_eq, gt, gte, lt, lte
tag_list string
eq
tax_category_id uuid
eq, not_eq
taxable boolean
eq
type string
eq, not_eq
updated_at datetime
eq, not_eq, gt, gte, lt, lte

Meta

Results can be aggregated on:

Name Description
archived array
count
discountable array
count
product_type array
count
show_in_store array
count
tag_list array
count
tax_category_id array
count
taxable array
count
total array
count

Includes

This request accepts the following includes:

photo

inventory_levels

Fetch a bundle

How to fetch a bundle:

  curl --get 'https://example.booqable.com/api/boomerang/bundles/7a7aeed9-35dd-40fe-8ece-5551e24ce953'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": {
      "id": "7a7aeed9-35dd-40fe-8ece-5551e24ce953",
      "type": "bundles",
      "attributes": {
        "created_at": "2027-01-01T09:13:00.000000+00:00",
        "updated_at": "2027-01-01T09:13:00.000000+00:00",
        "archived": false,
        "archived_at": null,
        "type": "bundles",
        "name": "iPad Bundle",
        "slug": "ipad-bundle",
        "product_type": "bundle",
        "extra_information": null,
        "photo_url": null,
        "description": null,
        "excerpt": null,
        "show_in_store": true,
        "sorting_weight": 0,
        "discountable": true,
        "taxable": true,
        "seo_title": null,
        "seo_description": null,
        "tag_list": [],
        "photo_id": null,
        "tax_category_id": null
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

GET /api/boomerang/bundles/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[bundles]=created_at,updated_at,archived
include string
List of comma seperated relationships to sideload. ?include=photo,bundle_items,tax_category

Includes

This request accepts the following includes:

photo

bundle_items => product_group => photo

products => photo

product => photo

tax_category

Create a bundle

How to create a bundle with bundle items:

  curl --request POST
       --url 'https://example.booqable.com/api/boomerang/bundles'
       --header 'content-type: application/json'
       --data '{
         "include": "bundle_items",
         "data": {
           "type": "bundles",
           "attributes": {
             "name": "iPad Pro Bundle",
             "bundle_items_attributes": [
               {
                 "quantity": 2,
                 "discount_percentage": 10,
                 "product_group_id": "1a247a34-c748-422e-8f6e-1a6d3992c656",
                 "product_id": "ca3c0fbf-03ac-4a05-8a65-d5bab132b59d"
               },
               {
                 "quantity": 2,
                 "discount_percentage": 15,
                 "product_group_id": "bf793cc3-ff25-497e-8a92-6cf9a8d99fa0",
                 "product_id": "07b0cf35-6809-4bec-8350-2dbe5a39a565"
               }
             ]
           }
         }
       }'

A 201 status response looks like this:

  {
    "data": {
      "id": "2f4b77bd-2e6d-4454-8933-babc61ed151f",
      "type": "bundles",
      "attributes": {
        "created_at": "2020-05-21T17:38:00.000000+00:00",
        "updated_at": "2020-05-21T17:38:00.000000+00:00",
        "archived": false,
        "archived_at": null,
        "type": "bundles",
        "name": "iPad Pro Bundle",
        "slug": "ipad-pro-bundle",
        "product_type": "bundle",
        "extra_information": null,
        "photo_url": null,
        "description": null,
        "excerpt": null,
        "show_in_store": true,
        "sorting_weight": 0,
        "discountable": true,
        "taxable": true,
        "seo_title": null,
        "seo_description": null,
        "tag_list": [],
        "photo_id": null,
        "tax_category_id": null
      },
      "relationships": {
        "bundle_items": {
          "data": [
            {
              "type": "bundle_items",
              "id": "df0b9888-284d-4211-8aa3-7c4bd3922ad5"
            },
            {
              "type": "bundle_items",
              "id": "f6e42e06-fab0-4f46-8f8e-ea8a9422304b"
            },
            {
              "type": "bundle_items",
              "id": "ae082f3d-ff30-456b-8adb-5b4919c8417a"
            },
            {
              "type": "bundle_items",
              "id": "0a030633-4d84-4191-8e44-c52eb68d811a"
            }
          ]
        }
      }
    },
    "included": [
      {
        "id": "df0b9888-284d-4211-8aa3-7c4bd3922ad5",
        "type": "bundle_items",
        "attributes": {
          "created_at": "2020-05-21T17:38:00.000000+00:00",
          "updated_at": "2020-05-21T17:38:00.000000+00:00",
          "quantity": 2,
          "discount_percentage": 10.0,
          "position": 1,
          "bundle_id": "2f4b77bd-2e6d-4454-8933-babc61ed151f",
          "product_group_id": "1a247a34-c748-422e-8f6e-1a6d3992c656",
          "product_id": "ca3c0fbf-03ac-4a05-8a65-d5bab132b59d"
        },
        "relationships": {}
      },
      {
        "id": "f6e42e06-fab0-4f46-8f8e-ea8a9422304b",
        "type": "bundle_items",
        "attributes": {
          "created_at": "2020-05-21T17:38:00.000000+00:00",
          "updated_at": "2020-05-21T17:38:00.000000+00:00",
          "quantity": 2,
          "discount_percentage": 15.0,
          "position": 2,
          "bundle_id": "2f4b77bd-2e6d-4454-8933-babc61ed151f",
          "product_group_id": "bf793cc3-ff25-497e-8a92-6cf9a8d99fa0",
          "product_id": "07b0cf35-6809-4bec-8350-2dbe5a39a565"
        },
        "relationships": {}
      },
      {
        "id": "ae082f3d-ff30-456b-8adb-5b4919c8417a",
        "type": "bundle_items",
        "attributes": {
          "created_at": "2020-05-21T17:38:00.000000+00:00",
          "updated_at": "2020-05-21T17:38:00.000000+00:00",
          "quantity": 2,
          "discount_percentage": 10.0,
          "position": 3,
          "bundle_id": "2f4b77bd-2e6d-4454-8933-babc61ed151f",
          "product_group_id": "1a247a34-c748-422e-8f6e-1a6d3992c656",
          "product_id": "ca3c0fbf-03ac-4a05-8a65-d5bab132b59d"
        },
        "relationships": {}
      },
      {
        "id": "0a030633-4d84-4191-8e44-c52eb68d811a",
        "type": "bundle_items",
        "attributes": {
          "created_at": "2020-05-21T17:38:00.000000+00:00",
          "updated_at": "2020-05-21T17:38:00.000000+00:00",
          "quantity": 2,
          "discount_percentage": 15.0,
          "position": 4,
          "bundle_id": "2f4b77bd-2e6d-4454-8933-babc61ed151f",
          "product_group_id": "bf793cc3-ff25-497e-8a92-6cf9a8d99fa0",
          "product_id": "07b0cf35-6809-4bec-8350-2dbe5a39a565"
        },
        "relationships": {}
      }
    ],
    "meta": {}
  }

HTTP Request

POST /api/boomerang/bundles

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[bundles]=created_at,updated_at,archived
include string
List of comma seperated relationships to sideload. ?include=photo,bundle_items,tax_category

Request body

This request accepts the following body:

Name Description
data[attributes][bundle_items_attributes][] array
Writing to this attribute allows to create or update bundle items at the same time as the bundle itself.
data[attributes][discountable] boolean
Whether discounts should be applied to items in this bundle.
data[attributes][excerpt] string
Excerpt used in the online store.
data[attributes][extra_information] string
Extra information about the bundle, shown on orders and documents.
data[attributes][name] string
Name of the bundle.
data[attributes][photo_base64] string
Base64 encoded photo, use this field to store a main photo.
data[attributes][remote_photo_url] string
Url to an image on the web.
data[attributes][seo_description] string
SEO meta description tag.
data[attributes][seo_title] string
SEO title tag.
data[attributes][show_in_store] boolean
Whether to show this item in the online.
data[attributes][slug] string
Slug of the bundle.
data[attributes][sorting_weight] integer
Defines sort order in the online store, the lower the weight - the higher it shows up in lists.
data[attributes][tag_list][] array
List of tags.
data[attributes][tax_category_id] uuid
Tax category for tax calculations. When present, this tax category overrides the tax category of the individual products.
data[attributes][taxable] boolean
Whether this bundle is taxable.

Includes

This request accepts the following includes:

photo

bundle_items => product_group => photo

product => photo

tax_category

Update a bundle

How to update a bundle with bundle items:

  curl --request PUT
       --url 'https://example.booqable.com/api/boomerang/bundles/ed81707b-f578-4a6e-82e8-062f3b5ae2d9'
       --header 'content-type: application/json'
       --data '{
         "include": "bundle_items",
         "data": {
           "id": "ed81707b-f578-4a6e-82e8-062f3b5ae2d9",
           "type": "bundles",
           "attributes": {
             "name": "iPad Pro Bundle",
             "bundle_items_attributes": [
               {
                 "id": "3357b030-9385-4491-843f-9bd93e88723a",
                 "_destroy": true
               },
               {
                 "quantity": 2,
                 "discount_percentage": 15,
                 "product_group_id": "a9609021-9ac0-45e8-8bfa-03c58a577154",
                 "product_id": "abff6839-af87-4377-857e-2b217552945d"
               }
             ]
           }
         }
       }'

A 200 status response looks like this:

  {
    "data": {
      "id": "ed81707b-f578-4a6e-82e8-062f3b5ae2d9",
      "type": "bundles",
      "attributes": {
        "created_at": "2023-01-20T01:56:00.000000+00:00",
        "updated_at": "2023-01-20T01:56:00.000000+00:00",
        "archived": false,
        "archived_at": null,
        "type": "bundles",
        "name": "iPad Pro Bundle",
        "slug": "ipad-pro-bundle",
        "product_type": "bundle",
        "extra_information": null,
        "photo_url": null,
        "description": null,
        "excerpt": null,
        "show_in_store": true,
        "sorting_weight": 0,
        "discountable": true,
        "taxable": true,
        "seo_title": null,
        "seo_description": null,
        "tag_list": [],
        "photo_id": null,
        "tax_category_id": null
      },
      "relationships": {
        "bundle_items": {
          "data": [
            {
              "type": "bundle_items",
              "id": "ddfe9f02-abf5-48bd-8fba-334decb8c339"
            },
            {
              "type": "bundle_items",
              "id": "d5abce78-6f6d-46ef-8e46-876a07eb7133"
            }
          ]
        }
      }
    },
    "included": [
      {
        "id": "ddfe9f02-abf5-48bd-8fba-334decb8c339",
        "type": "bundle_items",
        "attributes": {
          "created_at": "2023-01-20T01:56:00.000000+00:00",
          "updated_at": "2023-01-20T01:56:00.000000+00:00",
          "quantity": 2,
          "discount_percentage": 15.0,
          "position": 2,
          "bundle_id": "ed81707b-f578-4a6e-82e8-062f3b5ae2d9",
          "product_group_id": "a9609021-9ac0-45e8-8bfa-03c58a577154",
          "product_id": "abff6839-af87-4377-857e-2b217552945d"
        },
        "relationships": {}
      },
      {
        "id": "d5abce78-6f6d-46ef-8e46-876a07eb7133",
        "type": "bundle_items",
        "attributes": {
          "created_at": "2023-01-20T01:56:00.000000+00:00",
          "updated_at": "2023-01-20T01:56:00.000000+00:00",
          "quantity": 2,
          "discount_percentage": 15.0,
          "position": 3,
          "bundle_id": "ed81707b-f578-4a6e-82e8-062f3b5ae2d9",
          "product_group_id": "a9609021-9ac0-45e8-8bfa-03c58a577154",
          "product_id": "abff6839-af87-4377-857e-2b217552945d"
        },
        "relationships": {}
      }
    ],
    "meta": {}
  }

HTTP Request

PUT /api/boomerang/bundles/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[bundles]=created_at,updated_at,archived
include string
List of comma seperated relationships to sideload. ?include=photo,bundle_items,tax_category

Request body

This request accepts the following body:

Name Description
data[attributes][bundle_items_attributes][] array
Writing to this attribute allows to create or update bundle items at the same time as the bundle itself.
data[attributes][discountable] boolean
Whether discounts should be applied to items in this bundle.
data[attributes][excerpt] string
Excerpt used in the online store.
data[attributes][extra_information] string
Extra information about the bundle, shown on orders and documents.
data[attributes][name] string
Name of the bundle.
data[attributes][photo_base64] string
Base64 encoded photo, use this field to store a main photo.
data[attributes][remote_photo_url] string
Url to an image on the web.
data[attributes][seo_description] string
SEO meta description tag.
data[attributes][seo_title] string
SEO title tag.
data[attributes][show_in_store] boolean
Whether to show this item in the online.
data[attributes][slug] string
Slug of the bundle.
data[attributes][sorting_weight] integer
Defines sort order in the online store, the lower the weight - the higher it shows up in lists.
data[attributes][tag_list][] array
List of tags.
data[attributes][tax_category_id] uuid
Tax category for tax calculations. When present, this tax category overrides the tax category of the individual products.
data[attributes][taxable] boolean
Whether this bundle is taxable.

Includes

This request accepts the following includes:

photo

bundle_items => product_group => photo

product => photo

tax_category

Archive a bundle

How to delete a bundle:

  curl --request DELETE
       --url 'https://example.booqable.com/api/boomerang/bundles/ec090d58-5e64-4db7-89ae-80f6bcdd3d22'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": {
      "id": "ec090d58-5e64-4db7-89ae-80f6bcdd3d22",
      "type": "bundles",
      "attributes": {
        "created_at": "2023-08-27T09:39:03.000000+00:00",
        "updated_at": "2023-08-27T09:39:03.000000+00:00",
        "archived": true,
        "archived_at": "2023-08-27T09:39:03.000000+00:00",
        "type": "bundles",
        "name": "iPad Bundle",
        "slug": "ec090d58-5e64-4db7-89ae-80f6bcdd3d22",
        "product_type": "bundle",
        "extra_information": null,
        "photo_url": null,
        "description": null,
        "excerpt": null,
        "show_in_store": true,
        "sorting_weight": 0,
        "discountable": true,
        "taxable": true,
        "seo_title": null,
        "seo_description": null,
        "tag_list": [],
        "photo_id": null,
        "tax_category_id": null
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

DELETE /api/boomerang/bundles/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[bundles]=created_at,updated_at,archived

Includes

This request does not accept any includes

Bundle items

Bundle items define which products (variations) and product groups are included in a Bundle. When bundles are booked on an order, the quantity and discount percentage defined in a bundle item will be applied.

There are two types of bundle items:

Relationships

Name Description
bundle Bundle required
The Bundle this BundleItem is part of.
product Product optional
When non-null, then this is the prespecified Product that will be booked. When null, then the user has to choose a product variation from the product_group. This relation is required when product_group does not have variations.
product_group Product group required
When the product relation is non-null, then this is the ProductGroup that the Product belongs to. When the product relation is null, then this is the ProductGroup that the user has to choose a product variation from.

Check matching attributes under Fields to see which relations can be written.
Check each individual operation to see which relations can be included as a sideload.

Fields

Name Description
bundle_id uuid readonly-after-create
The Bundle this BundleItem is part of.
created_at datetime readonly
When the resource was created.
discount_percentage float
The discount percentage for this product when rented out as part of a bundle.
id uuid readonly
Primary key.
position integer
Position of this bundle item within the bundle. I.e sorting relative to other bundle items.
product_group_id uuid readonly-after-create
When the product relation is non-null, then this is the ProductGroup that the Product belongs to. When the product relation is null, then this is the ProductGroup that the user has to choose a product variation from.
product_id uuid nullable
When non-null, then this is the prespecified Product that will be booked. When null, then the user has to choose a product variation from the product_group. This relation is required when product_group does not have variations.
quantity integer
The quantity of the product included in the bundle.
updated_at datetime readonly
When the resource was last updated.

List bundle items

How to fetch a list of bundle items:

  curl --get 'https://example.booqable.com/api/boomerang/bundle_items'
       --header 'content-type: application/json'
       --data-urlencode 'filter[bundle_id]=b484afb9-abf3-4598-8fce-44d5d5c62784'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "3e60cc8c-7215-4b14-8a74-8fe96f550d33",
        "type": "bundle_items",
        "attributes": {
          "created_at": "2019-11-14T16:12:00.000000+00:00",
          "updated_at": "2019-11-14T16:12:00.000000+00:00",
          "quantity": 2,
          "discount_percentage": 15.0,
          "position": 1,
          "bundle_id": "b484afb9-abf3-4598-8fce-44d5d5c62784",
          "product_group_id": "935f7965-5c06-44eb-8472-f9aa3f1e036e",
          "product_id": "567ad7e5-6130-401e-84a8-d966a6ae6717"
        },
        "relationships": {}
      }
    ],
    "meta": {}
  }

HTTP Request

GET /api/boomerang/bundle_items

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[bundle_items]=created_at,updated_at,quantity
filter hash
The filters to apply ?filter[attribute][eq]=value
include string
List of comma seperated relationships to sideload. ?include=bundle,product,product_group
meta hash
Metadata to send along. ?meta[total][]=count
page[number] string
The page to request.
page[size] string
The amount of items per page.
sort string
How to sort the data. ?sort=attribute1,-attribute2

Filters

This request can be filtered on:

Name Description
bundle_id uuid
eq, not_eq
created_at datetime
eq, not_eq, gt, gte, lt, lte
discount_percentage float
eq, not_eq, gt, gte, lt, lte
id uuid
eq, not_eq
position integer
eq, not_eq, gt, gte, lt, lte
product_group_id uuid
eq, not_eq
product_id uuid
eq, not_eq
quantity integer
eq, not_eq, gt, gte, lt, lte
updated_at datetime
eq, not_eq, gt, gte, lt, lte

Meta

Results can be aggregated on:

Name Description
total array
count

Includes

This request accepts the following includes:

bundle

product => photo

product_group => photo

Fetch a bundle item

How to fetch a bundle item:

  curl --get 'https://example.booqable.com/api/boomerang/bundle_items/613a8167-828e-4728-8f62-810a41cd2ba5'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": {
      "id": "613a8167-828e-4728-8f62-810a41cd2ba5",
      "type": "bundle_items",
      "attributes": {
        "created_at": "2015-08-13T03:51:01.000000+00:00",
        "updated_at": "2015-08-13T03:51:01.000000+00:00",
        "quantity": 2,
        "discount_percentage": 15.0,
        "position": 1,
        "bundle_id": "2201586a-dcc4-4803-8d2c-2e6d02541f2b",
        "product_group_id": "08475ef9-150e-4113-8035-9a10812b06e9",
        "product_id": "56cf4f31-b9ac-4968-8899-b81f09e246a6"
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

GET /api/boomerang/bundle_items/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[bundle_items]=created_at,updated_at,quantity
include string
List of comma seperated relationships to sideload. ?include=bundle,product,product_group

Includes

This request accepts the following includes:

bundle

product => photo

product_group => photo

Create a bundle item

How to create a bundle item:

  curl --request POST
       --url 'https://example.booqable.com/api/boomerang/bundle_items'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "type": "bundle_items",
           "attributes": {
             "bundle_id": "aadf38b5-6d5e-4c54-8d7b-7cce2b00801a",
             "product_group_id": "9bc50456-e92e-4162-8610-8f8ca7323b5b",
             "product_id": "6fb4ee32-8b29-439a-856d-9847696afb13",
             "quantity": 2,
             "discount_percentage": 15
           }
         }
       }'

A 201 status response looks like this:

  {
    "data": {
      "id": "3b9d771b-6d67-42d8-83b3-289dedbb7a1e",
      "type": "bundle_items",
      "attributes": {
        "created_at": "2018-09-16T12:53:01.000000+00:00",
        "updated_at": "2018-09-16T12:53:01.000000+00:00",
        "quantity": 2,
        "discount_percentage": 15.0,
        "position": 2,
        "bundle_id": "aadf38b5-6d5e-4c54-8d7b-7cce2b00801a",
        "product_group_id": "9bc50456-e92e-4162-8610-8f8ca7323b5b",
        "product_id": "6fb4ee32-8b29-439a-856d-9847696afb13"
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

POST /api/boomerang/bundle_items

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[bundle_items]=created_at,updated_at,quantity
include string
List of comma seperated relationships to sideload. ?include=bundle,product,product_group

Request body

This request accepts the following body:

Name Description
data[attributes][bundle_id] uuid
The Bundle this BundleItem is part of.
data[attributes][discount_percentage] float
The discount percentage for this product when rented out as part of a bundle.
data[attributes][position] integer
Position of this bundle item within the bundle. I.e sorting relative to other bundle items.
data[attributes][product_group_id] uuid
When the product relation is non-null, then this is the ProductGroup that the Product belongs to. When the product relation is null, then this is the ProductGroup that the user has to choose a product variation from.
data[attributes][product_id] uuid
When non-null, then this is the prespecified Product that will be booked. When null, then the user has to choose a product variation from the product_group. This relation is required when product_group does not have variations.
data[attributes][quantity] integer
The quantity of the product included in the bundle.

Includes

This request accepts the following includes:

bundle

product => photo

product_group => photo

Update a bundle item

How to update a bundle item:

  curl --request PUT
       --url 'https://example.booqable.com/api/boomerang/bundle_items/b19d7917-4360-464c-8add-3d8003786467'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "id": "b19d7917-4360-464c-8add-3d8003786467",
           "type": "bundle_items",
           "attributes": {
             "quantity": 3,
             "discount_percentage": 20
           }
         }
       }'

A 200 status response looks like this:

  {
    "data": {
      "id": "b19d7917-4360-464c-8add-3d8003786467",
      "type": "bundle_items",
      "attributes": {
        "created_at": "2015-01-21T01:26:00.000000+00:00",
        "updated_at": "2015-01-21T01:26:00.000000+00:00",
        "quantity": 3,
        "discount_percentage": 20.0,
        "position": 1,
        "bundle_id": "f53691b2-481e-4f06-8b42-70a8260e0bea",
        "product_group_id": "997ec012-e358-4a2c-8bb9-97674479ed4f",
        "product_id": "73f4eef3-b748-4cd0-8f75-0e013f461872"
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

PUT /api/boomerang/bundle_items/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[bundle_items]=created_at,updated_at,quantity
include string
List of comma seperated relationships to sideload. ?include=bundle,product,product_group

Request body

This request accepts the following body:

Name Description
data[attributes][bundle_id] uuid
The Bundle this BundleItem is part of.
data[attributes][discount_percentage] float
The discount percentage for this product when rented out as part of a bundle.
data[attributes][position] integer
Position of this bundle item within the bundle. I.e sorting relative to other bundle items.
data[attributes][product_group_id] uuid
When the product relation is non-null, then this is the ProductGroup that the Product belongs to. When the product relation is null, then this is the ProductGroup that the user has to choose a product variation from.
data[attributes][product_id] uuid
When non-null, then this is the prespecified Product that will be booked. When null, then the user has to choose a product variation from the product_group. This relation is required when product_group does not have variations.
data[attributes][quantity] integer
The quantity of the product included in the bundle.

Includes

This request accepts the following includes:

bundle

product => photo

product_group => photo

Delete a bundle item

How to delete a bundle item:

  curl --request DELETE
       --url 'https://example.booqable.com/api/boomerang/bundle_items/791f0c17-84d2-4362-8ad5-b097d71cf9e6'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": {
      "id": "791f0c17-84d2-4362-8ad5-b097d71cf9e6",
      "type": "bundle_items",
      "attributes": {
        "created_at": "2021-05-16T17:50:00.000000+00:00",
        "updated_at": "2021-05-16T17:50:00.000000+00:00",
        "quantity": 2,
        "discount_percentage": 15.0,
        "position": 1,
        "bundle_id": "04391a33-673f-4548-89e1-44e58bdfb28a",
        "product_group_id": "bb5d0ce6-7858-4bcf-8875-352bd5587852",
        "product_id": "98855843-4132-4178-8120-0393eaf5604f"
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

DELETE /api/boomerang/bundle_items/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[bundle_items]=created_at,updated_at,quantity

Includes

This request does not accept any includes

Clusters

A cluster is a group of locations that share their inventory (and availability). Stock can move between locations within the same cluster, meaning they can be picked up at one location and returned to another.

Relationships

Name Description
locations Locations hasmany
The locations that make up this cluster.

Check matching attributes under Fields to see which relations can be written.
Check each individual operation to see which relations can be included as a sideload.

Fields

Name Description
created_at datetime readonly
When the resource was created.
id uuid readonly
Primary key.
location_ids array readonly-after-create
The locations that belong to this cluster.
name string
Name of the cluster.
updated_at datetime readonly
When the resource was last updated.

List clusters

How to fetch clusters:

  curl --get 'https://example.booqable.com/api/boomerang/clusters'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "c85988b4-e5f9-4b7b-8e84-59dc91306d07",
        "type": "clusters",
        "attributes": {
          "created_at": "2017-04-19T16:54:00.000000+00:00",
          "updated_at": "2017-04-19T16:54:00.000000+00:00",
          "name": "Main",
          "location_ids": []
        },
        "relationships": {}
      }
    ],
    "meta": {}
  }

HTTP Request

GET /api/boomerang/clusters

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[clusters]=created_at,updated_at,name
filter hash
The filters to apply ?filter[attribute][eq]=value
include string
List of comma seperated relationships to sideload. ?include=locations
meta hash
Metadata to send along. ?meta[total][]=count
page[number] string
The page to request.
page[size] string
The amount of items per page.
sort string
How to sort the data. ?sort=attribute1,-attribute2

Filters

This request can be filtered on:

Name Description
created_at datetime
eq, not_eq, gt, gte, lt, lte
id uuid
eq, not_eq
location_id uuid
eq, not_eq
name string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
updated_at datetime
eq, not_eq, gt, gte, lt, lte

Meta

Results can be aggregated on:

Name Description
total array
count

Includes

This request accepts the following includes:

locations

Fetch a cluster

How to fetch a single cluster:

  curl --get 'https://example.booqable.com/api/boomerang/clusters/242d27bb-1ff5-41ca-80d5-dd4a2c675525'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": {
      "id": "242d27bb-1ff5-41ca-80d5-dd4a2c675525",
      "type": "clusters",
      "attributes": {
        "created_at": "2014-08-27T15:06:00.000000+00:00",
        "updated_at": "2014-08-27T15:06:00.000000+00:00",
        "name": "Main",
        "location_ids": []
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

GET /api/boomerang/clusters/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[clusters]=created_at,updated_at,name
include string
List of comma seperated relationships to sideload. ?include=locations

Includes

This request accepts the following includes:

locations

Create a cluster

How to create a cluster:

  curl --request POST
       --url 'https://example.booqable.com/api/boomerang/clusters'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "type": "clusters",
           "attributes": {
             "name": "Amsterdam"
           }
         }
       }'

A 201 status response looks like this:

  {
    "data": {
      "id": "a4eb298e-c8b8-4b40-85cf-ec9dbbf68a92",
      "type": "clusters",
      "attributes": {
        "created_at": "2024-06-20T05:57:00.000000+00:00",
        "updated_at": "2024-06-20T05:57:00.000000+00:00",
        "name": "Amsterdam",
        "location_ids": []
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

POST /api/boomerang/clusters

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[clusters]=created_at,updated_at,name
include string
List of comma seperated relationships to sideload. ?include=locations

Request body

This request accepts the following body:

Name Description
data[attributes][location_ids][] array
The locations that belong to this cluster.
data[attributes][name] string
Name of the cluster.

Includes

This request accepts the following includes:

locations

Update a cluster

How to update a cluster:

  curl --request PUT
       --url 'https://example.booqable.com/api/boomerang/clusters/df280d1c-34d7-4b2d-89d8-289bf254f317'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "id": "df280d1c-34d7-4b2d-89d8-289bf254f317",
           "type": "clusters",
           "attributes": {
             "name": "Rotterdam"
           }
         }
       }'

A 200 status response looks like this:

  {
    "data": {
      "id": "df280d1c-34d7-4b2d-89d8-289bf254f317",
      "type": "clusters",
      "attributes": {
        "created_at": "2020-06-22T20:42:09.000000+00:00",
        "updated_at": "2020-06-22T20:42:09.000000+00:00",
        "name": "Rotterdam",
        "location_ids": []
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

PUT /api/boomerang/clusters/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[clusters]=created_at,updated_at,name
include string
List of comma seperated relationships to sideload. ?include=locations

Request body

This request accepts the following body:

Name Description
data[attributes][location_ids][] array
The locations that belong to this cluster.
data[attributes][name] string
Name of the cluster.

Includes

This request accepts the following includes:

locations

Delete a cluster

To delete a cluster make sure no active locations are associated with it anymore.

How to delete a cluster:

  curl --request DELETE
       --url 'https://example.booqable.com/api/boomerang/clusters/79f093e1-f668-4a70-8e91-6f10c351314a'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": {
      "id": "79f093e1-f668-4a70-8e91-6f10c351314a",
      "type": "clusters",
      "attributes": {
        "created_at": "2019-06-18T06:27:00.000000+00:00",
        "updated_at": "2019-06-18T06:27:00.000000+00:00",
        "name": "Main",
        "location_ids": []
      },
      "relationships": {}
    },
    "meta": {}
  }

A failure due to a cluster still being associated with locations:

  curl --request DELETE
       --url 'https://example.booqable.com/api/boomerang/clusters/475d542a-ad19-4eea-87be-bdc3a2726baf'
       --header 'content-type: application/json'

A 422 status response looks like this:

  {
    "errors": [
      {
        "code": "cluster_has_locations",
        "status": "422",
        "title": "Cluster has locations",
        "detail": "This cluster has 1 or more active locations",
        "meta": {
          "location_ids": [
            "cfa08864-2479-40cd-81ac-e6426c3c303a"
          ]
        }
      }
    ]
  }

HTTP Request

DELETE /api/boomerang/clusters/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[clusters]=created_at,updated_at,name
include string
List of comma seperated relationships to sideload. ?include=locations

Includes

This request accepts the following includes:

locations

Collections

Collections are used to create a hierarchy of products.

To change the ordering of items within a collection, use Sortings.

Relationships

Name Description
collection_items Collection items hasmany
All items that make up this collection. Each collection item adds either a product group or a bundle to this collection.

Check matching attributes under Fields to see which relations can be written.
Check each individual operation to see which relations can be included as a sideload.

Fields

Name Description
all_children array readonly extra
All child collections.
all_parents array readonly extra
All parent collections.
collection_type enum readonly-after-create
Dynamic collections are automatically updated. Static collections are defined by the user.
One of: static, dynamic.
created_at datetime readonly
When the resource was created.
depth integer readonly
How deep this collection sits in the hierarchy. Depth 1 are the top-level collection, depth 2 are the children, and depth 3 the grandchildren. Nesting is limited to 3 levels.
description string
A description of this collection.
hierarchical_name array[string] readonly extra
Names of all parents, with the name of this collection as last.
id uuid readonly
Primary key.
image_base64 string writeonly
Base64 encoded photo, use this field to add a photo.
image_large_url string readonly
URL of the large image for this collection.
image_url string readonly
URL of the image for this collection.
item_count integer
Number of collection items in this collection. Does (not?) include nested collections?.
name string
Name of this collection.
parent_id uuid
The ID of the parent collection.
position integer readonly
Relative position of this collection among its siblings within the same parent collection.
remote_image_url string writeonly
Url to an image on the web, use this field to add a photo.
remove_image boolean writeonly
Remove the current image.
seo_description string
SEO description.
seo_title string
SEO title.
show_in_store boolean
Whether to show this collection in the online store.
slug string
Slug used in online store URLs.
system boolean
When true, this collection is generated and maintained automatically by Booqable. System collections cannot be updated or deleted.
updated_at datetime readonly
When the resource was last updated.

List collections

How to fetch collections:

  curl --get 'https://example.booqable.com/api/boomerang/collections'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "e8b928ec-172a-4655-80f9-eea1a1be9c89",
        "type": "collections",
        "attributes": {
          "created_at": "2015-11-17T02:13:02.000000+00:00",
          "updated_at": "2015-11-17T02:13:02.000000+00:00",
          "name": "All Seasons",
          "slug": "all-seasons",
          "description": null,
          "seo_title": null,
          "seo_description": null,
          "collection_type": "manual",
          "system": false,
          "item_count": 0,
          "show_in_store": true,
          "parent_id": null,
          "depth": 1,
          "position": null,
          "image_url": null,
          "image_large_url": null
        },
        "relationships": {}
      }
    ],
    "meta": {}
  }

HTTP Request

GET /api/boomerang/collections

Request params

This request accepts the following parameters:

Name Description
extra_fields[] array
List of comma separated fields to include in addition to the default fields. ?extra_fields[collections]=all_parents,all_children,hierarchical_name
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[collections]=created_at,updated_at,name
filter hash
The filters to apply ?filter[attribute][eq]=value
meta hash
Metadata to send along. ?meta[total][]=count
page[number] string
The page to request.
page[size] string
The amount of items per page.
sort string
How to sort the data. ?sort=attribute1,-attribute2

Filters

This request can be filtered on:

Name Description
collection_type enum
eq
created_at datetime
eq, not_eq, gt, gte, lt, lte
depth integer
eq, not_eq, gt, gte, lt, lte
description string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
hierarchical_q string
eq
id uuid
eq, not_eq
name string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
parent_id uuid
eq, not_eq
position integer
eq, not_eq, gt, gte, lt, lte
q string
eq
seo_description string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
seo_title string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
show_in_store boolean
eq
slug string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
system boolean
eq
updated_at datetime
eq, not_eq, gt, gte, lt, lte

Meta

Results can be aggregated on:

Name Description
total array
count

Includes

This request does not accept any includes

Fetch a collection

How to fetch a single collection:

  curl --get 'https://example.booqable.com/api/boomerang/collections/e747596e-eb84-4e15-8b4e-9b160d64633c'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": {
      "id": "e747596e-eb84-4e15-8b4e-9b160d64633c",
      "type": "collections",
      "attributes": {
        "created_at": "2021-12-02T10:21:01.000000+00:00",
        "updated_at": "2021-12-02T10:21:01.000000+00:00",
        "name": "All Seasons",
        "slug": "all-seasons",
        "description": null,
        "seo_title": null,
        "seo_description": null,
        "collection_type": "manual",
        "system": false,
        "item_count": 0,
        "show_in_store": true,
        "parent_id": null,
        "depth": 1,
        "position": null,
        "image_url": null,
        "image_large_url": null
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

GET /api/boomerang/collections/{id}

Request params

This request accepts the following parameters:

Name Description
extra_fields[] array
List of comma separated fields to include in addition to the default fields. ?extra_fields[collections]=all_parents,all_children,hierarchical_name
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[collections]=created_at,updated_at,name
include string
List of comma seperated relationships to sideload. ?include=collection_items

Includes

This request accepts the following includes:

collection_items => item => photo

Create a collection

How to create a collection:

  curl --request POST
       --url 'https://example.booqable.com/api/boomerang/collections'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "type": "collections",
           "attributes": {
             "name": "Spring Collection"
           }
         }
       }'

A 201 status response looks like this:

  {
    "data": {
      "id": "067fbd40-bc13-4aec-8426-a75cc1a273f8",
      "type": "collections",
      "attributes": {
        "created_at": "2019-04-23T15:23:58.000000+00:00",
        "updated_at": "2019-04-23T15:23:58.000000+00:00",
        "name": "Spring Collection",
        "slug": "spring-collection",
        "description": null,
        "seo_title": null,
        "seo_description": null,
        "collection_type": null,
        "system": false,
        "item_count": 0,
        "show_in_store": true,
        "parent_id": null,
        "depth": 1,
        "position": null,
        "image_url": null,
        "image_large_url": null
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

POST /api/boomerang/collections

Request params

This request accepts the following parameters:

Name Description
extra_fields[] array
List of comma separated fields to include in addition to the default fields. ?extra_fields[collections]=all_parents,all_children,hierarchical_name
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[collections]=created_at,updated_at,name
include string
List of comma seperated relationships to sideload. ?include=collection_items

Request body

This request accepts the following body:

Name Description
data[attributes][collection_type] enum
Dynamic collections are automatically updated. Static collections are defined by the user.
One of: static, dynamic.
data[attributes][image_base64] string
Base64 encoded photo, use this field to add a photo.
data[attributes][item_count] integer
Number of collection items in this collection. Does (not?) include nested collections?.
data[attributes][name] string
Name of this collection.
data[attributes][parent_id] uuid
The ID of the parent collection.
data[attributes][remote_image_url] string
Url to an image on the web, use this field to add a photo.
data[attributes][remove_image] boolean
Remove the current image.
data[attributes][seo_description] string
SEO description.
data[attributes][seo_title] string
SEO title.
data[attributes][show_in_store] boolean
Whether to show this collection in the online store.
data[attributes][slug] string
Slug used in online store URLs.
data[attributes][system] boolean
When true, this collection is generated and maintained automatically by Booqable. System collections cannot be updated or deleted.

Includes

This request accepts the following includes:

collection_items => item => photo

Update a collection

How to update a collection:

  curl --request PUT
       --url 'https://example.booqable.com/api/boomerang/collections/6ee95651-79a3-47df-875d-6bceb66cb4e6'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "id": "6ee95651-79a3-47df-875d-6bceb66cb4e6",
           "type": "collections",
           "attributes": {
             "name": "Fall Collection"
           }
         }
       }'

A 200 status response looks like this:

  {
    "data": {
      "id": "6ee95651-79a3-47df-875d-6bceb66cb4e6",
      "type": "collections",
      "attributes": {
        "created_at": "2026-04-06T17:47:00.000000+00:00",
        "updated_at": "2026-04-06T17:47:00.000000+00:00",
        "name": "Fall Collection",
        "slug": "all-seasons",
        "description": null,
        "seo_title": null,
        "seo_description": null,
        "collection_type": "manual",
        "system": false,
        "item_count": 0,
        "show_in_store": true,
        "parent_id": null,
        "depth": 1,
        "position": null,
        "image_url": null,
        "image_large_url": null
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

PUT /api/boomerang/collections/{id}

Request params

This request accepts the following parameters:

Name Description
extra_fields[] array
List of comma separated fields to include in addition to the default fields. ?extra_fields[collections]=all_parents,all_children,hierarchical_name
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[collections]=created_at,updated_at,name
include string
List of comma seperated relationships to sideload. ?include=collection_items

Request body

This request accepts the following body:

Name Description
data[attributes][collection_type] enum
Dynamic collections are automatically updated. Static collections are defined by the user.
One of: static, dynamic.
data[attributes][image_base64] string
Base64 encoded photo, use this field to add a photo.
data[attributes][item_count] integer
Number of collection items in this collection. Does (not?) include nested collections?.
data[attributes][name] string
Name of this collection.
data[attributes][parent_id] uuid
The ID of the parent collection.
data[attributes][remote_image_url] string
Url to an image on the web, use this field to add a photo.
data[attributes][remove_image] boolean
Remove the current image.
data[attributes][seo_description] string
SEO description.
data[attributes][seo_title] string
SEO title.
data[attributes][show_in_store] boolean
Whether to show this collection in the online store.
data[attributes][slug] string
Slug used in online store URLs.
data[attributes][system] boolean
When true, this collection is generated and maintained automatically by Booqable. System collections cannot be updated or deleted.

Includes

This request accepts the following includes:

collection_items => item => photo

Delete a collection

To delete a collection make sure there are no nested collections anymore.

How to delete a collection:

  curl --request DELETE
       --url 'https://example.booqable.com/api/boomerang/collections/df45847d-b793-411a-82a7-2344685a75df'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": {
      "id": "df45847d-b793-411a-82a7-2344685a75df",
      "type": "collections",
      "attributes": {
        "created_at": "2022-02-26T11:23:14.000000+00:00",
        "updated_at": "2022-02-26T11:23:14.000000+00:00",
        "name": "All Seasons",
        "slug": "all-seasons",
        "description": null,
        "seo_title": null,
        "seo_description": null,
        "collection_type": "manual",
        "system": false,
        "item_count": 0,
        "show_in_store": true,
        "parent_id": null,
        "depth": 1,
        "position": null,
        "image_url": null,
        "image_large_url": null
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

DELETE /api/boomerang/collections/{id}

Request params

This request accepts the following parameters:

Name Description
extra_fields[] array
List of comma separated fields to include in addition to the default fields. ?extra_fields[collections]=all_parents,all_children,hierarchical_name
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[collections]=created_at,updated_at,name

Includes

This request does not accept any includes

Collection items

An item in a Collection.

CollectionItems cannot be changed directly, but their position can be updated through the Sortings resource.

Relationships

Name Description
collection Collection required
The Collection this CollectionItem is part of.
item Item required
The item. Can be a ProductGroup or a Bundle.

Check matching attributes under Fields to see which relations can be written.
Check each individual operation to see which relations can be included as a sideload.

Fields

Name Description
collection_id uuid readonly-after-create
The Collection this CollectionItem is part of.
created_at datetime readonly
When the resource was created.
id uuid readonly
Primary key.
implicit boolean readonly
A value of true indicates that this item was not added explicitly, but instead is included in one of the child Collections.
item_id uuid readonly-after-create
The item. Can be a ProductGroup or a Bundle.
position integer readonly
Position of this item within the Collection. I.e sorting relative to other CollectionItems.
source_collections array readonly extra
The child Collection(s) which explicitly include the ProductGroup/Bundle, and are the source(s) for this CollectionItem.

List collection items

How to fetch collection items:

  curl --get 'https://example.booqable.com/api/boomerang/collection_items'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "c1cd76e1-4623-455e-8573-566ce1ce6c28",
        "type": "collection_items",
        "attributes": {
          "created_at": "2023-01-20T16:48:01.000000+00:00",
          "updated_at": "2023-01-20T16:48:01.000000+00:00",
          "item_id": "33763613-da95-4e0a-89fd-1394814769da",
          "collection_id": "80277708-d325-42a0-87a1-7e45bb3167ec",
          "position": null,
          "implicit": false
        },
        "relationships": {}
      }
    ],
    "meta": {}
  }

HTTP Request

GET /api/boomerang/collection_items

Request params

This request accepts the following parameters:

Name Description
extra_fields[] array
List of comma separated fields to include in addition to the default fields. ?extra_fields[collection_items]=source_collections
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[collection_items]=created_at,item_id,collection_id
filter hash
The filters to apply ?filter[attribute][eq]=value
include string
List of comma seperated relationships to sideload. ?include=item,collection
meta hash
Metadata to send along. ?meta[total][]=count
page[number] string
The page to request.
page[size] string
The amount of items per page.
sort string
How to sort the data. ?sort=attribute1,-attribute2

Filters

This request can be filtered on:

Name Description
collection_id uuid
eq, not_eq
created_at datetime
eq, not_eq, gt, gte, lt, lte
exclude_system_collections boolean
eq
id uuid
eq, not_eq
implicit boolean
eq
item_id uuid
eq, not_eq
position integer
eq, not_eq, gt, gte, lt, lte

Meta

Results can be aggregated on:

Name Description
total array
count

Includes

This request accepts the following includes:

item => photo

collection

Create a collection item

How to create a collection item:

  curl --request POST
       --url 'https://example.booqable.com/api/boomerang/collection_items'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "type": "collection_items",
           "attributes": {
             "item_id": "facd8ef7-5f11-4dae-8318-f3a59f73560e",
             "collection_id": "d9c4b730-729f-4e5d-8809-1be451f56dac"
           }
         }
       }'

A 201 status response looks like this:

  {
    "data": {
      "id": "2f9668f0-65ed-4b5c-865d-f8e91d0b51cd",
      "type": "collection_items",
      "attributes": {
        "created_at": "2025-05-23T01:55:00.000000+00:00",
        "updated_at": "2025-05-23T01:55:00.000000+00:00",
        "item_id": "facd8ef7-5f11-4dae-8318-f3a59f73560e",
        "collection_id": "d9c4b730-729f-4e5d-8809-1be451f56dac",
        "position": null,
        "implicit": false
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

POST /api/boomerang/collection_items

Request params

This request accepts the following parameters:

Name Description
extra_fields[] array
List of comma separated fields to include in addition to the default fields. ?extra_fields[collection_items]=source_collections
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[collection_items]=created_at,item_id,collection_id

Request body

This request accepts the following body:

Name Description
data[attributes][collection_id] uuid
The Collection this CollectionItem is part of.
data[attributes][item_id] uuid
The item. Can be a ProductGroup or a Bundle.

Includes

This request does not accept any includes

Delete a collection item

How to delete a collection item:

  curl --request DELETE
       --url 'https://example.booqable.com/api/boomerang/collection_items/ec034cc0-89e0-42f0-8a00-b2a59de8c98a'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": {
      "id": "ec034cc0-89e0-42f0-8a00-b2a59de8c98a",
      "type": "collection_items",
      "attributes": {
        "created_at": "2018-01-04T10:28:00.000000+00:00",
        "updated_at": "2018-01-04T10:28:00.000000+00:00",
        "item_id": "cdb92bdf-3a07-413f-8f82-69cb2d3ea2b1",
        "collection_id": "fc597631-ca5b-4fcb-83eb-2b59c0f54073",
        "position": null,
        "implicit": false
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

DELETE /api/boomerang/collection_items/{id}

Request params

This request accepts the following parameters:

Name Description
extra_fields[] array
List of comma separated fields to include in addition to the default fields. ?extra_fields[collection_items]=source_collections
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[collection_items]=created_at,item_id,collection_id

Includes

This request does not accept any includes

Collection trees

Allows making multiple changes to the tree of collections at once.

Fields

Name Description
collections array writeonly
Array of hashes, which each describe an update to make.
id uuid readonly
Primary key.

Update the tree

How to update the tree:

  curl --request POST
       --url 'https://example.booqable.com/api/boomerang/collection_trees'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "type": "collection_trees",
           "attributes": {
             "collections": [
               {
                 "id": "7ee0b635-bd10-4ade-835f-08e7a341e36d",
                 "parent_id": "786ce8ea-70d2-46b4-8a1c-f59a62784714",
                 "position": 3
               },
               {
                 "id": "be1d0d57-55e2-47ed-8bd9-7aef1ccdc47d",
                 "parent_id": "f773a180-793f-4c5e-8640-a794e8b7a3b9",
                 "position": 4
               }
             ]
           }
         }
       }'

A 201 status response looks like this:

  {
    "data": {
      "id": "4583bb5e-28c4-4e74-8610-06c05f98a464",
      "type": "collection_trees"
    },
    "meta": {}
  }

HTTP Request

POST /api/boomerang/collection_trees

Request body

This request accepts the following body:

Name Description
data[attributes][collections][] array
Array of hashes, which each describe an update to make.

Includes

This request does not accept any includes

Companies

Every action performed in a Booqable account is scoped to a company. A company holds information and configuration about an account.

Fields

Name Description
address string readonly
The full address.
address_line_1 string
First address line.
address_line_2 string
Second address line.
billing_address hash readonly
A hash with the company billing address fields. Use it when fetching the company. See address property type for more information.
billing_address_attributes hash writeonly
A hash with the company billing address fields. Use it when updating the company billing address. See address property type for more information.
billing_address_city string
City (used for invoices received from Booqable).
billing_address_country string
Country (used for invoices received from Booqable).
billing_address_line_1 string
First address line (used for invoices received from Booqable).
billing_address_line_2 string
Second address line (used for invoices received from Booqable).
billing_address_region string
Region (used for invoices received from Booqable).
billing_address_zipcode string
Zipcode (used for invoices received from Booqable).
billing_company string
Company name (used for invoices received from Booqable).
billing_email string
Used to send billing emails to.
city string
City.
continent string readonly
Continent the company is situated.
country string
Country.
created_at datetime readonly
When the resource was created.
currency string
Currency of the company.
custom_domain string
Custom domain to use for hosted store and checkout.
custom_domain_validation hash
Validation details for the custom domain.
default_timezone string
Company's default timezone.
development boolean readonly
Whether this is a development account.
email string
Used in customer communication, on documents and as the reply-to address for emails that are being sent.
favicon_base64 string writeonly
To upload a favicon send it as a base64 encoded string.
favicon_url string readonly
Company favicon url.
financial_line_1 string
First extra financial information line (line bank account) used in customer communication, on documents and as the reply-to address for emails that are being sent.
financial_line_2 string
Second extra financial information line (line bank account) used in customer communication, on documents and as the reply-to address for emails that are being sent.
id uuid readonly
Primary key.
in_europe boolean readonly
Whether company is situated in europe.
installed_online_store boolean readonly
If the online store is installed, this boolean will return true.
logo_base64 string writeonly
To update a logo send it as base64 encoded string.
logo_url string readonly
Url of the uploaded logo.
main_address hash readonly
A hash with the company main address fields. Use it when fetching the company. See address property type for more information.
main_address_attributes hash writeonly
A hash with the company main address fields. Use it when updating the company main address. See address property type for more information.
market string
The market the company operates in.
medium string readonly
UTM medium present during signup.
name string
Name of the company.
pending_subscription boolean readonly
Whether the company has a pending subscription.
phone string
Phone number.
region string
Region.
remove_favicon boolean writeonly
Remove current favicon.
remove_logo boolean writeonly
Remove current logo.
revenue_last_year string readonly
Revenue last year given during signup.
shop_theme_id uuid
ID of installed shop theme.
slug string readonly
Company's slug, the part of the domainname before booqable.com.
source string readonly
UTM source present during signup.
subscription hash readonly extra
Details about the subscription.
team_size string readonly
Team size given during signup.
tenant_token string readonly
Token.
third_party_id string
ID used for third party tools.
updated_at datetime readonly
When the resource was last updated.
use_billing_address boolean
Whether to use billing address on invoices received from Booqable.
vat_number string
Company's vat number, used in customer communication and to define tax exempts.
website string
Website.
year_business_start string readonly
Year when company started, given during signup.
zipcode string
Zipcode.

Fetch a company

How to fetch a company:

  curl --get 'https://example.booqable.com/api/boomerang/companies/current'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": {
      "id": "9391cc27-0209-4fb5-8077-0e7af94f571d",
      "type": "companies",
      "attributes": {
        "created_at": "2025-12-03T02:00:00.000000+00:00",
        "updated_at": "2025-12-03T02:00:00.000000+00:00",
        "name": "iRent",
        "slug": "irent",
        "email": "[email protected]",
        "billing_email": null,
        "phone": null,
        "website": "www.booqable.com",
        "address_line_1": "Blokhuispoort",
        "address_line_2": "Leeuwarden",
        "zipcode": "8900AB",
        "city": "Leeuwarden",
        "region": null,
        "country": "Netherlands",
        "market": "AV / Camera",
        "use_billing_address": false,
        "billing_company": null,
        "billing_address_line_1": null,
        "billing_address_line_2": null,
        "billing_address_zipcode": null,
        "billing_address_city": null,
        "billing_address_region": null,
        "billing_address_country": null,
        "logo_url": null,
        "favicon_url": null,
        "default_timezone": "UTC",
        "currency": "usd",
        "financial_line_1": "Blokhuispoort",
        "financial_line_2": "Leeuwarden",
        "vat_number": null,
        "in_europe": null,
        "continent": null,
        "custom_domain": null,
        "custom_domain_validation": null,
        "development": false,
        "shop_theme_id": null,
        "installed_online_store": false,
        "source": null,
        "medium": null,
        "tenant_token": "e08844f444c33fcafbe78fef211e194c",
        "pending_subscription": false,
        "team_size": null,
        "revenue_last_year": null,
        "year_business_start": null,
        "address": "Blokhuispoort\nLeeuwarden\n8900AB Leeuwarden\nNetherlands",
        "main_address": {
          "meets_validation_requirements": false,
          "first_name": null,
          "last_name": null,
          "address1": "Blokhuispoort",
          "address2": "Leeuwarden",
          "city": "Leeuwarden",
          "region": null,
          "zipcode": "8900AB",
          "country": "Netherlands",
          "country_id": null,
          "province_id": null,
          "latitude": null,
          "longitude": null,
          "value": "Blokhuispoort\nLeeuwarden\n8900AB Leeuwarden\nNetherlands"
        },
        "billing_address": null,
        "third_party_id": "9391cc27-0209-4fb5-8077-0e7af94f571d"
      }
    },
    "meta": {}
  }

HTTP Request

GET /api/boomerang/companies/current

Request params

This request accepts the following parameters:

Name Description
extra_fields[] array
List of comma separated fields to include in addition to the default fields. ?extra_fields[companies]=subscription
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[companies]=created_at,updated_at,name

Includes

This request does not accept any includes

Fetch subscription details

The subscription has the following fields:

Name Description
trial_ends_at Datetime readonly
When the trial ends
activated Boolean readonly
Whether subscription is active
suspended Boolean readonly
Whether account is suspended
canceled Boolean readonly
Whether subscription is canceled
canceled_at Datetime readonly
When the subscription is canceled (can also be in the future)
on_hold Boolean readonly
Whether account is on-hold
needs_activation Boolean readonly
Whether account needs to activate a subscription
legacy Datetime readonly
Whether it's a legacy subscription
product String readonly
Which product is active, one of Essential, Pro, Premium, Legacy
plan_id String readonly
ID of the product (used internally by Booqable)
interval String readonly
Billing interval, one of month, year
current_period_end Datetime readonly
When the current billing period ends
quantity Integer readonly
Quantity of the subscription (used for legacy subscriptions to buy seats)
extra_employees Integer readonly
Extra employees billed for
extra_locations Integer readonly
Extra locations billed for
amount_in_cents Integer readonly
Amount in cents
discount_in_cents Integer readonly
Discount in cents
balance_in_cents Integer readonly
Balance in cents, will be deducted from the next invoice(s)
coupon String readonly
Coupon that's currently active
coupon_percent_off String* readonly
Percentage of discount on the current active coupon
coupon_duration String* readonly
Duration type of the current active coupon, one of forever, once, repeating
coupon_duration_in_months String* readonly
Amount of months the coupon is active. Only present when coupon duration is repeating.
strategy String readonly
Billing strategy, one of send_invoice, charge_automatically
source Hash readonly
Information about the payment source
enabled_features Hash readonly
Beta features that are currently enabled
allowed_features Hash readonly
List of allowed features for plan
restrictions Hash readonly
Restrictions applied to this account

How to fetch details about the company its subscription:

  curl --get 'https://example.booqable.com/api/boomerang/companies/current'
       --header 'content-type: application/json'
       --data-urlencode 'extra_fields[companies]=subscription'
       --data-urlencode 'fields[companies]=subscription'

A 200 status response looks like this:

  {
    "data": {
      "id": "b962f1eb-9fbc-42f9-81ac-a12d0b5a2174",
      "type": "companies",
      "attributes": {
        "subscription": {
          "trial_ends_at": "2019-05-03T10:16:00.000000+00:00",
          "activated": false,
          "active_subscription": false,
          "suspended": false,
          "canceled": false,
          "canceled_at": null,
          "on_hold": false,
          "needs_activation": false,
          "product": "Premium",
          "plan_id": "premium_monthly",
          "interval": "month",
          "current_period_end": null,
          "extra_employees": 0,
          "extra_locations": 0,
          "amount_in_cents": 29900,
          "discount_in_cents": 0,
          "balance_in_cents": 0,
          "coupon": null,
          "coupon_percent_off": null,
          "coupon_duration": null,
          "coupon_duration_in_months": null,
          "strategy": "charge_automatically",
          "source": null,
          "enabled_features": [],
          "allowed_features": [
            "bundles",
            "multiple_locations",
            "advanced_pricing",
            "api",
            "custom_fields",
            "overbookings",
            "customer_auth",
            "custom_domain",
            "barcodes",
            "reports",
            "permissions",
            "exports",
            "coupons",
            "shop_tracking",
            "sso",
            "iprestrictions",
            "2fa_enforcing",
            "remove_powered_by"
          ],
          "restrictions": {
            "employees": 15,
            "email_max_recipients": 2000,
            "rate_limit_max": 250,
            "rate_limit_period": 60,
            "locations": 3,
            "allow_extra_locations": true,
            "allow_extra_employees": true
          },
          "can_try_plan": true
        }
      }
    },
    "meta": {}
  }

HTTP Request

GET /api/boomerang/companies/current

Request params

This request accepts the following parameters:

Name Description
extra_fields[] array
List of comma separated fields to include in addition to the default fields. ?extra_fields[companies]=subscription
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[companies]=created_at,updated_at,name

Includes

This request does not accept any includes

Update a company

How to update a company:

  curl --request PUT
       --url 'https://example.booqable.com/api/boomerang/companies/current'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "id": "39b6d9bd-03cc-4869-8a7a-9e3ca8f59712",
           "type": "companies",
           "attributes": {
             "name": "iRent LLC"
           }
         }
       }'

A 200 status response looks like this:

  {
    "data": {
      "id": "39b6d9bd-03cc-4869-8a7a-9e3ca8f59712",
      "type": "companies",
      "attributes": {
        "created_at": "2020-02-19T10:28:01.000000+00:00",
        "updated_at": "2020-02-19T10:28:01.000000+00:00",
        "name": "iRent LLC",
        "slug": "irent",
        "email": "[email protected]",
        "billing_email": null,
        "phone": null,
        "website": "www.booqable.com",
        "address_line_1": "Blokhuispoort",
        "address_line_2": "Leeuwarden",
        "zipcode": "8900AB",
        "city": "Leeuwarden",
        "region": null,
        "country": "Netherlands",
        "market": "AV / Camera",
        "use_billing_address": false,
        "billing_company": null,
        "billing_address_line_1": null,
        "billing_address_line_2": null,
        "billing_address_zipcode": null,
        "billing_address_city": null,
        "billing_address_region": null,
        "billing_address_country": null,
        "logo_url": null,
        "favicon_url": null,
        "default_timezone": "UTC",
        "currency": "usd",
        "financial_line_1": "Blokhuispoort",
        "financial_line_2": "Leeuwarden",
        "vat_number": null,
        "in_europe": null,
        "continent": null,
        "custom_domain": null,
        "custom_domain_validation": null,
        "development": false,
        "shop_theme_id": null,
        "installed_online_store": false,
        "source": null,
        "medium": null,
        "tenant_token": "7a1067c6345a05d4627e8ec7bdeadbe6",
        "pending_subscription": false,
        "team_size": null,
        "revenue_last_year": null,
        "year_business_start": null,
        "address": "Blokhuispoort\nLeeuwarden\n8900AB Leeuwarden\nNetherlands",
        "main_address": {
          "meets_validation_requirements": false,
          "first_name": null,
          "last_name": null,
          "address1": "Blokhuispoort",
          "address2": "Leeuwarden",
          "city": "Leeuwarden",
          "region": null,
          "zipcode": "8900AB",
          "country": "Netherlands",
          "country_id": null,
          "province_id": null,
          "latitude": null,
          "longitude": null,
          "value": "Blokhuispoort\nLeeuwarden\n8900AB Leeuwarden\nNetherlands"
        },
        "billing_address": null,
        "third_party_id": "39b6d9bd-03cc-4869-8a7a-9e3ca8f59712"
      }
    },
    "meta": {}
  }

HTTP Request

PUT /api/boomerang/companies/current

Request params

This request accepts the following parameters:

Name Description
extra_fields[] array
List of comma separated fields to include in addition to the default fields. ?extra_fields[companies]=subscription
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[companies]=created_at,updated_at,name

Request body

This request accepts the following body:

Name Description
data[attributes][address_line_1] string
First address line.
data[attributes][address_line_2] string
Second address line.
data[attributes][billing_address_attributes] hash
A hash with the company billing address fields. Use it when updating the company billing address. See address property type for more information.
data[attributes][billing_address_city] string
City (used for invoices received from Booqable).
data[attributes][billing_address_country] string
Country (used for invoices received from Booqable).
data[attributes][billing_address_line_1] string
First address line (used for invoices received from Booqable).
data[attributes][billing_address_line_2] string
Second address line (used for invoices received from Booqable).
data[attributes][billing_address_region] string
Region (used for invoices received from Booqable).
data[attributes][billing_address_zipcode] string
Zipcode (used for invoices received from Booqable).
data[attributes][billing_company] string
Company name (used for invoices received from Booqable).
data[attributes][billing_email] string
Used to send billing emails to.
data[attributes][city] string
City.
data[attributes][country] string
Country.
data[attributes][currency] string
Currency of the company.
data[attributes][custom_domain] string
Custom domain to use for hosted store and checkout.
data[attributes][custom_domain_validation] hash
Validation details for the custom domain.
data[attributes][default_timezone] string
Company's default timezone.
data[attributes][email] string
Used in customer communication, on documents and as the reply-to address for emails that are being sent.
data[attributes][favicon_base64] string
To upload a favicon send it as a base64 encoded string.
data[attributes][financial_line_1] string
First extra financial information line (line bank account) used in customer communication, on documents and as the reply-to address for emails that are being sent.
data[attributes][financial_line_2] string
Second extra financial information line (line bank account) used in customer communication, on documents and as the reply-to address for emails that are being sent.
data[attributes][logo_base64] string
To update a logo send it as base64 encoded string.
data[attributes][main_address_attributes] hash
A hash with the company main address fields. Use it when updating the company main address. See address property type for more information.
data[attributes][market] string
The market the company operates in.
data[attributes][name] string
Name of the company.
data[attributes][phone] string
Phone number.
data[attributes][region] string
Region.
data[attributes][remove_favicon] boolean
Remove current favicon.
data[attributes][remove_logo] boolean
Remove current logo.
data[attributes][shop_theme_id] uuid
ID of installed shop theme.
data[attributes][third_party_id] string
ID used for third party tools.
data[attributes][use_billing_address] boolean
Whether to use billing address on invoices received from Booqable.
data[attributes][vat_number] string
Company's vat number, used in customer communication and to define tax exempts.
data[attributes][website] string
Website.
data[attributes][zipcode] string
Zipcode.

Includes

This request does not accept any includes

Countries

The Country resource describes countries, including the information required to validate the format of addresses.

Relationships

Name Description
provinces Provinces hasmany
The provinces/states of this country (or any other administrative subdivision).

Check matching attributes under Fields to see which relations can be written.
Check each individual operation to see which relations can be included as a sideload.

Fields

Name Description
alpha2 string readonly
ISO 3166-1 alpha-2 code.
city_autofill string readonly
The value to use for the city when autofilling.
created_at datetime readonly
When the resource was created.
form_layout string readonly
The layout of the address form.
id uuid readonly
Primary key.
name string readonly
Name of the country.
province_required boolean readonly
Whether a province is required for addresses in this country.
province_type string readonly
The province type of this country.
show_layout string readonly
The layout of the address when shown.
updated_at datetime readonly
When the resource was last updated.
zipcode_autofill string readonly
The value to use for the zipcode when autofilling.
zipcode_format string readonly
The format of the zipcode, as a regular expression.
zipcode_placeholder string readonly
The placeholder to use for the zipcode.
zipcode_required boolean readonly
Whether a zipcode is required for addresses in this country.
zipcode_type string readonly
The zipcode type of this country.

List countries

How to fetch a list of countries:

  curl --get 'https://example.booqable.com/api/boomerang/countries'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "adafbcae-49c4-4209-8932-8b822acb8924",
        "type": "countries",
        "attributes": {
          "created_at": "2028-11-04T19:33:00.000000+00:00",
          "updated_at": "2028-11-04T19:33:00.000000+00:00",
          "name": "Netherlands",
          "alpha2": "NL",
          "province_required": false,
          "province_type": "province",
          "form_layout": "{country}\n{first_name}{last_name}\n{address1}\n{address2}\n{zipcode}{city}",
          "show_layout": "{first_name} {last_name}\n{address1}\n{address2}\n{zipcode} {city}\n{country}",
          "zipcode_required": true,
          "zipcode_autofill": null,
          "zipcode_format": "\\d{4} ?[A-Z]{2}",
          "zipcode_placeholder": "1234 AB",
          "zipcode_type": "postcode",
          "city_autofill": null
        },
        "relationships": {}
      }
    ],
    "meta": {}
  }

HTTP Request

GET /api/boomerang/countries

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[countries]=created_at,updated_at,name
filter hash
The filters to apply ?filter[attribute][eq]=value
include string
List of comma seperated relationships to sideload. ?include=provinces
meta hash
Metadata to send along. ?meta[total][]=count
page[number] string
The page to request.
page[size] string
The amount of items per page.
sort string
How to sort the data. ?sort=attribute1,-attribute2

Filters

This request can be filtered on:

Name Description
alpha2 string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
city_autofill string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
created_at datetime
eq, not_eq, gt, gte, lt, lte
form_layout string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
id uuid
eq, not_eq
name string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
province_required boolean
eq
province_type string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
show_layout string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
updated_at datetime
eq, not_eq, gt, gte, lt, lte
zipcode_autofill string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
zipcode_format string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
zipcode_placeholder string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
zipcode_required boolean
eq
zipcode_type string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match

Meta

Results can be aggregated on:

Name Description
total array
count

Includes

This request accepts the following includes:

provinces

Coupons

Create codes to discount orders by a fixed amount or a percentage. Customers can redeem the codes online at checkout. Coupons can also be added to orders in the back office.

Fields

Name Description
active boolean
Whether coupon can be redeemed at the moment.
archived boolean readonly
Whether coupon is archived.
archived_at datetime readonly nullable
When the coupon was archived.
coupon_type string
How the discount is calculated.
created_at datetime readonly
When the resource was created.
id uuid readonly
Primary key.
identifier string
The code that customers need to type in.
updated_at datetime readonly
When the resource was last updated.
value integer
A percentage for type percentage or a value in cents for cents.

List coupons

How to fetch a list of coupons:

  curl --get 'https://example.booqable.com/api/boomerang/coupons'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "631bea2b-3cb8-4bbd-819d-7cb0257b110e",
        "type": "coupons",
        "attributes": {
          "created_at": "2021-07-21T18:25:00.000000+00:00",
          "updated_at": "2021-07-21T18:25:00.000000+00:00",
          "archived": false,
          "archived_at": null,
          "identifier": "SUMMER20OFF",
          "coupon_type": "percentage",
          "value": 20,
          "active": true
        }
      }
    ],
    "meta": {}
  }

HTTP Request

GET /api/boomerang/coupons

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[coupons]=created_at,updated_at,archived
filter hash
The filters to apply ?filter[attribute][eq]=value
meta hash
Metadata to send along. ?meta[total][]=count
page[number] string
The page to request.
page[size] string
The amount of items per page.
sort string
How to sort the data. ?sort=attribute1,-attribute2

Filters

This request can be filtered on:

Name Description
active boolean
eq
archived boolean
eq
archived_at datetime
eq, not_eq, gt, gte, lt, lte
coupon_type string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
created_at datetime
eq, not_eq, gt, gte, lt, lte
id uuid
eq, not_eq
identifier string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
updated_at datetime
eq, not_eq, gt, gte, lt, lte
value integer
eq, not_eq, gt, gte, lt, lte

Meta

Results can be aggregated on:

Name Description
total array
count

Includes

This request does not accept any includes

Fetch a coupon

How to fetch a coupon:

  curl --get 'https://example.booqable.com/api/boomerang/coupons/2a057098-ccb5-4179-800a-0d295431eaa3'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": {
      "id": "2a057098-ccb5-4179-800a-0d295431eaa3",
      "type": "coupons",
      "attributes": {
        "created_at": "2026-09-19T23:57:00.000000+00:00",
        "updated_at": "2026-09-19T23:57:00.000000+00:00",
        "archived": false,
        "archived_at": null,
        "identifier": "SUMMER20OFF",
        "coupon_type": "percentage",
        "value": 20,
        "active": true
      }
    },
    "meta": {}
  }

HTTP Request

GET /api/boomerang/coupons/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[coupons]=created_at,updated_at,archived

Includes

This request does not accept any includes

Create a coupon

How to create a coupon:

  curl --request POST
       --url 'https://example.booqable.com/api/boomerang/coupons'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "type": "coupons",
           "attributes": {
             "identifier": "WINTERDISCOUNT",
             "coupon_type": "cents",
             "value": 2000,
             "active": true
           }
         }
       }'

A 201 status response looks like this:

  {
    "data": {
      "id": "e2ba40bf-54f7-422e-844e-5d36bacd5bfa",
      "type": "coupons",
      "attributes": {
        "created_at": "2020-12-12T20:49:00.000000+00:00",
        "updated_at": "2020-12-12T20:49:00.000000+00:00",
        "archived": false,
        "archived_at": null,
        "identifier": "WINTERDISCOUNT",
        "coupon_type": "cents",
        "value": 2000,
        "active": true
      }
    },
    "meta": {}
  }

HTTP Request

POST /api/boomerang/coupons

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[coupons]=created_at,updated_at,archived

Request body

This request accepts the following body:

Name Description
data[attributes][active] boolean
Whether coupon can be redeemed at the moment.
data[attributes][coupon_type] string
How the discount is calculated.
data[attributes][identifier] string
The code that customers need to type in.
data[attributes][value] integer
A percentage for type percentage or a value in cents for cents.

Includes

This request does not accept any includes

Update a coupon

When updating a coupon the existing one is archived and a new one gets created:

How to update a coupon:

  curl --request PUT
       --url 'https://example.booqable.com/api/boomerang/coupons/90aa7e25-800f-4f23-84c2-1f077eaea4dd'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "id": "90aa7e25-800f-4f23-84c2-1f077eaea4dd",
           "type": "coupons",
           "attributes": {
             "identifier": "SUMMER30OFF",
             "coupon_type": "percentage",
             "value": 30
           }
         }
       }'

A 200 status response looks like this:

  {
    "data": {
      "id": "f3f44405-c4fe-424e-8fe4-bfdfe6a7f761",
      "type": "coupons",
      "attributes": {
        "created_at": "2021-03-12T23:40:01.000000+00:00",
        "updated_at": "2021-03-12T23:40:01.000000+00:00",
        "archived": false,
        "archived_at": null,
        "identifier": "SUMMER30OFF",
        "coupon_type": "percentage",
        "value": 30,
        "active": false
      }
    },
    "meta": {}
  }

How to deactivate a coupon:

  curl --request PUT
       --url 'https://example.booqable.com/api/boomerang/coupons/8c0f8005-b948-4ddc-855b-6825e4159246'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "id": "8c0f8005-b948-4ddc-855b-6825e4159246",
           "type": "coupons",
           "attributes": {
             "active": false
           }
         }
       }'

A 200 status response looks like this:

  {
    "data": {
      "id": "aa069e77-af42-4e2c-862a-53a56308bcc0",
      "type": "coupons",
      "attributes": {
        "created_at": "2022-08-10T18:19:00.000000+00:00",
        "updated_at": "2022-08-10T18:19:00.000000+00:00",
        "archived": false,
        "archived_at": null,
        "identifier": "SUMMER20OFF",
        "coupon_type": "percentage",
        "value": 20,
        "active": false
      }
    },
    "meta": {}
  }

HTTP Request

PUT /api/boomerang/coupons/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[coupons]=created_at,updated_at,archived

Request body

This request accepts the following body:

Name Description
data[attributes][active] boolean
Whether coupon can be redeemed at the moment.
data[attributes][coupon_type] string
How the discount is calculated.
data[attributes][identifier] string
The code that customers need to type in.
data[attributes][value] integer
A percentage for type percentage or a value in cents for cents.

Includes

This request does not accept any includes

Archive a coupon

How to archive a coupon:

  curl --request DELETE
       --url 'https://example.booqable.com/api/boomerang/coupons/48f7032a-1017-4616-82e3-be69134a1685'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": {
      "id": "48f7032a-1017-4616-82e3-be69134a1685",
      "type": "coupons",
      "attributes": {
        "created_at": "2015-09-09T21:54:00.000000+00:00",
        "updated_at": "2015-09-09T21:54:00.000000+00:00",
        "archived": true,
        "archived_at": "2015-09-09T21:54:00.000000+00:00",
        "identifier": "SUMMER20OFF",
        "coupon_type": "percentage",
        "value": 20,
        "active": true
      }
    },
    "meta": {}
  }

HTTP Request

DELETE /api/boomerang/coupons/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[coupons]=created_at,updated_at,archived

Includes

This request does not accept any includes

Customers

Customers are an essential part of your business.

Stored customer information like addresses, customer tax profiles, discounts, and customized security deposits are applied to an order when created or when assigned a new customer.

Relationships

Name Description
barcode Barcode optional
The barcode pointing to this customer.
merge_suggestion_customer Customer required
Holds the customer this customer is a possible duplicate of.
notes Notes hasmany
Notes added about (and invisible for) customers.
properties Properties hasmany
Custom structured data about this customer, based on DefaultProperties. Properties of customers can be updated in bulk by writing to the properties_attributes attribute.
tax_region Tax region optional
Tax region assigned to new orders for this customer.

Check matching attributes under Fields to see which relations can be written.
Check each individual operation to see which relations can be included as a sideload.

Fields

Name Description
archived boolean readonly
Whether customer is archived.
archived_at datetime readonly nullable
When the customer was archived.
created_at datetime readonly
When the resource was created.
deposit_type string
The deposit added to new orders of this customer by default.
deposit_value float
The value to use for deposit_type.
discount_percentage float
Default discount applied to each new order for this customer.
email string nullable
E-mail address used for communication.
email_marketing_consent_updated_at datetime readonly
When the email marketing consent was last updated.
email_marketing_consented boolean
Whether the customer has consented to receive email marketing.
id uuid readonly
Primary key.
legal_type string
Either person or commercial.
merge_suggestion_customer_id uuid
Holds the customer this customer is a possible duplicate of.
name string
Person or Company name.
number integer readonly
The assigned number.
properties hash readonly
A hash containing all basic property values. This is a simplified representation; sideload the properties relation if you need more detailed information of propertoes.
properties_attributes array writeonly
Create or update multiple properties to be associated with this customer.
tag_list array[string]
Case insensitive tag list.
tax_region_id uuid nullable
Tax region assigned to new orders for this customer.
updated_at datetime readonly
When the resource was last updated.

List customers

How to fetch a list of customers:

  curl --get 'https://example.booqable.com/api/boomerang/customers'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "b047cd19-e6ec-4914-8ddb-960e2ed984fa",
        "type": "customers",
        "attributes": {
          "created_at": "2018-06-02T01:12:12.000000+00:00",
          "updated_at": "2018-06-02T01:12:12.000000+00:00",
          "archived": false,
          "archived_at": null,
          "number": 1,
          "name": "John Doe",
          "email": "[email protected]",
          "deposit_type": "default",
          "deposit_value": 0.0,
          "discount_percentage": 0.0,
          "legal_type": "person",
          "email_marketing_consented": false,
          "email_marketing_consent_updated_at": null,
          "properties": {},
          "tag_list": [],
          "merge_suggestion_customer_id": null,
          "tax_region_id": null
        },
        "relationships": {}
      }
    ],
    "meta": {}
  }

HTTP Request

GET /api/boomerang/customers

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[customers]=created_at,updated_at,archived
filter hash
The filters to apply ?filter[attribute][eq]=value
include string
List of comma seperated relationships to sideload. ?include=barcode,properties,tax_region
meta hash
Metadata to send along. ?meta[total][]=count
page[number] string
The page to request.
page[size] string
The amount of items per page.
sort string
How to sort the data. ?sort=attribute1,-attribute2

Filters

This request can be filtered on:

Name Description
archived boolean
eq
archived_at datetime
eq, not_eq, gt, gte, lt, lte
conditions hash
eq
created_at datetime
eq, not_eq, gt, gte, lt, lte
deposit_type string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
deposit_value float
eq, not_eq, gt, gte, lt, lte
discount_percentage float
eq, not_eq, gt, gte, lt, lte
email string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
email_marketing_consented boolean
eq
id uuid
eq, not_eq, gt
legal_type string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
merge_suggestion_customer_id uuid
eq, not_eq
name string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
number integer
eq, not_eq, gt, gte, lt, lte
q string
eq
tag_list string
eq
tax_region_id uuid
eq, not_eq
updated_at datetime
eq, not_eq, gt, gte, lt, lte

Meta

Results can be aggregated on:

Name Description
archived array
count
discount_percentage array
maximum, minimum, average
legal_type array
count
tag_list array
count
total array
count

Includes

This request accepts the following includes:

barcode

properties

tax_region

Search customers

Use advanced search to make logical filter groups with and/or operators.

How to search for customers:

  curl --request POST
       --url 'https://example.booqable.com/api/boomerang/customers/search'
       --header 'content-type: application/json'
       --data '{
         "fields": {
           "customers": "id"
         },
         "filter": {
           "conditions": {
             "operator": "and",
             "attributes": [
               {
                 "operator": "or",
                 "attributes": [
                   {
                     "name": "john"
                   },
                   {
                     "name": "jane"
                   }
                 ]
               },
               {
                 "operator": "and",
                 "attributes": [
                   {
                     "discount_percentage": {
                       "gte": 50
                     }
                   },
                   {
                     "deposit_type": "none"
                   }
                 ]
               }
             ]
           }
         }
       }'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "fc31d64f-c136-4d37-8a09-e821bf52af93"
      },
      {
        "id": "987d8eb5-6236-4d00-8f7b-308f06d36519"
      }
    ]
  }

HTTP Request

POST api/boomerang/customers/search

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[customers]=created_at,updated_at,archived
filter hash
The filters to apply ?filter[attribute][eq]=value
include string
List of comma seperated relationships to sideload. ?include=barcode,properties,tax_region
meta hash
Metadata to send along. ?meta[total][]=count
page[number] string
The page to request.
page[size] string
The amount of items per page.
sort string
How to sort the data. ?sort=attribute1,-attribute2

Filters

This request can be filtered on:

Name Description
archived boolean
eq
archived_at datetime
eq, not_eq, gt, gte, lt, lte
conditions hash
eq
created_at datetime
eq, not_eq, gt, gte, lt, lte
deposit_type string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
deposit_value float
eq, not_eq, gt, gte, lt, lte
discount_percentage float
eq, not_eq, gt, gte, lt, lte
email string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
email_marketing_consented boolean
eq
id uuid
eq, not_eq, gt
legal_type string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
merge_suggestion_customer_id uuid
eq, not_eq
name string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
number integer
eq, not_eq, gt, gte, lt, lte
q string
eq
tag_list string
eq
tax_region_id uuid
eq, not_eq
updated_at datetime
eq, not_eq, gt, gte, lt, lte

Meta

Results can be aggregated on:

Name Description
archived array
count
discount_percentage array
maximum, minimum, average
legal_type array
count
tag_list array
count
total array
count

Includes

This request accepts the following includes:

barcode

properties

tax_region

Fetch a customer

How to fetch a customers:

  curl --get 'https://example.booqable.com/api/boomerang/customers/2270a849-1797-436e-8b18-ef3fd6058a01'
       --header 'content-type: application/json'
       --data-urlencode 'include=barcode,properties'

A 200 status response looks like this:

  {
    "data": {
      "id": "2270a849-1797-436e-8b18-ef3fd6058a01",
      "type": "customers",
      "attributes": {
        "created_at": "2028-05-22T08:53:00.000000+00:00",
        "updated_at": "2028-05-22T08:53:00.000000+00:00",
        "archived": false,
        "archived_at": null,
        "number": 1,
        "name": "John Doe",
        "email": "[email protected]",
        "deposit_type": "default",
        "deposit_value": 0.0,
        "discount_percentage": 0.0,
        "legal_type": "person",
        "email_marketing_consented": false,
        "email_marketing_consent_updated_at": null,
        "properties": {},
        "tag_list": [],
        "merge_suggestion_customer_id": null,
        "tax_region_id": null
      },
      "relationships": {
        "properties": {
          "data": []
        },
        "barcode": {
          "data": null
        }
      }
    },
    "meta": {}
  }

HTTP Request

GET /api/boomerang/customers/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[customers]=created_at,updated_at,archived
include string
List of comma seperated relationships to sideload. ?include=barcode,properties,tax_region

Includes

This request accepts the following includes:

barcode

properties

tax_region

Create a customer

How to create a customer:

  curl --request POST
       --url 'https://example.booqable.com/api/boomerang/customers'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "type": "customers",
           "attributes": {
             "name": "John Doe",
             "email": "[email protected]"
           }
         }
       }'

A 201 status response looks like this:

  {
    "data": {
      "id": "81f21c77-e757-43d7-842f-41c5c184945e",
      "type": "customers",
      "attributes": {
        "created_at": "2015-09-14T16:31:01.000000+00:00",
        "updated_at": "2015-09-14T16:31:01.000000+00:00",
        "archived": false,
        "archived_at": null,
        "number": 2,
        "name": "John Doe",
        "email": "[email protected]",
        "deposit_type": "default",
        "deposit_value": 0.0,
        "discount_percentage": 0.0,
        "legal_type": "person",
        "email_marketing_consented": false,
        "email_marketing_consent_updated_at": null,
        "properties": {},
        "tag_list": [],
        "merge_suggestion_customer_id": null,
        "tax_region_id": null
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

POST /api/boomerang/customers

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[customers]=created_at,updated_at,archived
include string
List of comma seperated relationships to sideload. ?include=barcode,properties,tax_region

Request body

This request accepts the following body:

Name Description
data[attributes][deposit_type] string
The deposit added to new orders of this customer by default.
data[attributes][deposit_value] float
The value to use for deposit_type.
data[attributes][discount_percentage] float
Default discount applied to each new order for this customer.
data[attributes][email] string
E-mail address used for communication.
data[attributes][email_marketing_consented] boolean
Whether the customer has consented to receive email marketing.
data[attributes][legal_type] string
Either person or commercial.
data[attributes][merge_suggestion_customer_id] uuid
Holds the customer this customer is a possible duplicate of.
data[attributes][name] string
Person or Company name.
data[attributes][properties_attributes][] array
Create or update multiple properties to be associated with this customer.
data[attributes][tag_list] array[string]
Case insensitive tag list.
data[attributes][tax_region_id] uuid
Tax region assigned to new orders for this customer.

Includes

This request accepts the following includes:

barcode

properties

tax_region

Update a customer

How to update a customer:

  curl --request PUT
       --url 'https://example.booqable.com/api/boomerang/customers/7eaf3c75-3143-4090-8ccf-32b899f324c9'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "id": "7eaf3c75-3143-4090-8ccf-32b899f324c9",
           "type": "customers",
           "attributes": {
             "name": "Jane Doe"
           }
         }
       }'

A 200 status response looks like this:

  {
    "data": {
      "id": "7eaf3c75-3143-4090-8ccf-32b899f324c9",
      "type": "customers",
      "attributes": {
        "created_at": "2014-02-18T23:31:00.000000+00:00",
        "updated_at": "2014-02-18T23:31:00.000000+00:00",
        "archived": false,
        "archived_at": null,
        "number": 1,
        "name": "Jane Doe",
        "email": "[email protected]",
        "deposit_type": "default",
        "deposit_value": 0.0,
        "discount_percentage": 0.0,
        "legal_type": "person",
        "email_marketing_consented": false,
        "email_marketing_consent_updated_at": null,
        "properties": {},
        "tag_list": [],
        "merge_suggestion_customer_id": null,
        "tax_region_id": null
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

PUT /api/boomerang/customers/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[customers]=created_at,updated_at,archived
include string
List of comma seperated relationships to sideload. ?include=barcode,properties,tax_region

Request body

This request accepts the following body:

Name Description
data[attributes][deposit_type] string
The deposit added to new orders of this customer by default.
data[attributes][deposit_value] float
The value to use for deposit_type.
data[attributes][discount_percentage] float
Default discount applied to each new order for this customer.
data[attributes][email] string
E-mail address used for communication.
data[attributes][email_marketing_consented] boolean
Whether the customer has consented to receive email marketing.
data[attributes][legal_type] string
Either person or commercial.
data[attributes][merge_suggestion_customer_id] uuid
Holds the customer this customer is a possible duplicate of.
data[attributes][name] string
Person or Company name.
data[attributes][properties_attributes][] array
Create or update multiple properties to be associated with this customer.
data[attributes][tag_list] array[string]
Case insensitive tag list.
data[attributes][tax_region_id] uuid
Tax region assigned to new orders for this customer.

Includes

This request accepts the following includes:

barcode

properties

tax_region

Archive a customer

How to archive a customer:

  curl --request DELETE
       --url 'https://example.booqable.com/api/boomerang/customers/7a496d55-729c-43e0-8a6b-8d505e0f3c70'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": {
      "id": "7a496d55-729c-43e0-8a6b-8d505e0f3c70",
      "type": "customers",
      "attributes": {
        "created_at": "2020-05-21T12:16:00.000000+00:00",
        "updated_at": "2020-05-21T12:16:00.000000+00:00",
        "archived": true,
        "archived_at": "2020-05-21T12:16:00.000000+00:00",
        "number": 1,
        "name": "John Doe",
        "email": "[email protected]",
        "deposit_type": "default",
        "deposit_value": 0.0,
        "discount_percentage": 0.0,
        "legal_type": "person",
        "email_marketing_consented": false,
        "email_marketing_consent_updated_at": null,
        "properties": {},
        "tag_list": [],
        "merge_suggestion_customer_id": null,
        "tax_region_id": null
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

DELETE /api/boomerang/customers/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[customers]=created_at,updated_at,archived

Includes

This request does not accept any includes

Default properties

Booqable comes with standard fields but you can also add custom properties to capture additional data.

Default properties show up in forms within Booqable and can be connected to checkout fields. 0

Default properties are searchable, show up in exports and can be used in email templates. The actual values of those properties are stored in the Property resource.

Properties inherit their configuration from a default property when they are connected.

When creating properties they are connected with their default when one of the following fields match: - name - identifier - default_property_id

Fields

Name Description
created_at datetime readonly
When the resource was created.
editable boolean readonly
Whether this property is editable.
id uuid readonly
Primary key.
identifier string
Key that will be used in exports, responses and custom field variables in templates.
name string
Name of the property (used as label and to compute identifier if left blank).
owner_type string readonly-after-create
The type of resource this default property is intended for and derived properties can be added to.
position integer
Which position the property has.
property_type enum
Determines how the data is rendered and the kind of input shown to the user.
One of: address, date_field, email, phone, select, text_area, text_field.
select_options array
For type select. The select options as array..
show_on array[string]
Array of items to show this custom field on. Zero or more from contract, invoice, packing, quote.
updated_at datetime readonly
When the resource was last updated.
validation_required boolean
Whether this property has to be validated.

List default properties

How to fetch a list of default properties:

  curl --get 'https://example.booqable.com/api/boomerang/default_properties'
       --header 'content-type: application/json'
       --data-urlencode 'include=owner'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "5d959acd-b782-4ee2-858b-d53452746abe",
        "type": "default_properties",
        "attributes": {
          "created_at": "2016-08-06T16:53:03.000000+00:00",
          "updated_at": "2016-08-06T16:53:03.000000+00:00",
          "name": "Phone",
          "identifier": "phone",
          "position": 1,
          "property_type": "phone",
          "show_on": [],
          "validation_required": false,
          "owner_type": "customers",
          "select_options": [],
          "editable": true
        }
      }
    ],
    "meta": {}
  }

HTTP Request

GET /api/boomerang/default_properties

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[default_properties]=created_at,updated_at,name
filter hash
The filters to apply ?filter[attribute][eq]=value
meta hash
Metadata to send along. ?meta[total][]=count
page[number] string
The page to request.
page[size] string
The amount of items per page.
sort string
How to sort the data. ?sort=attribute1,-attribute2

Filters

This request can be filtered on:

Name Description
created_at datetime
eq, not_eq, gt, gte, lt, lte
editable boolean
eq
id uuid
eq, not_eq
identifier string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
name string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
owner_type string
eq, not_eq
updated_at datetime
eq, not_eq, gt, gte, lt, lte
validation_required boolean
eq

Meta

Results can be aggregated on:

Name Description
total array
count

Includes

This request does not accept any includes

Fetch a default property

How to fetch a default property:

  curl --get 'https://example.booqable.com/api/boomerang/default_properties/e579fd95-e66a-48b3-8954-a1303f0d4543'
       --header 'content-type: application/json'
       --data-urlencode 'include=owner'

A 200 status response looks like this:

  {
    "data": {
      "id": "e579fd95-e66a-48b3-8954-a1303f0d4543",
      "type": "default_properties",
      "attributes": {
        "created_at": "2016-06-28T12:50:01.000000+00:00",
        "updated_at": "2016-06-28T12:50:01.000000+00:00",
        "name": "Phone",
        "identifier": "phone",
        "position": 1,
        "property_type": "phone",
        "show_on": [],
        "validation_required": false,
        "owner_type": "customers",
        "select_options": [],
        "editable": true
      }
    },
    "meta": {}
  }

HTTP Request

GET /api/boomerang/default_properties/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[default_properties]=created_at,updated_at,name

Includes

This request does not accept any includes

Create a default property

How to create a default property and assign it to an owner:

  curl --request POST
       --url 'https://example.booqable.com/api/boomerang/default_properties'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "type": "default_properties",
           "attributes": {
             "name": "Mobile phone",
             "property_type": "phone",
             "owner_type": "customers"
           }
         }
       }'

A 201 status response looks like this:

  {
    "data": {
      "id": "0be37be8-1023-49f4-838a-f1f4a10954ef",
      "type": "default_properties",
      "attributes": {
        "created_at": "2019-06-17T18:28:00.000000+00:00",
        "updated_at": "2019-06-17T18:28:00.000000+00:00",
        "name": "Mobile phone",
        "identifier": "mobile_phone",
        "position": 2,
        "property_type": "phone",
        "show_on": [],
        "validation_required": false,
        "owner_type": "customers",
        "select_options": [],
        "editable": true
      }
    },
    "meta": {}
  }

HTTP Request

POST /api/boomerang/default_properties

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[default_properties]=created_at,updated_at,name

Request body

This request accepts the following body:

Name Description
data[attributes][identifier] string
Key that will be used in exports, responses and custom field variables in templates.
data[attributes][name] string
Name of the property (used as label and to compute identifier if left blank).
data[attributes][owner_type] string
The type of resource this default property is intended for and derived properties can be added to.
data[attributes][position] integer
Which position the property has.
data[attributes][property_type] enum
Determines how the data is rendered and the kind of input shown to the user.
One of: address, date_field, email, phone, select, text_area, text_field.
data[attributes][select_options][] array
For type select. The select options as array..
data[attributes][show_on] array[string]
Array of items to show this custom field on. Zero or more from contract, invoice, packing, quote.
data[attributes][validation_required] boolean
Whether this property has to be validated.

Includes

This request does not accept any includes

Update a default property

How to update a default property:

  curl --request PUT
       --url 'https://example.booqable.com/api/boomerang/default_properties/1d9d3f48-7bac-4b62-8f42-8018003cc95b'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "id": "1d9d3f48-7bac-4b62-8f42-8018003cc95b",
           "type": "default_properties",
           "attributes": {
             "property_type": "text_field"
           }
         }
       }'

A 200 status response looks like this:

  {
    "data": {
      "id": "1d9d3f48-7bac-4b62-8f42-8018003cc95b",
      "type": "default_properties",
      "attributes": {
        "created_at": "2014-07-12T02:01:00.000000+00:00",
        "updated_at": "2014-07-12T02:01:00.000000+00:00",
        "name": "Phone",
        "identifier": "phone",
        "position": 1,
        "property_type": "text_field",
        "show_on": [],
        "validation_required": false,
        "owner_type": "customers",
        "select_options": [],
        "editable": true
      }
    },
    "meta": {}
  }

HTTP Request

PUT /api/boomerang/default_properties/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[default_properties]=created_at,updated_at,name

Request body

This request accepts the following body:

Name Description
data[attributes][identifier] string
Key that will be used in exports, responses and custom field variables in templates.
data[attributes][name] string
Name of the property (used as label and to compute identifier if left blank).
data[attributes][owner_type] string
The type of resource this default property is intended for and derived properties can be added to.
data[attributes][position] integer
Which position the property has.
data[attributes][property_type] enum
Determines how the data is rendered and the kind of input shown to the user.
One of: address, date_field, email, phone, select, text_area, text_field.
data[attributes][select_options][] array
For type select. The select options as array..
data[attributes][show_on] array[string]
Array of items to show this custom field on. Zero or more from contract, invoice, packing, quote.
data[attributes][validation_required] boolean
Whether this property has to be validated.

Includes

This request does not accept any includes

Delete a default property

How to delete a default property:

  curl --request DELETE
       --url 'https://example.booqable.com/api/boomerang/default_properties/8d8ff086-4c54-40aa-84dd-28fc56d8b3dd'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": {
      "id": "8d8ff086-4c54-40aa-84dd-28fc56d8b3dd",
      "type": "default_properties",
      "attributes": {
        "created_at": "2025-03-13T08:57:00.000000+00:00",
        "updated_at": "2025-03-13T08:57:00.000000+00:00",
        "name": "Phone",
        "identifier": "phone",
        "position": 1,
        "property_type": "phone",
        "show_on": [],
        "validation_required": false,
        "owner_type": "customers",
        "select_options": [],
        "editable": true
      }
    },
    "meta": {}
  }

HTTP Request

DELETE /api/boomerang/default_properties/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[default_properties]=created_at,updated_at,name

Includes

This request does not accept any includes

Delivery distance calculations

It calculates the distance (the route length) between the given locations and the delivery address.

Fields

Name Description
distance float readonly
The distance between the location and the delivery address.
distance_unit enum readonly
The unit of the distance.
One of: metric, imperial.
id uuid readonly
Primary key.
location_id uuid readonly
The location ID.

Calculate delivery distances

How to fetch a list of delivery distance calculations:

  curl --get 'https://example.booqable.com/api/boomerang/delivery_distance_calculations'
       --header 'content-type: application/json'
       --data-urlencode 'filter[delivery_address_property_id]=2e70e73b-04ee-4e00-835e-13ad1d52e6fc'
       --data-urlencode 'filter[location_ids][]=df2395bd-72f3-4078-8c07-4c1f636a1a03'
       --data-urlencode 'filter[location_ids][]=acea1410-5c2a-412d-8910-e48a9224a44d'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "f8d4975d-f633-4703-8e3d-8c7c36951675",
        "type": "delivery_distance_calculations",
        "attributes": {
          "distance": 10.0,
          "distance_unit": "km",
          "location_id": "df2395bd-72f3-4078-8c07-4c1f636a1a03"
        }
      },
      {
        "id": "8dc19268-75fd-4a1c-88e5-4a0bf08fb148",
        "type": "delivery_distance_calculations",
        "attributes": {
          "distance": 20.0,
          "distance_unit": "km",
          "location_id": "acea1410-5c2a-412d-8910-e48a9224a44d"
        }
      }
    ],
    "meta": {}
  }

HTTP Request

GET /api/boomerang/delivery_distance_calculations

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[delivery_distance_calculations]=distance,distance_unit,location_id
filter hash
The filters to apply ?filter[attribute][eq]=value
meta hash
Metadata to send along. ?meta[total][]=count
page[number] string
The page to request.
page[size] string
The amount of items per page.
sort string
How to sort the data. ?sort=attribute1,-attribute2

Filters

This request can be filtered on:

Name Description
delivery_address_property_id uuid
eq
location_ids array
eq

Meta

Results can be aggregated on:

Name Description
total array
count

Includes

This request does not accept any includes

Deposit holds

A deposit hold is the resource responsible for managing the held deposit on an order.

Relationships

Name Description
deposit_line Line required
The Line that was created or updated to hold the deppsit.
order Order required
The order a new deposit needs to be added to.

Check matching attributes under Fields to see which relations can be written.
Check each individual operation to see which relations can be included as a sideload.

Fields

Name Description
amount_in_cents integer writeonly
Amount to hold. If the order already has a hold, the amount will added to the previous one. The hold is clamped to order.deposit_in_cents.
deposit_line_id uuid readonly
The Line that was created or updated to hold the deppsit.
id uuid readonly
Primary key.
order_id uuid
The order a new deposit needs to be added to.
reason string writeonly
Reason for the hold. If the order already has a hold, the reason will overwrite the previous one.

Create

Hold a deposit:

  curl --request POST
       --url 'https://example.booqable.com/api/boomerang/deposit_holds'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "type": "deposit_holds",
           "attributes": {
             "order_id": "f20704d5-8868-46c8-8d43-4eb95a96ec2e",
             "amount_in_cents": 5000,
             "reason": "damages"
           }
         }
       }'

A 201 status response looks like this:

  {
    "data": {
      "id": "d785af99-53ec-4230-819f-c65f4fb7da9d",
      "type": "deposit_holds",
      "attributes": {
        "order_id": "f20704d5-8868-46c8-8d43-4eb95a96ec2e",
        "deposit_line_id": "e98315a1-7fbe-48ac-810a-c0823f8a663a"
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

POST /api/boomerang/deposit_holds

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[deposit_holds]=order_id,deposit_line_id
include string
List of comma seperated relationships to sideload. ?include=deposit_line,order

Request body

This request accepts the following body:

Name Description
data[attributes][amount_in_cents] integer
Amount to hold. If the order already has a hold, the amount will added to the previous one. The hold is clamped to order.deposit_in_cents.
data[attributes][order_id] uuid
The order a new deposit needs to be added to.
data[attributes][reason] string
Reason for the hold. If the order already has a hold, the reason will overwrite the previous one.

Includes

This request accepts the following includes:

deposit_line => tax_category

tax_values

order => tax_values

Documents

Documents hold financial and or legal information about an order. There are three types of documents: quote, contract, invoice.

When creating quotes and contracts, the following data is copied from the current state of the order:

Quotes and contracts are always finalized; to make a revision, archive the document, make changes to the order, and create a new one.

Invoices are automatically generated and updated based on changes made to an order. When an invoice is finalized, and further changes are made to the order, a new invoice is created with prorated changes.

The payment status of the invoice is automatically updated when payments are made for the associated order.

Relationships

Name Description
coupon Coupon optional
The associated coupon.
customer Customer optional
The associated customer.
lines Lines hasmany
The lines of this document.
order Order required
The order this document is for.
tax_region Tax region optional
The associated tax region.
tax_values Tax values hasmany
The calculated taxes, one value for each applicable tax rate.

Check matching attributes under Fields to see which relations can be written.
Check each individual operation to see which relations can be included as a sideload.

Fields

Name Description
address string
Customer Address. If left blank, automatically populated with the customer address of the associated order.
archived boolean readonly
Whether document is archived.
archived_at datetime readonly nullable
When the document was archived.
body string
Custom content displayed on a document, agreement details on a contract, for instance. Applicable to quote and contract. Populated with setting {document_type}.body, but can also be overridden for a specific document.
confirmed boolean
Whether document is confirmed, applies to quote and contract.
coupon_discount_in_cents integer readonly
Coupon discount (incl. or excl. taxes based on tax_strategy.
coupon_id uuid nullable
The associated coupon.
created_at datetime readonly
When the resource was created.
customer_id uuid nullable
The associated customer.
date date
Date the document was finalized.
deposit_held_in_cents integer readonly
Amount of deposit held.
deposit_in_cents integer readonly
Deposit.
deposit_paid_in_cents integer readonly
How much of the deposit is paid.
deposit_refunded_in_cents integer readonly
How much of the deposit is refunded.
deposit_to_refund_in_cents integer readonly
Amount of deposit (still) to be refunded.
deposit_type enum nullable
Kind of deposit added.
One of: none, percentage_total, percentage, fixed.
deposit_value float
The value to use for deposit_type.
discount_in_cents integer readonly
Discount (incl. or excl. taxes based on tax_strategy.
discount_percentage float
The discount percentage applied to this order.
document_type enum readonly-after-create
Type of document.
One of: invoice, contract, quote.
due_date date
The latest date by which the invoice must be fully paid.
finalized boolean
Whether document is finalized (quote and contract are always finalized).
footer string
The footer of a document. Populated with setting {document_type}.footer, but can also be overridden for a specific document.
grand_total_in_cents integer readonly
Total excl. taxes (excl. deposit).
grand_total_with_tax_in_cents integer readonly
Amount incl. taxes (excl. deposit).
id uuid readonly
Primary key.
name string
Customer name. If left blank, automatically populated with the customer name of the associated order.
number integer
The document number, must be unique per type. Automatically generated if left blank.
order_id uuid readonly-after-create
The order this document is for.
paid_in_cents integer readonly
How much was paid.
prefix string
Add a prefix to document numbers to make it easier to identify different documents. You can add dynamic values (like a year or order number) and custom prefixes e.g. {year}-{customer_number}.
prefix_with_number string readonly
Rendered prefix with document number.
price_in_cents integer readonly
Subtotal excl. taxes (excl. deposit).
reference string
A project number or other reference.
revised boolean
Whether document is revised (applies only to invoice).
sent boolean
Whether document is sent (with Booqable).
signature_url string readonly
Url where the signature is stored.
status enum
Status (possible values depend on document type).
One of: confirmed, unconfirmed, revised, partially_paid, payment_due, paid, process_deposit, overpaid.
tag_list array
Case insensitive tag list.
tax_in_cents integer readonly
Total tax.
tax_region_id uuid nullable
The associated tax region.
to_be_paid_in_cents integer readonly
Amount that (still) has to be paid.
total_discount_in_cents integer readonly
Total discount (incl. or excl. taxes based on tax_strategy.
updated_at datetime readonly
When the resource was last updated.

List documents

How to fetch a list of documents:

  curl --get 'https://example.booqable.com/api/boomerang/documents'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "a216b9f8-4f61-4eda-8672-3c6e94c9fbe2",
        "type": "documents",
        "attributes": {
          "created_at": "2027-05-20T13:53:01.000000+00:00",
          "updated_at": "2027-05-20T13:53:01.000000+00:00",
          "archived": false,
          "archived_at": null,
          "document_type": "invoice",
          "number": null,
          "prefix": null,
          "prefix_with_number": null,
          "date": null,
          "due_date": null,
          "name": "John Doe",
          "address": null,
          "body": null,
          "footer": "",
          "reference": null,
          "revised": false,
          "finalized": false,
          "sent": false,
          "confirmed": false,
          "status": "payment_due",
          "signature_url": null,
          "deposit_type": "percentage",
          "deposit_value": 10.0,
          "tag_list": [],
          "price_in_cents": 80250,
          "grand_total_in_cents": 72225,
          "grand_total_with_tax_in_cents": 87392,
          "discount_in_cents": 8025,
          "coupon_discount_in_cents": 0,
          "total_discount_in_cents": 8025,
          "deposit_in_cents": 10000,
          "deposit_paid_in_cents": 0,
          "deposit_refunded_in_cents": 0,
          "deposit_held_in_cents": 0,
          "deposit_to_refund_in_cents": 0,
          "to_be_paid_in_cents": 97392,
          "paid_in_cents": 0,
          "tax_in_cents": 15167,
          "discount_percentage": 10.0,
          "order_id": "e10da0d6-7881-4991-851f-ef302c712dea",
          "customer_id": "6b39f922-ebba-4e73-841c-563dd37107d7",
          "tax_region_id": null,
          "coupon_id": null
        },
        "relationships": {}
      }
    ],
    "meta": {}
  }

HTTP Request

GET /api/boomerang/documents

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[documents]=created_at,updated_at,archived
filter hash
The filters to apply ?filter[attribute][eq]=value
include string
List of comma seperated relationships to sideload. ?include=customer,order
meta hash
Metadata to send along. ?meta[total][]=count
page[number] string
The page to request.
page[size] string
The amount of items per page.
sort string
How to sort the data. ?sort=attribute1,-attribute2

Filters

This request can be filtered on:

Name Description
address string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
archived boolean
eq
archived_at datetime
eq, not_eq, gt, gte, lt, lte
conditions hash
eq
confirmed boolean
eq
coupon_discount_in_cents integer
eq, not_eq, gt, gte, lt, lte
coupon_id uuid
eq, not_eq
created_at datetime
eq, not_eq, gt, gte, lt, lte
customer_id uuid
eq, not_eq
date date
eq, not_eq, gt, gte, lt, lte
date_or_created_at datetime
eq, not_eq, gt, gte, lt, lte, between
deposit_held_in_cents integer
eq, not_eq, gt, gte, lt, lte
deposit_in_cents integer
eq, not_eq, gt, gte, lt, lte
deposit_paid_in_cents integer
eq, not_eq, gt, gte, lt, lte
deposit_refunded_in_cents integer
eq, not_eq, gt, gte, lt, lte
deposit_to_refund_in_cents integer
eq, not_eq, gt, gte, lt, lte
deposit_type enum
eq
discount_in_cents integer
eq, not_eq, gt, gte, lt, lte
discount_percentage float
eq, not_eq, gt, gte, lt, lte
document_type enum
eq, not_eq
due_date date
eq, not_eq, gt, gte, lt, lte
finalized boolean
eq
grand_total_in_cents integer
eq, not_eq, gt, gte, lt, lte
grand_total_with_tax_in_cents integer
eq, not_eq, gt, gte, lt, lte
id uuid
eq, not_eq, gt
name string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
number integer
eq, not_eq, gt, gte, lt, lte
order_id uuid
eq, not_eq
paid_in_cents integer
eq, not_eq, gt, gte, lt, lte
prefix string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
prefix_with_number string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
price_in_cents integer
eq, not_eq, gt, gte, lt, lte
q string
eq
revised boolean
eq
sent boolean
eq
status enum
eq
tag_list string
eq
tax_in_cents integer
eq, not_eq, gt, gte, lt, lte
tax_region_id uuid
eq, not_eq
to_be_paid_in_cents integer
eq, not_eq, gt, gte, lt, lte
total_discount_in_cents integer
eq, not_eq, gt, gte, lt, lte
updated_at datetime
eq, not_eq, gt, gte, lt, lte

Meta

Results can be aggregated on:

Name Description
coupon_discount_in_cents array
sum, maximum, minimum, average
currency array
count
deposit_held_in_cents array
sum, maximum, minimum, average
deposit_in_cents array
sum, maximum, minimum, average
deposit_paid_in_cents array
sum, maximum, minimum, average
deposit_refunded_in_cents array
sum, maximum, minimum, average
deposit_to_refund_in_cents array
sum, maximum, minimum, average
deposit_type array
count
discount_in_cents array
sum, maximum, minimum, average
discount_percentage array
maximum, minimum, average
grand_total_in_cents array
sum, maximum, minimum, average
grand_total_with_tax_in_cents array
sum, maximum, minimum, average
paid_in_cents array
sum, maximum, minimum, average
price_in_cents array
sum, maximum, minimum, average
status array
count
tag_list array
count
tax_in_cents array
sum, maximum, minimum, average
tax_strategy array
count
to_be_paid_in_cents array
sum, maximum, minimum, average
total array
count
total_discount_in_cents array
sum, maximum, minimum, average

Includes

This request accepts the following includes:

customer

order

Search documents

Use advanced search to make logical filter groups with and/or operators.

How to search for documents:

  curl --request POST
       --url 'https://example.booqable.com/api/boomerang/documents/search'
       --header 'content-type: application/json'
       --data '{
         "fields": {
           "documents": "id"
         },
         "filter": {
           "conditions": {
             "operator": "and",
             "attributes": [
               {
                 "operator": "or",
                 "attributes": [
                   {
                     "status": "paid"
                   },
                   {
                     "deposit_type": "none"
                   }
                 ]
               },
               {
                 "operator": "and",
                 "attributes": [
                   {
                     "date": {
                       "gte": "2028-11-16T15:29:00.000000+00:00"
                     }
                   },
                   {
                     "date": {
                       "lte": "2028-11-22T15:29:00.000000+00:00"
                     }
                   }
                 ]
               }
             ]
           }
         }
       }'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "c9fa6121-84c0-4a28-893a-cceb9d2be169"
      },
      {
        "id": "3608f8e0-6ba6-4d67-81e0-800ee85ea024"
      }
    ]
  }

HTTP Request

POST api/boomerang/documents/search

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[documents]=created_at,updated_at,archived
filter hash
The filters to apply ?filter[attribute][eq]=value
include string
List of comma seperated relationships to sideload. ?include=customer,order
meta hash
Metadata to send along. ?meta[total][]=count
page[number] string
The page to request.
page[size] string
The amount of items per page.
sort string
How to sort the data. ?sort=attribute1,-attribute2

Filters

This request can be filtered on:

Name Description
address string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
archived boolean
eq
archived_at datetime
eq, not_eq, gt, gte, lt, lte
conditions hash
eq
confirmed boolean
eq
coupon_discount_in_cents integer
eq, not_eq, gt, gte, lt, lte
coupon_id uuid
eq, not_eq
created_at datetime
eq, not_eq, gt, gte, lt, lte
customer_id uuid
eq, not_eq
date date
eq, not_eq, gt, gte, lt, lte
date_or_created_at datetime
eq, not_eq, gt, gte, lt, lte, between
deposit_held_in_cents integer
eq, not_eq, gt, gte, lt, lte
deposit_in_cents integer
eq, not_eq, gt, gte, lt, lte
deposit_paid_in_cents integer
eq, not_eq, gt, gte, lt, lte
deposit_refunded_in_cents integer
eq, not_eq, gt, gte, lt, lte
deposit_to_refund_in_cents integer
eq, not_eq, gt, gte, lt, lte
deposit_type enum
eq
discount_in_cents integer
eq, not_eq, gt, gte, lt, lte
discount_percentage float
eq, not_eq, gt, gte, lt, lte
document_type enum
eq, not_eq
due_date date
eq, not_eq, gt, gte, lt, lte
finalized boolean
eq
grand_total_in_cents integer
eq, not_eq, gt, gte, lt, lte
grand_total_with_tax_in_cents integer
eq, not_eq, gt, gte, lt, lte
id uuid
eq, not_eq, gt
name string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
number integer
eq, not_eq, gt, gte, lt, lte
order_id uuid
eq, not_eq
paid_in_cents integer
eq, not_eq, gt, gte, lt, lte
prefix string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
prefix_with_number string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
price_in_cents integer
eq, not_eq, gt, gte, lt, lte
q string
eq
revised boolean
eq
sent boolean
eq
status enum
eq
tag_list string
eq
tax_in_cents integer
eq, not_eq, gt, gte, lt, lte
tax_region_id uuid
eq, not_eq
to_be_paid_in_cents integer
eq, not_eq, gt, gte, lt, lte
total_discount_in_cents integer
eq, not_eq, gt, gte, lt, lte
updated_at datetime
eq, not_eq, gt, gte, lt, lte

Meta

Results can be aggregated on:

Name Description
coupon_discount_in_cents array
sum, maximum, minimum, average
currency array
count
deposit_held_in_cents array
sum, maximum, minimum, average
deposit_in_cents array
sum, maximum, minimum, average
deposit_paid_in_cents array
sum, maximum, minimum, average
deposit_refunded_in_cents array
sum, maximum, minimum, average
deposit_to_refund_in_cents array
sum, maximum, minimum, average
deposit_type array
count
discount_in_cents array
sum, maximum, minimum, average
discount_percentage array
maximum, minimum, average
grand_total_in_cents array
sum, maximum, minimum, average
grand_total_with_tax_in_cents array
sum, maximum, minimum, average
paid_in_cents array
sum, maximum, minimum, average
price_in_cents array
sum, maximum, minimum, average
status array
count
tag_list array
count
tax_in_cents array
sum, maximum, minimum, average
tax_strategy array
count
to_be_paid_in_cents array
sum, maximum, minimum, average
total array
count
total_discount_in_cents array
sum, maximum, minimum, average

Includes

This request accepts the following includes:

customer

order

Fetch a document

How to fetch a documents:

  curl --get 'https://example.booqable.com/api/boomerang/documents/9c32036d-e60c-47b1-8ff2-7e28343dac1b'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": {
      "id": "9c32036d-e60c-47b1-8ff2-7e28343dac1b",
      "type": "documents",
      "attributes": {
        "created_at": "2021-05-18T10:30:00.000000+00:00",
        "updated_at": "2021-05-18T10:30:00.000000+00:00",
        "archived": false,
        "archived_at": null,
        "document_type": "invoice",
        "number": null,
        "prefix": null,
        "prefix_with_number": null,
        "date": null,
        "due_date": null,
        "name": "John Doe",
        "address": null,
        "body": null,
        "footer": "",
        "reference": null,
        "revised": false,
        "finalized": false,
        "sent": false,
        "confirmed": false,
        "status": "payment_due",
        "signature_url": null,
        "deposit_type": "percentage",
        "deposit_value": 10.0,
        "tag_list": [],
        "price_in_cents": 80250,
        "grand_total_in_cents": 72225,
        "grand_total_with_tax_in_cents": 87392,
        "discount_in_cents": 8025,
        "coupon_discount_in_cents": 0,
        "total_discount_in_cents": 8025,
        "deposit_in_cents": 10000,
        "deposit_paid_in_cents": 0,
        "deposit_refunded_in_cents": 0,
        "deposit_held_in_cents": 0,
        "deposit_to_refund_in_cents": 0,
        "to_be_paid_in_cents": 97392,
        "paid_in_cents": 0,
        "tax_in_cents": 15167,
        "discount_percentage": 10.0,
        "order_id": "9c1a27c9-93ab-45fc-810c-ad69b9ab9617",
        "customer_id": "35578b5e-ed35-40b4-8e46-6d218d036c42",
        "tax_region_id": null,
        "coupon_id": null
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

GET /api/boomerang/documents/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[documents]=created_at,updated_at,archived
include string
List of comma seperated relationships to sideload. ?include=customer,order,tax_region

Includes

This request accepts the following includes:

customer

order

tax_region

lines => item => photo

tax_values

coupon

Create a document

How to create a contract:

  curl --request POST
       --url 'https://example.booqable.com/api/boomerang/documents'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "type": "documents",
           "attributes": {
             "document_type": "contract",
             "order_id": "c7d596a9-f29d-4dd8-8f81-dac3bef16c03"
           }
         }
       }'

A 201 status response looks like this:

  {
    "data": {
      "id": "33d005c3-65d8-4a49-80fa-5bc116112f39",
      "type": "documents",
      "attributes": {
        "created_at": "2022-10-18T11:28:01.000000+00:00",
        "updated_at": "2022-10-18T11:28:01.000000+00:00",
        "archived": false,
        "archived_at": null,
        "document_type": "contract",
        "number": 1,
        "prefix": null,
        "prefix_with_number": "1",
        "date": "2025-02-10",
        "due_date": null,
        "name": "John Doe",
        "address": "",
        "body": "",
        "footer": "",
        "reference": null,
        "revised": false,
        "finalized": true,
        "sent": false,
        "confirmed": false,
        "status": "unconfirmed",
        "signature_url": null,
        "deposit_type": "percentage",
        "deposit_value": 10.0,
        "tag_list": [],
        "price_in_cents": 80250,
        "grand_total_in_cents": 72225,
        "grand_total_with_tax_in_cents": 87392,
        "discount_in_cents": 8025,
        "coupon_discount_in_cents": 0,
        "total_discount_in_cents": 8025,
        "deposit_in_cents": 10000,
        "deposit_paid_in_cents": 0,
        "deposit_refunded_in_cents": 0,
        "deposit_held_in_cents": 0,
        "deposit_to_refund_in_cents": 0,
        "to_be_paid_in_cents": 0,
        "paid_in_cents": 0,
        "tax_in_cents": 15167,
        "discount_percentage": 10.0,
        "order_id": "c7d596a9-f29d-4dd8-8f81-dac3bef16c03",
        "customer_id": "2f4f9473-239b-4b05-8bb3-e9f933d42d64",
        "tax_region_id": null,
        "coupon_id": null
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

POST /api/boomerang/documents

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[documents]=created_at,updated_at,archived
include string
List of comma seperated relationships to sideload. ?include=customer,order,tax_region

Request body

This request accepts the following body:

Name Description
data[attributes][address] string
Customer Address. If left blank, automatically populated with the customer address of the associated order.
data[attributes][body] string
Custom content displayed on a document, agreement details on a contract, for instance. Applicable to quote and contract. Populated with setting {document_type}.body, but can also be overridden for a specific document.
data[attributes][confirmed] boolean
Whether document is confirmed, applies to quote and contract.
data[attributes][coupon_id] uuid
The associated coupon.
data[attributes][customer_id] uuid
The associated customer.
data[attributes][date] date
Date the document was finalized.
data[attributes][deposit_type] enum
Kind of deposit added.
One of: none, percentage_total, percentage, fixed.
data[attributes][deposit_value] float
The value to use for deposit_type.
data[attributes][discount_percentage] float
The discount percentage applied to this order.
data[attributes][document_type] enum
Type of document.
One of: invoice, contract, quote.
data[attributes][due_date] date
The latest date by which the invoice must be fully paid.
data[attributes][finalized] boolean
Whether document is finalized (quote and contract are always finalized).
data[attributes][footer] string
The footer of a document. Populated with setting {document_type}.footer, but can also be overridden for a specific document.
data[attributes][name] string
Customer name. If left blank, automatically populated with the customer name of the associated order.
data[attributes][number] integer
The document number, must be unique per type. Automatically generated if left blank.
data[attributes][order_id] uuid
The order this document is for.
data[attributes][prefix] string
Add a prefix to document numbers to make it easier to identify different documents. You can add dynamic values (like a year or order number) and custom prefixes e.g. {year}-{customer_number}.
data[attributes][reference] string
A project number or other reference.
data[attributes][revised] boolean
Whether document is revised (applies only to invoice).
data[attributes][sent] boolean
Whether document is sent (with Booqable).
data[attributes][status] enum
Status (possible values depend on document type).
One of: confirmed, unconfirmed, revised, partially_paid, payment_due, paid, process_deposit, overpaid.
data[attributes][tag_list][] array
Case insensitive tag list.
data[attributes][tax_region_id] uuid
The associated tax region.

Includes

This request accepts the following includes:

customer

order

tax_region

lines => item => photo

tax_values

coupon

Update a document

How to update a document:

  curl --request PUT
       --url 'https://example.booqable.com/api/boomerang/documents/6b8e0c59-4b01-42e6-8477-bbfa4cea11f3'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "id": "6b8e0c59-4b01-42e6-8477-bbfa4cea11f3",
           "type": "documents",
           "attributes": {
             "name": "Jane Doe"
           }
         }
       }'

A 200 status response looks like this:

  {
    "data": {
      "id": "6b8e0c59-4b01-42e6-8477-bbfa4cea11f3",
      "type": "documents",
      "attributes": {
        "created_at": "2016-09-18T03:33:01.000000+00:00",
        "updated_at": "2016-09-18T03:33:01.000000+00:00",
        "archived": false,
        "archived_at": null,
        "document_type": "invoice",
        "number": null,
        "prefix": null,
        "prefix_with_number": null,
        "date": null,
        "due_date": null,
        "name": "Jane Doe",
        "address": null,
        "body": null,
        "footer": "",
        "reference": null,
        "revised": false,
        "finalized": false,
        "sent": false,
        "confirmed": false,
        "status": "payment_due",
        "signature_url": null,
        "deposit_type": "percentage",
        "deposit_value": 10.0,
        "tag_list": [],
        "price_in_cents": 80250,
        "grand_total_in_cents": 72225,
        "grand_total_with_tax_in_cents": 87392,
        "discount_in_cents": 8025,
        "coupon_discount_in_cents": 0,
        "total_discount_in_cents": 8025,
        "deposit_in_cents": 10000,
        "deposit_paid_in_cents": 0,
        "deposit_refunded_in_cents": 0,
        "deposit_held_in_cents": 0,
        "deposit_to_refund_in_cents": 0,
        "to_be_paid_in_cents": 97392,
        "paid_in_cents": 0,
        "tax_in_cents": 15167,
        "discount_percentage": 10.0,
        "order_id": "6952ae61-0c41-4a20-8379-52f56e41884c",
        "customer_id": "da876af0-82ef-4a18-8e51-86680fba81bc",
        "tax_region_id": null,
        "coupon_id": null
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

PUT /api/boomerang/documents/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[documents]=created_at,updated_at,archived
include string
List of comma seperated relationships to sideload. ?include=customer,order,tax_region

Request body

This request accepts the following body:

Name Description
data[attributes][address] string
Customer Address. If left blank, automatically populated with the customer address of the associated order.
data[attributes][body] string
Custom content displayed on a document, agreement details on a contract, for instance. Applicable to quote and contract. Populated with setting {document_type}.body, but can also be overridden for a specific document.
data[attributes][confirmed] boolean
Whether document is confirmed, applies to quote and contract.
data[attributes][coupon_id] uuid
The associated coupon.
data[attributes][customer_id] uuid
The associated customer.
data[attributes][date] date
Date the document was finalized.
data[attributes][deposit_type] enum
Kind of deposit added.
One of: none, percentage_total, percentage, fixed.
data[attributes][deposit_value] float
The value to use for deposit_type.
data[attributes][discount_percentage] float
The discount percentage applied to this order.
data[attributes][document_type] enum
Type of document.
One of: invoice, contract, quote.
data[attributes][due_date] date
The latest date by which the invoice must be fully paid.
data[attributes][finalized] boolean
Whether document is finalized (quote and contract are always finalized).
data[attributes][footer] string
The footer of a document. Populated with setting {document_type}.footer, but can also be overridden for a specific document.
data[attributes][name] string
Customer name. If left blank, automatically populated with the customer name of the associated order.
data[attributes][number] integer
The document number, must be unique per type. Automatically generated if left blank.
data[attributes][order_id] uuid
The order this document is for.
data[attributes][prefix] string
Add a prefix to document numbers to make it easier to identify different documents. You can add dynamic values (like a year or order number) and custom prefixes e.g. {year}-{customer_number}.
data[attributes][reference] string
A project number or other reference.
data[attributes][revised] boolean
Whether document is revised (applies only to invoice).
data[attributes][sent] boolean
Whether document is sent (with Booqable).
data[attributes][status] enum
Status (possible values depend on document type).
One of: confirmed, unconfirmed, revised, partially_paid, payment_due, paid, process_deposit, overpaid.
data[attributes][tag_list][] array
Case insensitive tag list.
data[attributes][tax_region_id] uuid
The associated tax region.

Includes

This request accepts the following includes:

customer

order

tax_region

lines => item => photo

tax_values

coupon

Archive a document

When archiving an invoice make sure delete_invoices permission is enabled.

How to archive a document:

  curl --request DELETE
       --url 'https://example.booqable.com/api/boomerang/documents/e00df330-8241-466f-8706-d2db3d03494d'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": {
      "id": "e00df330-8241-466f-8706-d2db3d03494d",
      "type": "documents",
      "attributes": {
        "created_at": "2018-05-06T00:22:02.000000+00:00",
        "updated_at": "2018-05-06T00:22:02.000000+00:00",
        "archived": true,
        "archived_at": "2018-05-06T00:22:02.000000+00:00",
        "document_type": "invoice",
        "number": null,
        "prefix": null,
        "prefix_with_number": null,
        "date": null,
        "due_date": null,
        "name": "John Doe",
        "address": null,
        "body": null,
        "footer": "",
        "reference": null,
        "revised": false,
        "finalized": false,
        "sent": false,
        "confirmed": false,
        "status": "payment_due",
        "signature_url": null,
        "deposit_type": "percentage",
        "deposit_value": 10.0,
        "tag_list": [],
        "price_in_cents": 80250,
        "grand_total_in_cents": 72225,
        "grand_total_with_tax_in_cents": 87392,
        "discount_in_cents": 8025,
        "coupon_discount_in_cents": 0,
        "total_discount_in_cents": 8025,
        "deposit_in_cents": 10000,
        "deposit_paid_in_cents": 0,
        "deposit_refunded_in_cents": 0,
        "deposit_held_in_cents": 0,
        "deposit_to_refund_in_cents": 0,
        "to_be_paid_in_cents": 97392,
        "paid_in_cents": 0,
        "tax_in_cents": 15167,
        "discount_percentage": 10.0,
        "order_id": "9253db70-5ed8-44a6-8d0b-f1af78e021fe",
        "customer_id": "3af62bd7-4635-4714-8680-79d8e23ec549",
        "tax_region_id": null,
        "coupon_id": null
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

DELETE /api/boomerang/documents/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[documents]=created_at,updated_at,archived

Includes

This request does not accept any includes

Emails

Emails allow you to easily communicate with your customers by using optional templates. Booqable keeps a history of e-mail being sent for orders or customers.

Relationships

Name Description
customer Customer required
Customer this email is associated with. Attributes from this order are available when rendering the template.
email_template Email template required
The template used to generate this email.
employee Employee required
Employee who sent the email.
order Order required
The order this email is associated with. Attributes from this order are available when rendering the template.

Check matching attributes under Fields to see which relations can be written.
Check each individual operation to see which relations can be included as a sideload.

Fields

Name Description
body string
Email body.
created_at datetime readonly
When the email was created by the user, or automatically by Booqable. At this time, the email has not been sent yet.
customer_id uuid readonly-after-create
Customer this email is associated with. Attributes from this order are available when rendering the template.
document_ids array
Documents to send as attachments to the email.
email_template_id uuid readonly-after-create
The template used to generate this email.
employee_id uuid readonly
Employee who sent the email.
has_error boolean readonly
Whether any errors occur when sending this email.
id uuid readonly
Primary key.
order_id uuid readonly-after-create
The order this email is associated with. Attributes from this order are available when rendering the template.
recipients string
Comma seperated list of recipient email addresses, all addresses must be valid for the email to send.
sent boolean readonly
Whether the email was sent successfully.
subject string
Email subject.
updated_at datetime readonly
The last time the email was updated. Typically this is updated after a delivery attempt has failed.

List emails

How to fetch a list of emails:

  curl --get 'https://example.booqable.com/api/boomerang/emails'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "b882543c-57cc-4fcf-8a1e-dc471e664ac4",
        "type": "emails",
        "attributes": {
          "created_at": "2016-11-24T02:24:00.000000+00:00",
          "updated_at": "2016-11-24T02:24:00.000000+00:00",
          "subject": "Order confirmation",
          "body": "We hereby confirm your order with number #123",
          "recipients": "[email protected]",
          "has_error": false,
          "sent": false,
          "document_ids": [],
          "order_id": null,
          "customer_id": "878c23b8-3fa0-44b1-856f-7fd95560fabc",
          "email_template_id": null,
          "employee_id": null
        },
        "relationships": {}
      }
    ],
    "meta": {}
  }

How to fetch a list of emails for a specific order:

  curl --get 'https://example.booqable.com/api/boomerang/emails'
       --header 'content-type: application/json'
       --data-urlencode 'filter[order_id]=f97ca4a9-7d59-46d9-8df1-6cc7dae11393'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "a1b5a25c-bd16-4249-8052-72ebda9c133d",
        "type": "emails",
        "attributes": {
          "created_at": "2024-08-21T09:09:01.000000+00:00",
          "updated_at": "2024-08-21T09:09:01.000000+00:00",
          "subject": "Order confirmation",
          "body": "We hereby confirm your order with number #123",
          "recipients": "[email protected]",
          "has_error": false,
          "sent": false,
          "document_ids": [],
          "order_id": "f97ca4a9-7d59-46d9-8df1-6cc7dae11393",
          "customer_id": "659dbd01-2c4c-42b8-890e-afe1f60d29ec",
          "email_template_id": null,
          "employee_id": null
        },
        "relationships": {}
      }
    ],
    "meta": {}
  }

HTTP Request

GET /api/boomerang/emails

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[emails]=created_at,updated_at,subject
filter hash
The filters to apply ?filter[attribute][eq]=value
include string
List of comma seperated relationships to sideload. ?include=customer,order
meta hash
Metadata to send along. ?meta[total][]=count
page[number] string
The page to request.
page[size] string
The amount of items per page.
sort string
How to sort the data. ?sort=attribute1,-attribute2

Filters

This request can be filtered on:

Name Description
created_at datetime
eq, not_eq, gt, gte, lt, lte
customer_id uuid
eq, not_eq
email_template_id uuid
eq, not_eq
employee_id uuid
eq, not_eq
has_error boolean
eq
id uuid
eq, not_eq
order_id uuid
eq, not_eq
sent boolean
eq
updated_at datetime
eq, not_eq, gt, gte, lt, lte

Meta

Results can be aggregated on:

Name Description
has_error array
count
total array
count

Includes

This request accepts the following includes:

customer

order

Create and sending an email

How to create and send an email:

  curl --request POST
       --url 'https://example.booqable.com/api/boomerang/emails'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "type": "emails",
           "attributes": {
             "recipients": "[email protected],[email protected]",
             "subject": "Order confirmation",
             "body": "Hi {{customer.name}}",
             "email_template_id": "4b2e6043-c307-4b1c-8f2d-872b85d20fc4",
             "order_id": "c504d320-966c-4b0d-88fb-9490bc6483e5",
             "customer_id": "c353e670-ad55-43ad-803b-3e12456726de",
             "document_ids": [
               "b308505b-b1cb-485c-8d0e-7d937d2f38a5"
             ]
           }
         }
       }'

A 201 status response looks like this:

  {
    "data": {
      "id": "b0779013-b390-48c6-8286-123716b0a3e1",
      "type": "emails",
      "attributes": {
        "created_at": "2025-09-16T16:16:01.000000+00:00",
        "updated_at": "2025-09-16T16:16:01.000000+00:00",
        "subject": "Order confirmation",
        "body": "Hi {{customer.name}}",
        "recipients": "[email protected],[email protected]",
        "has_error": false,
        "sent": false,
        "document_ids": [
          "b308505b-b1cb-485c-8d0e-7d937d2f38a5"
        ],
        "order_id": "c504d320-966c-4b0d-88fb-9490bc6483e5",
        "customer_id": "c353e670-ad55-43ad-803b-3e12456726de",
        "email_template_id": "4b2e6043-c307-4b1c-8f2d-872b85d20fc4",
        "employee_id": "1a34d41c-d99a-49de-8090-cb632e9ef172"
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

POST /api/boomerang/emails

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[emails]=created_at,updated_at,subject
include string
List of comma seperated relationships to sideload. ?include=customer,order,email_template

Request body

This request accepts the following body:

Name Description
data[attributes][body] string
Email body.
data[attributes][customer_id] uuid
Customer this email is associated with. Attributes from this order are available when rendering the template.
data[attributes][document_ids][] array
Documents to send as attachments to the email.
data[attributes][email_template_id] uuid
The template used to generate this email.
data[attributes][order_id] uuid
The order this email is associated with. Attributes from this order are available when rendering the template.
data[attributes][recipients] string
Comma seperated list of recipient email addresses, all addresses must be valid for the email to send.
data[attributes][subject] string
Email subject.

Includes

This request accepts the following includes:

customer

order

email_template

Email templates

Email templates allow for creating pre-filled emails with dynamic data. Booqable comes with a couple of default templates which can be updated but not deleted.

For more information about using variables for dynamic data in e-mail templates see our help center

Fields

Name Description
automated boolean readonly
When true, this template is used by built-in features and can not be deleted. Updating is possible.
body string
Email body template.
context enum
Which resource or process the template applies to.
One of: order, invoice, document, all, payment, user.
created_at datetime readonly
When the resource was created.
default boolean readonly
Whether this is a system default template.
id uuid readonly
Primary key.
identifier string readonly
A unique identifier assigned to this template.
name string
Name of the template.
subject string
Email subject line template.
updated_at datetime readonly
When the resource was last updated.

List email templates

How to fetch a list of email templates:

  curl --get 'https://example.booqable.com/api/boomerang/email_templates'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "e0a7c360-45c6-4a04-81c5-8886d3aeb275",
        "type": "email_templates",
        "attributes": {
          "created_at": "2018-07-14T00:07:00.000000+00:00",
          "updated_at": "2018-07-14T00:07:00.000000+00:00",
          "name": "Webshop confirmation",
          "identifier": "webshop_confirmation",
          "subject": "We received your order",
          "context": "all",
          "body": "We'll get started on it right away",
          "default": false,
          "automated": false
        }
      }
    ],
    "meta": {}
  }

HTTP Request

GET /api/boomerang/email_templates

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[email_templates]=created_at,updated_at,name
filter hash
The filters to apply ?filter[attribute][eq]=value
meta hash
Metadata to send along. ?meta[total][]=count
page[number] string
The page to request.
page[size] string
The amount of items per page.
sort string
How to sort the data. ?sort=attribute1,-attribute2

Filters

This request can be filtered on:

Name Description
automated boolean
eq
context enum
eq
created_at datetime
eq, not_eq, gt, gte, lt, lte
default boolean
eq
id uuid
eq, not_eq
identifier string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
name string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
updated_at datetime
eq, not_eq, gt, gte, lt, lte

Meta

Results can be aggregated on:

Name Description
total array
count

Includes

This request does not accept any includes

Fetch an email template

How to fetch an email template:

  curl --get 'https://example.booqable.com/api/boomerang/email_templates/95b3a72d-9c05-4c26-8679-d2ecd5ff2739'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": {
      "id": "95b3a72d-9c05-4c26-8679-d2ecd5ff2739",
      "type": "email_templates",
      "attributes": {
        "created_at": "2023-09-05T22:46:01.000000+00:00",
        "updated_at": "2023-09-05T22:46:01.000000+00:00",
        "name": "Webshop confirmation",
        "identifier": "webshop_confirmation",
        "subject": "We received your order",
        "context": "all",
        "body": "We'll get started on it right away",
        "default": false,
        "automated": false
      }
    },
    "meta": {}
  }

HTTP Request

GET /api/boomerang/email_templates/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[email_templates]=created_at,updated_at,name
include string
List of comma seperated relationships to sideload. ?include=emails

Includes

This request accepts the following includes:

emails

Create an email template

How to create a email template:

  curl --request POST
       --url 'https://example.booqable.com/api/boomerang/email_templates'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "type": "email_templates",
           "attributes": {
             "name": "Webshop confirmation",
             "subject": "We received your order (#{{order.number}})",
             "body": "We'll get started on it right away. Your order number is #{{order.number}}.",
             "context": "order"
           }
         }
       }'

A 201 status response looks like this:

  {
    "data": {
      "id": "fdb97b9d-4542-44dc-856e-510228b6d83a",
      "type": "email_templates",
      "attributes": {
        "created_at": "2019-09-07T19:36:01.000000+00:00",
        "updated_at": "2019-09-07T19:36:01.000000+00:00",
        "name": "Webshop confirmation",
        "identifier": "webshop_confirmation",
        "subject": "We received your order (#{{order.number}})",
        "context": "order",
        "body": "We'll get started on it right away. Your order number is #{{order.number}}.",
        "default": false,
        "automated": false
      }
    },
    "meta": {}
  }

HTTP Request

POST /api/boomerang/email_templates

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[email_templates]=created_at,updated_at,name

Request body

This request accepts the following body:

Name Description
data[attributes][body] string
Email body template.
data[attributes][context] enum
Which resource or process the template applies to.
One of: order, invoice, document, all, payment, user.
data[attributes][name] string
Name of the template.
data[attributes][subject] string
Email subject line template.

Includes

This request does not accept any includes

Update an email template

How to update an email template:

  curl --request PUT
       --url 'https://example.booqable.com/api/boomerang/email_templates/8cc919ef-bada-48fa-8d22-1ee523f0e88f'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "id": "8cc919ef-bada-48fa-8d22-1ee523f0e88f",
           "type": "email_templates",
           "attributes": {
             "name": "Order confirmation"
           }
         }
       }'

A 200 status response looks like this:

  {
    "data": {
      "id": "8cc919ef-bada-48fa-8d22-1ee523f0e88f",
      "type": "email_templates",
      "attributes": {
        "created_at": "2027-11-19T06:26:00.000000+00:00",
        "updated_at": "2027-11-19T06:26:00.000000+00:00",
        "name": "Order confirmation",
        "identifier": "webshop_confirmation",
        "subject": "We received your order",
        "context": "all",
        "body": "We'll get started on it right away",
        "default": false,
        "automated": false
      }
    },
    "meta": {}
  }

How to update a default email template:

  curl --request PUT
       --url 'https://example.booqable.com/api/boomerang/email_templates/f4304c84-6349-470c-875b-7bc8ac0dd626'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "id": "f4304c84-6349-470c-875b-7bc8ac0dd626",
           "type": "email_templates",
           "attributes": {
             "name": "Order confirmation"
           }
         }
       }'

A 200 status response looks like this:

  {
    "data": {
      "id": "f4304c84-6349-470c-875b-7bc8ac0dd626",
      "type": "email_templates",
      "attributes": {
        "created_at": "2017-06-27T23:42:00.000000+00:00",
        "updated_at": "2017-06-27T23:42:00.000000+00:00",
        "name": "Order confirmation",
        "identifier": "webshop_confirmation",
        "subject": "We received your order",
        "context": "all",
        "body": "We'll get started on it right away",
        "default": true,
        "automated": false
      }
    },
    "meta": {}
  }

HTTP Request

PUT /api/boomerang/email_templates/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[email_templates]=created_at,updated_at,name

Request body

This request accepts the following body:

Name Description
data[attributes][body] string
Email body template.
data[attributes][context] enum
Which resource or process the template applies to.
One of: order, invoice, document, all, payment, user.
data[attributes][name] string
Name of the template.
data[attributes][subject] string
Email subject line template.

Includes

This request does not accept any includes

Delete an email template

How to delete a email template:

  curl --request DELETE
       --url 'https://example.booqable.com/api/boomerang/email_templates/1353d9c3-b214-4b45-8153-505e3ab4d573'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": {
      "id": "1353d9c3-b214-4b45-8153-505e3ab4d573",
      "type": "email_templates",
      "attributes": {
        "created_at": "2019-10-07T17:21:00.000000+00:00",
        "updated_at": "2019-10-07T17:21:00.000000+00:00",
        "name": "Sales Tax",
        "identifier": "sales_tax",
        "subject": "This is a subject!",
        "context": "all",
        "body": "Hi there user!",
        "default": false,
        "automated": false
      }
    },
    "meta": {}
  }

HTTP Request

DELETE /api/boomerang/email_templates/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[email_templates]=created_at,updated_at,name

Includes

This request does not accept any includes

Employees

Employees give access to a Booqable account. You can set different permissions for each employee and let other people use Booqable without giving them access to sensitive information.

Employees also allow you to streamline Booqable's interface for specific roles or use cases. For example, if you create an account for someone dedicated to looking after your financials and accounting, it wouldn't need to manage your products and stock levels.

Fields

Name Description
active boolean
Whether this employee is active (counts towards billing).
allowed_session_id string
Allowed session id.
avatar_base64 string writeonly
Base64 encoded avatar.
avatar_url string readonly
Url to avatar.
confirmed boolean readonly
Whether this employee confirmed it's email address.
created_at datetime readonly
When the resource was created.
current_password string writeonly
Current password, needed to update password or email address.
deactivated_at datetime writeonly
Employee deactivation date.
email string
Employee's e-mail address.
firstname string
First name of the employee.
has_two_factor_autentication boolean readonly
Whether two factor authentication is enabled.
id uuid readonly
Primary key.
large_avatar_url string readonly
Url to avatar (Large).
lastname string
Last name of the employee.
locale string
Locale of the employee, used as application locale.
name string readonly
Full name of the employee.
owner boolean readonly
Whether this employee is the account owner.
password string writeonly
Set a new password.
password_confirmation string writeonly
Confirm new password.
permissions array
Zero or more from: reports, products, settings, security_settings, account, exports, cancel_orders, revert_orders, delete_invoices, make_invoice_revisions, override_rental_period. All permissions are always returned when the roles & permissions feature is not included in the current pricing plan or if the employee is the account owner.
remove_avatar boolean writeonly
Remove current avatar.
third_party_id string
ID used for third party tools.
time_to_confirm integer readonly
Time in days left to confirm.
unconfirmed_email string readonly
Unconfirmed e-mail address if present.
updated_at datetime readonly
When the resource was last updated.
viewed_whats_new_at datetime
Date when this employee viewed product updates for the last time.

List employees

How to fetch a list of employees:

  curl --get 'https://example.booqable.com/api/boomerang/employees'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "9e27ff9f-0909-42c7-81b2-3bb9f34ad507",
        "type": "employees",
        "attributes": {
          "created_at": "2021-09-07T07:00:00.000000+00:00",
          "updated_at": "2023-07-29T03:51:00.000000+00:00",
          "name": "John Doe",
          "firstname": "John",
          "lastname": "Doe",
          "locale": null,
          "email": "[email protected]",
          "unconfirmed_email": null,
          "viewed_whats_new_at": "2023-06-07T12:19:00.000000+00:00",
          "active": true,
          "owner": true,
          "confirmed": true,
          "time_to_confirm": 0,
          "permissions": [
            "reports",
            "products",
            "settings",
            "security_settings",
            "account",
            "exports",
            "cancel_orders",
            "revert_orders",
            "delete_invoices",
            "make_invoice_revisions",
            "override_rental_period"
          ],
          "has_two_factor_autentication": false,
          "allowed_session_id": null,
          "avatar_url": "https://gravatar.com/avatar/f3eb64211cf620aa291957f1f66d5f39.png?d=404",
          "large_avatar_url": "https://gravatar.com/avatar/f3eb64211cf620aa291957f1f66d5f39.png?d=mm&size=200",
          "third_party_id": "9e27ff9f-0909-42c7-81b2-3bb9f34ad507-1679574840"
        }
      }
    ],
    "meta": {}
  }

HTTP Request

GET /api/boomerang/employees

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[employees]=created_at,updated_at,name
filter hash
The filters to apply ?filter[attribute][eq]=value
meta hash
Metadata to send along. ?meta[total][]=count
page[number] string
The page to request.
page[size] string
The amount of items per page.
sort string
How to sort the data. ?sort=attribute1,-attribute2

Filters

This request can be filtered on:

Name Description
active boolean
eq
confirmed boolean
eq
created_at datetime
eq, not_eq, gt, gte, lt, lte
deactivated_at datetime
eq, not_eq, gt, gte, lt, lte
email string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
id uuid
eq, not_eq
locale string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
owner boolean
eq
third_party_id string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
updated_at datetime
eq, not_eq, gt, gte, lt, lte

Meta

Results can be aggregated on:

Name Description
total array
count

Includes

This request does not accept any includes

Fetch an employee

How to fetch a employee:

  curl --get 'https://example.booqable.com/api/boomerang/employees/4c367dac-4839-49f3-89e4-ff584a1f30e0'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": {
      "id": "4c367dac-4839-49f3-89e4-ff584a1f30e0",
      "type": "employees",
      "attributes": {
        "created_at": "2015-05-14T01:40:00.000000+00:00",
        "updated_at": "2017-01-20T23:07:00.000000+00:00",
        "name": "John Doe",
        "firstname": "John",
        "lastname": "Doe",
        "locale": null,
        "email": "[email protected]",
        "unconfirmed_email": null,
        "viewed_whats_new_at": "2017-02-10T06:59:00.000000+00:00",
        "active": true,
        "owner": true,
        "confirmed": true,
        "time_to_confirm": 0,
        "permissions": [
          "reports",
          "products",
          "settings",
          "security_settings",
          "account",
          "exports",
          "cancel_orders",
          "revert_orders",
          "delete_invoices",
          "make_invoice_revisions",
          "override_rental_period"
        ],
        "has_two_factor_autentication": false,
        "allowed_session_id": null,
        "avatar_url": "https://gravatar.com/avatar/b9e4d02e55a6d091223dfb568620be4b.png?d=404",
        "large_avatar_url": "https://gravatar.com/avatar/b9e4d02e55a6d091223dfb568620be4b.png?d=mm&size=200",
        "third_party_id": "4c367dac-4839-49f3-89e4-ff584a1f30e0-1679574840"
      }
    },
    "meta": {}
  }

HTTP Request

GET /api/boomerang/employees/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[employees]=created_at,updated_at,name

Includes

This request does not accept any includes

Update an employee

How to update an employee:

  curl --request PUT
       --url 'https://example.booqable.com/api/boomerang/employees/cebcf411-1b2a-402f-8d77-43c67daf282f'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "id": "cebcf411-1b2a-402f-8d77-43c67daf282f",
           "type": "employees",
           "attributes": {
             "firstname": "Jane"
           }
         }
       }'

A 200 status response looks like this:

  {
    "data": {
      "id": "cebcf411-1b2a-402f-8d77-43c67daf282f",
      "type": "employees",
      "attributes": {
        "created_at": "2016-10-03T04:30:00.000000+00:00",
        "updated_at": "2021-10-23T16:21:00.000000+00:00",
        "name": "Jane Doe",
        "firstname": "Jane",
        "lastname": "Doe",
        "locale": null,
        "email": "[email protected]",
        "unconfirmed_email": null,
        "viewed_whats_new_at": "2021-07-24T23:16:00.000000+00:00",
        "active": true,
        "owner": false,
        "confirmed": true,
        "time_to_confirm": 0,
        "permissions": [
          "reports",
          "products",
          "settings",
          "security_settings",
          "account",
          "exports",
          "cancel_orders",
          "revert_orders",
          "delete_invoices",
          "make_invoice_revisions",
          "override_rental_period"
        ],
        "has_two_factor_autentication": false,
        "allowed_session_id": null,
        "avatar_url": "https://gravatar.com/avatar/716558eb15f1e4801c770410e3eed8fe.png?d=404",
        "large_avatar_url": "https://gravatar.com/avatar/716558eb15f1e4801c770410e3eed8fe.png?d=mm&size=200",
        "third_party_id": "cebcf411-1b2a-402f-8d77-43c67daf282f-1579642440"
      }
    },
    "meta": {}
  }

How to de-activate an employee:

  curl --request PUT
       --url 'https://example.booqable.com/api/boomerang/employees/b40a7c1c-5190-4d54-8cea-405d36944a87'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "id": "b40a7c1c-5190-4d54-8cea-405d36944a87",
           "type": "employees",
           "attributes": {
             "active": false
           }
         }
       }'

A 200 status response looks like this:

  {
    "data": {
      "id": "b40a7c1c-5190-4d54-8cea-405d36944a87",
      "type": "employees",
      "attributes": {
        "created_at": "2014-10-16T17:49:01.000000+00:00",
        "updated_at": "2019-11-06T05:40:01.000000+00:00",
        "name": "John Doe",
        "firstname": "John",
        "lastname": "Doe",
        "locale": null,
        "email": "[email protected]",
        "unconfirmed_email": null,
        "viewed_whats_new_at": "2019-08-07T12:35:01.000000+00:00",
        "active": false,
        "owner": false,
        "confirmed": true,
        "time_to_confirm": 0,
        "permissions": [
          "reports",
          "products",
          "settings",
          "security_settings",
          "account",
          "exports",
          "cancel_orders",
          "revert_orders",
          "delete_invoices",
          "make_invoice_revisions",
          "override_rental_period"
        ],
        "has_two_factor_autentication": false,
        "allowed_session_id": null,
        "avatar_url": "https://gravatar.com/avatar/8a0e879db54c50c14de0c4203a4e7a93.png?d=404",
        "large_avatar_url": "https://gravatar.com/avatar/8a0e879db54c50c14de0c4203a4e7a93.png?d=mm&size=200",
        "third_party_id": "b40a7c1c-5190-4d54-8cea-405d36944a87-1579642440"
      }
    },
    "meta": {}
  }

How to set permissions:

  curl --request PUT
       --url 'https://example.booqable.com/api/boomerang/employees/94b3f0ff-ef32-49be-8f5f-7aa6916cc901'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "id": "94b3f0ff-ef32-49be-8f5f-7aa6916cc901",
           "type": "employees",
           "attributes": {
             "permissions": [
               "reports",
               "settings"
             ]
           }
         }
       }'

A 200 status response looks like this:

  {
    "data": {
      "id": "94b3f0ff-ef32-49be-8f5f-7aa6916cc901",
      "type": "employees",
      "attributes": {
        "created_at": "2027-04-16T02:37:01.000000+00:00",
        "updated_at": "2032-05-05T14:28:01.000000+00:00",
        "name": "John Doe",
        "firstname": "John",
        "lastname": "Doe",
        "locale": null,
        "email": "[email protected]",
        "unconfirmed_email": null,
        "viewed_whats_new_at": "2032-02-04T21:23:01.000000+00:00",
        "active": true,
        "owner": false,
        "confirmed": true,
        "time_to_confirm": 0,
        "permissions": [
          "reports",
          "settings"
        ],
        "has_two_factor_autentication": false,
        "allowed_session_id": null,
        "avatar_url": "https://gravatar.com/avatar/ae75ea2be6c7d7aa987d98145aa7618c.png?d=404",
        "large_avatar_url": "https://gravatar.com/avatar/ae75ea2be6c7d7aa987d98145aa7618c.png?d=mm&size=200",
        "third_party_id": "94b3f0ff-ef32-49be-8f5f-7aa6916cc901-1579642440"
      }
    },
    "meta": {}
  }

HTTP Request

PUT /api/boomerang/employees/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[employees]=created_at,updated_at,name

Request body

This request accepts the following body:

Name Description
data[attributes][active] boolean
Whether this employee is active (counts towards billing).
data[attributes][allowed_session_id] string
Allowed session id.
data[attributes][avatar_base64] string
Base64 encoded avatar.
data[attributes][current_password] string
Current password, needed to update password or email address.
data[attributes][deactivated_at] datetime
Employee deactivation date.
data[attributes][email] string
Employee's e-mail address.
data[attributes][firstname] string
First name of the employee.
data[attributes][lastname] string
Last name of the employee.
data[attributes][locale] string
Locale of the employee, used as application locale.
data[attributes][password] string
Set a new password.
data[attributes][password_confirmation] string
Confirm new password.
data[attributes][permissions][] array
Zero or more from: reports, products, settings, security_settings, account, exports, cancel_orders, revert_orders, delete_invoices, make_invoice_revisions, override_rental_period. All permissions are always returned when the roles & permissions feature is not included in the current pricing plan or if the employee is the account owner.
data[attributes][remove_avatar] boolean
Remove current avatar.
data[attributes][third_party_id] string
ID used for third party tools.
data[attributes][viewed_whats_new_at] datetime
Date when this employee viewed product updates for the last time.

Includes

This request does not accept any includes

Employee invitations

Employees give access to a Booqable account. You can invite employees by sending an invitation. For more info about employees see Employees.

Relationships

Name Description
employee Employee optional
The employee that is invited.

Check matching attributes under Fields to see which relations can be written.
Check each individual operation to see which relations can be included as a sideload.

Fields

Name Description
email string writeonly
Employee's e-mail address.
employee_id uuid nullable
The employee that is invited.
firstname string writeonly
First name of the employee.
id uuid
Specify employee ID to re-send invitation.
lastname string writeonly
Last name of the employee.
permissions array[string] writeonly
Zero or more from: reports, products, settings, security_settings, account, exports, cancel_orders, revert_orders, delete_invoices, make_invoice_revisions, override_rental_period.

Send invitations

How to create an invitation:

  curl --request POST
       --url 'https://example.booqable.com/api/boomerang/employee_invitations'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "type": "employee_invitations",
           "attributes": {
             "firstname": "John",
             "lastname": "Doe",
             "email": "[email protected]"
           }
         },
         "include": "employee"
       }'

A 201 status response looks like this:

  {
    "data": {
      "id": "bb80bf32-f049-4ea9-8090-006821195ab4",
      "type": "employee_invitations",
      "attributes": {
        "employee_id": "1ccdaa36-f317-4feb-8a06-003668fc0c59"
      },
      "relationships": {
        "employee": {
          "data": {
            "type": "employees",
            "id": "1ccdaa36-f317-4feb-8a06-003668fc0c59"
          }
        }
      }
    },
    "included": [
      {
        "id": "1ccdaa36-f317-4feb-8a06-003668fc0c59",
        "type": "employees",
        "attributes": {
          "created_at": "2020-01-26T19:11:05.000000+00:00",
          "updated_at": "2020-01-26T19:11:05.000000+00:00",
          "name": "John Doe",
          "firstname": "John",
          "lastname": "Doe",
          "locale": null,
          "email": "[email protected]",
          "unconfirmed_email": null,
          "viewed_whats_new_at": "2020-01-26T19:11:05.000000+00:00",
          "active": true,
          "owner": false,
          "confirmed": false,
          "time_to_confirm": 0,
          "permissions": [],
          "has_two_factor_autentication": false,
          "allowed_session_id": null,
          "avatar_url": "https://gravatar.com/avatar/31ff5e6c9b0f2e3b5d27340dd84e003a.png?d=404",
          "large_avatar_url": "https://gravatar.com/avatar/31ff5e6c9b0f2e3b5d27340dd84e003a.png?d=mm&size=200",
          "third_party_id": "1ccdaa36-f317-4feb-8a06-003668fc0c59-1739179516"
        }
      }
    ],
    "meta": {}
  }

To re-send an invitation we supply the ID the employee for which the invitation was sent. Note that you can also update other fields.:

  curl --request POST
       --url 'https://example.booqable.com/api/boomerang/employee_invitations'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "type": "employee_invitations",
           "attributes": {
             "id": "a5f55cdd-7e5a-46ea-84db-1c8352c8fa06",
             "email": "[email protected]"
           }
         },
         "include": "employee"
       }'

A 201 status response looks like this:

  {
    "data": {
      "id": "a5f55cdd-7e5a-46ea-84db-1c8352c8fa06",
      "type": "employee_invitations",
      "attributes": {
        "employee_id": "a5f55cdd-7e5a-46ea-84db-1c8352c8fa06"
      },
      "relationships": {
        "employee": {
          "data": {
            "type": "employees",
            "id": "a5f55cdd-7e5a-46ea-84db-1c8352c8fa06"
          }
        }
      }
    },
    "included": [
      {
        "id": "a5f55cdd-7e5a-46ea-84db-1c8352c8fa06",
        "type": "employees",
        "attributes": {
          "created_at": "2020-05-11T21:58:00.000000+00:00",
          "updated_at": "2020-05-11T21:58:00.000000+00:00",
          "name": "John Doe",
          "firstname": "John",
          "lastname": "Doe",
          "locale": null,
          "email": "[email protected]",
          "unconfirmed_email": null,
          "viewed_whats_new_at": "2020-05-11T21:58:00.000000+00:00",
          "active": true,
          "owner": true,
          "confirmed": true,
          "time_to_confirm": 0,
          "permissions": [
            "reports",
            "products",
            "settings",
            "security_settings",
            "account",
            "exports",
            "cancel_orders",
            "revert_orders",
            "delete_invoices",
            "make_invoice_revisions",
            "override_rental_period"
          ],
          "has_two_factor_autentication": false,
          "allowed_session_id": null,
          "avatar_url": "https://gravatar.com/avatar/98d4e49bbf9d94d0b9c6155e3e6ad46c.png?d=404",
          "large_avatar_url": "https://gravatar.com/avatar/98d4e49bbf9d94d0b9c6155e3e6ad46c.png?d=mm&size=200",
          "third_party_id": "a5f55cdd-7e5a-46ea-84db-1c8352c8fa06-1739179517"
        }
      }
    ],
    "meta": {}
  }

HTTP Request

POST /api/boomerang/employee_invitations

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[employee_invitations]=employee_id
include string
List of comma seperated relationships to sideload. ?include=employee

Request body

This request accepts the following body:

Name Description
data[attributes][email] string
Employee's e-mail address.
data[attributes][employee_id] uuid
The employee that is invited.
data[attributes][firstname] string
First name of the employee.
data[attributes][id] uuid
Specify employee ID to re-send invitation.
data[attributes][lastname] string
Last name of the employee.
data[attributes][permissions] array[string]
Zero or more from: reports, products, settings, security_settings, account, exports, cancel_orders, revert_orders, delete_invoices, make_invoice_revisions, override_rental_period.

Includes

This request accepts the following includes:

employee

Inventory breakdowns

Fetch quantitive information about product inventory compared to the current time, broken down by:

Useful for

Relationships

Name Description
location Location required
The location to which this breakdown record applies.
product Product required
The product whose availability this breakdown record describes.

Check matching attributes under Fields to see which relations can be written.
Check each individual operation to see which relations can be included as a sideload.

Fields

Name Description
from datetime
When the amount of items will be available (only for status expected).
id uuid readonly
Primary key.
inventory_breakdown_type string
One of regular, temporary.
location_id uuid readonly
The location to which this breakdown record applies.
product_id uuid readonly
The product whose availability this breakdown record describes.
started integer
The amount if items that are started for product and location. Only rendered when applicable.
status string
One of expected, in_stock, expired.
stock_count integer
The total amount of stock for product and location.
till datetime
When the amount of items will become unavailable (only for type temporary and/or status expired).

List inventory breakdowns

How to fetch a breakdown of all items in stock:

  curl --get 'https://example.booqable.com/api/boomerang/inventory_breakdowns'
       --header 'content-type: application/json'
       --data-urlencode 'filter[product_group_id]=fc4bfed6-545d-4ffe-8b66-81e8dbde9d4e'
       --data-urlencode 'filter[status]=in_stock'
       --data-urlencode 'stats[inventory_breakdown_type][]=sum'
       --data-urlencode 'stats[started][]=sum'
       --data-urlencode 'stats[status][]=sum'
       --data-urlencode 'stats[stock_count][]=sum'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "4d112455-70ef-47ab-8e13-317982d7a785",
        "type": "inventory_breakdowns",
        "attributes": {
          "stock_count": 100,
          "started": 50,
          "status": "in_stock",
          "inventory_breakdown_type": "regular",
          "location_id": "93539676-0eec-4298-8221-d37c766028c4",
          "product_id": "856d3a4c-8f1c-4392-8837-b1033d097162"
        },
        "relationships": {}
      },
      {
        "id": "cfc74ef9-ca0f-4337-8020-dc4ecddbde48",
        "type": "inventory_breakdowns",
        "attributes": {
          "till": "2020-08-15T02:26:01.000000+00:00",
          "stock_count": 5,
          "started": 0,
          "status": "in_stock",
          "inventory_breakdown_type": "temporary",
          "location_id": "93539676-0eec-4298-8221-d37c766028c4",
          "product_id": "856d3a4c-8f1c-4392-8837-b1033d097162"
        },
        "relationships": {}
      }
    ],
    "meta": {
      "stats": {
        "inventory_breakdown_type": {
          "sum": {
            "regular": 100,
            "temporary": 5
          }
        },
        "started": {
          "sum": 50
        },
        "status": {
          "sum": {
            "in_stock": 105,
            "expected": 17,
            "expired": 22
          }
        },
        "stock_count": {
          "sum": 105
        }
      }
    }
  }

How to fetch a breakdown of all expected items:

  curl --get 'https://example.booqable.com/api/boomerang/inventory_breakdowns'
       --header 'content-type: application/json'
       --data-urlencode 'filter[product_group_id]=3142a9c7-40c2-4dff-8a3d-61aef93400cf'
       --data-urlencode 'filter[status]=expected'
       --data-urlencode 'stats[inventory_breakdown_type][]=sum'
       --data-urlencode 'stats[started][]=sum'
       --data-urlencode 'stats[status][]=sum'
       --data-urlencode 'stats[stock_count][]=sum'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "d6f88a18-89e5-409d-84ae-8e3e2af10659",
        "type": "inventory_breakdowns",
        "attributes": {
          "from": "2017-11-18T03:35:00.000000+00:00",
          "stock_count": 12,
          "status": "expected",
          "inventory_breakdown_type": "regular",
          "location_id": "53f12674-6a2f-4878-804c-eb4dd3aa204f",
          "product_id": "11b3f75f-518c-4e76-8979-2efbc4019818"
        },
        "relationships": {}
      },
      {
        "id": "7f3caf33-119d-43b7-8bd5-8c7bd5de639a",
        "type": "inventory_breakdowns",
        "attributes": {
          "from": "2017-11-18T03:35:00.000000+00:00",
          "till": "2017-12-19T03:35:00.000000+00:00",
          "stock_count": 5,
          "status": "expected",
          "inventory_breakdown_type": "temporary",
          "location_id": "53f12674-6a2f-4878-804c-eb4dd3aa204f",
          "product_id": "11b3f75f-518c-4e76-8979-2efbc4019818"
        },
        "relationships": {}
      }
    ],
    "meta": {
      "stats": {
        "inventory_breakdown_type": {
          "sum": {
            "regular": 12,
            "temporary": 5
          }
        },
        "started": {
          "sum": 0
        },
        "status": {
          "sum": {
            "in_stock": 105,
            "expected": 17,
            "expired": 22
          }
        },
        "stock_count": {
          "sum": 17
        }
      }
    }
  }

How to fetch a breakdown of all expired items:

  curl --get 'https://example.booqable.com/api/boomerang/inventory_breakdowns'
       --header 'content-type: application/json'
       --data-urlencode 'filter[product_group_id]=8d1d8d66-b01e-4300-83da-7418f5acaaea'
       --data-urlencode 'filter[status]=expired'
       --data-urlencode 'stats[inventory_breakdown_type][]=sum'
       --data-urlencode 'stats[started][]=sum'
       --data-urlencode 'stats[status][]=sum'
       --data-urlencode 'stats[stock_count][]=sum'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "b5e5064e-831e-4883-8a71-2e612ddbb495",
        "type": "inventory_breakdowns",
        "attributes": {
          "till": "2022-08-20T18:59:00.000000+00:00",
          "stock_count": 22,
          "status": "expired",
          "inventory_breakdown_type": "temporary",
          "location_id": "8a5cbdf6-c713-419f-868e-14208fd6df91",
          "product_id": "243a8fd8-a17c-4b5e-878c-3e0646778c26"
        },
        "relationships": {}
      }
    ],
    "meta": {
      "stats": {
        "inventory_breakdown_type": {
          "sum": {
            "regular": 0,
            "temporary": 22
          }
        },
        "started": {
          "sum": 0
        },
        "status": {
          "sum": {
            "in_stock": 105,
            "expected": 17,
            "expired": 22
          }
        },
        "stock_count": {
          "sum": 22
        }
      }
    }
  }

HTTP Request

GET /api/boomerang/inventory_breakdowns

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[inventory_breakdowns]=from,till,stock_count
filter hash
The filters to apply ?filter[attribute][eq]=value
include string
List of comma seperated relationships to sideload. ?include=location,product
meta hash
Metadata to send along. ?meta[total][]=count
page[number] string
The page to request.
page[size] string
The amount of items per page.
sort string
How to sort the data. ?sort=attribute1,-attribute2

Filters

This request can be filtered on:

Name Description
inventory_breakdown_type string
eq
location_id uuid
eq
product_group_id uuid
eq
product_id uuid
eq
status string required
eq

Meta

Results can be aggregated on:

Name Description
inventory_breakdown_type array
sum
started array
sum
status array
sum
stock_count array
sum, count
total array
count

Includes

This request accepts the following includes:

location

product => photo

Inventory levels

Inventory levels provide information on item availability. It describes availability, stock counts, and planned quantities for given items.

Relationships

Name Description
item Item required
The item to return data for, this can be a single ID or an array of multiple IDs.
location Location required
The location to filter on.
order Order required
The order to filter on.

Check matching attributes under Fields to see which relations can be written.
Check each individual operation to see which relations can be included as a sideload.

Fields

Name Description
cluster_available integer readonly
The available quantity for the cluster the given location is part of.
cluster_needed integer readonly
The needed quantity for the cluster the given location is part of. This quantity does not contain what has already been returned for an order (planned - stopped).
cluster_plannable integer readonly
The planned quantity for the cluster the given location is part of.
cluster_planned integer readonly
The planned quantity for the cluster the given location is part of.
cluster_stock_count integer readonly
The stock count for the cluster the given location is part of.
id uuid readonly
Primary key.
item_id uuid readonly
The item to return data for, this can be a single ID or an array of multiple IDs.
location_available integer readonly
The available quantity for the given location.
location_id uuid readonly
The location to filter on.
location_needed integer readonly
The needed quantity for the given location. This quantity does not contain what has already been returned for an order (planned - stopped).
location_plannable integer readonly
The number of products that can be planned for the given location.
location_planned integer readonly
The planned quantity for the given location.
location_stock_count integer readonly
The quantity of stock present for the given the location.
order_id uuid readonly
The order to filter on.

Fetch inventory levels for a product

How to fetch inventory levels for a product:

  curl --get 'https://example.booqable.com/api/boomerang/inventory_levels'
       --header 'content-type: application/json'
       --data-urlencode 'filter[from]=2022-01-01 09:00:00'
       --data-urlencode 'filter[item_id]=d4ef30b8-8959-4262-8dcd-d90c23a4ee8a'
       --data-urlencode 'filter[till]=2022-01-02 09:00:00'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "72684141-dea4-42b5-8c69-080d056a0e8c",
        "type": "inventory_levels",
        "attributes": {
          "location_available": 0,
          "location_stock_count": 0,
          "location_plannable": 0,
          "location_planned": 0,
          "location_needed": 0,
          "cluster_available": 0,
          "cluster_stock_count": 0,
          "cluster_plannable": 0,
          "cluster_planned": 0,
          "cluster_needed": 0,
          "item_id": "d4ef30b8-8959-4262-8dcd-d90c23a4ee8a",
          "location_id": "95c73381-5770-48e8-8a43-af7513a32ed9",
          "order_id": null
        },
        "relationships": {}
      }
    ],
    "meta": {}
  }

HTTP Request

GET /api/boomerang/inventory_levels

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[inventory_levels]=location_available,location_stock_count,location_plannable
filter hash
The filters to apply ?filter[attribute][eq]=value
include string
List of comma seperated relationships to sideload. ?include=item,location
meta hash
Metadata to send along. ?meta[total][]=count
page[number] string
The page to request.
page[size] string
The amount of items per page.
sort string
How to sort the data. ?sort=attribute1,-attribute2

Filters

This request can be filtered on:

Name Description
from datetime required
eq
item_id uuid
eq
location_id uuid
eq
order_id uuid
eq
till datetime required
eq

Meta

Results can be aggregated on:

Name Description
total array
count

Includes

This request accepts the following includes:

item

location

Fetch inventory levels for a product for a specific location

How to fetch inventory levels for a product for a specific location:

  curl --get 'https://example.booqable.com/api/boomerang/inventory_levels'
       --header 'content-type: application/json'
       --data-urlencode 'filter[from]=2022-01-01 09:00:00'
       --data-urlencode 'filter[item_id]=f13f0c48-b1bd-48ef-81be-94aba9cee2fc'
       --data-urlencode 'filter[location_id]=fcf25ba2-1c63-4cf3-842b-be17908108c4'
       --data-urlencode 'filter[till]=2022-01-02 09:00:00'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "7f66e4b6-37f8-4f22-8c62-e35634c5ebb5",
        "type": "inventory_levels",
        "attributes": {
          "location_available": 0,
          "location_stock_count": 0,
          "location_plannable": 0,
          "location_planned": 0,
          "location_needed": 0,
          "cluster_available": 0,
          "cluster_stock_count": 0,
          "cluster_plannable": 0,
          "cluster_planned": 0,
          "cluster_needed": 0,
          "item_id": "f13f0c48-b1bd-48ef-81be-94aba9cee2fc",
          "location_id": "fcf25ba2-1c63-4cf3-842b-be17908108c4",
          "order_id": null
        },
        "relationships": {}
      }
    ],
    "meta": {}
  }

HTTP Request

GET /api/boomerang/inventory_levels

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[inventory_levels]=location_available,location_stock_count,location_plannable
filter hash
The filters to apply ?filter[attribute][eq]=value
include string
List of comma seperated relationships to sideload. ?include=item,location
meta hash
Metadata to send along. ?meta[total][]=count
page[number] string
The page to request.
page[size] string
The amount of items per page.
sort string
How to sort the data. ?sort=attribute1,-attribute2

Filters

This request can be filtered on:

Name Description
from datetime required
eq
item_id uuid
eq
location_id uuid
eq
order_id uuid
eq
till datetime required
eq

Meta

Results can be aggregated on:

Name Description
total array
count

Includes

This request accepts the following includes:

item

location

Invoice finalizations

Pro forma invoices are automatically generated and updated when changes are made to an order. The InvoiceFinalizationResource resource allows to request the finalization of the current pro forma invoice. Further changes to the order will trigger a new pro forma invoice to be generated with prorated changes.

Relationships

Name Description
document Document required
The invoice that needs to be finalized.

Check matching attributes under Fields to see which relations can be written.
Check each individual operation to see which relations can be included as a sideload.

Fields

Name Description
document_id uuid
The invoice that needs to be finalized.
id uuid readonly
Primary key.

Finalize invoice

Finalize a pro forma invoice:

  curl --request POST
       --url 'https://example.booqable.com/api/boomerang/invoice_finalizations'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "type": "invoice_finalization",
           "attributes": {
             "document_id": "ef4f4bbd-55b2-4355-8436-74a4dde8fe55"
           }
         }
       }'

A 200 status response looks like this:

  {
    "data": {
      "id": "797e55bb-b625-41fd-876a-c97b5ed135b0",
      "type": "invoice_finalizations",
      "attributes": {
        "document_id": "ef4f4bbd-55b2-4355-8436-74a4dde8fe55"
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

POST /api/boomerang/invoice_finalizations

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[invoice_finalizations]=document_id
include string
List of comma seperated relationships to sideload. ?include=document

Request body

This request accepts the following body:

Name Description
data[attributes][document_id] uuid
The invoice that needs to be finalized.

Includes

This request accepts the following includes:

document => order => documents

Invoice revisions

Revises the last finalized invoice for an order by combining it with the current pro forma invoice and creating a new finalized invoice.

Creating a revision requires that there is a finalized invoice, and that there is a pro forma invoice (i.e. changes must have been made to the order since the last finalized invoice).

Relationships

Name Description
order Order required
The order for which the last invoice needs to be revised.
revised_invoice Document required
The finalized invoice that was revised.
revision_invoice Document required
The replacement invoice that was generated.

Check matching attributes under Fields to see which relations can be written.
Check each individual operation to see which relations can be included as a sideload.

Fields

Name Description
id uuid readonly
Primary key.
order_id uuid
The order for which the last invoice needs to be revised.
revised_invoice_id uuid readonly
The finalized invoice that was revised.
revision_invoice_id uuid readonly
The replacement invoice that was generated.

Revise invoice

Revise a finalized invoice:

  curl --request POST
       --url 'https://example.booqable.com/api/boomerang/invoice_revisions'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "type": "invoice_revisions",
           "attributes": {
             "order_id": "7b026e88-c408-4d9b-8ff7-4dc889f66f8b"
           }
         }
       }'

A 200 status response looks like this:

  {
    "data": {
      "id": "75c7effe-1ae6-409a-8cb4-4003f6e2f901",
      "type": "invoice_revisions",
      "attributes": {
        "order_id": "7b026e88-c408-4d9b-8ff7-4dc889f66f8b",
        "revised_invoice_id": "5c7bff8c-1cec-4027-8049-2d29ac25ee0e",
        "revision_invoice_id": "fcb6ea7b-1d93-482b-828e-ae3ab98226c0"
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

POST /api/boomerang/invoice_revisions

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[invoice_revisions]=order_id,revised_invoice_id,revision_invoice_id
include string
List of comma seperated relationships to sideload. ?include=order,revised_invoice,revision_invoice

Request body

This request accepts the following body:

Name Description
data[attributes][order_id] uuid
The order for which the last invoice needs to be revised.

Includes

This request accepts the following includes:

order

revised_invoice

revision_invoice

Item prices

Allows you to calculate pricing for an item based on parameters.

You can calculate a price in a couple ways:

Relationships

Name Description
item Item required
Required, the item or items to calculate price for.
price_ruleset Price ruleset required
The advanced pricing rules the apply.
price_structure Price structure required
Optional price structure to use, if the item has a price structure associated with it that will be used by default.
price_tile Price tile required
The price tile that was selected from the price strucure.

Check matching attributes under Fields to see which relations can be written.
Check each individual operation to see which relations can be included as a sideload.

Fields

Name Description
charge_label string readonly
Label for the charge period.
charge_length integer
Length of charge period in seconds.
from datetime
Start of charge period.
id uuid readonly
Primary key.
item_id uuid
Required, the item or items to calculate price for.
original_charge_label string readonly
Label of charge period before charge rules are applied.
original_charge_length integer readonly
Length of charge period before charge rules are applied.
original_price_each_in_cents integer readonly
Price per item before charge rules are applied.
price_each_in_cents integer readonly
Final price per item.
price_rule_values hash readonly
What price rules were applied.
price_ruleset_id uuid
The advanced pricing rules the apply.
price_structure_id uuid
Optional price structure to use, if the item has a price structure associated with it that will be used by default.
price_tile_id uuid readonly
The price tile that was selected from the price strucure.
till datetime
End of charge period.

Calculate the price of products and/or bundles

Calculating price for a period:

  curl --get 'https://example.booqable.com/api/boomerang/item_prices'
       --header 'content-type: application/json'
       --data-urlencode 'filter[from]=2030-01-01 12:00:00 UTC'
       --data-urlencode 'filter[item_id][]=6a8292cc-4002-4f8e-8da2-1e182dbacc08'
       --data-urlencode 'filter[item_id][]=6ac6ad52-9587-4088-8fd8-af88a9295a8e'
       --data-urlencode 'filter[till]=2030-01-14 12:00:00 UTC'
       --data-urlencode 'include=item'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "7d3ef505-b175-4f03-8151-9d77c4e8d823",
        "type": "item_prices",
        "attributes": {
          "item_id": "6a8292cc-4002-4f8e-8da2-1e182dbacc08",
          "from": "2028-03-25T10:11:00.000000+00:00",
          "till": "2028-04-07T10:11:00.000000+00:00",
          "original_charge_length": 1123200,
          "charge_length": 1123200,
          "original_charge_label": "13 days",
          "charge_label": "13 days",
          "original_price_each_in_cents": 31200,
          "price_each_in_cents": 31200,
          "price_rule_values": null,
          "price_structure_id": null,
          "price_ruleset_id": null,
          "price_tile_id": null
        },
        "relationships": {
          "item": {
            "data": {
              "type": "products",
              "id": "6a8292cc-4002-4f8e-8da2-1e182dbacc08"
            }
          }
        }
      },
      {
        "id": "1200d3ab-3efd-419e-8837-dbefde64a5c8",
        "type": "item_prices",
        "attributes": {
          "item_id": "6ac6ad52-9587-4088-8fd8-af88a9295a8e",
          "from": "2028-03-25T10:11:00.000000+00:00",
          "till": "2028-04-07T10:11:00.000000+00:00",
          "original_charge_length": 1123200,
          "charge_length": 1123200,
          "original_charge_label": "13 days",
          "charge_label": "13 days",
          "original_price_each_in_cents": 74100,
          "price_each_in_cents": 74100,
          "price_rule_values": null,
          "price_structure_id": null,
          "price_ruleset_id": null,
          "price_tile_id": null
        },
        "relationships": {
          "item": {
            "data": {
              "type": "products",
              "id": "6ac6ad52-9587-4088-8fd8-af88a9295a8e"
            }
          }
        }
      }
    ],
    "included": [
      {
        "id": "6a8292cc-4002-4f8e-8da2-1e182dbacc08",
        "type": "products",
        "attributes": {
          "created_at": "2023-05-05T07:36:00.000000+00:00",
          "updated_at": "2023-05-05T07:36:00.000000+00:00",
          "archived": false,
          "archived_at": null,
          "type": "products",
          "name": "Product 1000004",
          "group_name": "Product 1000004",
          "slug": "product-1000004",
          "sku": "PRODUCT 1000006",
          "lead_time": 0,
          "lag_time": 0,
          "product_type": "rental",
          "tracking_type": "bulk",
          "trackable": false,
          "has_variations": false,
          "variation": false,
          "extra_information": null,
          "photo_url": null,
          "description": null,
          "excerpt": null,
          "show_in_store": true,
          "sorting_weight": 1,
          "base_price_in_cents": 100,
          "price_type": "simple",
          "price_period": "hour",
          "deposit_in_cents": 0,
          "discountable": true,
          "taxable": true,
          "seo_title": null,
          "seo_description": null,
          "tag_list": [],
          "properties": {},
          "photo_id": null,
          "tax_category_id": null,
          "price_ruleset_id": null,
          "price_structure_id": null,
          "allow_shortage": false,
          "shortage_limit": 0,
          "variation_values": [],
          "product_group_id": "248e9f40-8ade-4dd1-8bbc-2049129c3146"
        },
        "relationships": {}
      },
      {
        "id": "6ac6ad52-9587-4088-8fd8-af88a9295a8e",
        "type": "products",
        "attributes": {
          "created_at": "2023-05-05T07:36:00.000000+00:00",
          "updated_at": "2023-05-05T07:36:00.000000+00:00",
          "archived": false,
          "archived_at": null,
          "type": "products",
          "name": "Product 1000005",
          "group_name": "Product 1000005",
          "slug": "product-1000005",
          "sku": "PRODUCT 1000007",
          "lead_time": 0,
          "lag_time": 0,
          "product_type": "rental",
          "tracking_type": "bulk",
          "trackable": false,
          "has_variations": false,
          "variation": false,
          "extra_information": null,
          "photo_url": null,
          "description": null,
          "excerpt": null,
          "show_in_store": true,
          "sorting_weight": 1,
          "base_price_in_cents": 5700,
          "price_type": "simple",
          "price_period": "day",
          "deposit_in_cents": 0,
          "discountable": true,
          "taxable": true,
          "seo_title": null,
          "seo_description": null,
          "tag_list": [],
          "properties": {},
          "photo_id": null,
          "tax_category_id": null,
          "price_ruleset_id": null,
          "price_structure_id": null,
          "allow_shortage": false,
          "shortage_limit": 0,
          "variation_values": [],
          "product_group_id": "88d23396-b095-4122-82f6-992f846605af"
        },
        "relationships": {}
      }
    ],
    "meta": {}
  }

Calculating price charge length:

  curl --get 'https://example.booqable.com/api/boomerang/item_prices'
       --header 'content-type: application/json'
       --data-urlencode 'filter[charge_length]=36000'
       --data-urlencode 'filter[item_id]=f513ca7d-c6b0-432c-84fa-1b60f29a4cfa'
       --data-urlencode 'include=item'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "f010a8cf-b5d9-4ff8-853c-307a79289325",
        "type": "item_prices",
        "attributes": {
          "item_id": "f513ca7d-c6b0-432c-84fa-1b60f29a4cfa",
          "from": null,
          "till": null,
          "original_charge_length": 36000,
          "charge_length": 36000,
          "original_charge_label": "10 hours",
          "charge_label": "10 hours",
          "original_price_each_in_cents": null,
          "price_each_in_cents": 1000,
          "price_rule_values": null,
          "price_structure_id": null,
          "price_ruleset_id": null,
          "price_tile_id": null
        },
        "relationships": {
          "item": {
            "data": {
              "type": "products",
              "id": "f513ca7d-c6b0-432c-84fa-1b60f29a4cfa"
            }
          }
        }
      }
    ],
    "included": [
      {
        "id": "f513ca7d-c6b0-432c-84fa-1b60f29a4cfa",
        "type": "products",
        "attributes": {
          "created_at": "2023-06-13T08:19:05.000000+00:00",
          "updated_at": "2023-06-13T08:19:05.000000+00:00",
          "archived": false,
          "archived_at": null,
          "type": "products",
          "name": "Product 1000006",
          "group_name": "Product 1000006",
          "slug": "product-1000006",
          "sku": "PRODUCT 1000008",
          "lead_time": 0,
          "lag_time": 0,
          "product_type": "rental",
          "tracking_type": "bulk",
          "trackable": false,
          "has_variations": false,
          "variation": false,
          "extra_information": null,
          "photo_url": null,
          "description": null,
          "excerpt": null,
          "show_in_store": true,
          "sorting_weight": 1,
          "base_price_in_cents": 100,
          "price_type": "simple",
          "price_period": "hour",
          "deposit_in_cents": 0,
          "discountable": true,
          "taxable": true,
          "seo_title": null,
          "seo_description": null,
          "tag_list": [],
          "properties": {},
          "photo_id": null,
          "tax_category_id": null,
          "price_ruleset_id": null,
          "price_structure_id": null,
          "allow_shortage": false,
          "shortage_limit": 0,
          "variation_values": [],
          "product_group_id": "c9235b08-a9f1-43e5-8ae8-cf204f682b53"
        },
        "relationships": {}
      }
    ],
    "meta": {}
  }

HTTP Request

GET /api/boomerang/item_prices

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[item_prices]=item_id,from,till
filter hash
The filters to apply ?filter[attribute][eq]=value
include string
List of comma seperated relationships to sideload. ?include=price_tile,price_structure,item
meta hash
Metadata to send along. ?meta[total][]=count
page[number] string
The page to request.
page[size] string
The amount of items per page.
sort string
How to sort the data. ?sort=attribute1,-attribute2

Filters

This request can be filtered on:

Name Description
charge_length integer
eq
from datetime
eq
item_id uuid
eq
original_charge_length integer
eq
price_ruleset_id uuid
eq
price_structure_id uuid
eq
till datetime
eq

Meta

Results can be aggregated on:

Name Description
total array
count

Includes

This request accepts the following includes:

price_tile

price_structure

item

Items

The Item resource makes it possible to fetch (and search!) the following resources in a single request:

The description of the relationships and attributes of these resources can be found in their respective sections

List items

How to fetch a list of items:

  curl --get 'https://example.booqable.com/api/boomerang/items'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "d7759df8-1381-4df4-832c-9ddde2efce9a",
        "type": "bundles",
        "attributes": {
          "created_at": "2027-05-05T08:14:00.000000+00:00",
          "updated_at": "2027-05-05T08:14:00.000000+00:00",
          "archived": false,
          "archived_at": null,
          "type": "bundles",
          "name": "iPad Bundle",
          "slug": "ipad-bundle",
          "product_type": "bundle",
          "extra_information": null,
          "photo_url": null,
          "description": null,
          "excerpt": null,
          "show_in_store": true,
          "sorting_weight": 0,
          "discountable": true,
          "taxable": true,
          "seo_title": null,
          "seo_description": null,
          "tag_list": [
            "tablets",
            "apple"
          ],
          "photo_id": null,
          "tax_category_id": null
        },
        "relationships": {}
      },
      {
        "id": "c721f29a-0574-4af4-8fb2-ab4715f97998",
        "type": "product_groups",
        "attributes": {
          "created_at": "2027-05-05T08:14:00.000000+00:00",
          "updated_at": "2027-05-05T08:14:00.000000+00:00",
          "archived": false,
          "archived_at": null,
          "type": "product_groups",
          "name": "iPad Pro",
          "group_name": null,
          "slug": "ipad-pro",
          "sku": "SKU",
          "lead_time": 0,
          "lag_time": 0,
          "product_type": "rental",
          "tracking_type": "trackable",
          "trackable": true,
          "has_variations": false,
          "variation": false,
          "extra_information": "Charging cable and case included",
          "photo_url": null,
          "description": "The Apple iPad Pro (2021) 12.9 inches 128GB Space Gray is one of the most powerful and fastest tablets of this moment thanks to the new M1 chip. This chip ensures that demanding apps from Adobe or 3D games run smoothly",
          "excerpt": null,
          "show_in_store": true,
          "sorting_weight": 0,
          "base_price_in_cents": 1995,
          "price_type": "simple",
          "price_period": "day",
          "deposit_in_cents": 10000,
          "discountable": true,
          "taxable": true,
          "seo_title": null,
          "seo_description": null,
          "tag_list": [
            "tablets",
            "apple"
          ],
          "properties": {},
          "photo_id": null,
          "tax_category_id": "58186c7a-50b1-4584-881d-3054f4f5790d",
          "price_ruleset_id": null,
          "price_structure_id": null,
          "allow_shortage": true,
          "shortage_limit": 3,
          "variation_fields": [],
          "flat_fee_price_in_cents": 1995,
          "structure_price_in_cents": 0,
          "stock_item_properties": []
        },
        "relationships": {}
      },
      {
        "id": "89e8b2cd-7a7e-47b2-8571-1379ad6e21f1",
        "type": "products",
        "attributes": {
          "created_at": "2027-05-05T08:14:00.000000+00:00",
          "updated_at": "2027-05-05T08:14:00.000000+00:00",
          "archived": false,
          "archived_at": null,
          "type": "products",
          "name": "iPad Pro",
          "group_name": "iPad Pro",
          "slug": "ipad-pro",
          "sku": "SKU",
          "lead_time": 0,
          "lag_time": 0,
          "product_type": "rental",
          "tracking_type": "trackable",
          "trackable": true,
          "has_variations": false,
          "variation": false,
          "extra_information": "Charging cable and case included",
          "photo_url": null,
          "description": "The Apple iPad Pro (2021) 12.9 inches 128GB Space Gray is one of the most powerful and fastest tablets of this moment thanks to the new M1 chip. This chip ensures that demanding apps from Adobe or 3D games run smoothly",
          "excerpt": null,
          "show_in_store": true,
          "sorting_weight": 1,
          "base_price_in_cents": 1995,
          "price_type": "simple",
          "price_period": "day",
          "deposit_in_cents": 10000,
          "discountable": true,
          "taxable": true,
          "seo_title": null,
          "seo_description": null,
          "tag_list": [
            "tablets",
            "apple"
          ],
          "properties": {},
          "photo_id": null,
          "tax_category_id": "58186c7a-50b1-4584-881d-3054f4f5790d",
          "price_ruleset_id": null,
          "price_structure_id": null,
          "allow_shortage": true,
          "shortage_limit": 3,
          "variation_values": [],
          "product_group_id": "c721f29a-0574-4af4-8fb2-ab4715f97998"
        },
        "relationships": {}
      }
    ],
    "meta": {}
  }

HTTP Request

GET /api/boomerang/items

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[items]=created_at,updated_at,archived
filter hash
The filters to apply ?filter[attribute][eq]=value
include string
List of comma seperated relationships to sideload. ?include=barcode,bundle_items,inventory_levels
meta hash
Metadata to send along. ?meta[total][]=count
page[number] string
The page to request.
page[size] string
The amount of items per page.
sort string
How to sort the data. ?sort=attribute1,-attribute2

Filters

This request can be filtered on:

Name Description
archived boolean
eq
archived_at datetime
eq, not_eq, gt, gte, lt, lte
base_price_in_cents integer
eq, not_eq, gt, gte, lt, lte
collection_id uuid
eq, not_eq
conditions hash
eq
created_at datetime
eq, not_eq, gt, gte, lt, lte
deposit_in_cents integer
eq, not_eq, gt, gte, lt, lte
description string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
discountable boolean
eq
excerpt string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
extra_information string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
group_name string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
has_variations boolean
eq
id uuid
eq, not_eq, gt
lag_time integer
eq, not_eq, gt, gte, lt, lte
lead_time integer
eq, not_eq, gt, gte, lt, lte
name string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
photo_id uuid
eq, not_eq
price_period enum
eq
price_ruleset_id uuid
eq, not_eq
price_structure_id uuid
eq, not_eq
price_type enum
eq
product_group_id uuid
eq
product_type enum
eq
q string
eq
seo_description string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
seo_title string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
show_in_store boolean
eq
sku string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
slug string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
sorting_weight integer
eq, not_eq, gt, gte, lt, lte
tag_list string
eq
tax_category_id uuid
eq, not_eq
taxable boolean
eq
trackable boolean
eq
tracking_type enum
eq
type string
eq, not_eq
updated_at datetime
eq, not_eq, gt, gte, lt, lte
variation boolean
eq

Meta

Results can be aggregated on:

Name Description
archived array
count
base_price_in_cents array
sum, maximum, minimum, average
deposit_in_cents array
sum, maximum, minimum, average
discountable array
count
price_period array
count
price_type array
count
product_type array
count
show_in_store array
count
tag_list array
count
tax_category_id array
count
taxable array
count
total array
count
tracking_type array
count

Includes

This request accepts the following includes:

barcode

bundle_items

inventory_levels

photo

properties

Search items

Use advanced search to make logical filter groups with and/or operators.

How to search for items:

  curl --request POST
       --url 'https://example.booqable.com/api/boomerang/items/search'
       --header 'content-type: application/json'
       --data '{
         "fields": {
           "items": "id"
         },
         "filter": {
           "conditions": {
             "operator": "or",
             "attributes": [
               {
                 "operator": "and",
                 "attributes": [
                   {
                     "discountable": true
                   },
                   {
                     "taxable": true
                   }
                 ]
               },
               {
                 "operator": "and",
                 "attributes": [
                   {
                     "show_in_store": true
                   },
                   {
                     "taxable": true
                   }
                 ]
               }
             ]
           }
         }
       }'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "569def8b-7636-476f-8a1f-be15feb8defb"
      },
      {
        "id": "90acfcac-e08a-40a8-8189-769b49dd2197"
      },
      {
        "id": "000f9d47-49fe-4495-8d4c-39a2187d00f2"
      },
      {
        "id": "b71ea42f-340e-4143-81c1-ca6a463d21ac"
      },
      {
        "id": "f5b4b96e-515c-42f6-8214-95013aa9cdc4"
      }
    ]
  }

HTTP Request

POST api/boomerang/items/search

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[items]=created_at,updated_at,archived
filter hash
The filters to apply ?filter[attribute][eq]=value
include string
List of comma seperated relationships to sideload. ?include=barcode,bundle_items,inventory_levels
meta hash
Metadata to send along. ?meta[total][]=count
page[number] string
The page to request.
page[size] string
The amount of items per page.
sort string
How to sort the data. ?sort=attribute1,-attribute2

Filters

This request can be filtered on:

Name Description
archived boolean
eq
archived_at datetime
eq, not_eq, gt, gte, lt, lte
base_price_in_cents integer
eq, not_eq, gt, gte, lt, lte
collection_id uuid
eq, not_eq
conditions hash
eq
created_at datetime
eq, not_eq, gt, gte, lt, lte
deposit_in_cents integer
eq, not_eq, gt, gte, lt, lte
description string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
discountable boolean
eq
excerpt string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
extra_information string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
group_name string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
has_variations boolean
eq
id uuid
eq, not_eq, gt
lag_time integer
eq, not_eq, gt, gte, lt, lte
lead_time integer
eq, not_eq, gt, gte, lt, lte
name string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
photo_id uuid
eq, not_eq
price_period enum
eq
price_ruleset_id uuid
eq, not_eq
price_structure_id uuid
eq, not_eq
price_type enum
eq
product_group_id uuid
eq
product_type enum
eq
q string
eq
seo_description string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
seo_title string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
show_in_store boolean
eq
sku string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
slug string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
sorting_weight integer
eq, not_eq, gt, gte, lt, lte
tag_list string
eq
tax_category_id uuid
eq, not_eq
taxable boolean
eq
trackable boolean
eq
tracking_type enum
eq
type string
eq, not_eq
updated_at datetime
eq, not_eq, gt, gte, lt, lte
variation boolean
eq

Meta

Results can be aggregated on:

Name Description
archived array
count
base_price_in_cents array
sum, maximum, minimum, average
deposit_in_cents array
sum, maximum, minimum, average
discountable array
count
price_period array
count
price_type array
count
product_type array
count
show_in_store array
count
tag_list array
count
tax_category_id array
count
taxable array
count
total array
count
tracking_type array
count

Includes

This request accepts the following includes:

barcode

bundle_items

inventory_levels

photo

properties

Fetch an item

How to fetch an item:

  curl --get 'https://example.booqable.com/api/boomerang/items/15cd96a9-f5ba-4fb6-8ca3-16b2581f1385'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": {
      "id": "15cd96a9-f5ba-4fb6-8ca3-16b2581f1385",
      "type": "product_groups",
      "attributes": {
        "created_at": "2015-07-22T22:42:00.000000+00:00",
        "updated_at": "2015-07-22T22:42:00.000000+00:00",
        "archived": false,
        "archived_at": null,
        "type": "product_groups",
        "name": "iPad Pro",
        "group_name": null,
        "slug": "ipad-pro",
        "sku": "SKU",
        "lead_time": 0,
        "lag_time": 0,
        "product_type": "rental",
        "tracking_type": "trackable",
        "trackable": true,
        "has_variations": false,
        "variation": false,
        "extra_information": "Charging cable and case included",
        "photo_url": null,
        "description": "The Apple iPad Pro (2021) 12.9 inches 128GB Space Gray is one of the most powerful and fastest tablets of this moment thanks to the new M1 chip. This chip ensures that demanding apps from Adobe or 3D games run smoothly",
        "excerpt": null,
        "show_in_store": true,
        "sorting_weight": 0,
        "base_price_in_cents": 1995,
        "price_type": "simple",
        "price_period": "day",
        "deposit_in_cents": 10000,
        "discountable": true,
        "taxable": true,
        "seo_title": null,
        "seo_description": null,
        "tag_list": [
          "tablets",
          "apple"
        ],
        "properties": {},
        "photo_id": null,
        "tax_category_id": "2a2acff0-f752-4c88-85d7-23015f91caff",
        "price_ruleset_id": null,
        "price_structure_id": null,
        "allow_shortage": true,
        "shortage_limit": 3,
        "variation_fields": [],
        "flat_fee_price_in_cents": 1995,
        "structure_price_in_cents": 0,
        "stock_item_properties": []
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

GET /api/boomerang/items/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[items]=created_at,updated_at,archived
include string
List of comma seperated relationships to sideload. ?include=barcode,bundle_items,inventory_levels

Includes

This request accepts the following includes:

barcode

bundle_items

inventory_levels

photo

properties

Lines

Lines make up the individual elements of an order, document, or cart. They contain information about pricing, planning, or markup.

Lines can only be created for orders. On invoices, lines are automatically generated based on price changes of the order. For quotes and contracts, lines are generated through the Document resource.

Kinds of Lines

  1. Planning lines Lines that have an associated Planning. These lines can not be created through the Line resource but are created by submitting a book_* action to OrderFulfilments. Updating or destroying a line linked to a planning will also destroy the planning.

  2. Custom lines Lines created through the resource that don't have a planning associated with it. Can be of one of type charge, section.

Types of Lines

Bundles

Nested lines contain information about individual items in a bundle; for these lines, the quantity and price information can not be updated directly but should be updated through the parent line instead.

Sorting Lines

# example of lines when using bundles
(position=1) Product A
(position=2) Product B
(position=3) Bundle
  (position=1) Product C
  (position=2) Product D

When using Bundles, the line.position attribute is not unique. Special care needs to be taken to sort all lines correctly.

When booking a bundle:

To correctly sort all lines so they appear as they do within Booqable:

Relationships

Name Description
item Item optional
The Product or Bundle that was booked, when this Line has an associated Planning.
nested_lines Lines hasmany
When item is a Bundle, then there is a nested_line that corresponds for each BundleItem.
order Order required
The Order this Line belongs to.
owner Order, Document required
The resource this Line belongs to. Either the Order directly, or a Document.
parent_line Line optional
When present, then this Line is part of a Bundle, and corresponds to a BundleItem. Inverse of nested_lines relation.
planning Planning optional
The Planning for which this Lines was created. that contains the logistical information related to this Line.
price_structure Price structure optional
The PriceStructure used to calculate the price.
price_tile Price tile optional
The PriceTile that was selected to calculate the price.
tax_category Tax category optional
TaxCategory applied to this Line.

Check matching attributes under Fields to see which relations can be written.
Check each individual operation to see which relations can be included as a sideload.

Fields

Name Description
archived boolean readonly
Whether line is archived.
archived_at datetime readonly nullable
When the line was archived.
charge_label string nullable
Charge label.
charge_length integer nullable
The charge length in seconds. It can be different than the time planned. Setting charge_length to null will trigger recalculation of the price based on order period and price rules.
To recalculate prices for the entire order, use OrderPriceRecalculation.
confirm_shortage boolean writeonly
Whether to confirm a shortage when updating quantity on a line.
created_at datetime readonly
When the resource was created.
discountable boolean
Whether line is discountable.
display_price_in_cents integer readonly
Price of this line to display based on the tax setting of the company (inclusive vs. exclusive).
extra_information string nullable
Extra information about the line.
id uuid readonly
Primary key.
item_id uuid readonly nullable
The Product or Bundle that was booked, when this Line has an associated Planning.
line_type enum readonly-after-create
Type of line.
One of: section, deposit_charge, proration, charge, legacy_migration, delivery_rate.
order_id uuid readonly
The Order this Line belongs to.
original_charge_label string nullable
The original charge label of the product (without price rule adjustments).
original_charge_length integer readonly
The original charge length of the product (without price rule adjustments).
original_price_each_in_cents integer readonly
The original price of the product (without price rule adjustments).
owner_id uuid readonly-after-create
The resource this Line belongs to. Either the Order directly, or a Document.
owner_type enum readonly-after-create
The resource type of the owner.
One of: orders, documents.
parent_line_id uuid readonly nullable
When present, then this Line is part of a Bundle, and corresponds to a BundleItem. Inverse of nested_lines relation.
planning_id uuid readonly nullable
The Planning for which this Lines was created. that contains the logistical information related to this Line.
position integer nullable
The ordering of lines on an order or document. See this section to understand how to sort when using bundles.
price_each_in_cents integer
Price of each line.
price_in_cents integer readonly
Price of each line x quantity.
price_rule_values hash readonly nullable
Breakdown of applied price rules.
price_structure_id uuid nullable
The PriceStructure used to calculate the price.
price_tile_id uuid nullable
The PriceTile that was selected to calculate the price.
quantity integer
The quantity to calculate with. When updating quantity of a line with an associated planning, the planning also gets updated, which may lead to a shortage error.
relevant boolean readonly
When false this line should not be shown to users. It is only needed for calculation of prorations.
tax_category_id uuid nullable
TaxCategory applied to this Line.
taxable boolean
Whether line is taxable.
title string nullable
Title of the line.
updated_at datetime readonly
When the resource was last updated.

List lines

How to fetch a list of lines:

  curl --get 'https://example.booqable.com/api/boomerang/lines'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": [
      {
        "id": "ae4a88a4-9a7a-4caf-811c-27f85ebe167f",
        "type": "lines",
        "attributes": {
          "created_at": "2023-08-08T15:06:00.000000+00:00",
          "updated_at": "2023-08-08T15:06:00.000000+00:00",
          "archived": false,
          "archived_at": null,
          "title": "Macbook Pro",
          "extra_information": "Comes with a mouse",
          "quantity": 1,
          "original_price_each_in_cents": 72500,
          "original_charge_length": null,
          "original_charge_label": null,
          "price_each_in_cents": 80250,
          "price_in_cents": 80250,
          "display_price_in_cents": 80250,
          "position": 1,
          "charge_label": "29 days",
          "charge_length": 2505600,
          "price_rule_values": {
            "charge": {
              "from": "1978-09-28T05:41:00.000000+00:00",
              "till": "1978-10-27T05:41:00.000000+00:00",
              "adjustments": [
                {
                  "name": "Pickup day"
                },
                {
                  "name": "Return day"
                }
              ]
            },
            "price": [
              {
                "name": "High-Season",
                "charge_length": 1339200,
                "multiplier": "0.2",
                "price_in_cents": 7750,
                "adjustments": [
                  {
                    "from": "1978-10-11T17:41:00.000000+00:00",
                    "till": "1978-10-27T05:41:00.000000+00:00",
                    "charge_length": 1339200,
                    "charge_label": "372 hours",
                    "price_in_cents": 7750
                  }
                ],
                "stacked": false
              }
            ]
          },
          "discountable": true,
          "taxable": true,
          "line_type": "charge",
          "relevant": true,
          "order_id": "db61e960-dc39-40c0-8967-af01657ec0d0",
          "item_id": "dfb7e7c5-6c92-44de-8fd3-beb9fe5dee6e",
          "tax_category_id": "4c97f8cd-9bbf-4048-819a-f50d8b7bff7b",
          "price_structure_id": null,
          "price_tile_id": null,
          "planning_id": "9cf6e39a-f13f-46c3-89db-f1fd269f1bfd",
          "parent_line_id": null,
          "owner_id": "db61e960-dc39-40c0-8967-af01657ec0d0",
          "owner_type": "orders"
        },
        "relationships": {}
      }
    ],
    "meta": {}
  }

HTTP Request

GET /api/boomerang/lines

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[lines]=created_at,updated_at,archived
filter hash
The filters to apply ?filter[attribute][eq]=value
include string
List of comma seperated relationships to sideload. ?include=order,owner,tax_category
meta hash
Metadata to send along. ?meta[total][]=count
page[number] string
The page to request.
page[size] string
The amount of items per page.
sort string
How to sort the data. ?sort=attribute1,-attribute2

Filters

This request can be filtered on:

Name Description
archived boolean
eq
archived_at datetime
eq, not_eq, gt, gte, lt, lte
created_at datetime
eq, not_eq, gt, gte, lt, lte
discountable boolean
eq
id uuid
eq, not_eq
item_id uuid
eq, not_eq
line_type enum
eq
order_id uuid
eq
owner_id uuid
eq, not_eq
owner_type enum
eq, not_eq
parent_line_id uuid
eq, not_eq
planning_id uuid
eq, not_eq
price_structure_id uuid
eq, not_eq
price_tile_id uuid
eq, not_eq
quantity integer
eq, not_eq, gt, gte, lt, lte
relevant boolean
eq
tax_category_id uuid
eq, not_eq
taxable boolean
eq
title string
eq, not_eq, eql, not_eql, prefix, not_prefix, suffix, not_suffix, match, not_match
updated_at datetime
eq, not_eq, gt, gte, lt, lte

Meta

Results can be aggregated on:

Name Description
total array
count

Includes

This request accepts the following includes:

order

owner

tax_category

planning => item => photo

Fetch a line

How to fetch a line:

  curl --get 'https://example.booqable.com/api/boomerang/lines/b4c827b6-c766-42d8-831c-87f9a610b8fa'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": {
      "id": "b4c827b6-c766-42d8-831c-87f9a610b8fa",
      "type": "lines",
      "attributes": {
        "created_at": "2022-10-10T21:41:02.000000+00:00",
        "updated_at": "2022-10-10T21:41:02.000000+00:00",
        "archived": false,
        "archived_at": null,
        "title": "Macbook Pro",
        "extra_information": "Comes with a mouse",
        "quantity": 1,
        "original_price_each_in_cents": 72500,
        "original_charge_length": null,
        "original_charge_label": null,
        "price_each_in_cents": 80250,
        "price_in_cents": 80250,
        "display_price_in_cents": 80250,
        "position": 1,
        "charge_label": "29 days",
        "charge_length": 2505600,
        "price_rule_values": {
          "charge": {
            "from": "1977-11-30T12:16:02.000000+00:00",
            "till": "1977-12-29T12:16:02.000000+00:00",
            "adjustments": [
              {
                "name": "Pickup day"
              },
              {
                "name": "Return day"
              }
            ]
          },
          "price": [
            {
              "name": "High-Season",
              "charge_length": 1339200,
              "multiplier": "0.2",
              "price_in_cents": 7750,
              "adjustments": [
                {
                  "from": "1977-12-14T00:16:02.000000+00:00",
                  "till": "1977-12-29T12:16:02.000000+00:00",
                  "charge_length": 1339200,
                  "charge_label": "372 hours",
                  "price_in_cents": 7750
                }
              ],
              "stacked": false
            }
          ]
        },
        "discountable": true,
        "taxable": true,
        "line_type": "charge",
        "relevant": true,
        "order_id": "a206e703-8fe7-4045-826a-36b938ea47d4",
        "item_id": "d4996c4d-efe0-4972-8124-37812a882d50",
        "tax_category_id": "28930517-53d0-4346-865d-0988b23e5ea6",
        "price_structure_id": null,
        "price_tile_id": null,
        "planning_id": "01296b4b-a633-4808-8993-91a287f01c9b",
        "parent_line_id": null,
        "owner_id": "a206e703-8fe7-4045-826a-36b938ea47d4",
        "owner_type": "orders"
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

GET /api/boomerang/lines/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[lines]=created_at,updated_at,archived
include string
List of comma seperated relationships to sideload. ?include=order,owner,tax_category

Includes

This request accepts the following includes:

order => tax_values

owner => tax_values

tax_category

parent_line

nested_lines => planning

planning => item => photo

Create a line

Lines created through this endpoint, so-called custom lines, can only have the type charge or section. Custom charge lines enable you to add charges not (directly) connected to a product to an order. Sections allow to add some organization to orders.

Order totals are automatically re-calculated after the creation of a new line and an invoice sync will be triggered if changes are relevant.

How to create a line:

  curl --request POST
       --url 'https://example.booqable.com/api/boomerang/lines'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "type": "lines",
           "attributes": {
             "owner_id": "e429675c-a2e8-46c3-88f4-316a4bdd2e5d",
             "owner_type": "orders",
             "price_each_in_cents": 1000
           }
         }
       }'

A 201 status response looks like this:

  {
    "data": {
      "id": "69903b58-4d14-4bcb-8490-66c5df3ee4df",
      "type": "lines",
      "attributes": {
        "created_at": "2017-01-15T11:15:00.000000+00:00",
        "updated_at": "2017-01-15T11:15:00.000000+00:00",
        "archived": false,
        "archived_at": null,
        "title": null,
        "extra_information": null,
        "quantity": 1,
        "original_price_each_in_cents": null,
        "original_charge_length": null,
        "original_charge_label": null,
        "price_each_in_cents": 1000,
        "price_in_cents": 1000,
        "display_price_in_cents": 1000,
        "position": 1,
        "charge_label": null,
        "charge_length": null,
        "price_rule_values": null,
        "discountable": true,
        "taxable": true,
        "line_type": "charge",
        "relevant": true,
        "order_id": "e429675c-a2e8-46c3-88f4-316a4bdd2e5d",
        "item_id": null,
        "tax_category_id": null,
        "price_structure_id": null,
        "price_tile_id": null,
        "planning_id": null,
        "parent_line_id": null,
        "owner_id": "e429675c-a2e8-46c3-88f4-316a4bdd2e5d",
        "owner_type": "orders"
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

POST /api/boomerang/lines

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[lines]=created_at,updated_at,archived
include string
List of comma seperated relationships to sideload. ?include=order,owner,tax_category

Request body

This request accepts the following body:

Name Description
data[attributes][charge_label] string
Charge label.
data[attributes][charge_length] integer
The charge length in seconds. It can be different than the time planned. Setting charge_length to null will trigger recalculation of the price based on order period and price rules.
To recalculate prices for the entire order, use OrderPriceRecalculation.
data[attributes][confirm_shortage] boolean
Whether to confirm a shortage when updating quantity on a line.
data[attributes][discountable] boolean
Whether line is discountable.
data[attributes][extra_information] string
Extra information about the line.
data[attributes][line_type] enum
Type of line.
One of: section, deposit_charge, proration, charge, legacy_migration, delivery_rate.
data[attributes][original_charge_label] string
The original charge label of the product (without price rule adjustments).
data[attributes][owner_id] uuid
The resource this Line belongs to. Either the Order directly, or a Document.
data[attributes][owner_type] enum
The resource type of the owner.
One of: orders, documents.
data[attributes][position] integer
The ordering of lines on an order or document. See this section to understand how to sort when using bundles.
data[attributes][price_each_in_cents] integer
Price of each line.
data[attributes][price_structure_id] uuid
The PriceStructure used to calculate the price.
data[attributes][price_tile_id] uuid
The PriceTile that was selected to calculate the price.
data[attributes][quantity] integer
The quantity to calculate with. When updating quantity of a line with an associated planning, the planning also gets updated, which may lead to a shortage error.
data[attributes][tax_category_id] uuid
TaxCategory applied to this Line.
data[attributes][taxable] boolean
Whether line is taxable.
data[attributes][title] string
Title of the line.

Includes

This request accepts the following includes:

order => tax_values

owner => tax_values

tax_category

parent_line

nested_lines => planning

planning => item => photo

Update a line

Change information, pricing, or increase the quantity of a line. Note that when updating the quantity of a line associated with a planning, the quantity of the planninig will also be updated, which may result in a shortage error.

Order totals are automatically re-calculated after updating a line and an invoice sync will be triggered if changes are relevant.

How to update a line:

  curl --request PUT
       --url 'https://example.booqable.com/api/boomerang/lines/fc2e8815-5ad2-4d0b-8a28-777a6b57d933'
       --header 'content-type: application/json'
       --data '{
         "data": {
           "id": "fc2e8815-5ad2-4d0b-8a28-777a6b57d933",
           "type": "lines",
           "attributes": {
             "price_each_in_cents": 1000
           }
         }
       }'

A 200 status response looks like this:

  {
    "data": {
      "id": "fc2e8815-5ad2-4d0b-8a28-777a6b57d933",
      "type": "lines",
      "attributes": {
        "created_at": "2027-03-06T23:03:01.000000+00:00",
        "updated_at": "2027-03-06T23:03:01.000000+00:00",
        "archived": false,
        "archived_at": null,
        "title": "Macbook Pro",
        "extra_information": "Comes with a mouse",
        "quantity": 1,
        "original_price_each_in_cents": 72500,
        "original_charge_length": null,
        "original_charge_label": null,
        "price_each_in_cents": 1000,
        "price_in_cents": 1000,
        "display_price_in_cents": 1000,
        "position": 1,
        "charge_label": "29 days",
        "charge_length": 2505600,
        "price_rule_values": null,
        "discountable": true,
        "taxable": true,
        "line_type": "charge",
        "relevant": true,
        "order_id": "33b62e2b-8553-4919-8719-0de973ab048e",
        "item_id": "6079761a-dac1-4eb8-88a9-d5c43040d760",
        "tax_category_id": "87821aa9-fd93-4b69-8e67-01c17fd816d6",
        "price_structure_id": null,
        "price_tile_id": null,
        "planning_id": "cdd8227f-b71f-41ae-83a9-4e47d0c1a2b6",
        "parent_line_id": null,
        "owner_id": "33b62e2b-8553-4919-8719-0de973ab048e",
        "owner_type": "orders"
      },
      "relationships": {}
    },
    "meta": {}
  }

HTTP Request

PUT /api/boomerang/lines/{id}

Request params

This request accepts the following parameters:

Name Description
fields[] array
List of comma separated fields to include instead of the default fields. ?fields[lines]=created_at,updated_at,archived
include string
List of comma seperated relationships to sideload. ?include=order,owner,tax_category

Request body

This request accepts the following body:

Name Description
data[attributes][charge_label] string
Charge label.
data[attributes][charge_length] integer
The charge length in seconds. It can be different than the time planned. Setting charge_length to null will trigger recalculation of the price based on order period and price rules.
To recalculate prices for the entire order, use OrderPriceRecalculation.
data[attributes][confirm_shortage] boolean
Whether to confirm a shortage when updating quantity on a line.
data[attributes][discountable] boolean
Whether line is discountable.
data[attributes][extra_information] string
Extra information about the line.
data[attributes][line_type] enum
Type of line.
One of: section, deposit_charge, proration, charge, legacy_migration, delivery_rate.
data[attributes][original_charge_label] string
The original charge label of the product (without price rule adjustments).
data[attributes][owner_id] uuid
The resource this Line belongs to. Either the Order directly, or a Document.
data[attributes][owner_type] enum
The resource type of the owner.
One of: orders, documents.
data[attributes][position] integer
The ordering of lines on an order or document. See this section to understand how to sort when using bundles.
data[attributes][price_each_in_cents] integer
Price of each line.
data[attributes][price_structure_id] uuid
The PriceStructure used to calculate the price.
data[attributes][price_tile_id] uuid
The PriceTile that was selected to calculate the price.
data[attributes][quantity] integer
The quantity to calculate with. When updating quantity of a line with an associated planning, the planning also gets updated, which may lead to a shortage error.
data[attributes][tax_category_id] uuid
TaxCategory applied to this Line.
data[attributes][taxable] boolean
Whether line is taxable.
data[attributes][title] string
Title of the line.

Includes

This request accepts the following includes:

order => tax_values

owner => tax_values

tax_category

parent_line

nested_lines => planning

planning => item => photo

Archive a line

How to delete a line:

  curl --request DELETE
       --url 'https://example.booqable.com/api/boomerang/lines/4ad8090f-0878-4fb1-8e5e-2dea58fd8ef6'
       --header 'content-type: application/json'

A 200 status response looks like this:

  {
    "data": {
      "id": "4ad8090f-0878-4fb1-8e5e-2dea58fd8ef6",
      "type": "lines",
      "attributes"