Getting Started
From zero to generated, compiled code in under a minute.
0 Install the CLI
The api CLI is a Ruby script with no gem dependencies — just clone and add to your PATH.
git clone https://github.com/mbryzek/devops.git ~/apibuilder-cli
export PATH="$HOME/apibuilder-cli/bin:$PATH" Requires Ruby (any recent version). Add the export line to your shell profile to make it permanent.
1 Initialize
Run api init from your project directory
to create an anonymous org (a temporary workspace so you can try API Builder without creating an account)
and set up your project config. No signup required.
api init --language typescript # TypeScript project
api init --language scala # Scala project
api init --language typescript --language scala # both This writes your credentials to ~/.apibuilder/config and creates a .api/config in the current directory
with default generators for your language. For a TypeScript project, the generated config looks like:
# .api/config (generated by api init)
<your-org>:
- generators:
typescript: ./src/generated
applications:
my-api: You only need to run api init once per machine.
If you already have ~/.apibuilder/config, skip this step.
2 Write a Spec
Create spec/my-api.json with your API definition.
The file name determines the application name — spec/my-api.json maps to the my-api application in your config.
See the api.json reference for the full format.
{
"name": "my-api",
"namespace": "com.example.api.v0",
"models": {
"user": {
"fields": [
{ "name": "id", "type": "string" },
{ "name": "email", "type": "string" }
]
}
},
"resources": {
"user": {
"operations": [
{
"method": "GET",
"path": "/users/:id",
"responses": { "200": { "type": "user" } }
}
]
}
}
} The namespace becomes the package name in generated code
(e.g. com.example.api.v0 in Scala,
or the module path in TypeScript).
3 Generate Code
Upload your spec and generate code in one step:
api This reads your .api/config, validates and uploads
each spec, then runs the configured code generators. You should see output like:
==> Auto-detected operations: upload, codegen
==> Processing 1 organization
==> Submitting batch (1 application, operations: upload, codegen)
==> Batch completed
==> Downloading generated code...
==> Extracting files...
wrote ./src/generated/my-api.ts
1 written, 0 unchanged
==> Done (2.1 seconds) If nothing is generated, make sure your spec defines at least one resource — code generators produce output from resources and their operations. See available generators for the full list.
You can also validate a spec without generating code: api validate spec/my-api.json
4 Compile and Verify
Generated code creates type-safe contracts between your spec and your implementation. The compiler enforces that they stay in sync — if it compiles, your code matches the spec. If not, the compiler errors tell you exactly what to fix.
sbt compile # Scala
tsc --noEmit # TypeScript5 Write Tests
API Builder generates mock clients that implement the same interface as real clients but return test data without making HTTP calls. Override only what you need per test:
// Scala example using generated mock client
val mock = new MockClient()
val user = mock.users.getById("test-id")
assert(user.id == "test-id") Mock clients are generated automatically when you include the bryzek_play_mock_client (Scala) generator
in your .api/config.
✓ What You End Up With
After completing these steps, your project structure looks like:
my-project/
.api/
config # generator config (created by api init)
spec/
my-api.json # your API spec
src/
generated/
my-api.ts # generated client code (don't edit)
index.ts # your implementation Files in src/generated/ are overwritten each time you run api — commit them to source control but don't edit them by hand.
✦ For AI Agents
Give your AI agent the full API Builder workflow as a skill. The skill teaches the agent spec authoring, validation, code generation, compiler verification, and testing.
Explore the full API specification format.
api.json Reference