# How to Execute Composio Tools with Specific Versions and Version Pinning

> Execute Composio tools with specific versions using version pinning. Control toolkit versions globally or per execution for deterministic behavior and to prevent breaking changes.

- Repository: [Composio/composio](https://github.com/composiohq/composio)
- Tags: how-to-guide
- Published: 2026-02-19

---

**Pin toolkit versions globally via the `toolkitVersions` constructor option or override per execution using the `version` parameter in `ToolExecuteParams` to ensure deterministic behavior and prevent breaking changes from automatic updates.**

Production AI agents require stable tool definitions to avoid unexpected failures when upstream APIs change. The Composio SDK (from the `ComposioHQ/composio` repository) provides a robust versioning system that lets you lock toolkit versions either across your entire application or for individual tool calls. This guide explains how to execute tools with specific versions using the TypeScript SDK, referencing the actual implementation in [`ts/packages/core/src/models/Tools.ts`](https://github.com/ComposioHQ/composio/blob/main/ts/packages/core/src/models/Tools.ts) and supporting utilities.

## Understanding Version Resolution

Composio resolves tool versions through a strict hierarchy designed to prevent accidental execution of unpinned code. The resolution flow implemented in `executeComposioTool` ([`ts/packages/core/src/models/Tools.ts`](https://github.com/ComposioHQ/composio/blob/main/ts/packages/core/src/models/Tools.ts), lines 78–90) follows this priority:

1. **Explicit per-call version** – The `version` field in `ToolExecuteParams` takes highest precedence
2. **Global toolkit mapping** – The SDK checks `getToolkitVersion(toolkitSlug, this.toolkitVersions)` (defined in [`ts/packages/core/src/utils/toolkitVersion.ts`](https://github.com/ComposioHQ/composio/blob/main/ts/packages/core/src/utils/toolkitVersion.ts))
3. **Safety validation** – If the resolved version equals `"latest"` and `dangerouslySkipVersionCheck` is false, the SDK throws `ComposioToolVersionRequiredError`

This architecture ensures that unversioned tool calls fail loudly in production rather than silently adopting potentially breaking changes.

## Setting Global Toolkit Versions

Configure version pinning at SDK initialization to apply defaults across all tool executions. Pass a `toolkitVersions` map to the `Composio` constructor, mapping toolkit slugs to specific version strings:

```typescript
import { Composio } from '@composio/core';
import 'dotenv/config';

const composio = new Composio({
  apiKey: process.env.COMPOSIO_API_KEY,
  // Pin GitHub toolkit to a known stable version
  toolkitVersions: { 
    github: '20250909_00',
    gmail: '20241001_00' 
  },
});

console.log('Active version mapping:', composio.getConfig());

```

*Source:* [[`ts/examples/versioning/src/index.ts`](https://github.com/ComposioHQ/composio/blob/main/ts/examples/versioning/src/index.ts)](https://github.com/ComposioHQ/composio/blob/next/ts/examples/versioning/src/index.ts)

When you call `tools.execute()` without an explicit version parameter, the SDK automatically injects the mapped version from `this.toolkitVersions` via the `getToolkitVersion` utility.

## Executing Tools with Specific Versions Per Call

Override global defaults for individual executions by including the `version` field in your execution parameters. This approach is essential when testing new toolkit versions in staging while keeping production pinned to stable releases:

```typescript
// Global map pins GitHub to 20250909_00, but we need a newer version for this call
const result = await composio.tools.execute('GITHUB_GET_REPOS', {
  userId: 'default',
  version: '20251115_01',  // Overrides global mapping for this execution only
  arguments: { owner: 'composio' },
});

```

The `version` parameter maps directly to the `version` query parameter in the `/tools/execute` API request, ensuring the specific tool definition is loaded server-side.

### Bypassing Version Checks for Development

To execute against the latest toolkit version without explicit pinning, set `dangerouslySkipVersionCheck: true`. **Only use this in development environments**:

```typescript
const result = await composio.tools.execute('HACKERNEWS_GET_USER', {
  userId: 'default',
  arguments: { userId: 'pg' },
  dangerouslySkipVersionCheck: true,  // Allows "latest" without error
});

```

*Source:* Version safety check in `executeComposioTool` ([`ts/packages/core/src/models/Tools.ts`](https://github.com/ComposioHQ/composio/blob/main/ts/packages/core/src/models/Tools.ts), lines 78–83)

## Inspecting Available Versions Before Execution

Before pinning a version, inspect what versions are available for a specific tool. The `getRawComposioToolBySlug` method retrieves tool metadata including the `availableVersions` array:

```typescript
const tool = await composio.tools.getRawComposioToolBySlug('GITHUB_GET_REPOS');
console.log('Available versions:', tool.availableVersions);
// Output: ['20250909_00', '20251115_01', 'latest']

```

*Source:* `getRawComposioToolBySlug` implementation ([`ts/packages/core/src/models/Tools.ts`](https://github.com/ComposioHQ/composio/blob/main/ts/packages/core/src/models/Tools.ts), lines 507–527)

This allows you to programmatically select appropriate versions or validate that a pinned version still exists before deployment.

## Production Best Practices for Version Pinning

**Pin versions at the SDK level** for baseline stability across your application, then use per-call overrides only for specific edge cases or A/B testing new toolkit releases.

**Never set `dangerouslySkipVersionCheck: true` in production**. The `ComposioToolVersionRequiredError` exists specifically to prevent deployments from accidentally depending on mutable "latest" versions that can change without warning.

**Version your `toolkitVersions` configuration** alongside your application code. Treat version pins as dependencies—review changelogs when upgrading pinned versions, and test thoroughly in staging environments before promoting to production.

## Summary

- **Global pinning** uses the `toolkitVersions` constructor option to set default versions for entire toolkits across all executions
- **Per-call pinning** overrides globals via the `version` field in execution parameters, targeting [`ts/packages/core/src/models/Tools.ts`](https://github.com/ComposioHQ/composio/blob/main/ts/packages/core/src/models/Tools.ts)
- **Safety enforcement** prevents accidental "latest" usage via `ComposioToolVersionRequiredError` unless `dangerouslySkipVersionCheck` is explicitly enabled
- **Version discovery** is available through `getRawComposioToolBySlug`, which exposes `availableVersions` from the tool metadata

## Frequently Asked Questions

### What happens if I don't specify a version and haven't set global toolkit versions?

The SDK calls `getToolkitVersion` (in [`ts/packages/core/src/utils/toolkitVersion.ts`](https://github.com/ComposioHQ/composio/blob/main/ts/packages/core/src/utils/toolkitVersion.ts)), which returns `"latest"` for unmapped toolkits. Since `"latest"` is not an explicit version, `executeComposioTool` throws `ComposioToolVersionRequiredError` unless you set `dangerouslySkipVersionCheck: true`.

### Can I mix global and per-call version pinning?

Yes. The `version` parameter in individual `tools.execute()` calls always takes precedence over the global `toolkitVersions` map. This allows you to maintain stable defaults while testing newer versions on specific tool calls.

### How do I find the correct version string to pin?

Use `getRawComposioToolBySlug('TOOL_NAME')` to inspect the `availableVersions` property. This returns an array of valid version strings (e.g., `['20250909_00', '20251115_01']`) that you can then reference in your configuration.

### Is it safe to use `dangerouslySkipVersionCheck` in production?

No. This flag bypasses the safety check that prevents execution against mutable "latest" versions. Only use it during local development or CI testing. Production systems should always use explicit version pins to ensure deterministic behavior and prevent breaking changes from automatic toolkit updates.