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:
{resource_name}_attributes
array of resources to create, update and associate.{resource_name}_ids
array of resources to associate.{resource_name}_id
id off the resource to associate.
When side posting is supported, it will be mentioned in the resource-specific documentation.
Advanced search
The following resources support advanced searching with POST requests:
- Order
- Item
- Bundle
- ProductGroup
- Product
- Document
- Planning
- Customer
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
- Go to your account settings page
{company-name-here}.booqable.com/employees/current
- Name your new token
- 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:
ES256
RS256
HS256
- Go to your account settings page
{company-name-here}.booqable.com/employees/current
- Name your new authentication method
- Insert your public key (for
ES256
andRS256
only) - 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:
- QR code: QR codes are flexible in size, have high fault tolerance, and fast readability.
- EAN-8: Ideal for identifying small items, stores eight digits.
- EAN-13: Can store a relatively large amount of data (13 digits) in a small area.
- Code 39: Stores both digits and characters. The size of the barcode makes them unsuitable to use on small items.
- Code 93: A more compact alternative to Code 39 (about 25% shorter).
- Code 128: A high-density barcode that can store any character of the ASCII 128 character set.
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:
"fixed" or "specified": The products are fixed, and the customer does not get to choose.
"unspecified": One or more of the products in the bundle has multiple product variations, and the customer gets to choose from them. In this case, pricing and availability of the bundle depends on the customer's selected product variation.
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:
"fixed" or "specified": The
product_id
is set and fixed, and the customer does not get to choose. These BundleItems do not need to be specified when booking a bundle."unspecified": The
product_id
isnull
, and the customer gets to choose one of the product variations. These BundleItems must to be specified when booking a bundle.
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:
- Customer information (when present)
- Pricing and deposit
- Lines
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:
- Location
- Product
- Type
- Mutation date(s)
Useful for
- Examining what the current inventory looks, and will look, like for products
- Performing an inventory count (total in stock vs. out with a customer)
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:
- Providing a
from
andtill
, charge label and length will be derived from the dates provided - Providing a
charge_length
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
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.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
charge
Regular charge line which contains price information. These lines are automatically generatef for each Planning, but they can also be added manually for one-off charges.section
Behaves as a visual section on orders and documents.deposit_charge
A deposit charge line generated by a deposit hold action. This line is always calculated from a price including taxes.proration
Whether this line is a proration, these lines only appear on invoices and can't be updated or destroyed by the resource; they are automatically synced.refund
This line was created due to a refund.legacy_migration
Proration bundled as one line. This lines appear on invoices that were made before Booqable was able to sync invoices automatically.
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:
- The parent line is assigned a
position
based on the other lines already on the order. - The child lines are assigned a
position
based on how the bundle is configured.
To correctly sort all lines so they appear as they do within Booqable:
- Child lines should be sorted relative to their siblings of the same parent.
To do this, child lines need to be grouped by the
parent_line_id
attribute.
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"