clients - BevvyTech/BrewskiDocs GitHub Wiki

Clients

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.

GET /clients/search

  • 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:
    {
      "results": [
        { "id": "5e7f...", "name": "Lantern Taproom" },
        { "id": "7c2a...", "name": "Lantern Taproom β€” Receiving Dock" }
      ]
    }
    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.

GET /clients

  • 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:
    {
      "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"
              }
            ]
          }
        }
      ]
    }
    Send "awrsNumber": null to 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: billingAddress and shippingAddress remain in the payload for backwards compatibility with existing clients, but they are derived from the structured addressBook data. New integrations should rely on addressBook.billing and addressBook.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.

POST /clients

  • 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.

PATCH /clients/:id

  • 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.

POST /clients/claim/email

  • Auth: Bearer token. Caller must belong to the target team.
  • Body:
    {
      "teamId": "d43c046a-10a1-4f52-bd0a-9bf16f828ab7",
      "email": "[email protected]"
    }
    • email must match the client’s contactEmail and the client must be flagged as wholesale.
  • Response 200: { "client": { ... } } matching the payload returned by GET /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.

POST /clients/claim/code

  • Auth: Bearer token. Caller must belong to the target team.
  • Body:
    {
      "teamId": "d43c046a-10a1-4f52-bd0a-9bf16f828ab7",
      "code": "BRSK-2025-ZETA"
    }
    • code is a pairing code issued by the client (single-use or reusable).
  • Response 200: { "client": { ... } } matching GET /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.

POST /clients/:id/people

  • 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.

PATCH /clients/:id/people/:personId

  • 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 site field to tie the contact to a specific venue from the address book. Send an empty string to clear the association.

DELETE /clients/:id/people/:personId

  • Response 204
  • Errors: 401 unauthorized, 403 when caller is not on the team, 404 when contact missing.
⚠️ **GitHub.com Fallback** ⚠️