Pooli Mobile App Background Pooli Mobile App Background

API Overview

Welcome to the Pooli API, a complementary extension to our intuitive Pooli app interface. While the app provides a user-friendly way to manage your pool, our API opens up additional possibilities, enabling advanced interactions with your pool data programmatically. This powerful combination means that you can now automate routine tasks, integrate with other systems, or even create custom applications, all while continuing to enjoy the ease and familiarity of the Pooli app. The Pooli API serves as your versatile gateway to comprehensive and efficient pool management.

Version: 1.0 (Alpha) - Date: August 4, 2025

Note: This is a beta version of the Pooli API and may be subject to changes and updates.

OpenAPI specification

The machine-readable definition is an OpenAPI 3 spec.

The development host is https://dev-api.pooli.app.

Key Features

  • Programmatic Pool Management: Seamlessly create and delete pools using our API. This feature allows for dynamic management of pool data, offering flexibility and control to automate your pool maintenance and management tasks.
  • Reading Inventory: Get real-time access to your pool inventory. View available supplies, equipment status, and reorder levels with simple API calls.
  • Managing To-Dos: Stay on top of your pool maintenance tasks. The API provides functionalities to manage and update your to-do lists, helping you prioritize and schedule maintenance activities efficiently.
  • Adding Logs: Easily add detailed logs to track pool maintenance, chemical levels, and more. Our API allows for quick log entries, ensuring you have up-to-date information about your pool's condition.
  • Accessing All Logs: Retrieve comprehensive log data for any specified time range. This feature is ideal for analyzing trends, monitoring pool health over time, and making informed decisions about pool care.

With the Pooli API, you can create custom scripts and applications that leverage these features, streamlining your pool management process and enhancing your pool experience. Our robust, easy-to-use API is designed to empower users, developers, and pool enthusiasts alike to innovate and optimize pool care.

For feature requests, bug reports, or any questions, please email support@pooli.app.

Rate Limiting and Quotas

At Pooli, we have implemented rate limiting to ensure fair and efficient usage of our API. The rate limits vary based on the user's membership status in the Pool Club.

Pool Club Members

Pool Club members enjoy the benefit of unlimited API requests. This privilege allows for more extensive use of the API, facilitating advanced automation, integration, and application development without the concern of hitting usage caps. Discover the huge list of features and benefits of being a Pool Club member and consider signing up to enjoy these advantages.

Non-Club Members

Non-club members are subject to a rate limit of 60 requests per hour. This limit ensures that all users have fair access to the API while preventing excessive use that could impact service quality.

It is important for all users to be aware of these limits to avoid interruptions in service. If you encounter any issues or have questions about our rate limiting policies, please contact support@pooli.app.

Authentication

The Pooli API authenticates every request with a Bearer credential. A long-lived API key is a valid Bearer credential. An access token from POST /v1/auth/token is also a valid Bearer credential. Each key belongs to one user.

Step 1: Generate Your API Key

Log in to your Pooli Dashboard. Navigate to the API section and generate your unique API key. This key is associated with your account and provides access to your user-specific documents.

Rate Limiting

Rate limiting is applied on a per-user basis to ensure fair usage and system stability. Be mindful of your request frequency to stay within the rate limits. See Rate Limiting and Quotas.

API Base URLs

The Pooli API is available at the following endpoints:

  • Production: https://api.pooli.app
  • Development: https://dev-api.pooli.app

Using the API Key

Send the long-lived API key on every request that should run as that key:

Authorization: Bearer YOUR_API_KEY

Personal routes under /v1/users are for the key's own user only. The user id in the path must be the user id on the key.

Versioning

API versions are specified in the url. The current version is v1. For example, to fetch all pools for a user:

curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  'https://api.pooli.app/v1/users/YOUR_USER_ID/pools'

To fetch a specific pool:

curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  'https://api.pooli.app/v1/users/YOUR_USER_ID/pools/YOUR_POOL_ID'

