> ## Documentation Index > Fetch the complete documentation index at: https://bunny.net/docs/llms.txt > Use this file to discover all available pages before exploring further. # Android SDK > Integrate Bunny Stream into your Android apps with the Kotlin SDK - playback, uploads, camera capture, and embed view token authentication. The Bunny Stream Android SDK lets you quickly integrate the Bunny Stream player, uploads, and video management into your Android applications. ## Key Features * **Complete API Integration:** Full support for the Bunny REST Stream API * **Efficient Video Upload:** TUS protocol implementation for reliable, resumable uploads * **Advanced Video Player:** Custom-built player with full Bunny CDN integration * **Camera Upload Support:** Built-in capabilities for recording and uploading videos directly from the device camera * **Type-Safe API:** Fully typed Kotlin API for compile-time safety * **Background Processing:** Support for background uploads and downloads * **Comprehensive Error Handling:** Detailed error information and recovery options ## What is the Bunny Stream Android SDK? Bunny Stream is an Android library designed to seamlessly integrate Bunny's powerful video streaming capabilities into your Android applications. The library provides a robust set of tools for video management, playback, uploading, and camera-based video uploads, all through an intuitive **Kotlin API**. > [card] [Android SDK](https://github.com/BunnyWay/bunny-stream-android) > > [https://github.com/BunnyWay/bunny-stream-android](https://github.com/BunnyWay/bunny-stream-android) ## Token authentication When using the Android SDK, **two authentication layers exist**: * **Embed View Token Authentication** — controls access to the video. * **CDN Token Authentication** — protects delivery from Bunny CDN and is handled automatically by the SDK. This section focuses on **Embed View Token Authentication**, which must be handled by a **customer-managed backend or Edge Script** containing custom business logic that decides whether a client is allowed to play back a video by returning an embed view token. ### Embed View Token Authentication Embed View Token Authentication: * Authorizes a viewer to play a specific video * Is enforced at the **Stream API level** * Is required for private or restricted videos **Android SDK responsibility** * The **customer backend generates the token**. * The app requests the token and passes it to the `PlayVideo` call. * The SDK uses the token for playback; **CDN token signing happens automatically**. ### Supported authentication methods | Method | Android SDK | | - | - | | Embed View Token Authentication | Supported via customer backend | | CDN Token Authentication | Automatic | | Client-side token signing | Not supported | > [!WARNING] > > The **Video Library API Key** must **never** be included in your Android app. It is a secret that only your backend or Edge Script should hold. ### Backend requirements Your backend (or Edge Script) must: * Securely store the **Video Library API Key**, as it serves as a secret that must not be stored in the mobile app. * Authenticate the app user with your custom business logic. * Generate the embed view token by following the [token authentication signing procedure](https://bunny.net/docs/docs/stream/token-authentication#signing-procedure) (the token security key is your Video Library API Key). * Return `token` and `expires` values in the response: ```json theme={null} { "token": "SIGNED_EMBED_VIEW_TOKEN", "expires": 1710000000 } ``` > [!NOTE] > > Tokens should be **short-lived** (1–5 minutes recommended), unless you have a specific use case that requires a longer expiration. ### Edge Script example Below is an example Edge Script that generates embed view tokens. Store `VIDEO_LIBRARY_API_KEY` as an **Edge Script Secret**. ```typescript theme={null} BunnySDK.net.http.serve(async (request: Request): Promise => { const url = new URL(request.url); const apiKey = BunnySDK.env.VIDEO_LIBRARY_API_KEY; const videoId = url.searchParams.get("videoId"); const expires = Math.floor(Date.now() / 1000) + 300; // 5 minutes or adjust if needed if (!videoId) { return new Response(JSON.stringify({ error: "Missing videoId" }), { status: 400, headers: { "Content-Type": "application/json" }, }); } /* * ============================================================ * Custom authentication / authorization logic * ------------------------------------------------------------ * Perform your business checks here: * - Validate user identity (e.g. by using JWT, API key, or some other auth headers) * - Verify entitlement to this video * - Apply subscription / access rules * * Only generate a token if access is allowed. * ============================================================ */ // Example: // if (!isUserAuthorized(request, videoId)) { // return new Response( // JSON.stringify({ error: "Unauthorized" }), // { status: 403, headers: { "Content-Type": "application/json" } } // ); // } const token = generateEmbedViewToken(apiKey, videoId, expires); return new Response(JSON.stringify({ token, expires }), { headers: { "Content-Type": "application/json" }, }); }); /** * Embed View Token generation (per Bunny Stream docs): * * Token data sequence: * Video Library API Key + videoId + expires * * Steps: * 1. Concatenate the values in the order above (no separators) * 2. Generate HMAC-SHA256 using the Video Library API Key * 3. Base64 encode: : */ function generateEmbedViewToken( apiKey: string, videoId: string, expires: number, ): string { // @ts-ignore - crypto is available in the Edge runtime const crypto = require("crypto"); const data = apiKey + videoId + expires; const signature = crypto .createHmac("sha256", apiKey) .update(data) .digest("hex"); return Buffer.from(`${signature}:${expires}`).toString("base64"); } ``` ### Android SDK usage The `PlayVideo` call supports token parameters: ```kotlin theme={null} PlayVideo( ... videoId = "abc123", token = token, expires = expires ... ) ``` **Flow** **1. Request the embed token** Call your backend or Edge Script from the app to request a token for the target `videoId`. **2. Receive the token** Your backend returns `{ token, expires }`. **3. Play the video** Pass the `token` and `expires` values to the `PlayVideo` call. ## Important notes * The **Video Library API Key** must **never** be included in mobile apps. * Embed View Token Authentication is **required** if you don't want to publicly expose your videos. * CDN Token Authentication is applied to CDN URLs automatically if it is turned on in the video library. This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.