# Input Parameters > Source: `src/content/docs/actors/input.mdx` > Canonical URL: https://rivet.dev/docs/actors/input > Description: Pass initialization data to actors when creating instances --- Actors can receive input parameters when created, allowing for flexible initialization and configuration. Input is passed during actor creation and is available in lifecycle hooks. ## Passing Input to Actors Input is provided when creating actor instances using the `input` property: ```typescript import { actor, setup } from "rivetkit"; import { createClient } from "rivetkit/client"; interface GameInput { gameMode: string; maxPlayers: number; difficulty?: string; } const game = actor({ createState: (c, input: GameInput) => ({ gameMode: input.gameMode, maxPlayers: input.maxPlayers, difficulty: input.difficulty ?? "medium", }), actions: {} }); const registry = setup({ use: { game } }); const client = createClient("http://localhost:6420"); // Client side - create with input const gameHandle = await client.game.create(["game-123"], { input: { gameMode: "tournament", maxPlayers: 8, difficulty: "hard", } }); // getOrCreate can also accept input (used only if creating) const gameHandle2 = client.game.getOrCreate(["game-456"], { createWithInput: { gameMode: "casual", maxPlayers: 4, } }); ``` ## Accessing Input in Lifecycle Hooks Input is available as the second argument to the `createState` and `onCreate` lifecycle hooks: ```typescript import { actor } from "rivetkit"; interface ChatRoomInput { roomName: string; isPrivate: boolean; maxUsers?: number; } interface ChatRoomState { name: string; isPrivate: boolean; maxUsers: number; users: Record; messages: string[]; } // Mock function for demonstration function setupPrivateRoomLogging(roomName: string) { console.log(`Setting up logging for private room: ${roomName}`); } const chatRoom = actor({ createState: (c, input: ChatRoomInput): ChatRoomState => ({ name: input?.roomName ?? "Unnamed Room", isPrivate: input?.isPrivate ?? false, maxUsers: input?.maxUsers ?? 50, users: {}, messages: [], }), onCreate: (c, input: ChatRoomInput) => { console.log(`Creating room: ${input.roomName}`); // Setup external services based on input if (input.isPrivate) { setupPrivateRoomLogging(input.roomName); } }, actions: { // Input remains accessible in actions via initial state getRoomInfo: (c) => ({ name: c.state.name, isPrivate: c.state.isPrivate, maxUsers: c.state.maxUsers, currentUsers: Object.keys(c.state.users).length, }), }, }); ``` ## Input Validation You can validate input parameters in the `createState` or `onCreate` hooks: ```typescript import { actor } from "rivetkit"; import { z } from "zod"; const GameInputSchema = z.object({ gameMode: z.enum(["casual", "tournament", "ranked"]), maxPlayers: z.number().min(2).max(16), difficulty: z.enum(["easy", "medium", "hard"]).optional(), }); type GameInput = z.infer; interface GameState { gameMode: string; maxPlayers: number; difficulty: string; players: Record; gameState: string; } const game = actor({ createState: (c, inputRaw: GameInput): GameState => { // Validate input const input = GameInputSchema.parse(inputRaw); return { gameMode: input.gameMode, maxPlayers: input.maxPlayers, difficulty: input.difficulty ?? "medium", players: {}, gameState: "waiting", }; }, actions: { // Actions can access the validated input via state getGameInfo: (c) => ({ gameMode: c.state.gameMode, maxPlayers: c.state.maxPlayers, difficulty: c.state.difficulty, currentPlayers: Object.keys(c.state.players).length, }), }, }); ``` ## Input vs Connection Parameters Input parameters are different from connection parameters: - **Input**: - Passed when creating the actor instance - Use for actor-wide configuration - Available in lifecycle hooks - **Connection parameters**: - Passed when connecting to an existing actor - Used for connection-specific configuration - Available in connection hooks ```typescript import { actor, setup } from "rivetkit"; import { createClient } from "rivetkit/client"; interface RoomInput { roomName: string; isPrivate: boolean; } const chatRoom = actor({ createState: (c, input: RoomInput) => ({ name: input.roomName, isPrivate: input.isPrivate }), createConnState: (c, params: { userId: string; displayName: string }) => ({ userId: params.userId, displayName: params.displayName, }), actions: {} }); const registry = setup({ use: { chatRoom } }); const client = createClient("http://localhost:6420"); // Actor creation with input const room = await client.chatRoom.create(["room-123"], { input: { roomName: "General Discussion", isPrivate: false, }, }); ``` ## Input Best Practices ### Use Type Safety Define input types to ensure type safety: ```typescript import { actor } from "rivetkit"; interface GameInput { gameMode: "casual" | "tournament" | "ranked"; maxPlayers: number; difficulty?: "easy" | "medium" | "hard"; } interface GameState { gameMode: string; maxPlayers: number; difficulty: string; } const game = actor({ createState: (c, input: GameInput): GameState => ({ gameMode: input.gameMode, maxPlayers: input.maxPlayers, difficulty: input.difficulty ?? "medium", }), actions: { // Actions are now type-safe }, }); ``` ### Store Input in State Input is only available in `createState` and `onCreate` lifecycle hooks. If you need to access input data later (in actions, timers, or other hooks), store it in the actor's state during creation. This is the recommended pattern because input shapes can evolve over time, and persisting input in state ensures you always have access to the values the actor was created with: ```typescript import { actor } from "rivetkit"; interface GameInput { gameMode: string; maxPlayers: number; difficulty?: string; } interface GameConfig { gameMode: string; maxPlayers: number; difficulty: string; } interface GameState { config: GameConfig; players: Record; gameState: string; } const game = actor({ createState: (c, input: GameInput): GameState => ({ // Store input configuration in state config: { gameMode: input.gameMode, maxPlayers: input.maxPlayers, difficulty: input?.difficulty ?? "medium", }, // Runtime state players: {}, gameState: "waiting", }), actions: { getConfig: (c) => c.state.config, updateDifficulty: (c, difficulty: string) => { c.state.config.difficulty = difficulty; }, }, }); ``` ## API Reference - [`CreateOptions`](/typedoc/interfaces/rivetkit.client_mod.CreateOptions.html) - Options for creating actors - [`CreateRequest`](/typedoc/types/rivetkit.client_mod.CreateRequest.html) - Request type for creation - [`ActorDefinition`](/typedoc/classes/rivetkit.mod.ActorDefinition.html) - Actor definition returned by `actor()` _Source doc path: /docs/actors/input_