Replace YOUR_API_KEY, YOUR_USER_ID, and YOUR_POOL_ID with your API key, user ID, and pool ID. An access token can stand in for the API key in the same Authorization header.

Access tokens

Endpoint: POST /v1/auth/token

Description: Exchanges a long-lived API key for an access token. The token lasts 15 minutes. You can request a longer lifetime, up to 60 minutes. Send the access token as Authorization: Bearer YOUR_ACCESS_TOKEN.

curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  'https://api.pooli.app/v1/auth/token'

Endpoint: POST /v1/auth/token/refresh

Description: Issues a new access token from a current access token. The new token follows the same lifetime: 15 minutes, with a maximum of 60 minutes.

curl -X POST \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  'https://api.pooli.app/v1/auth/token/refresh'

API key lifecycle

These routes manage the caller's API key. Authenticate with that key, or with an access token issued for it.

Regenerate

Endpoint: POST /v1/auth/keys/regenerate

Description: Invalidates outstanding access tokens and keeps the same API key string.

curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  'https://api.pooli.app/v1/auth/keys/regenerate'

Rotate

Endpoint: POST /v1/auth/keys/rotate

Description: Issues a new API key. The previous key keeps working until graceEndsAt. The grace period defaults to 7 days. Set it from 0 to 90 days. The response includes graceEndsAt.

curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  'https://api.pooli.app/v1/auth/keys/rotate'

Revoke

Endpoint: POST /v1/auth/keys/revoke

Description: Revokes the API key. Revocation takes effect immediately.

curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  'https://api.pooli.app/v1/auth/keys/revoke'

Acting as another user

On organization routes, the organization owner can send X-Pooli-Act-As set to the user id to act as. The header is owner-only. It is rejected on /v1/users routes.

curl -X GET \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "X-Pooli-Act-As: USER_ID" \
  -H "Content-Type: application/json" \
  'https://api.pooli.app/v1/organizations/ORG_ID/pools'

Idempotency-Key

Idempotency-Key is required on creates for customers, organization pools, stops, inventory, and reminders. Send a new key for each new create. Send the same key again when you retry that create.

Idempotency-Key: 6f1c2b4e-9a7d-4c31-8e2a-1b5d0f3a7c88

Roles

Personal routes under /v1/users are for the key's own user only.

Organization routes accept an organization owner, an organization admin, or an active technician, within these limits:

  • Owner and admin: billing (invoices and payments), estimates, service subscriptions, customer create, organization pool create, patch, and delete, CSV import, and technician status.
  • Owner, admin, and active technicians: creating stops, and creating, patching, and deleting organization logs.

An active technician is a user in the organization's technicians collection with status active. Technician status values are active, inactive, and rejected.

See Organization Endpoints for each route.

User Endpoints

These endpoints allow individual users to manage their personal pool data, logs, inventory, and reminders. Personal routes are for the key's own user only.

Pools Endpoints

Manage and retrieve information about pools with these endpoints. They allow you to fetch, create, and delete pool data associated with a specific user or organization. Personal routes under /v1/users are for the key's own user only.

GET Endpoints

  • Fetch All Pools

    Endpoint: GET /:uid/pools

    Description: Retrieves a list of all pools associated with the given user ID (uid). Includes sanitized data.

    Access: uid must be the user id on the API key.

    Parameters: uid (path) - User ID for pool association.

  • Fetch Specific Pool

    Endpoint: GET /:uid/pools/:poolId

    Description: Retrieves detailed information about a specific pool associated with the user ID (uid).

    Access: uid must be the user id on the API key.

    Parameters: uid (path) - User ID, poolId (path) - Pool ID.

