Customers API
The Customers API provides full CRUD operations for managing customer master data and contact information.
Required Scope: customers:read, customers:write, customers:delete
List Customers
Retrieve a paginated list of customers with optional filters.
GET /api/v1/customersQuery Parameters
| Parameter | Type | Description |
|---|---|---|
code | string | Filter by customer code (partial match) |
name | string | Filter by customer name (partial match) |
eori | string | Filter by EORI number (partial match) |
country | string | Filter by country (2-letter ISO code) |
portal_access | boolean | Filter by portal access status (true/false) |
sort | string | Sort field: customer_code, customer_name, customer_country_code, created_at (default: customer_name) |
direction | string | Sort direction: asc (default) or desc |
page | integer | Page number (default: 1) |
per_page | integer | Results per page (default: 25, max: 100) |
Example Request
curl https://app.borderbolt.com/api/v1/customers \
-H "Authorization: Bearer {token}" \
-G \
--data-urlencode "country=NL" \
--data-urlencode "sort=customer_name"Example Response
{
"data": [
{
"id": 501,
"customer_code": "CUST001",
"customer_name": "Example B.V.",
"customer_eori_number": "NL123456789012",
"customer_vat_number": "NL123456789B01",
"customer_address": "Hoofdstraat",
"customer_address_number": "1",
"customer_postal_code": "1012AB",
"customer_city": "Amsterdam",
"customer_country_code": "NL",
"representation_type": "2",
"customs_declaration_office": "NL000412",
"portal_access_enabled": false,
"created_at": "2025-01-15T10:00:00.000000Z",
"updated_at": "2026-03-20T14:30:00.000000Z"
}
],
"meta": {
"current_page": 1,
"last_page": 7,
"per_page": 25,
"total": 156
}
}Get Customer
Retrieve a single customer with their contacts.
GET /api/v1/customers/{id}Example Request
curl https://app.borderbolt.com/api/v1/customers/501 \
-H "Authorization: Bearer {token}"Example Response
{
"data": {
"id": 501,
"customer_code": "CUST001",
"customer_name": "Example B.V.",
"customer_eori_number": "NL123456789012",
"customer_vat_number": "NL123456789B01",
"customer_address": "Hoofdstraat",
"customer_address_number": "1",
"customer_postal_code": "1012AB",
"customer_city": "Amsterdam",
"customer_country_code": "NL",
"representation_type": "2",
"customs_declaration_office": "NL000412",
"warehouse_licence": "NL123456",
"warehouse_licence_type": "U",
"portal_access_enabled": false,
"poa_valid_until": "2027-01-01",
"contacts": [
{
"id": 1001,
"name": "John Doe",
"email": "john.doe@example.nl",
"phone": "+31 20 1234568",
"position": "Logistics Manager",
"department": "Logistics",
"is_primary": true,
"receives_notifications": true,
"receives_approvals": false,
"language": "nl"
}
],
"created_at": "2025-01-15T10:00:00.000000Z",
"updated_at": "2026-03-20T14:30:00.000000Z"
}
}Not Found
{
"error": "not_found",
"message": "Customer not found."
}HTTP 404 is returned when the customer does not exist.
Get Customer by Code
Retrieve a customer by their unique customer code.
GET /api/v1/customers/code/{code}Example Request
curl https://app.borderbolt.com/api/v1/customers/code/CUST001 \
-H "Authorization: Bearer {token}"Returns the same response format as Get Customer.
Create Customer
Create a new customer.
POST /api/v1/customersRequest Body
| Field | Required | Type | Description |
|---|---|---|---|
customer_code | Yes | string | Unique customer code (max 50 chars) |
customer_name | Yes | string | Customer legal name (max 255 chars) |
customer_address | No | string | Street name |
customer_address_number | No | string | House number |
customer_postal_code | No | string | Postal/ZIP code |
customer_city | No | string | City |
customer_country_code | No | string | 2-letter ISO country code |
customer_eori_number | No | string | EORI number |
customer_vat_number | No | string | VAT/BTW number |
representation_type | No | string | Customs representation type (1 = direct, 2 = indirect) |
customs_declaration_office | No | string | Default customs office code |
Example Request
curl -X POST https://app.borderbolt.com/api/v1/customers \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"customer_code": "CUST002",
"customer_name": "New Customer B.V.",
"customer_eori_number": "NL987654321012",
"customer_vat_number": "NL987654321B01",
"customer_address": "Kerkstraat",
"customer_address_number": "10",
"customer_postal_code": "1234AB",
"customer_city": "Rotterdam",
"customer_country_code": "NL",
"representation_type": "2"
}'Example Response
{
"data": {
"id": 502,
"customer_code": "CUST002",
"customer_name": "New Customer B.V.",
"customer_eori_number": "NL987654321012",
"customer_country_code": "NL",
"created_at": "2026-03-25T10:00:00.000000Z",
"updated_at": "2026-03-25T10:00:00.000000Z"
},
"message": "Customer created successfully."
}HTTP 201 is returned on success. HTTP 422 is returned if customer_code is already taken or validation fails.
Update Customer
Update an existing customer. Only fields included in the request body are changed.
PUT /api/v1/customers/{id}Request Body
Same fields as Create Customer, except customer_code cannot be updated.
Example Request
curl -X PUT https://app.borderbolt.com/api/v1/customers/502 \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"customer_eori_number": "NL111111111012",
"customs_declaration_office": "NL000412"
}'Example Response
{
"data": {
"id": 502,
"customer_code": "CUST002",
"customer_name": "New Customer B.V.",
"customer_eori_number": "NL111111111012",
"customs_declaration_office": "NL000412",
"updated_at": "2026-04-01T09:15:00.000000Z"
},
"message": "Customer updated successfully."
}Delete Customer
Delete a customer.
DELETE /api/v1/customers/{id}Example Request
curl -X DELETE https://app.borderbolt.com/api/v1/customers/502 \
-H "Authorization: Bearer {token}"Example Response
{
"message": "Customer deleted successfully."
}Deletion Restriction: Customers with linked declarations, transits, or dossiers cannot be deleted. Disable portal access instead by setting portal_access_enabled: false via Update Customer.
Customer Contacts
List Contacts
Retrieve all contacts for a customer.
GET /api/v1/customers/{id}/contactscurl https://app.borderbolt.com/api/v1/customers/501/contacts \
-H "Authorization: Bearer {token}"{
"data": [
{
"id": 1001,
"customer_masterdata_id": 501,
"name": "John Doe",
"email": "john.doe@example.nl",
"phone": "+31 20 1234568",
"position": "Logistics Manager",
"department": "Logistics",
"is_primary": true,
"receives_notifications": true,
"receives_approvals": false,
"language": "nl",
"notes": null,
"created_at": "2025-01-15T10:00:00.000000Z",
"updated_at": "2025-01-15T10:00:00.000000Z"
}
]
}Add Contact
Add a new contact to a customer.
POST /api/v1/customers/{id}/contactsRequest Body
| Field | Required | Type | Description |
|---|---|---|---|
name | Yes | string | Contact person name (max 255 chars) |
email | No | string | Email address |
phone | No | string | Phone number (max 50 chars) |
role | No | string | Job title/role (max 100 chars) |
is_primary | No | boolean | Mark as primary contact (default: false) |
curl -X POST https://app.borderbolt.com/api/v1/customers/501/contacts \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"name": "Jane Smith",
"email": "jane.smith@example.nl",
"phone": "+31 20 7654321",
"role": "Customs Coordinator",
"is_primary": false
}'{
"data": {
"id": 1002,
"customer_masterdata_id": 501,
"name": "Jane Smith",
"email": "jane.smith@example.nl",
"phone": "+31 20 7654321",
"is_primary": false,
"created_at": "2026-04-01T09:00:00.000000Z",
"updated_at": "2026-04-01T09:00:00.000000Z"
},
"message": "Contact added successfully."
}HTTP 201 is returned on success.
Update Contact
Update an existing contact. Contact update uses a flat route — the contact ID alone is sufficient.
PUT /api/v1/contacts/{contact_id}curl -X PUT https://app.borderbolt.com/api/v1/contacts/1002 \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"email": "jane.new@example.nl",
"is_primary": true
}'{
"data": {
"id": 1002,
"name": "Jane Smith",
"email": "jane.new@example.nl",
"is_primary": true,
"updated_at": "2026-04-01T10:00:00.000000Z"
},
"message": "Contact updated successfully."
}Delete Contact
Delete a contact. Contact delete also uses a flat route.
DELETE /api/v1/contacts/{contact_id}curl -X DELETE https://app.borderbolt.com/api/v1/contacts/1002 \
-H "Authorization: Bearer {token}"{
"message": "Contact deleted successfully."
}Field Reference
Customer Fields
| Field | Type | Description |
|---|---|---|
id | integer | Unique identifier |
customer_code | string | Unique customer code |
customer_name | string | Customer legal name |
customer_address | string | Street name |
customer_address_number | string | House / building number |
customer_postal_code | string | Postal code |
customer_city | string | City |
customer_country_code | string | 2-letter ISO country code |
customer_eori_number | string | EORI number (e.g. NL123456789012) |
customer_vat_number | string | VAT/BTW number |
representation_type | string | 1 = direct, 2 = indirect representation |
customs_declaration_office | string | Default customs office code |
warehouse_licence | string | Warehouse licence number |
warehouse_licence_type | string | Warehouse licence type code |
portal_access_enabled | boolean | Whether customer has portal access |
poa_valid_until | date | Power of Attorney expiry date (YYYY-MM-DD) |
Contact Fields
| Field | Type | Description |
|---|---|---|
id | integer | Unique identifier |
customer_masterdata_id | integer | Parent customer ID |
name | string | Contact person name |
email | string | Email address |
phone | string | Phone number |
position | string | Job title |
department | string | Department |
is_primary | boolean | Primary contact flag |
receives_notifications | boolean | Whether this contact receives event notifications |
receives_approvals | boolean | Whether this contact receives approval requests |
language | string | Preferred language (nl, en) |
notes | string | Internal notes |
Validation Rules
Customer Code
- Must be unique within your tenant
- Maximum 50 characters
- Cannot be changed after creation
EORI Number
- Format: 2-letter country code followed by up to 15 alphanumeric characters
- NL format:
NL+ 12 digits, e.g.NL123456789012
Country Code
- ISO 3166-1 alpha-2 (2 characters), e.g.
NL,BE,DE,GB