TL;DR
CodeSpeak is a formal specification language—created by Kotlin’s creator—for communicating with Large Language Models (LLMs). Unlike natural language prompts, CodeSpeak uses structured syntax to minimize ambiguity, ensure consistent output, and make LLM-driven software development more predictable.
Introduction
When you prompt an LLM with “Generate a REST API for user management,” you might get back unexpected code. Did it include authentication, rate limiting, or input validation? Probably not exactly as you intended. The LLM makes assumptions, making debugging and iteration tedious.
This ambiguity is a core problem for LLM-based development. Natural language is flexible, but that flexibility leads to inconsistent results—across runs, models, or even temperature settings.
CodeSpeak solves this by letting you write structured specifications, not English prompts. It’s like TypeScript for prompts: you get type safety and clarity, reducing misinterpretation.
💡 If you need reliable, testable results from LLM-generated code, Apidog integrates with AI coding tools to validate API specs, test endpoints, and catch issues before deployment. CodeSpeak makes generation predictable. Apidog ensures it works.
In this guide, you’ll see how CodeSpeak works, how to use it for API development, syntax examples, and how to integrate it with your API test automation (like Apidog).
What Is CodeSpeak?
CodeSpeak is a DSL for writing formal specifications that LLMs interpret with high accuracy. Created by Dmitry Jemerov, Kotlin’s lead designer, CodeSpeak addresses the ambiguity of natural language in software specifications.
The Core Problem
Prompting an LLM with “create a user authentication system” forces the model to infer:
- The authentication method (JWT/session/OAuth)
- Password requirements
- Token expiration
- Error handling
- Database schema
- API endpoint structure
Each guess can diverge from your intent. CodeSpeak removes these guess points with explicit specs.
How CodeSpeak Differs from Prompts
Traditional prompt:
Create a REST API endpoint for user login that accepts email and password,
returns a JWT token, and handles invalid credentials gracefully.
CodeSpeak spec:
endpoint POST /auth/login {
request {
body {
email: string @format(email) @required
password: string @minLength(8) @required
}
}
response 200 {
body {
token: string @format(jwt)
expiresIn: number @unit(seconds)
}
}
response 401 {
body {
error: string @enum("invalid_credentials", "account_locked")
}
}
}
The CodeSpeak version is explicit—no ambiguity for the LLM.
Key Features
- Type Safety: Explicit types for all variables
-
Constraints: Built-in validators (
@required,@minLength, etc.) - Structure: Clear hierarchy for requests, responses, and models
- Composability: Reusable type definitions
- Determinism: Same spec yields same output every time
Why CodeSpeak Matters for API Development
API work requires precision. A missing rule or ambiguous error message can break clients. With LLMs generating API code, precision is even more critical.
The Cost of Ambiguity
If you prompt “add pagination to the users endpoint,” an LLM might use page/limit while your standard is offset/count—leading to inconsistency.
With CodeSpeak, specify pagination once:
pagination {
style: offset-based
parameters {
offset: number @default(0) @min(0)
count: number @default(20) @min(1) @max(100)
}
}
All endpoints using this stay consistent.
Benefits for API Teams
- Consistency: All endpoints follow the same patterns
- Faster Code Review: Review the spec, not just generated code
- Automated Testing: CodeSpeak maps directly to API test cases. Apidog can import OpenAPI and generate test suites
- Less Debugging: Specs document intent, reducing “why did it do that?”
- Version Control: Specs are text—easy to diff and track
CodeSpeak vs Natural Language Prompts
When should you use CodeSpeak instead of English? It depends on how much precision you need.
When to Use Natural Language
Best for:
- Exploratory tasks: “Show me ways to implement rate limiting”
- High-level architecture: “Design a microservice e-commerce platform”
- Code explanation/brainstorming
Natural language is fast for open-ended or brainstorming tasks.
When to Use CodeSpeak
Best for:
- Production code generation
- API contracts
- Data models
- Validation rules
- Consistent, repeatable patterns
If code will be deployed or used by others, use CodeSpeak.
Comparison Table
| Aspect | Natural Language | CodeSpeak |
|---|---|---|
| Precision | Low, requires guessing | High, explicit |
| Consistency | Varies by run | Deterministic |
| Learning Curve | None | Moderate |
| Verbosity | Concise | Verbose |
| Best For | Exploration | Production code, APIs |
| Error Rate | Higher | Lower (spec checked) |
| Iteration | Fast draft | Slower to write |
| Documentation | Implicit | Spec = docs |
Hybrid Approach
Use both! For example:
- Design in natural language (“Design user authentication with JWT”)
- Implement with CodeSpeak (write specs per endpoint)
- Iterate using natural language (“Add rate limiting”)
- Lock in with CodeSpeak (update spec)
How CodeSpeak Works
You write a CodeSpeak spec, the LLM interprets it, and generates code to match.
The Compilation Model
It's not compiled in the traditional sense. Instead:
- Write the spec
- LLM parses the spec
- LLM generates code
- You validate output
Type System
Primitive Types:
-
string,number,boolean,null
Complex Types:
-
object,array,enum,union
Type Modifiers:
-
@required,@optional,@nullable,@default(value)
Constraint System
Add validation to types.
String Constraints:
-
@minLength(n),@maxLength(n),@pattern(regex),@format(type)
Number Constraints:
-
@min(n),@max(n),@multipleOf(n),@integer
Array Constraints:
-
@minItems(n),@maxItems(n),@uniqueItems
Composition and Reuse
Define reusable components:
type User {
id: string @format(uuid) @required
email: string @format(email) @required
name: string @minLength(1) @maxLength(100) @required
createdAt: string @format(iso8601) @required
}
type PaginatedResponse<T> {
data: array<T> @required
pagination: object {
offset: number @required
count: number @required
total: number @required
} @required
}
endpoint GET /users {
response 200 {
body: PaginatedResponse<User>
}
}
Using CodeSpeak for API Testing with Apidog
CodeSpeak gives you precise API specs. Apidog turns those specs into automated tests.
Workflow Overview
- Write CodeSpeak spec: Formal API definition
- Generate code: Use LLM to implement
- Import to Apidog: Convert CodeSpeak to OpenAPI
- Generate tests: Apidog builds test cases
- Run validation: Verify implementation matches spec
Converting CodeSpeak to OpenAPI
CodeSpeak maps directly to OpenAPI 3.0.
CodeSpeak:
endpoint POST /users {
request {
body {
email: string @format(email) @required
name: string @minLength(1) @required
}
}
response 201 {
body {
id: string @format(uuid)
email: string
name: string
}
}
}
OpenAPI Equivalent:
paths:
/users:
post:
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [email, name]
properties:
email:
type: string
format: email
name:
type: string
minLength: 1
responses:
'201':
content:
application/json:
schema:
type: object
properties:
id:
type: string
format: uuid
email:
type: string
name:
type: string
You can script or prompt an LLM to convert CodeSpeak → OpenAPI.
Testing in Apidog
- Import the spec: Settings → Import → OpenAPI 3.0
- Generate test cases: Apidog auto-generates endpoint tests
- Add test data: Define valid/invalid inputs per constraints
- Run tests and Validate responses: Execute and check spec compliance
Apidog validates your implementation against the spec. CodeSpeak ensures your spec is unambiguous.
Example: Testing a Login Endpoint
CodeSpeak Spec:
endpoint POST /auth/login {
request {
body {
email: string @format(email) @required
password: string @minLength(8) @required
}
}
response 200 {
body {
token: string @format(jwt) @required
expiresIn: number @min(1) @required
}
}
response 401 {
body {
error: string @enum("invalid_credentials") @required
}
}
response 422 {
body {
error: string @enum("validation_error") @required
fields: array<string> @required
}
}
}
Auto-generated Apidog Test Cases:
- Valid login: Correct email/password → expect 200 with JWT
- Invalid email format: Malformed email → expect 422
- Short password: 7-chars → expect 422
- Wrong credentials: Valid format, wrong password → 401
- Missing fields: Empty body → 422
You define the test data; Apidog generates and runs the tests.
CodeSpeak Syntax and Examples
Basic Endpoint Definition
endpoint GET /health {
response 200 {
body {
status: string @enum("ok", "degraded", "down") @required
timestamp: string @format(iso8601) @required
}
}
}
CRUD Operations
Create:
endpoint POST /products {
request {
headers {
Authorization: string @pattern("^Bearer .+") @required
}
body {
name: string @minLength(1) @maxLength(200) @required
price: number @min(0) @required
category: string @enum("electronics", "clothing", "food") @required
inStock: boolean @default(true)
}
}
response 201 {
body {
id: string @format(uuid) @required
name: string @required
price: number @required
category: string @required
inStock: boolean @required
createdAt: string @format(iso8601) @required
}
}
response 401 {
body {
error: string @enum("unauthorized") @required
}
}
}
Read:
endpoint GET /products/:id {
parameters {
id: string @format(uuid) @required
}
response 200 {
body {
id: string @format(uuid) @required
name: string @required
price: number @required
category: string @required
inStock: boolean @required
createdAt: string @format(iso8601) @required
updatedAt: string @format(iso8601) @required
}
}
response 404 {
body {
error: string @enum("not_found") @required
}
}
}
Update:
endpoint PATCH /products/:id {
parameters {
id: string @format(uuid) @required
}
request {
headers {
Authorization: string @pattern("^Bearer .+") @required
}
body {
name: string @minLength(1) @maxLength(200) @optional
price: number @min(0) @optional
inStock: boolean @optional
}
}
response 200 {
body {
id: string @format(uuid) @required
name: string @required
price: number @required
inStock: boolean @required
updatedAt: string @format(iso8601) @required
}
}
response 404 {
body {
error: string @enum("not_found") @required
}
}
}
Delete:
endpoint DELETE /products/:id {
parameters {
id: string @format(uuid) @required
}
request {
headers {
Authorization: string @pattern("^Bearer .+") @required
}
}
response 204 {}
response 404 {
body {
error: string @enum("not_found") @required
}
}
}
Pagination and Filtering
endpoint GET /products {
query {
offset: number @default(0) @min(0) @optional
limit: number @default(20) @min(1) @max(100) @optional
category: string @enum("electronics", "clothing", "food") @optional
minPrice: number @min(0) @optional
maxPrice: number @min(0) @optional
inStock: boolean @optional
}
response 200 {
body {
data: array<object {
id: string @format(uuid) @required
name: string @required
price: number @required
category: string @required
inStock: boolean @required
}> @required
pagination: object {
offset: number @required
limit: number @required
total: number @required
} @required
}
}
}
Nested Resources
endpoint GET /users/:userId/orders {
parameters {
userId: string @format(uuid) @required
}
query {
status: string @enum("pending", "shipped", "delivered", "cancelled") @optional
}
response 200 {
body {
data: array<object {
id: string @format(uuid) @required
userId: string @format(uuid) @required
status: string @enum("pending", "shipped", "delivered", "cancelled") @required
items: array<object {
productId: string @format(uuid) @required
quantity: number @min(1) @required
price: number @min(0) @required
}> @required
total: number @min(0) @required
createdAt: string @format(iso8601) @required
}> @required
}
}
}
File Upload
endpoint POST /products/:id/image {
parameters {
id: string @format(uuid) @required
}
request {
headers {
Authorization: string @pattern("^Bearer .+") @required
Content-Type: string @enum("multipart/form-data") @required
}
body {
image: file @mimeType("image/jpeg", "image/png") @maxSize(5242880) @required
}
}
response 200 {
body {
imageUrl: string @format(url) @required
}
}
response 413 {
body {
error: string @enum("file_too_large") @required
}
}
}
Best Practices for CodeSpeak
Start with Types
Define data models up front:
type Product {
id: string @format(uuid) @required
name: string @minLength(1) @maxLength(200) @required
price: number @min(0) @required
category: string @enum("electronics", "clothing", "food") @required
inStock: boolean @required
createdAt: string @format(iso8601) @required
updatedAt: string @format(iso8601) @required
}
endpoint GET /products/:id {
response 200 {
body: Product
}
}
Use Enums for Fixed Values
Avoid free-form strings:
Bad:
status: string @required
Good:
status: string @enum("pending", "approved", "rejected") @required
Document with Comments
Add comments for clarity:
// User authentication endpoint
// Rate limit: 5 requests per minute per IP
endpoint POST /auth/login {
request {
body {
// Must be a valid email format
email: string @format(email) @required
// Minimum 8 characters, must include number and special char
password: string @minLength(8) @required
}
}
response 200 {
body {
// JWT token valid for 24 hours
token: string @format(jwt) @required
expiresIn: number @default(86400) @required
}
}
}
Version Your Specs
Store specs in version control beside your code:
/api-specs
/v1
auth.codespeak
users.codespeak
products.codespeak
/v2
auth.codespeak
users.codespeak
Validate Before Generating
Prompt your LLM to review your CodeSpeak spec for errors before code generation:
Prompt: “Review this CodeSpeak spec for errors, inconsistencies, or missing constraints: [paste spec]”
Catch missing fields, naming mismatches, invalid constraints, or missing error responses.
Test the Spec, Not Just the Code
Validate your CodeSpeak specs:
- Are all required fields marked?
- Does every endpoint have error responses?
- Are constraints realistic?
- Do response types match requests where needed?
Limitations and Considerations
Learning Curve
CodeSpeak requires learning syntax and conventions. Budget a week or two for your team to get comfortable.
Verbosity
Specs are more verbose than natural language, but this forces necessary explicitness.
LLM Support
Not all LLMs handle CodeSpeak equally. Code-focused models (GPT-4, Claude, Copilot) work best. Test with your LLM before committing.
Maintenance Overhead
You must update specs with API changes. The upside: the same spec serves as documentation and can regenerate code.
Not a Silver Bullet
CodeSpeak reduces ambiguity, but LLMs can still make mistakes:
- Inefficient code
- Missed edge cases
- Security bugs
- Logic errors
Still use code review and testing—CodeSpeak just makes intent unambiguous.
Real-World Use Cases
Use Case 1: API Consistency Across Teams
Problem: Multiple teams use LLMs for API code; endpoints are inconsistent (pagination params, error formats, etc).
Solution: Platform team creates CodeSpeak templates for common patterns:
// Standard pagination
type Pagination {
offset: number @default(0) @min(0)
limit: number @default(20) @min(1) @max(100)
}
// Standard error response
type ErrorResponse {
error: string @required
message: string @required
requestId: string @format(uuid) @required
}
All teams use these in their specs, ensuring consistency.
Result: Client integration time drops by 40% due to predictable endpoints.
Use Case 2: Rapid Prototyping with Validation
Problem: Startup needs to prototype 20 endpoints in 2 weeks. LLM-generated code is buggy due to vague specs.
Solution: Write and review CodeSpeak specs for all endpoints. Catch issues (e.g., missing auth, inconsistent ID formats, no rate limiting) in review. Generate code and tests via Apidog.
Result: Shipped all endpoints on time with 60% fewer bugs.
Use Case 3: API Documentation from Specs
Problem: API docs are always out-of-date.
Solution: Specs are the source of truth. Update spec, regenerate code and docs from it.
Result: API confusion tickets drop by 50%.
Conclusion
CodeSpeak adds type safety and structure to LLM workflows. For API devs, this means:
- Consistency: Uniform endpoint patterns
- Precision: No ambiguity
- Testability: Specs → test cases
- Documentation: Specs = docs
- Maintainability: Explicit, trackable changes
Use CodeSpeak for production, natural language for exploration. The verbosity is a feature: it enforces clarity.
Key Takeaways:
- CodeSpeak is a formal LLM spec language
- It eliminates ambiguity in API specs
- Use for production code; use natural language for exploration
- Specs integrate with tools like Apidog for automated testing
- Verbosity enforces explicit design
FAQ
Is CodeSpeak a programming language?
No. CodeSpeak is a specification language. You don’t compile it; you use it to describe what you want, and an LLM generates real code from it.
Do I need to learn CodeSpeak to use LLMs for coding?
No. Natural language prompts still work. CodeSpeak is optional—best when you need precise, consistent results. For prototyping or exploration, natural language is fine.
Which LLMs support CodeSpeak?
Works best with code-focused models like GPT-4, Claude Opus, or GitHub Copilot. Test your LLM with CodeSpeak examples to confirm compatibility.
Can I convert existing OpenAPI specs to CodeSpeak?
Yes. OpenAPI and CodeSpeak map closely. You can script or prompt an LLM to convert YAML to CodeSpeak—types, constraints, endpoints map directly.
How does CodeSpeak compare to OpenAPI?
OpenAPI documents existing APIs. CodeSpeak tells LLMs what to generate. They’re complementary: generate OpenAPI from CodeSpeak, then use tools like Apidog to test implementation.
Is CodeSpeak open source?
As of March 2026, CodeSpeak is newly announced. Check the official CodeSpeak website for licensing and community resources.
Can CodeSpeak prevent all LLM errors?
No. It reduces ambiguity, but LLMs can still produce buggy code, miss edge cases, or add security issues. Code review and testing are still necessary.
How long does it take to write a CodeSpeak spec?
A basic endpoint: 5-10 minutes. Complex endpoints: 20-30 minutes. Slower than English prompts, but faster than debugging unclear LLM output.






Top comments (0)