POST Endpoints

  • Create Pool

    POST Endpoint: Create Pool

    Endpoint: POST /:uid/pools

    Description: Creates a new pool associated with the given user ID (uid). The pool data must adhere to a specific format, as outlined below.

    Access: uid must be the user id on the API key.

    URL Parameters: uid (path) - User ID.

    Body Parameters: The pool parameter is a complex object with the following properties:

    {
                "name": [String],
                "poolType": ["vinyl", "plaster", "fiberglass", default: "plaster"],
                "filterCategory": ["de", "sand", "cartridge", default: "cartridge"],
                "sanitizingChemical": ["chlorine", "bromine", "swg", "biguanides", "peroxide", "natural", "freshwater"],
                "gallonEstimate": [Number],
                "isIndoor": [Boolean, default: false],
                "supplimentalSanitizers": ["mineral", "ozone", "uv", "ionize", "aop", "enzyme", "unknown", default: []],
    }

    Each property in the pool object has specific data types and constraints. Some properties, such as sanitizingChemical, poolType, filterCategory, and supplimentalSanitizers, are restricted to predefined values as specified in their respective enums.

DELETE Endpoints

  • Delete Specific Pool

    Endpoint: DELETE /:uid/pools/:poolId

    Description: Deletes a specific pool identified by poolId for the given user ID (uid).

    Access: uid must be the user id on the API key.

    Parameters: uid (path) - User ID, poolId (path) - Pool ID to be deleted.

Organization Pool Endpoints

These endpoints allow organizations to manage pools. Callers must be an organization owner, an organization admin, or an active technician. Create, patch, and delete are limited to the owner and admin. See Roles.

Organization GET Endpoints

  • Fetch All Organization Pools

    Endpoint: GET /:orgId/pools

    Description: Retrieves a list of all pools associated with the given organization ID. Includes sanitized data.

    Access: Organization owner, admin, or active technician.

    Parameters: orgId (path) - Organization ID for pool association.

  • Fetch Specific Organization Pool

    Endpoint: GET /:orgId/pools/:poolId

    Description: Retrieves detailed information about a specific pool associated with the organization ID.

    Access: Organization owner, admin, or active technician.

    Parameters: orgId (path) - Organization ID, poolId (path) - Pool ID.

Organization POST Endpoints

  • Create Organization Pool

    Endpoint: POST /:orgId/pools

    Description: Creates a new pool associated with the given organization ID. Uses the same pool data format as user pools.

    Access: Organization owner or admin.

    Idempotency-Key: Required. Send a new Idempotency-Key for each new pool, and the same key when retrying that create.

    Parameters: orgId (path) - Organization ID.

    Body Parameters: Same pool object structure as user pool creation.

Organization PATCH Endpoint

  • Update Organization Pool

    Endpoint: PATCH /:orgId/pools/:poolId

    Description: Updates a pool for the given organization ID.

    Access: Organization owner or admin.

    Parameters: orgId (path) - Organization ID, poolId (path) - Pool ID.

Organization DELETE Endpoints

  • Delete Specific Organization Pool

    Endpoint: DELETE /:orgId/pools/:poolId

    Description: Deletes a specific pool identified by poolId for the given organization ID.

    Access: Organization owner or admin.

    Parameters: orgId (path) - Organization ID, poolId (path) - Pool ID to be deleted.

Logs Endpoints

These endpoints allow for the management and retrieval of log entries related to pool maintenance, tests, products, and more. Available for both user pools and organization pools. Personal routes are for the key's own user only. Send the API key or an access token as a Bearer credential.

GET Endpoints

  • Fetch All Logs for a Pool

    Endpoint: GET /:uid/pools/:poolId/logs

    Description: Retrieves all log entries for a specific pool. Supports pagination and filtering by log type.

    Access: uid must be the user id on the API key.

    Parameters: uid (path), poolId (path), startAfter (query, optional), type (query, optional).

  • Fetch Specific Log Entry

    Endpoint: GET /:uid/pools/:poolId/logs/:logId

    Description: Retrieves a specific log entry by its ID for a given pool.

    Access: uid must be the user id on the API key.

    Parameters: uid (path), poolId (path), logId (path).

