Clients - BevvyTech/BrewskiDocs GitHub Wiki
| Method | Path | Description |
|---|---|---|
GET |
/clients |
Paginated clients for a team with order counts. |
GET |
/clients/search |
Lightweight lookup by client or delivery-site name (returns id + display name). |
POST |
/clients |
Create a client for the given team. |
POST |
/clients/claim/email |
Link an existing wholesale client to the team by contact email. |
POST |
/clients/claim/code |
Link an existing wholesale client via pairing code. |
PATCH |
/clients/:id |
Update an existing client. |
POST |
/clients/:id/people |
Add a contact person to a client. |
PATCH |
/clients/:id/people/:personId |
Update a contact person. |
DELETE |
/clients/:id/people/:personId |
Remove a contact person. |
- Auth: Bearer token. Any authenticated admin user; results are scoped to the callerβs active teams.
-
Query Parameters:
-
query(string, required) β Partial match (min 2 characters) against client names or active delivery-site names. -
limit(int β€ 25, default 10) β Maximum number of entries to return.
-
-
Response 200:
When a delivery site matches the query the display name includes both the client and site name for disambiguation. The endpoint intentionally returns only IDs and display names to minimise data exposure.
{ "results": [ { "id": "5e7f...", "name": "Lantern Taproom" }, { "id": "7c2a...", "name": "Lantern Taproom β Receiving Dock" } ] }
-
Query Parameters:
-
teamId(uuid, required) -
filter(recent | never | once) -
recentDays(int β€ 365, defaults to 30) -
sort(name | lastOrderedAt, default name) -
direction(asc | desc, default asc) -
page,pageSize(β€ 200)
-
-
Response 200:
Send
{ "teamId": "d43c046a-10a1-4f52-bd0a-9bf16f828ab7", "filter": null, "sort": "name", "direction": "asc", "page": 1, "pageSize": 25, "total": 2, "pages": 1, "results": [ { "id": "5e7f...", "name": "Lantern Taproom", "contactEmail": "[email protected]", "contactPhone": "+44 20 7946 0011", "address": "1 Brew Street, London", "billingAddress": "1 Brew Street, London", "shippingAddress": "Warehouse 3, London", "notes": "Prefers Monday deliveries", "awrsNumber": "XAW000000123", "paymentTermsAmount": 14, "paymentTermsUnit": "days", "whatThreeWords": "keg.cellar.taps", "deposits": { "keg": { "enabled": true, "amountMinor": 2500 }, "cask": { "enabled": null, "amountMinor": null }, "summary": { "balanceMinor": -2500, "creditMinor": 2500, "liabilityMinor": 0 } }, "orderCount": 6, "lastOrderedAt": "2025-01-28T09:13:00.000Z", "addressBook": { "billing": { "id": "b0cb5d57-02e7-47f4-8fd9-244555d7d0f9", "addressLine1": "Lantern Taproom", "addressLine2": "112 King Street", "addressLine3": null, "locality": "London", "region": "United Kingdom", "postalCode": "SW1A 1AA", "countryCode": "GB", "instructions": null, "createdAt": "2025-02-04T12:30:00.000Z", "updatedAt": "2025-02-04T12:30:00.000Z" }, "deliverySites": [ { "id": "35d91e6c-6861-4d35-8e8a-1686b1d1330f", "name": "Lantern Taproom Receiving Dock", "addressLine1": "Lantern Taproom", "addressLine2": "Receiving Dock", "addressLine3": "4 Mason Yard", "locality": "London", "region": "United Kingdom", "postalCode": "SW1A 1AB", "countryCode": "GB", "instructions": "Deliveries 09:00β15:00 via rear alley.", "createdAt": "2025-02-04T12:30:00.000Z", "updatedAt": "2025-02-04T12:30:00.000Z" } ] } } ] }"awrsNumber": nullto clear an existing registration reference.
Providing the optional addressBook object replaces the entire stored address book for the client. Send billing: null to remove the billing record or omit addressBook altogether to leave previously stored addresses unchanged.
- Errors: 401 unauthorized, 403 when caller is not on the team.
Note:
billingAddressandshippingAddressremain in the payload for backwards compatibility with existing clients, but they are derived from the structuredaddressBookdata. New integrations should rely onaddressBook.billingandaddressBook.deliverySites.
awrsNumber is optional and accepts uppercase letters, digits, spaces, and hyphens up to 32 characters. When omitted the client record remains without an AWRS reference.
Deposit overrides use the top-level fields kegDepositEnabled, kegDepositMinor, caskDepositEnabled, and caskDepositMinor. Provide explicit booleans and prices (in minor units) to override the team default, or send null to clear a client-specific value. The deposits.summary object reports the rolling ledger balance (balanceMinor), available credit (creditMinor when negative), and outstanding liability (liabilityMinor when positive). See Docs/api/Deposits.md for full ledger behaviour.
- Auth: Bearer token. Caller must belong to the target team.
-
Body:
{ "teamId": "d43c046a-10a1-4f52-bd0a-9bf16f828ab7", "name": "Lantern Taproom", "contactEmail": "[email protected]", "contactPhone": "+44 20 7946 0011", "address": "1 Brew Street, London", "awrsNumber": "XAW000000123", "kegDepositEnabled": true, "kegDepositMinor": 2500, "caskDepositEnabled": null, "caskDepositMinor": null, "addressBook": { "billing": { "addressLine1": "Lantern Taproom", "addressLine2": "112 King Street", "locality": "London", "postalCode": "SW1A 1AA", "countryCode": "GB" }, "deliverySites": [ { "name": "Lantern Taproom Receiving Dock", "addressLine1": "Lantern Taproom", "addressLine2": "Receiving Dock", "addressLine3": "4 Mason Yard", "locality": "London", "postalCode": "SW1A 1AB", "countryCode": "GB", "instructions": "Deliveries 09:00β15:00 via rear alley." } ] }, "paymentTermsAmount": 14, "paymentTermsUnit": "days", "whatThreeWords": "keg.cellar.taps" } -
Response 201:
{ "client": { "id": "5e7f...", "teamId": "d43c046a-10a1-4f52-bd0a-9bf16f828ab7", "name": "Lantern Taproom", "contactEmail": "[email protected]", "contactPhone": "+44 20 7946 0011", "address": "1 Brew Street, London", "billingAddress": "1 Brew Street, London", "shippingAddress": null, "vatNumber": null, "awrsNumber": "XAW000000123", "notes": "Prefers Monday deliveries", "paymentTermsAmount": 14, "paymentTermsUnit": "days", "whatThreeWords": "keg.cellar.taps", "deposits": { "keg": { "enabled": true, "amountMinor": 2500 }, "cask": { "enabled": null, "amountMinor": null }, "summary": { "balanceMinor": 0, "creditMinor": 0, "liabilityMinor": 0 } }, "createdAt": "2025-02-04T12:30:00.000Z", "updatedAt": "2025-02-04T12:30:00.000Z", "addressBook": { "billing": { "id": "b0cb5d57-02e7-47f4-8fd9-244555d7d0f9", "addressLine1": "Lantern Taproom", "addressLine2": "112 King Street", "addressLine3": null, "locality": "London", "region": "United Kingdom", "postalCode": "SW1A 1AA", "countryCode": "GB", "instructions": null, "createdAt": "2025-02-04T12:30:00.000Z", "updatedAt": "2025-02-04T12:30:00.000Z" }, "deliverySites": [ { "id": "35d91e6c-6861-4d35-8e8a-1686b1d1330f", "name": "Lantern Taproom Receiving Dock", "addressLine1": "Lantern Taproom", "addressLine2": "Receiving Dock", "addressLine3": "4 Mason Yard", "locality": "London", "region": "United Kingdom", "postalCode": "SW1A 1AB", "countryCode": "GB", "instructions": "Deliveries 09:00β15:00 via rear alley.", "createdAt": "2025-02-04T12:30:00.000Z", "updatedAt": "2025-02-04T12:30:00.000Z" } ] } } } - Errors: 400 (validation), 401 unauthorized, 403 when caller is not on the team.
- Auth: Bearer token. Caller must belong to the clientβs team.
-
Body (any subset):
{ "name": "Lantern Taproom", "address": "1 Brew Street, London", "whatThreeWords": "keg.cellar.taps", "awrsNumber": "XAW000000123", "paymentTermsAmount": 21, "paymentTermsUnit": "days", "addressBook": { "billing": { "id": "b0cb5d57-02e7-47f4-8fd9-244555d7d0f9", "addressLine1": "Lantern Taproom", "addressLine2": "112 King Street", "locality": "London", "postalCode": "SW1A 1AA", "countryCode": "GB" }, "deliverySites": [ { "id": "35d91e6c-6861-4d35-8e8a-1686b1d1330f", "name": "Lantern Taproom Receiving Dock", "addressLine1": "Lantern Taproom", "addressLine2": "Receiving Dock", "addressLine3": "4 Mason Yard", "locality": "London", "postalCode": "SW1A 1AB", "countryCode": "GB" } ] } } -
Response 200:
{ "client": { "id": "5e7f...", "teamId": "d43c046a-10a1-4f52-bd0a-9bf16f828ab7", "name": "Lantern Taproom", "email": "[email protected]", "phone": "+44 20 7946 0011", "address": "1 Brew Street, London", "billingAddress": "1 Brew Street, London", "shippingAddress": null, "vatNumber": null, "awrsNumber": "XAW000000123", "notes": "Prefers Monday deliveries", "paymentTermsAmount": 21, "paymentTermsUnit": "days", "whatThreeWords": "keg.cellar.taps", "deposits": { "keg": { "enabled": null, "amountMinor": null }, "cask": { "enabled": true, "amountMinor": 1800 }, "summary": { "balanceMinor": -2500, "creditMinor": 2500, "liabilityMinor": 0 } }, "createdAt": "2025-02-04T12:30:00.000Z", "updatedAt": "2025-02-06T09:15:00.000Z", "addressBook": { "billing": { "id": "b0cb5d57-02e7-47f4-8fd9-244555d7d0f9", "addressLine1": "Lantern Taproom", "addressLine2": "112 King Street", "addressLine3": null, "locality": "London", "region": "United Kingdom", "postalCode": "SW1A 1AA", "countryCode": "GB", "instructions": null, "createdAt": "2025-02-04T12:30:00.000Z", "updatedAt": "2025-02-04T12:30:00.000Z" }, "deliverySites": [ { "id": "35d91e6c-6861-4d35-8e8a-1686b1d1330f", "name": "Lantern Taproom Receiving Dock", "addressLine1": "Lantern Taproom", "addressLine2": "Receiving Dock", "addressLine3": "4 Mason Yard", "locality": "London", "region": "United Kingdom", "postalCode": "SW1A 1AB", "countryCode": "GB", "instructions": "Deliveries 09:00β15:00 via rear alley.", "createdAt": "2025-02-04T12:30:00.000Z", "updatedAt": "2025-02-06T09:15:00.000Z" } ] } } } - Errors: 400 (validation), 401 unauthorized, 403 when caller is not on the team, 404 when client missing.
- Auth: Bearer token. Caller must belong to the target team.
-
Body:
{ "teamId": "d43c046a-10a1-4f52-bd0a-9bf16f828ab7", "email": "[email protected]" }-
emailmust match the clientβscontactEmailand the client must be flagged as wholesale.
-
-
Response 200:
{ "client": { ... } }matching the payload returned byGET /clients/:id. -
Errors:
-
400β client is not available for claims (non-wholesale). -
401β unauthorized. -
403β caller is not a member of the team. -
404β client not found for the supplied email. -
409β client already linked to the team.
-
- Auth: Bearer token. Caller must belong to the target team.
-
Body:
{ "teamId": "d43c046a-10a1-4f52-bd0a-9bf16f828ab7", "code": "BRSK-2025-ZETA" }-
codeis a pairing code issued by the client (single-use or reusable).
-
-
Response 200:
{ "client": { ... } }matchingGET /clients/:id. -
Errors:
-
400β client is not available for claims via pairing code. -
401β unauthorized. -
403β caller is not a member of the team. -
404β pairing code not found. -
409β pairing code already used or client already linked to the team. -
410β pairing code expired.
-
-
Body:
{ "name": "Jane Operator", "position": "General Manager", "email": "[email protected]", "phone": "+44 20 7946 0022", "mobile": "+44 7700 900223", "site": "Lantern Taproom Receiving Dock" } -
Response 201:
{ "person": { "id": "cnt-1...", "clientId": "5e7f...", "name": "Jane Operator", "position": "General Manager", "email": "[email protected]", "phone": "+44 20 7946 0022", "mobile": "+44 7700 900223", "site": "Lantern Taproom Receiving Dock", "createdAt": "2025-02-04T12:45:00.000Z", "updatedAt": "2025-02-04T12:45:00.000Z" } } - Errors: 400 (validation), 401 unauthorized, 403 when caller is not on the team, 404 when client missing.
-
Body: any subset of
name,position,email,phone,mobile,site. -
Response 200:
{ "person": { ... } }with updated values. - Errors: 400 (validation), 401 unauthorized, 403 when caller is not on the team, 404 when contact missing.
Tip: Use the
sitefield to tie the contact to a specific venue from the address book. Send an empty string to clear the association.
- Response 204
- Errors: 401 unauthorized, 403 when caller is not on the team, 404 when contact missing.