> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stateset.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Run StateSet Freight locally

> Start the TMS demo, inspect loads and operations, then configure a persistent workspace and verify its tenant and role.

Start from a checkout of `stateset-freight` with Rust **1.90+**, Node.js **22**, and npm.
The synthetic demo can run without PostgreSQL; real workspaces require it.

**Working surface:** local Freight web app and REST API.**Bring:** repository access; PostgreSQL and individual credentials for real work.**Finish with:** visible synthetic loads and a verified tenant/role read.

## Open the synthetic demo

Run from the Freight repository root on a fresh checkout:

```bash theme={null}
cp .env.example .env
npm --prefix web ci
bash scripts/dev.sh
```

Open **[http://127.0.0.1:3010](http://127.0.0.1:3010)**. The API listens on **[http://127.0.0.1:8090](http://127.0.0.1:8090)**.
The example configuration sets `FREIGHT_DEMO=true`; the script supplies configuration to both
API and web processes and stops its API on exit.

Inspect the synthetic customers, loads, carriers, drivers, and equipment. Open a load to
review its route and version, then inspect the operations queue, documents, and finance views.
Use the demo indicator to confirm that you are working with synthetic records.

```bash theme={null}
curl --fail-with-body --silent --show-error http://127.0.0.1:8090/ready
```

Without `DATABASE_URL`, changes reset when the API restarts. Secret-free demos also use a
web-process recovery key; recovery across web restarts requires a stable configured secret
or keyring. If an incompatible compiler cache prevents startup, the repository documents
`RUSTC_WRAPPER= bash scripts/dev.sh` as a local workaround.

## Configure a persistent real workspace

Stop the development script. Configure an isolated PostgreSQL database and update `.env`:

```dotenv theme={null}
FREIGHT_DEMO=false
DATABASE_URL=postgres://freight:password@127.0.0.1:5432/freight
FREIGHT_API_KEYS_JSON='{"replace-with-a-random-token-of-at-least-32-characters":{"tenant_id":"your-org","subject":"user:dispatcher-1","role":"operations"}}'
FREIGHT_SESSION_SECRET=replace-with-an-independent-random-secret-of-at-least-32-characters
FREIGHT_WEB_ORIGIN=http://127.0.0.1:3010
```

Replace the database credentials and both secrets with your own values. Restart
`bash scripts/dev.sh` and sign in with the configured workspace credential. An operations
identity can plan and dispatch; finance approval requires a separate authorized identity.
Use explicit identity objects rather than the legacy string-to-tenant mapping, which grants
administrator access.

For remote use, configure HTTPS, the actual `FREIGHT_WEB_ORIGIN`, and
`FREIGHT_COOKIE_SECURE=true`. Both API and web must receive `FREIGHT_DEMO=false`.
The development script exports the root `.env`; a manually
started Next.js process needs exported variables or `web/.env.local`.

## Verify the data source

Set `FREIGHT_TOKEN` in your shell to an existing configured credential. These calls read the
verified identity and the bounded shipment catalog:

```bash theme={null}
export FREIGHT_API_URL=http://127.0.0.1:8090

curl --fail-with-body --silent --show-error "$FREIGHT_API_URL/v1/access" \
  --header "Authorization: Bearer $FREIGHT_TOKEN"

curl --fail-with-body --silent --show-error "$FREIGHT_API_URL/v1/loads?limit=25" \
  --header "Authorization: Bearer $FREIGHT_TOKEN"
```

Confirm `tenant_id` and `access.subject`, `access.role`, and `access.capabilities` before
entering customer, carrier, load, or invoice data. Use returned record IDs for later requests.

**Checkpoint:** the access response identifies the intended tenant and actor,
and the catalog is either explicitly empty or contains the expected loads.

## Before deployment

Default `FREIGHT_MIGRATIONS=apply` applies schema upgrades at startup. With separate database
identities, run the built `stateset-freight --migrate` binary as schema owner, reconcile runtime
grants, then serve with `FREIGHT_MIGRATIONS=verify`. Preserve the complete matching migration
ledger, business data, files, recovery keys, credentials, and configuration during backup and
restore. Do not downgrade an older writer over newer storage.

Continue with [REST and MCP](/stateset-freight/api-and-mcp) or
[the OMS/WMS/TMS handoff](/guides/oms-wms-tms).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.