POST Endpoint

  • Create Log Entry

    Endpoint: POST /:uid/pools/:poolId/logs

    Description: Creates a new log entry for a pool. The log structure varies based on the log type.

    Access: uid must be the user id on the API key.

    Parameters: uid (path), poolId (path), type (query), data (body).

    Example Request:

    curl -X POST \
      -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "chemicalReading": {
          "temp": 78,
          "orp": 500,
          "ph": 7.1,
          "alkalinity": 100,
          "calcium": 250,
          "cyanuricAcid": 50
        }
      }' \
      'https://api.pooli.app/v1/users/{userId}/pools/{poolId}/logs?type=test'

    Development Endpoint:

    'https://dev-api.pooli.app/v1/users/{userId}/pools/{poolId}/logs?type=test'

DELETE Endpoint

  • Delete Log Entry

    Endpoint: DELETE /:uid/pools/:poolId/logs/:logId

    Description: Deletes a specific log entry for a given pool.

    Access: uid must be the user id on the API key.

    Parameters: uid (path), poolId (path), logId (path).

Organization Log Endpoints

These endpoints allow organizations to manage log entries for their pools. Reading logs is available to the organization owner, an admin, or an active technician. Creating, patching, and deleting organization logs is available to the owner, an admin, and active technicians. See Roles.

Organization GET Endpoints

  • Fetch All Logs for an Organization Pool

    Endpoint: GET /:orgId/pools/:poolId/logs

    Description: Retrieves all log entries for a specific organization pool. Supports pagination and filtering by log type.

    Access: Organization owner, admin, or active technician.

    Parameters: orgId (path), poolId (path), startAfter (query, optional), type (query, optional).

  • Fetch Specific Organization Log Entry

    Endpoint: GET /:orgId/pools/:poolId/logs/:logId

    Description: Retrieves a specific log entry by its ID for a given organization pool.

    Access: Organization owner, admin, or active technician.

    Parameters: orgId (path), poolId (path), logId (path).

Organization POST Endpoint

  • Create Organization Log Entry

    Endpoint: POST /:orgId/pools/:poolId/logs

    Description: Creates a new log entry for an organization pool. Uses the same log structure and types as user logs.

    Access: Organization owner, admin, or active technician.

    Parameters: orgId (path), poolId (path), type (query), data (body).

Organization PATCH Endpoint

  • Update Organization Log Entry

    Endpoint: PATCH /:orgId/pools/:poolId/logs/:logId

    Description: Updates a log entry for an organization pool.

    Access: Organization owner, admin, or active technician.

    Parameters: orgId (path), poolId (path), logId (path).

Organization DELETE Endpoint

  • Delete Organization Log Entry

    Endpoint: DELETE /:orgId/pools/:poolId/logs/:logId

    Description: Deletes a specific log entry for a given organization pool.

    Access: Organization owner, admin, or active technician.

    Parameters: orgId (path), poolId (path), logId (path).

Log Types and Their Fields

The following rules define the required and optional fields for each log type. Common fields for all logs include:

  • creatorName: string (optional)
  • createdAt: date (defaults to current date if not provided)
  • updatedAt: date (optional)

Test Log

Used to record pool chemical and equipment readings.

Type: type=test

  • scan: object, optional (default: null)
  • targets: object, optional (as defined by targetParser)
  • chemicalReading: object, required
    • totalChlorine: number, default null
    • freeChlorine: number, default null
    • totalBromine: number, default null
    • peroxide: number, default null
    • ph: number, default null
    • temp: number, default null
    • cyanuricAcid: number, default null
    • calcium: number, default null (total hardness - includes magnesium and other minerals)
    • cch: number, default null (calcium hardness - calcium content only, always less than total hardness)
    • salt: number, default null
    • alkalinity: number, default null
    • phosphates: number, default null
    • totalDissolvedSolids: number, default null
    • combinedChlorine: number, default null
    • copper: number, default null
    • borates: number, default null
    • swgProduction: number, default null
    • testMethod: string, default null
    • biguanide: number, default null
    • iron: number, default null
    • orp: number, default null
  • gallonEstimate: number, optional
  • equipmentReading: object, optional
    • otherMethod: string, default null
    • swgPercent: number, default null
    • observation: string, default null
    • filterPressure: number, default null
    • testMethod: string, default null

