# Configuring the SDK (/docs/guides/configuring)





`configure` is the single entry point for the SDK. Call it once at app startup,
before any other Rovenue method. Every other method is invalid until
`configure` has run.

<Callout type="warn">
  Calling any other SDK method before `configure` has run is a programming error,
  not a runtime condition to catch — on iOS it's a hard crash (not a throwable
  error), and on Android it throws a plain, non-`RovenueException`
  `IllegalStateException`. See [Calling the SDK before
  configure()](/docs/reference/errors#calling-the-sdk-before-configure) for the
  full per-platform breakdown. Put `configure` at the earliest possible entry
  point — `App.tsx` on React Native, `AppDelegate.application(_:didFinishLaunchingWithOptions:)`
  on iOS, or `Application.onCreate()` on Android — to make this impossible to get wrong.
</Callout>

### Types on this page [#types-on-this-page]

```ts
type RovenueConfig = {
  apiKey: string;       // your public SDK key (prefix rov_pub_)
  baseUrl?: string;     // optional — defaults to https://api.rovenue.io
  logLevel?: 'off' | 'error' | 'warn' | 'info' | 'debug' | 'trace'; // default 'warn'
  appVersion?: string;  // overrides the platform manifest value
};
```

| Field        | Type                                                         | Required | Description                                                                                                                        |
| ------------ | ------------------------------------------------------------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `apiKey`     | `string`                                                     | Yes      | Your **public** SDK key (`rov_pub_…`). Never use the secret key in the app.                                                        |
| `baseUrl`    | `string`                                                     | No       | Your Rovenue API base URL. Defaults to the hosted endpoint `https://api.rovenue.io`; override only when self-hosting.              |
| `logLevel`   | `'off' \| 'error' \| 'warn' \| 'info' \| 'debug' \| 'trace'` | No       | Verbosity of SDK logs. Defaults to `'warn'` — turn up to `'info'`/`'debug'` locally, never ship `'debug'`/`'trace'` in production. |
| `appVersion` | `string`                                                     | No       | App version string. Auto-read from the platform manifest — only override for standalone JVM builds.                                |

> Swift and Kotlin mirror these with platform-idiomatic parameter labels. See [Types](/docs/reference/types).

***

## Setting up [#setting-up]

<Steps>
  <Step>
    ### Find your API key [#find-your-api-key]

    Open your Rovenue dashboard, navigate to your
    project, and copy the **public** SDK key. It starts with `rov_pub_`.

    <Callout type="warn">
      Never embed your **secret** key (`rov_sec_…`) in the app binary. Secret keys
      are for server-to-server calls only. See [Methods — Configuration](/docs/reference/methods#configuration).
    </Callout>
  </Step>

  <Step>
    ### Call `configure` at startup [#call-configure-at-startup]

    Pass a `RovenueConfig` object (React Native) or named parameters (Swift /
    Kotlin) at the very first line of your app's lifecycle hook.

    <Tabs groupId="platform" items="['React Native', 'Swift', 'Kotlin']">
      <Tab value="React Native">
        ```ts
        import { Rovenue } from '@rovenue/react-native-sdk';

        Rovenue.configure({
          apiKey: 'rov_pub_...',
          logLevel: 'info',  // optional — turn up from the 'warn' default in dev
          appVersion: '1.2', // optional — inferred from app.json by default
        });
        ```
      </Tab>

      <Tab value="Swift">
        ```swift
        import Rovenue

        // AppDelegate.application(_:didFinishLaunchingWithOptions:)
        Rovenue.configure(
          apiKey: "rov_pub_...",
          logLevel: .info,     // optional — turn up from the .warn default
          appVersion: "1.2"   // optional — inferred from CFBundleShortVersionString
        )
        ```
      </Tab>

      <Tab value="Kotlin">
        ```kotlin
        import dev.rovenue.sdk.Rovenue

        // Application.onCreate()
        Rovenue.configure(
          apiKey = "rov_pub_...",
          logLevel = LogLevel.INFO, // optional — turn up from the LogLevel.WARN default
          appVersion = "1.2",  // optional — inferred from versionName
        )
        ```
      </Tab>
    </Tabs>

    <Callout type="info">
      **Self-hosting?** Pass `baseUrl` to point the SDK at your own deployment, e.g. RN `Rovenue.configure({ apiKey: 'rov_pub_...', baseUrl: 'https://api.acme.com' })`, Swift `Rovenue.configure(apiKey: "rov_pub_...", baseUrl: "https://api.acme.com")`, Kotlin `Rovenue.configure(apiKey = "rov_pub_...", baseUrl = "https://api.acme.com")`. The host must use `https://` — plain `http://` is accepted only for `localhost` during local development.
    </Callout>
  </Step>

  <Step>
    ### Verify the singleton is ready [#verify-the-singleton-is-ready]

    After `configure`, all SDK methods become available. On iOS and Android,
    subsequent calls go through the shared singleton (`Rovenue.shared`). On React
    Native they go directly through the `Rovenue` namespace.

    <Tabs groupId="platform" items="['React Native', 'Swift', 'Kotlin']">
      <Tab value="React Native">
        ```ts
        import { Rovenue } from '@rovenue/react-native-sdk';

        // Smoke-check: log the SDK version
        console.log('Rovenue SDK', Rovenue.getVersion());
        ```
      </Tab>

      <Tab value="Swift">
        ```swift
        // Smoke-check: log the SDK version
        print("Rovenue SDK", Rovenue.shared.getVersion())
        ```
      </Tab>

      <Tab value="Kotlin">
        ```kotlin
        // Smoke-check: log the SDK version
        println("Rovenue SDK ${Rovenue.shared.getVersion()}")
        ```
      </Tab>
    </Tabs>

    <Callout type="info">
      `configure` is a **static entry point**. On iOS and Android it initialises
      the shared singleton; every method afterwards is called on that instance
      (`Rovenue.shared.entitlement(…)` in Swift/Kotlin), or directly on `Rovenue`
      in React Native.
    </Callout>
  </Step>

  <Step>
    ### (Optional) Attach a log handler [#optional-attach-a-log-handler]

    Set a custom log handler immediately after `configure` to route SDK logs into
    your own logging infrastructure.

    <Tabs groupId="platform" items="['React Native', 'Swift', 'Kotlin']">
      <Tab value="React Native">
        ```ts
        import { Rovenue } from '@rovenue/react-native-sdk';

        Rovenue.setLogHandler((entry) => {
          myLogger.log(entry.level, entry.message);
        });
        ```
      </Tab>

      <Tab value="Swift">
        ```swift
        Rovenue.shared.setLogHandler { entry in
          myLogger.log(level: entry.level, message: entry.message)
        }
        ```
      </Tab>

      <Tab value="Kotlin">
        ```kotlin
        Rovenue.shared.setLogHandler { entry ->
          myLogger.log(entry.level, entry.message)
        }
        ```
      </Tab>
    </Tabs>
  </Step>
</Steps>

***

## Platform defaults for `appVersion` [#platform-defaults-for-appversion]

| Platform           | Source                                     |
| ------------------ | ------------------------------------------ |
| iOS / Expo         | `CFBundleShortVersionString` / `app.json`  |
| Android            | `versionName` in `build.gradle`            |
| Standalone JVM SDK | No manifest — provide the value explicitly |

***

<Callout type="info">
  **Next steps:** After configuring the SDK, identify the logged-in user with
  [`identify()`](/docs/guides/identifying-users) and check their entitlements
  with [`entitlement()`](/docs/guides/entitlements). See also:
  [Methods — Configuration](/docs/reference/methods#configuration).
</Callout>
