# Set up BitLabs — agent instructions

You are an AI agent integrating BitLabs monetization (offers and surveys)
into a publisher's app. Follow this page exactly. It is the routing layer: it
owns the ORDER of the integration and the exact questions to ask, and it
points you at the maintained reference pages for every detail — read those
pages, never work from memory of them.

## Access

BitLabs is **invite-only**. The human applies on the website; once invited
they create a Management API key under Dashboard → Company → API Keys. The
creation dialog shows the key **once**, together with the **Workspace ID** —
have them copy both. There is no API to discover the workspace from the key.

## Install the CLI (if `bitlabs --version` fails)

Download the archive for the machine you run on from
`https://bitlabs-cli.pages.dev/releases/latest/` — files are
`bitlabs_<version>_<darwin|linux|windows>_<amd64|arm64>.tar.gz` (`.zip` on
Windows) plus `checksums.txt`. Verify, then put both binaries on `PATH`:

```bash
curl -fsSLO https://bitlabs-cli.pages.dev/releases/latest/checksums.txt
curl -fsSLO "https://bitlabs-cli.pages.dev/releases/latest/$(grep -o 'bitlabs_[0-9.]*_darwin_arm64.tar.gz' checksums.txt)"   # pick your platform
shasum -a 256 -c checksums.txt --ignore-missing
tar -xzf bitlabs_*_darwin_arm64.tar.gz && install -m 0755 bitlabs bitlabs-mcp "$HOME/.local/bin/"
bitlabs --version
```

## Ground rules

- BitLabs has **no sign-in flow for agents**. Two values from the dashboard
  are everything you need to call the Management API (create the app, apply
  settings, read the App Token used in the integration): the **Workspace
  ID** (an identifier) and the **Workspace API Key** (`blpub_…`, the only
  secret). Collect them the way the best CLIs collect a token — say exactly
  where they come from and what they look like, ask for both in one message,
  accept them as pasted, and never echo the key back or write it into the
  publisher's project files. Storage: agents with a shell run
  `bitlabs login --workspace-id <id> --with-token` and feed the key on
  stdin (or the human runs `bitlabs login`, which prompts for both with the
  key hidden); hosts and CI set `BITLABS_API_KEY` + `BITLABS_WORKSPACE_ID`
  environment variables; `bitlabs whoami` shows which is in use.
- The **App UUID** is an identifier used only in CLI/tool arguments.
- The **App Token** (publishable) and **S2S Token** are cached automatically
  when the app configuration exposes them. The documented configuration does
  not include them, so setup may finish partially ready with explicit next
  steps naming the dashboard sections to copy each from — relay those steps
  verbatim; do not ask for tokens any other way.
- Never invent, guess, or reuse credentials from unrelated context.
- **Every integration call carries the publisher's user id** — the id of the
  end user in the publisher's own system (≤255 characters, none of
  `% $ * & #`). Ask how their app identifies users if it is not obvious;
  never invent one and never ship a placeholder. The same id comes back as
  `uid` in the reward callback.
- When a step says ask, ask with **exactly the options listed** — never add
  an "other" option and never assume a default. Use the host's buttons or
  choice UI if it has one; otherwise a numbered list.

## Integration order

1. **Collect the credentials, then bootstrap.** Run `bitlabs whoami`. If it
   reports no credentials, ask the human, in one message:
   > "I need two values from your BitLabs dashboard: your **Workspace ID**
   > and a **Workspace API Key**. Go to https://dashboard.bitlabs.ai →
   > Company → API Keys → create a key (any name, your workspace). The
   > dialog shows the key once (it starts with `blpub_`) next to the
   > Workspace ID — paste both here."
   Store them: `printf '%s' '<key>' | bitlabs login --workspace-id <id> --with-token`
   (the key never appears as a command argument). If you cannot run
   commands, give the human that command to run and continue with the same
   steps from their pasted output. Then run `bitlabs setup bootstrap --json`.
   It lists the
   workspace's apps (the list carries no names — matching reads each app's
   config), reuses the app matching `--app-name` (default "BitLabs Agent
   App") or creates it (a 403 on create means the workspace app limit is
   reached), and caches the App Token and S2S Token when the configuration
   exposes them. When it reports `ready: false`, relay its `next_steps`
   verbatim — App Token from Dashboard → Apps → the app → Integration, S2S
   token from the app's server-to-server section — and ask for nothing
   beyond them.
2. **Ask which demand formats to enable.** Offer exactly two options,
   multi-select: **Offers**, **Surveys**. No other option.
3. **Ask which integration they are building.** Offer exactly three,
   single-select: **iframe** (web offerwall embedded in a page),
   **User-based API** (direct REST — they render their own UI),
   **Mobile SDK**. No other option. If they choose Mobile SDK, ask one more
   question: **Android**, **iOS**, or **Flutter**. No other option.
4. **Ask the currency name.** Suggest **Coins**, **Points**, **Gems**,
   **Credits** — and accept any name they type.
5. **Ask the currency factor** — how many units equal 1 USD. Suggest
   **100**, **1000**, **10** — and accept any positive whole number they
   type.
6. **Configure the app** with those answers:
   `bitlabs setup configure-app --demand offers,surveys --currency-name Coins --currency-factor 100`
   (list only the formats they picked). It writes the documented identifiers
   (`app.features.offers.enabled`, `app.features.surveys.enabled`,
   `general.currency.symbol.content`, `general.currency.factor`,
   `app.behaviour.default_tab`) as the Management API's top-level
   `{internalIdentifier, value}` array and reads them back. A 403 means an
   identifier is not allowed.
7. **Build the integration they chose, passing their user id on every call:**
   - **iframe** → `bitlabs iframe validate-params --uid <USER_ID>`, then
     `bitlabs iframe generate-html --uid <USER_ID> --token <APP_TOKEN>` (or
     `generate-url`); `bitlabs iframe runtime-messages` for live theming.
   - **User-based API** → `bitlabs offers list --user-id <USER_ID>` and/or
     `bitlabs surveys list --user-id <USER_ID>` for the formats enabled in
     step 2; open the returned `click_url` (`continue_url` when already
     started); track with `offers history`, `surveys get-click` /
     `update-click`, `users history`. The API renders UI and tracks state;
     it never credits.
   - **Mobile SDK** → `bitlabs webview snippet --platform android|ios|flutter`;
     the WebView loads the offerwall URL with `uid=<USER_ID>&token=<APP_TOKEN>`.
8. **When the integration is finished, suggest wiring S2S reward callbacks
   into their current system** — rewards credit only through them:
   `bitlabs callbacks set-url --url https://<their-server>/bitlabs/callback`
   stores the templated URL (never a hash parameter — BitLabs appends
   `&hash=` at fire time); `bitlabs callbacks get-url` confirms;
   `bitlabs callbacks endpoint-template --framework express|fastify|next|generic`
   gives the handler (recompute HMAC-SHA1 over the URL without `hash` using
   the App Secret, reject mismatches, deduplicate by `tx`); then
   `bitlabs callbacks verify-hash` and `bitlabs callbacks-api test-url`.

## Where everything lives

- Docs home and API references: https://developer.bitlabs.ai/docs
- Dashboard (accounts, keys, app config, callback tester):
  https://dashboard.bitlabs.ai
- CLI + agent adapter: the CLI page on this site (install, TESTING guide,
  `setup checklist --json` returns this exact order with the options to
  offer at each question).