Product Log

Type: type=product

  • amount: number, default 0
  • productName: string, required
  • unitType: string, required
  • form: string, required
  • productType: string, required
  • solution: object, required
    • customType: string, default null
    • form: string
    • name: string
    • percent: number, default null
    • productType: string

Note Log

Type: type=note

  • note: string, required
  • attachments: object, default null

Maintenance Log

Type: type=maintenance

  • maintenances: array, required
    • Each item:
      • name: string
      • category: string
      • duration: number, default null
      • aggregationName: string, optional

Inventory Endpoint

These endpoints allow for retrieving and creating inventory data for a specific user. Personal routes are for the key's own user only.

GET Endpoint

  • Fetch Inventory

    Endpoint: GET /:uid/inventory

    Description: Retrieves the inventory data associated with the specified user ID (uid).

    Access: The uid must be the user id on the API key.

    Parameters: uid (path) - User ID for which the inventory data is to be fetched.

POST Endpoint

  • Create Inventory

    Endpoint: POST /:uid/inventory

    Description: Creates inventory for the user.

    Access: The uid must be the user id on the API key.

    Idempotency-Key: Required. Send a new Idempotency-Key for each new create, and the same key when retrying that create.

    Parameters: uid (path) - User ID.

Reminders Endpoint

These endpoints allow for retrieving and creating reminders for a specific user and pool. Personal routes are for the key's own user only.

GET Endpoint

  • Fetch Reminders

    Endpoint: GET /:uid/pools/:poolId/reminders

    Description: Retrieves the reminders data associated with the specified user ID (uid) and pool.

    Access: The uid must be the user id on the API key.

    Parameters: uid (path) - User ID for which the reminders data is to be fetched, poolId (path) - Pool ID.

POST Endpoint

  • Create Reminder

    Endpoint: POST /:uid/pools/:poolId/reminders

    Description: Creates a reminder for the user and pool.

    Access: The uid must be the user id on the API key.

    Idempotency-Key: Required. Send a new Idempotency-Key for each new reminder, and the same key when retrying that create.

    Parameters: uid (path) - User ID, poolId (path) - Pool ID.

Organization Endpoints

These endpoints enable organizations to manage technicians, customers, pools, stops, logs, billing, estimates, and service subscriptions. The caller must be an organization owner, an admin, or an active technician, within the limits in Roles.

Organization Endpoints

These endpoints allow organizations to manage their resources including technicians, customers, pools, stops, logs, billing, estimates, and service subscriptions. Callers must be an organization owner, an organization admin, or an active technician, within the limits in Roles.

Technician Management

Get Organization Technicians

Endpoint: GET /:orgId/technicians

Description: Retrieves all technicians associated with the organization.

Access: Organization owner, admin, or active technician.

Parameters: orgId (path) - Organization ID.

Query Parameters: status (optional) - Filter by technician status: active, inactive, or rejected.

Update Technician Status

Endpoint: POST /:orgId/technicians/:techId/status

Description: Sets a technician's status.

Access: Organization owner or admin.

Parameters: orgId (path) - Organization ID, techId (path) - Technician ID.

Body Parameters: status (string) - active, inactive, or rejected. message (string, optional) - Status message.

Pool Management

Get All Organization Pools

Endpoint: GET /:orgId/pools

Description: Retrieves all pools associated with the organization. Includes sanitized data.

