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

# BYOR quickstart

> Use your existing agent and session logic without building a receiver.

**Start here for most integrations.** The CLI receives call requests from Chert and invokes your application callbacks. Your application returns a ready LiveKit session; the wrapper does not create rooms or dispatch agents.

## Before you start

Ask Chert for the private-preview package and pilot access. Use Node **22.23.2 or 24.14.0**, a POSIX host, and a durable local state directory. Start your agent using its normal command.

<Steps>
  <Step title="Install and initialize">
    From your application's directory, replace the tarball path with the file supplied by Chert:

    ```bash theme={null}
    npm install --save-exact /path/to/chert-local-transport-proof-0.0.0.tgz
    npx --no-install chert init --non-interactive --mode byor \
      --config "$PWD/chert.json" --state-dir "$PWD/.chert/state"
    ```

    This creates `chert.json` and `chert-handler.ts`. It refuses to overwrite existing files. Keep the config and state out of version control.
  </Step>

  <Step title="Connect the generated callbacks">
    Edit `chert-handler.ts` to call your application's existing session logic. No HTTP server is needed.

    | Callback | Your application does |
    | - | - |
    | `health()` | Reports `available`, `unavailable`, or `unknown` without creating a session. |
    | `prepare(call, context)` | Persists `call.operation_id`, then returns a ready session or declines before the deadline. |
    | `lifecycle(call, event, context)` | Processes each `event.event_id` idempotently; acknowledges after durable processing. |
    | `recover(call, context)` | Looks up the original operation, handles cancellation when required, and reports verified settlement and cleanup. |

    A ready-session response has this shape (values come from your application):

    ```typescript theme={null}
    return {
      action: "accept",
      ready: true,
      session_ref: session.reference,
      session_expires_at: session.expiresAtMs,
      livekit_url: session.livekitUrl,
      participant_token: session.bridgeToken,
      remote_participant_identity: session.agentIdentity,
    };
    ```

    Use a non-secret session reference and a short-lived, call-scoped token. Expiry is an absolute Unix timestamp in milliseconds and must fit the token lifetime. Return `{ action: "decline" }` when you cannot prepare the call.

    <Note>
      The generated handler deliberately declines until you implement it. A returned `accept` must mean the session is actually ready. Preparation has a four-second budget; the CLI does not make slow agent cold starts faster.
    </Note>

    Honor `context.signal` and `context.remaining_ms`. Recovery must inspect the original operation, never repeat preparation. Report `settled: true` only when no further creation can complete, and `cleanup: "clean"` only after verifying resources are cleaned up or absent.

    The installed package includes a complete session-store example in `node_modules/chert-local-transport-proof/examples/byor/`. Adapt it to your application's durable storage and cleanup logic.
  </Step>

  <Step title="Compile and check">
    Export the handler as an **ES module** and point the config at its compiled JavaScript. Use your application's existing ESM build. For a new standalone project, set `"type": "module"` in `package.json` and compile the generated file:

    ```bash theme={null}
    npm pkg set type=module
    npm install --save-dev --save-exact typescript@6.0.2 @types/node@24.13.6
    npx tsc --module NodeNext --target ES2023 --skipLibCheck ./chert-handler.ts
    npx --no-install chert check --config "$PWD/chert.json" --json
    ```

    `check` is non-allocating and currently exits **3** for partial diagnostics. Read the reported checks; this alone is not a failed installation or proof of a working FaceTime call.
  </Step>

  <Step title="Enroll, activate, and run">
    Follow [Connect your project](/facetime-cli/connect) to create an enrolled config and activate your chosen line. Run the connector with that config:

    ```bash theme={null}
    npx --no-install chert byor --config "$PWD/chert.enrolled.json" --json
    ```

    Keep your agent and connector running. Coordinate a real inbound audio test with Chert, confirm conversation audio, end the call, and verify cleanup before testing again.
  </Step>
</Steps>

Missing or failed health is shown as unknown, not ready. Known-unavailable health declines calls; unknown health still allows bounded per-call preparation, which must explicitly establish readiness. Unresolved cleanup blocks new calls at the preview's capacity of one.
