# Quickstart

Create a project, mint a publish token, and send your first broadcast through the MoQ CDN.

## Set up with the CLI

With Node 22 or later, the [CLI](/cli) handles login and setup. Each create uses a key you can reuse after an uncertain outcome:

<!-- cli-quickstart -->
```sh
npx @moq/pro login
npx @moq/pro projects create --idempotency-key quickstart-cli-project-1 --json
# Set PID to the returned id.
npx @moq/pro keys create "$PID" --idempotency-key quickstart-cli-key-1 --json
# Set KID to the returned id, and EXPIRES to an RFC 3339 time one hour ahead.
npx @moq/pro token publish "$PID" "$KID" hello.hang --expires "$EXPIRES" \
  --idempotency-key "quickstart-cli-mint-$EXPIRES" --json
```
<!-- /cli-quickstart -->

Use the returned URL as `PUBLISH_URL` in the upstream publisher command below. The CLI prints JSON automatically when redirected; `--json` makes that explicit. Its [command reference](/cli) is generated from `--help`.

## Create an account token

Sign in to [MoQ Pro](https://moq.pro/login), then open [API Tokens](https://moq.pro/settings/tokens). Create a **write** token with access to **all projects**. Copy it when it appears: the dashboard only shows the secret once.

An account token manages CDN resources. A signing key mints the separate media token that publishers and viewers use to connect to a relay. Keep both kinds of credential private.

The commands below need a POSIX shell, curl, and jq. Set your account token without putting it in shell history:

```sh
read -r MOQ_API_TOKEN
export MOQ_API_TOKEN
API=https://api.moq.pro/v1
```

## Create a project

```sh
PROJECT=$(curl --fail-with-body --silent --show-error "$API/projects" \
  -H "Authorization: Bearer $MOQ_API_TOKEN" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: "quickstart-project-1"' \
  --data '{}')
PID=$(printf '%s' "$PROJECT" | jq -er '.id')
printf '%s\n' "$PID"
```

Use the returned immutable `id` in API paths and relay URLs. You can give a project a vanity name later. Accounts have a cap on owned projects; if you reach it, [ask support for more](mailto:support@moq.pro).

For subsequent independent runs, choose new idempotency keys. The [API reference](/api) describes create replay, errors, and pagination from the same specification used by the API.

## Create a signing key

```sh
KEY=$(curl --fail-with-body --silent --show-error "$API/projects/$PID/keys" \
  -H "Authorization: Bearer $MOQ_API_TOKEN" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: "quickstart-key-1"' \
  --data '{"algorithm":"HS256","label":"Quickstart"}')
KID=$(printf '%s' "$KEY" | jq -er '.id')
```

The key stays in the API so you can mint media tokens without downloading private signing material.

## Mint a publish URL

Grant permission to publish the broadcast named `hello.hang` for one hour. The `.hang` suffix names the media format, so the dashboard can preview it:

```sh
EXPIRES=$(($(date +%s) + 3600))
BODY=$(jq -nc --arg root "$PID" --argjson exp "$EXPIRES" \
  '{root: $root, publish: ["hello.hang"], exp: ($exp | todate)}')
TOKEN=$(curl --fail-with-body --silent --show-error "$API/projects/$PID/keys/$KID/token" \
  -H "Authorization: Bearer $MOQ_API_TOKEN" \
  -H 'Content-Type: application/json' \
  -H "Idempotency-Key: \"quickstart-mint-$EXPIRES\"" \
  --data "$BODY" | jq -er '.token')
PUBLISH_URL="https://cdn.moq.pro/$PID/hello.hang?jwt=$TOKEN"
```

The account token is used only with the management API. The `jwt` in the publish URL is the scoped media token; anyone with that URL can publish `hello.hang` until it expires. The idempotency key follows the expiry, so re-running the block mints a fresh token.

## Publish with the upstream CLI

Install [the upstream moq CLI](https://doc.moq.dev/bin/cli) and FFmpeg. With Rust installed, `cargo install moq-cli` installs the `moq` command.

```sh
ffmpeg -re -f lavfi -i testsrc=size=1280x720:rate=30 \
  -c:v libx264 -preset veryfast -tune zerolatency -g 60 -pix_fmt yuv420p \
  -f mpegts - | moq --connect "$PUBLISH_URL" import ts
```

While it runs, open your project in the [dashboard](https://moq.pro/project). The Broadcasts page shows `hello.hang` with a live preview and its traffic. Stop FFmpeg with Ctrl-C when finished.

Use [the upstream docs](https://doc.moq.dev) for media formats, clients, and protocol details. The management [API reference](/api) covers CDN resources.