Access: Organization owner, admin, or active technician.

Parameters: orgId (path) - Organization ID.

Query Parameters: assigned (optional) - Filter for assigned/unassigned pools.

Get Specific Organization Pool

Endpoint: GET /:orgId/pools/:poolId

Description: Retrieves detailed information about a specific pool.

Access: Organization owner, admin, or active technician.

Parameters: orgId (path) - Organization ID, poolId (path) - Pool ID.

Create Organization Pool

Endpoint: POST /:orgId/pools

Description: Creates a new pool for the organization. Uses the same pool data format as user pools.

Access: Organization owner or admin.

Idempotency-Key: Required. Send a new Idempotency-Key for each new pool, and the same key when retrying that create.

Parameters: orgId (path) - Organization ID.

Body Parameters: pool (object) - Pool data with same structure as user pool creation.

Example Pool Object:
{
    "name": "Organization Pool 1",
    "poolType": "plaster",
    "filterCategory": "cartridge",
    "sanitizingChemical": "chlorine",
    "gallonEstimate": 20000,
    "isIndoor": false,
    "supplimentalSanitizers": ["mineral"]
}
Example request:
curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6f1c2b4e-9a7d-4c31-8e2a-1b5d0f3a7c88" \
  -d '{
    "name": "Organization Pool 1",
    "poolType": "plaster",
    "filterCategory": "cartridge",
    "sanitizingChemical": "chlorine",
    "gallonEstimate": 20000,
    "isIndoor": false,
    "supplimentalSanitizers": ["mineral"]
  }' \
  'https://api.pooli.app/v1/organizations/{orgId}/pools'

Update Organization Pool

Endpoint: PATCH /:orgId/pools/:poolId

Description: Updates an organization pool. Send the pool fields to change.

Access: Organization owner or admin.

Parameters: orgId (path) - Organization ID, poolId (path) - Pool ID.

Delete Organization Pool

Endpoint: DELETE /:orgId/pools/:poolId

Description: Deletes a specific pool from the organization.

Access: Organization owner or admin.

Parameters: orgId (path) - Organization ID, poolId (path) - Pool ID.

Log Management

Get Organization Pool Logs

Endpoint: GET /:orgId/pools/:poolId/logs

Description: Retrieves all log entries for an organization pool. Supports pagination and filtering.

Access: Organization owner, admin, or active technician.

Parameters: orgId (path) - Organization ID, poolId (path) - Pool ID.

Query Parameters: startAfter (optional) - Pagination cursor, type (optional) - Log type filter.

Get Specific Organization Log

Endpoint: GET /:orgId/pools/:poolId/logs/:logId

Description: Retrieves a specific log entry for an organization pool.

Access: Organization owner, admin, or active technician.

Parameters: orgId (path) - Organization ID, poolId (path) - Pool ID, logId (path) - Log ID.

Create Organization Pool Log

Endpoint: POST /:orgId/pools/:poolId/logs

Description: Creates a new log entry for an organization pool. Uses the same log structure and types as user logs.

Access: Organization owner, admin, or active technician.

Parameters: orgId (path) - Organization ID, poolId (path) - Pool ID.

Query Parameters: type (required) - Log type (test, maintenance, product, etc.).

Body Parameters: Log data structure varies by type - see log types section below.

Example Test Log Creation:
curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "chemicalReading": {
      "temp": 78,
      "orp": 500,
      "ph": 7.1,
      "alkalinity": 100,
      "calcium": 250,
      "cyanuricAcid": 50
    }
  }' \
  'https://api.pooli.app/v1/organizations/{orgId}/pools/{poolId}/logs?type=test'

Update Organization Pool Log

Endpoint: PATCH /:orgId/pools/:poolId/logs/:logId

Description: Updates a log entry on an organization pool. The body uses the same fields as the log type.

Access: Organization owner, admin, or active technician.

