Documentation Index
Fetch the complete documentation index at: https://mintlify.com/modal-labs/modal-client/llms.txt
Use this file to discover all available pages before exploring further.
The ModalClient is the main entry point for interacting with Modal’s cloud infrastructure. This guide covers initialization and configuration options.
Basic initialization
Create a client with default settings:
import { ModalClient } from "modal";
const modal = new ModalClient();
The client will automatically use credentials from:
- Constructor parameters (if provided)
- Environment variables (
MODAL_TOKEN_ID, MODAL_TOKEN_SECRET)
- Configuration file (
~/.modal.toml)
Configuration options
The ModalClient constructor accepts a ModalClientParams object with these options:
Authentication
Provide credentials directly to the client:
const modal = new ModalClient({
tokenId: "ak-YOUR_TOKEN_ID",
tokenSecret: "as-YOUR_TOKEN_SECRET",
});
Credentials in constructor parameters take precedence over environment variables and config files.
Environment
Specify which Modal environment to use:
const modal = new ModalClient({
environment: "staging",
});
Custom endpoint
Connect to a custom Modal API endpoint:
const modal = new ModalClient({
endpoint: "https://custom-api.modal.com:443",
});
Timeouts
Set default timeout for API calls (in milliseconds):
const modal = new ModalClient({
timeoutMs: 30000, // 30 seconds
});
You can also override timeouts on individual calls.
Retries
Configure maximum retry attempts for failed requests:
const modal = new ModalClient({
maxRetries: 5, // Default is 3
});
Logging
The SDK includes built-in logging for debugging and observability.
Log levels
Set the log level to control verbosity:
const modal = new ModalClient({
logLevel: "debug", // "debug" | "info" | "warn" | "error"
});
Available log levels:
debug - Detailed debugging information
info - General informational messages
warn - Warning messages
error - Error messages only
Custom logger
Provide your own logger implementation:
import type { Logger } from "modal";
const customLogger: Logger = {
debug: (...args) => console.log("[DEBUG]", ...args),
info: (...args) => console.log("[INFO]", ...args),
warn: (...args) => console.warn("[WARN]", ...args),
error: (...args) => console.error("[ERROR]", ...args),
};
const modal = new ModalClient({
logger: customLogger,
});
Environment variable logging
You can also set the log level via environment variable:
export MODAL_LOGLEVEL=debug
Custom gRPC middleware
Add custom middleware for telemetry, tracing, and observability.
The Modal gRPC API is not considered a public API and can change without warning. Use custom middleware at your own risk.
Basic middleware example
import { ModalClient } from "modal";
import type { ClientMiddleware } from "nice-grpc";
const loggingMiddleware: ClientMiddleware = async function* (call, options) {
const startTime = Date.now();
console.log(`Starting call to ${call.method.path}`);
try {
const result = yield* call.next(call.request, options);
const duration = Date.now() - startTime;
console.log(`Call completed in ${duration}ms`);
return result;
} catch (error) {
const duration = Date.now() - startTime;
console.error(`Call failed after ${duration}ms:`, error);
throw error;
}
};
const modal = new ModalClient({
grpcMiddleware: [loggingMiddleware],
});
Advanced telemetry example
Integrate with OpenTelemetry or other observability tools:
import { ModalClient } from "modal";
import type { ClientMiddleware } from "nice-grpc";
import { trace, context } from "@opentelemetry/api";
const tracingMiddleware: ClientMiddleware = async function* (call, options) {
const tracer = trace.getTracer("modal-client");
const span = tracer.startSpan(call.method.path, {
kind: 1, // CLIENT
});
try {
const result = yield* context.with(
trace.setSpan(context.active(), span),
async () => call.next(call.request, options)
);
span.setStatus({ code: 1 }); // OK
return result;
} catch (error) {
span.setStatus({ code: 2, message: String(error) }); // ERROR
span.recordException(error as Error);
throw error;
} finally {
span.end();
}
};
const modal = new ModalClient({
grpcMiddleware: [tracingMiddleware],
});
For a complete telemetry example, see the telemetry example in the Modal repository.
Service properties
The ModalClient provides access to all Modal services:
const modal = new ModalClient();
// Service properties
modal.apps // App management
modal.sandboxes // Sandbox operations
modal.functions // Function calling
modal.functionCalls // Function call management
modal.cls // Class calling
modal.images // Image building
modal.volumes // Volume management
modal.queues // Queue operations
modal.secrets // Secret management
modal.proxies // Proxy management
modal.cloudBucketMounts // Cloud bucket mounts
Client methods
version()
Get the SDK version:
const version = modal.version();
console.log("Modal SDK version:", version); // e.g., "0.7.3-dev.0"
environmentName()
Get the current environment name:
const env = modal.environmentName();
console.log("Environment:", env);
imageBuilderVersion()
Get the image builder version:
const builderVersion = modal.imageBuilderVersion();
console.log("Image builder version:", builderVersion); // e.g., "2024.10"
close()
Close the client and clean up resources:
const modal = new ModalClient();
try {
// Use the client...
const app = await modal.apps.fromName("my-app");
} finally {
modal.close();
}
Complete configuration example
Here’s a fully configured client with all options:
import { ModalClient } from "modal";
import type { ClientMiddleware } from "nice-grpc";
const telemetryMiddleware: ClientMiddleware = async function* (call, options) {
// Custom telemetry logic...
return yield* call.next(call.request, options);
};
const modal = new ModalClient({
// Authentication
tokenId: process.env.CUSTOM_MODAL_ID,
tokenSecret: process.env.CUSTOM_MODAL_SECRET,
// Environment
environment: "production",
// Network settings
endpoint: "https://api.modal.com:443",
timeoutMs: 60000,
maxRetries: 5,
// Logging
logLevel: "info",
// Custom middleware
grpcMiddleware: [telemetryMiddleware],
});
// Use the client
try {
const app = await modal.apps.fromName("my-app", {
createIfMissing: true,
});
const image = modal.images.fromRegistry("python:3.13");
const sb = await modal.sandboxes.create(app, image);
// Work with sandbox...
await sb.terminate();
} finally {
modal.close();
}
Migration from v0.4
If you’re upgrading from v0.4 or earlier, note these breaking changes:
Old API (v0.4)
import { initializeClient, Function_, App } from "modal";
initializeClient({
tokenId: "...",
tokenSecret: "...",
});
const app = await App.lookup("my-app");
const func = await Function_.lookup("my-app", "my-function");
New API (v0.5+)
import { ModalClient } from "modal";
const modal = new ModalClient({
tokenId: "...",
tokenSecret: "...",
});
const app = await modal.apps.fromName("my-app");
const func = await modal.functions.fromName("my-app", "my-function");
See the Migration Guide for a complete list of changes.
Next steps
Basic usage
Learn basic patterns and workflows
API reference
Explore the full API documentation