> For the complete documentation index, see [llms.txt](https://docs.flxbl.io/flxbl/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.flxbl.io/flxbl/sfp/environment-management/pools/scratch-org-pools/defining-a-pool.md).

# Defining a pool

A scratch org pool is described by a pool definition file — a JSON file kept in the repository and validated against `pooldefinition.schema.json`. The definition below describes a pool tagged `DEV-POOL` with a capacity of 20 scratch orgs.

```json
{
    "tag": "DEV-POOL",
    "maxAllocation": 20,
    "expiry": 10,
    "batchSize": 10,
    "configFilePath": "config/project-scratch-def.json",
    "relaxAllIPRanges": true,
    "installAll": true,
    "enableSourceTracking": true,
    "retryOnFailure": true,
    "succeedOnDeploymentErrors": true,
    "fetchArtifacts": {
        "npm": {
            "scope": "myproject"
        }
    }
}
```

## Registering the definition with the server

From v51 the definition is stored on sfp server. Push the file once, then prepare the pool by tag:

```bash
sfp server pool config push -f config/poolconfig.json \
  -r <owner>/<repo> \
  --dev-hub-username <devhub> \
  --branch main
```

```bash
sfp server pool scratch init -p DEV-POOL -r <owner>/<repo>
```

`sfp server pool config push` validates the file against the schema before it is stored, so a malformed definition is rejected at push time rather than mid-prepare. The `--branch` value determines which branch prepare checks out when it builds the pool, and `--dev-hub-username` determines which registered Dev Hub creates the scratch orgs.

`sfp server pool scratch init` also answers to the aliases `sfp prepare`, `sfp pool prepare`, `sfp pool scratch prepare` and `sfp pool scratch init`.

Pool state — membership, credentials and allocation — lives on sfp server, so `--repository` and `--tag` are required; the earlier local mode (`--poolconfig`/`-f` with `--targetdevhubusername`/`-v`) has been removed.

## Configuration properties

| Property                            | Type            | Description                                                                                                                                                                                         |
| ----------------------------------- | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| tag                                 | string          | Name used to identify the scratch org pool                                                                                                                                                          |
| waitTime                            | int             | Minutes the command should wait for a scratch org to be created, Default is 6 minutes                                                                                                               |
| expiry                              | int             | Number of days for which the scratch orgs are active                                                                                                                                                |
| maxAllocation                       | int             | Maximum capacity of the pool                                                                                                                                                                        |
| batchSize                           | int             | Number of processes for creating scratch orgs in parallel                                                                                                                                           |
| configFilePath                      | string          | Path to scratch org definition JSON file                                                                                                                                                            |
| succeedOnDeploymentErrors           | boolean         | Whether to persist scratch org to the pool for a deployment error, default:true                                                                                                                     |
| snapshotPool                        | string          | Name of an earlier prepared pool to build this pool on top of (multi-stage prepare). Prepare claims only as many AVAILABLE orgs from the snapshot pool as this pool is short of its `maxAllocation` |
| installAll                          | boolean         | Install all package artifacts, in addition to the managed package dependencies                                                                                                                      |
| releaseConfigFile                   | string          | Path to a release config file to create pools with selected packages. Use in conjunction with installAll                                                                                            |
| enableSourceTracking                | boolean         | Enable source tracking by deploying packages using source:push and persisting source tracking files                                                                                                 |
| disableSourcePackageOverride        | boolean         | Disable overriding unlocked packages as source packages, Rather install unlocked packages as unlocked                                                                                               |
| relaxAllIPRanges                    | boolean         | Relax all IP addresses, allowing all global access to scratch orgs                                                                                                                                  |
| ipRangesToBeRelaxed                 | array           | Range of IP addresses that can access the scratch orgs                                                                                                                                              |
| retryOnFailure                      | boolean         | Retry installation of a package on a failed deployment                                                                                                                                              |
| maxRetryCount                       | number          | Maximum number of times a package should be retried while deploying to a scratchorg, The default is 2                                                                                               |
| keys                                | string          | Keys for managed package dependencies, as `packageA:pw123 packageB:pw123`. Overridden by the `--keys` flag                                                                                          |
| noAnchestors                        | boolean         | Exclude second-generation managed package ancestors from the scratch org, default:false                                                                                                             |
| enableVlocity                       | boolean         | Apply Vlocity pack settings and run the Vlocity initial install on each org                                                                                                                         |
| preDependencyInstallationScriptPath | string          | Path to a script executed before package dependencies are installed in a scratch org. See [Lifecycle scripts](#lifecycle-scripts)                                                                   |
| postDeploymentScriptPath            | string          | Path to a script executed after all packages (dependencies + repository) are installed. See [Lifecycle scripts](#lifecycle-scripts)                                                                 |
| fetchArtifacts                      | boolean\|object | Where prepare sources artifacts from. See [Artifact sources](#artifact-sources)                                                                                                                     |
| fetchArtifacts.artifactFetchScript  | string          | Path to the shell script containing logic for fetching artifacts from a universal registry, if not using npm                                                                                        |
| fetchArtifacts.npm                  | object          | Fetch artifacts from an NPM registry                                                                                                                                                                |
| fetchArtifacts.npm.scope            | string          | Scope of the NPM package                                                                                                                                                                            |
| fetchArtifacts.npm.npmrcPath        | string          | Path to the `.npmrc` used to authenticate to the NPM registry. Overridden by the `--npmrcpath` flag                                                                                                 |

A package carrying `"ignoreOnStage": ["prepare"]` in `sfdx-project.json` is excluded from the pool, whether artifacts are fetched or built.

## Checkpoint packages

A package marked `"checkpointForPrepare": true` in `sfdx-project.json` is treated as a checkpoint during prepare. It is set per package, not in the pool definition, but it changes how `succeedOnDeploymentErrors` behaves.

When `succeedOnDeploymentErrors` is `true` and a package fails to deploy, prepare keeps the org only if at least one checkpoint package deployed; otherwise the org is deleted rather than added to the pool. When `succeedOnDeploymentErrors` is `false`, any failure deletes the org, so checkpoint packages add nothing.

See [Checkpoint packages](/flxbl/sfp/environment-management/pools/scratch-org-pools/pool-operations/preparing-pools/checkpoint-packages.md) for the full behaviour and an example.

## Artifact sources

`fetchArtifacts` selects where the artifacts installed into each scratch org come from.

| Value                                     | Behaviour                                                                   |
| ----------------------------------------- | --------------------------------------------------------------------------- |
| `true`                                    | Fetch from the server's internal artifact registry. Requires `--repository` |
| `{ "npm": { "scope": "myproject" } }`     | Fetch from an NPM registry using the given scope                            |
| `{ "artifactFetchScript": "./fetch.sh" }` | Run the given script to fetch each artifact                                 |
| omitted or `false`                        | Build every package from the head of the branch instead of fetching         |

Prepare resolves each package's version from its latest git tag and fetches that version. A package whose artifact is missing from the registry is skipped with a warning, which surfaces later as a deployment failure.

{% hint style="warning" %}
Building rather than fetching produces a pool from the current head of the branch, which is not the same set of packages that has been validated and released. Pools are intended to be prepared from previously validated artifacts.
{% endhint %}

## Lifecycle scripts

The pool definition accepts two script hooks. Both run once per scratch org, inside the org's own preparation job.

| Property                              | Runs                                                                                                                         |
| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `preDependencyInstallationScriptPath` | After IP ranges are relaxed and the sfpowerscripts artifact package is installed, before any package dependency is installed |
| `postDeploymentScriptPath`            | After every artifact has been deployed to the org                                                                            |

The full per-org sequence is:

```
relax IP ranges
  → install sfpowerscripts artifact package
    → preDependencyInstallationScriptPath
      → install external package dependencies
        → Vlocity configuration (if enableVlocity)
          → deploy all artifacts
            → postDeploymentScriptPath
```

### Parameters

Both scripts receive positional parameters, in the same style as the package-level [pre/post deployment scripts](https://docs.flxbl.io/flxbl/sfp/building-artifacts/configuring-installation-behaviour-of-a-package/pre-post-deployment-script).

**`preDependencyInstallationScriptPath`**

| Position | Value                       |
| -------- | --------------------------- |
| 1        | Username of the scratch org |
| 2        | Username of the Dev Hub     |

**`postDeploymentScriptPath`**

| Position | Value                                                                                                                     |
| -------- | ------------------------------------------------------------------------------------------------------------------------- |
| 1        | Username of the scratch org                                                                                               |
| 2        | Username of the Dev Hub                                                                                                   |
| 3        | Deployment status. `succeed` once the deployment stage has run; empty when `installAll` is false, as nothing was deployed |

{% hint style="info" %}
The deployment status does not distinguish a partial deployment. When `succeedOnDeploymentErrors` keeps an org whose packages did not all deploy, the script still receives `succeed`. A script that must react to a partial deployment should check the org itself rather than this parameter.
{% endhint %}

### Execution

* Paths are resolved relative to the project directory. In server mode that is the worktree prepare checks out for the configured branch, not the directory the command was launched from.
* Scripts run with the project directory as their working directory, under a 30 minute timeout.
* `NO_COLOR=1` and `FORCE_COLOR=0` are set for the script, so `sf ... --json` output stays parseable by tools such as `jq`.
* Scripts are executed with `sh -e`. A non-zero exit fails the preparation job for that scratch org: the org is deleted from the Dev Hub, counted against `failedToCreate`, and reported to the server as an error. `succeedOnDeploymentErrors` does not cover this — it applies to package deployment failures, not to hook failures.

### Example

```json
{
    "tag": "DEV-POOL",
    "maxAllocation": 20,
    "installAll": true,
    "preDependencyInstallationScriptPath": "scripts/pool/enable-deliverability.sh",
    "postDeploymentScriptPath": "scripts/pool/seed-data.sh"
}
```

```bash
#!/bin/bash
# scripts/pool/seed-data.sh
set -e

SCRATCH_ORG_USERNAME=$1
DEVHUB_USERNAME=$2
DEPLOYMENT_STATUS=$3

if [ -z "$DEPLOYMENT_STATUS" ]; then
  echo "No packages were deployed, skipping data seed"
  exit 0
fi

sf data import tree --plan data/seed-plan.json --target-org "$SCRATCH_ORG_USERNAME"
sf org assign permset --name Seeded_Data_Access --target-org "$SCRATCH_ORG_USERNAME"
```

Scripts are read from the repository at the branch prepare checked out, so they may reference other files in the repository. This differs from package-level pre/post deployment scripts, which are copied into the artifact and run detached from version control.

## Schema

The JSON schema for the pool definition file is [`pooldefinition.schema.json`](https://source.flxbl.io/flxbl/sfp-pro) in `resources/schemas`. It is applied by `sfp server pool config push` and by the local-file path of `sfp server pool scratch init`.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.flxbl.io/flxbl/sfp/environment-management/pools/scratch-org-pools/defining-a-pool.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