Parameters: orgId (path) - Organization ID, poolId (path) - Pool ID, logId (path) - Log ID.

Delete Organization Pool Log

Endpoint: DELETE /:orgId/pools/:poolId/logs/:logId

Description: Deletes a specific log entry from an organization pool.

Access: Organization owner, admin, or active technician.

Parameters: orgId (path) - Organization ID, poolId (path) - Pool ID, logId (path) - Log ID.

Customers

Create customer

Description: Creates a customer for the organization.

Access: Organization owner or admin.

Idempotency-Key: Required on create. Send a new Idempotency-Key for each new customer, and the same key when retrying that create.

Stops

Create stop

Description: Creates a stop for the organization.

Access: Organization owner, admin, or active technician.

Idempotency-Key: Required on create. Send a new Idempotency-Key for each new stop, and the same key when retrying that create.

Billing

Invoices and payments

Description: Invoice and payment routes for the organization.

Access: Organization owner or admin.

Estimates

Estimates

Description: Estimate routes for the organization.

Access: Organization owner or admin.

Service subscriptions

Service subscriptions

Description: Service subscription routes for the organization.

Access: Organization owner or admin.

Organization Authentication

Access Requirements: Organization endpoints require that the API key holder is an organization owner, an organization admin, or an active technician:

  • Organization owner: User ID matches the organization's ownerUserId
  • Organization admin
  • Active technician: User exists in the organization's technicians collection with status: "active"

Owner and admin can use billing (invoices and payments), estimates, service subscriptions, customer create, organization pool create, patch, and delete, CSV import, and technician status.

Owner, admin, and active technicians can create stops, and can create, patch, and delete organization logs.

The organization owner can send X-Pooli-Act-As on these routes. See Acting as another user and Roles.

Error Response: Unauthorized users receive 403 Access denied: Not authorized for this organization

Customers & Pools CSV Import

Bulk import customers and pools for an organization. Each row typically represents one pool; customer columns may repeat.

Access: Organization owner or admin.

  • Upload in the app (Customers/Pools screen → Import menu)
  • Or upload on the web in your Organization dashboard ("Import Customers & Pools CSV")
  • API: Firebase Callable customers-importCsv (group prefix required)

Request payload:

{
  organizationId: "ORG_ID",
  csvText: "organizationId,customer_name,...\n...",
  // Optional advanced mapping/defaults; see guide for details
  mapping: { /* header alias overrides */ },
  defaults: { /* e.g., organizationId if not in every row */ }
}

Example client call:

// Web / Firebase Functions client
const importFn = firebase.functions().httpsCallable('customers-importCsv');
await importFn({ organizationId: 'abc123', csvText });

See the CSV Import Guide for exact fields, header aliases, defaults, and full examples.

Products CSV Import

Bulk create and update organization products from a CSV. Designed for retailers to upload their catalog in one click.

  • Available via app and web dashboard only (no public callable API)
  • Web: use the Products section on the Organization dashboard ("Import Products CSV")

Required columns: organizationId and either product_id (for updates) or both name and category (for new products).

Optional columns: description, defaultPrice, isTaxable, type (oneTime|subscription), stripeProductId, stripePriceId, cost, msrp, notes, tags (comma/semicolon/pipe separated), useMsrpForMarkup, deliverable, activeInStore, photos (comma/semicolon/pipe separated URLs).

Example header + rows (showing advanced fields on second row):

organizationId,product_id,name,category,defaultPrice,isTaxable,type,deliverable,activeInStore,tags,cost,msrp,notes,useMsrpForMarkup,photos
abc123,,Chlorine Tabs,Chemicals,19.99,true,oneTime,true,true,chlorine;tabs,,,,,
abc123,P123,Monthly Service,Services,120.00,true,subscription,false,false,service;recurring,80.00,150.00,"Includes filter cleaning",true,https://example.com/img1.jpg|https://example.com/img2.jpg