OSS-first docs
These docs teach the open system first: contracts, generated surfaces, runtimes, governance, and incremental adoption. Studio shows up as the operating layer on top, not as the source of truth.
Generate client from schema
Automatically generate type-safe API clients in any language from your contracts.
Client Development Problems
- Writing API clients is repetitive
- Manual clients have type mismatches
- Keeping clients in sync with APIs
- Language-specific client maintenance
Automated Solutions
- Generate clients for multiple languages
- Type-safe request/response handling
- Automatic client updates from contracts
- Consistent error handling across languages
Contract Definition
Define your API contract once, generate clients for any language.
import { defineContract } from '@contractspec/lib.contracts-spec';
import { SchemaModel, ScalarTypeEnum } from '@contractspec/lib.schema';
export const ApiContract = defineContract({
name: 'MyAPI',
version: '1.0.0',
baseUrl: 'https://api.example.com',
operations: {
getUsers: {
goal: 'Retrieve paginated list of users',
method: 'GET',
path: '/users',
input: new SchemaModel({
type: 'object',
properties: {
page: { type: 'integer', minimum: 1, default: 1 },
limit: { type: 'integer', minimum: 1, maximum: 100, default: 20 },
},
}),
output: new SchemaModel({
type: 'object',
properties: {
users: {
type: 'array',
items: {
type: 'object',
properties: {
id: { type: 'string', required: true },
email: { type: 'string', required: true },
name: { type: 'string', required: true },
},
},
},
pagination: {
type: 'object',
properties: {
page: { type: 'integer', required: true },
limit: { type: 'integer', required: true },
total: { type: 'integer', required: true },
},
},
},
}),
},
createUser: {
goal: 'Create a new user account',
method: 'POST',
path: '/users',
input: new SchemaModel({
type: 'object',
properties: {
email: { type: 'string', format: 'email', required: true },
name: { type: 'string', minLength: 1, required: true },
},
}),
output: new SchemaModel({
type: 'object',
properties: {
id: { type: 'string', required: true },
email: { type: 'string', required: true },
name: { type: 'string', required: true },
createdAt: { type: 'string', format: 'date-time', required: true },
},
}),
},
},
metadata: {
description: 'User management API with authentication',
tags: ['users', 'authentication'],
},
});Generate Multiple Clients
Generate type-safe clients for any language from the same contract.
# Generate all supported language clients
contractspec generate clients \
--contract ./src/contracts/api.contract.ts \
--output ./generated/clients \
--languages typescript,python,go,java,csharp
# Generate specific language client
contractspec generate clients \
--contract ./src/contracts/api.contract.ts \
--output ./generated/clients \
--languages typescript \
--format npm-package
# Options
# --with-types: Include TypeScript definitions
# --with-tests: Generate client test suites
# --with-docs: Include client documentation
# --framework: Use specific HTTP client frameworkGenerated Client Examples
Each generated client is fully type-safe and idiomatic.
TypeScript Client
import { MyAPIClient } from './client';
const client = new MyAPIClient({
baseUrl: 'https://api.example.com',
apiKey: process.env.API_KEY,
});
// Type-safe method calls
const users = await client.getUsers({
page: 1,
limit: 10,
});
const newUser = await client.createUser({
email: 'user@example.com',
name: 'John Doe',
});
// Full type inference
// users: GetUsersResponse
// newUser: CreateUserResponsePython Client
from myapi_client import MyAPIClient
client = MyAPIClient(
base_url='https://api.example.com',
api_key=os.getenv('API_KEY')
)
# Type-safe method calls
users = await client.get_users(
page=1,
limit=10
)
new_user = await client.create_user(
email='user@example.com',
name='John Doe'
)
# Full type hints
# users: GetUsersResponse
# new_user: CreateUserResponseGo Client
package main
import (
"context"
"myapi_client"
)
func main() {
client := myapi_client.NewMyAPIClient(
myapi_client.WithBaseURL("https://api.example.com"),
myapi_client.WithAPIKey(os.Getenv("API_KEY")),
)
// Type-safe method calls
users, err := client.GetUsers(&myapi_client.GetUsersParams{
Page: 1,
Limit: 10,
})
newUser, err := client.CreateUser(&myapi_client.CreateUserParams{
Email: "user@example.com",
Name: "John Doe",
})
// Full type checking at compile time
// users: *GetUsersResponse
// newUser: *CreateUserResponse
}Advanced Features
Generated clients include enterprise-grade features out of the box.
// Advanced client features
const client = new MyAPIClient({
baseUrl: 'https://api.example.com',
apiKey: 'your-api-key',
// Retry configuration
retryConfig: {
maxRetries: 3,
backoffMultiplier: 2,
maxDelay: 30000,
},
// Request/Response interceptors
interceptors: {
request: [(config) => {
// Add authentication headers
config.headers.Authorization = `Bearer ${await getAuthToken()}`;
return config;
}],
response: [(response) => {
// Log API calls
console.log(`API Call: ${response.config.method} ${response.config.url}`);
return response;
}],
},
// Error handling
errorHandler: (error) => {
if (error.status === 401) {
// Refresh token and retry
return refreshTokenAndRetry(error.originalRequest);
}
throw error;
},
});
// Automatic request deduplication
const user1 = client.getUser({ id: '123' });
const user2 = client.getUser({ id: '123' }); // Uses cached result
// Request cancellation
const controller = new AbortController();
const promise = client.getUsers({ page: 1, signal: controller.signal });
controller.abort(); // Cancels the requestWhy ContractSpec
Keep educational and comparison content reachable without letting it define the primary OSS learning path.