> Version notice: This site documents BAML v0, the legacy DSL. BAML v1 is a separate, fully featured programming language in public beta. If the user intends to use BAML v1, ignore this site's content and use the BAML v1 documentation instead. If the intended version is unclear, clarify it before using this page. > For clean Markdown of any page, append .md to the page URL. For the complete documentation index, see https://docs.boundaryml.com/llms.txt. For MCP access, connect to https://docs.boundaryml.com/_mcp/server. > **Info** > > Requires BAML version >=0.55 > **Warning** > > This feature is a preview feature and may change. Please provide feedback either > in [Discord][discord] or on [GitHub][openapi-feedback-github-issue] so that > we can stabilize the feature and keep you updated! BAML allows you to expose your BAML functions as RESTful APIs: ![](/_fern-img/5142ce652691ef14685748a28861e342e019ed32d4c3de56b3f4fd4a5f5ccf1f.webp) We integrate with [OpenAPI](https://www.openapis.org/) (universal API definitions), so you can get typesafe client libraries for free! ### Install BAML VSCode Extension [https://marketplace.visualstudio.com/items?itemName=boundary.baml-extension](https://marketplace.visualstudio.com/items?itemName=boundary.baml-extension) * syntax highlighting * testing playground * prompt previews ### Install NPX + OpenAPI #### macOS (brew) ```bash brew install npm openapi-generator # 'npm' will install npx # 'openapi-generator' will install both Java and openapi-generator-cli ``` #### Linux (apt) OpenAPI requires `default-jdk` ```bash apt install npm default-jdk -y # 'npm' will install npx; 'default-jdk' will install java ``` #### Linux (yum/dnf) OpenAPI requires Java ```bash dnf install npm java-21-openjdk -y # dnf is the successor to yum ``` Amazon Linux 2023: ```bash dnf install npm java-21-amazon-corretto -y # 'npm' will install npx # 'java-21-amazon-corretto' will install java ``` Amazon Linux 2: ```bash curl -sL https://rpm.nodesource.com/setup_16.x | bash - yum install nodejs -y # 'nodejs' will install npx amazon-linux-extras install java-openjdk11 -y # 'java-openjdk11' will install java ``` #### Windows To install `npx` and `java` (for OpenAPI): 1. Use the [Node.js installer](https://nodejs.org/en/download/prebuilt-installer) to install `npx` (default installer settings are fine). 2. Run `npm install -g npm@latest` to update `npx` (there is currently an [issue][npx-windows-issue] with the default install of `npx` on Windows where it doesn't work out of the box). 3. Run the [Adoptium OpenJDK `.msi` installer](https://adoptium.net/temurin/releases/?os=windows) (install the JDK; default installer settings are fine). You can verify that `npx` and `java` are installed by running: ```powershell npx -version java -version ``` #### Other To install `npx`, use the [Node.js installer](https://nodejs.org/en/download/prebuilt-installer). To install `java` (for OpenAPI), use the [Adoptium OpenJDK packages](https://adoptium.net/installation/linux/). ### Add BAML to your existing project This will give you some starter BAML code in a `baml_src` directory. #### C\# ```bash npx @boundaryml/baml init \ --client-type rest/openapi --openapi-client-type csharp ``` #### C++ > **Tip** > > OpenAPI supports [5 different C++ client types][openapi-client-types]; > any of them will work with BAML. ```bash npx @boundaryml/baml init \ --client-type rest/openapi --openapi-client-type cpp-restsdk ``` #### Go ```bash npx @boundaryml/baml init \ --client-type rest/openapi --openapi-client-type go ``` #### Java ```bash npx @boundaryml/baml init \ --client-type rest/openapi --openapi-client-type java ``` Notice that `on_generate` has been initialized for you to: * run the OpenAPI generator to generate a Java client library, and *also* * run `mvn clean install` to install the generated client library to your local Maven repository > **Warning** > > If you only use Maven through an IDE (e.g. IntelliJ IDEA), you should > remove `&& mvn clean install` from the generated `on_generate` command. #### PHP ```bash npx @boundaryml/baml init \ --client-type rest/openapi --openapi-client-type php ``` #### Ruby ```bash npx @boundaryml/baml init \ --client-type rest/openapi --openapi-client-type ruby ``` #### Rust ```bash npx @boundaryml/baml init \ --client-type rest/openapi --openapi-client-type rust ``` #### Other As long as there's an OpenAPI client generator that works with your stack, you can use it with BAML. Check out the [full list in the OpenAPI docs][openapi-client-types]. ```bash npx @boundaryml/baml init \ --client-type rest/openapi --openapi-client-type $OPENAPI_CLIENT_TYPE ``` ### Start the BAML development server ```bash npx @boundaryml/baml dev --preview ``` This will do four things: * serve your BAML functions over a RESTful interface on `localhost:2024` * generate an OpenAPI schema in `baml_client/openapi.yaml` * run `openapi-generator -g $OPENAPI_CLIENT_TYPE` in `baml_client` directory to generate an OpenAPI client for you to use * re-run the above steps whenever you modify any `.baml` files > **Note** > > BAML-over-REST is currently a preview feature. Please provide feedback > either in [Discord][discord] or on [GitHub][openapi-feedback-github-issue] > so that we can stabilize the feature and keep you updated! ### Check that the server is running After running the `npx @boundaryml/baml dev` command, you can check that the server is up and running by making an HTTP request to these routes: 1. [`http://localhost:2024/_debug/ping`](http://localhost:2024/_debug/ping): Open in the browser or use `curl` to check that the server is up. You should see a text response similar to this: `pong (from baml v0.206.1)`. 2. [`http://localhost:2024/docs`](http://localhost:2024/docs): Open in the browser to see and interact with all your routes through the Swagger UI generated from the OpenAPI schema. > **Note** > > If using Docker, replace `localhost` with the container hostname or IP as > appropriate. ### Use a BAML function in any language! `openapi-generator` will generate a `README` with instructions for installing and using your client; we've included snippets for some of the most popular languages below. Check out [`baml-examples`](https://github.com/BoundaryML/baml-examples) for example projects with instructions for running them. > **Note** > > We've tested the below listed OpenAPI clients, but not all of them. If you run > into issues with any of the OpenAPI clients, please let us know, either in > [Discord][discord] or by commenting on > [GitHub][openapi-feedback-github-issue] so that we can either help you out > or fix it! #### Go Run this with `go run main.go`: **`main.go`** ```go main.go package main import ( "context" "fmt" "log" baml "my-golang-app/baml_client" ) func main() { cfg := baml.NewConfiguration() b := baml.NewAPIClient(cfg).DefaultAPI extractResumeRequest := baml.ExtractResumeRequest{ Resume: "Ada Lovelace (@gmail.com) was an English mathematician and writer", } resp, r, err := b.ExtractResume(context.Background()).ExtractResumeRequest(extractResumeRequest).Execute() if err != nil { fmt.Printf("Error when calling b.ExtractResume: %v\n", err) fmt.Printf("Full HTTP response: %v\n", r) return } log.Printf("Response from server: %v\n", resp) } ``` #### Java First, add the OpenAPI-generated client to your project. #### If you have 'mvn' in your PATH You can use the default `on_generate` command, which will tell `baml dev` to install the OpenAPI-generated client into your local Maven repository by running `mvn clean install` every time you save a change to a BAML file. To depend on the client in your local Maven repo, you can use these configs: **`pom.xml`** ```xml pom.xml org.openapitools openapi-java-client 0.1.0 compile ``` **`settings.gradle.kts`** ```kotlin settings.gradle.kts repositories { mavenCentral() mavenLocal() } dependencies { implementation("org.openapitools:openapi-java-client:0.1.0") } ``` #### If you don't have 'mvn' in your PATH You'll probably want to comment out `on_generate` and instead use either the [OpenAPI Maven plugin] or [OpenAPI Gradle plugin] to build your OpenAPI client. [OpenAPI Maven plugin]: https\://github.com/OpenAPITools/openapi-generator/tree/master/modules/openapi-generator-maven-plugin[OpenAPI Gradle plugin]: https\://github.com/OpenAPITools/openapi-generator/tree/master/modules/openapi-generator-gradle-plugin **`pom.xml`** ```xml pom.xml org.openapitools openapi-generator-maven-plugin 7.8.0 generate ${project.basedir}/baml_client/openapi.yaml baml ${project.build.directory}/generated-sources/openapi com.boundaryml.baml_client.api com.boundaryml.baml_client.model com.boundaryml.baml_client true ``` **`settings.gradle.kts`** ```kotlin settings.gradle.kts plugins { id("org.openapi.generator") version "7.8.0" } openApiGenerate { generatorName.set("java") // Change to 'kotlin', 'spring', etc. if needed inputSpec.set("${projectDir}/baml_client/openapi.yaml") outputDir.set("$buildDir/generated-sources/openapi") apiPackage.set("com.boundaryml.baml_client.api") modelPackage.set("com.boundaryml.baml_client.model") invokerPackage.set("com.boundaryml.baml_client") additionalProperties.set(mapOf("java8" to "true")) } sourceSets["main"].java { srcDir("$buildDir/generated-sources/openapi/src/main/java") } tasks.named("compileJava") { dependsOn("openApiGenerate") } ``` Then, copy this code into wherever your `main` function is: ```Java import com.boundaryml.baml_client.ApiClient; import com.boundaryml.baml_client.ApiException; import com.boundaryml.baml_client.Configuration; // NOTE: baml_client/README.md will suggest importing from models.* - that is wrong. // See https://github.com/OpenAPITools/openapi-generator/issues/19431 for more details. import com.boundaryml.baml_client.model.*; import com.boundaryml.baml_client.api.DefaultApi; public class Example { public static void main(String[] args) { ApiClient defaultClient = Configuration.getDefaultApiClient(); DefaultApi apiInstance = new DefaultApi(defaultClient); ExtractResumeRequest extractResumeRequest = new ExtractResumeRequest(); // ExtractResumeRequest | try { Resume result = apiInstance.extractResume(extractResumeRequest); System.out.println(result); } catch (ApiException e) { System.err.println("Exception when calling DefaultApi#extractResume"); System.err.println("Status code: " + e.getCode()); System.err.println("Reason: " + e.getResponseBody()); System.err.println("Response headers: " + e.getResponseHeaders()); e.printStackTrace(); } } } ``` #### PHP > **Warning** > > The PHP OpenAPI generator doesn't support OpenAPI's `oneOf` type, which is > what we map BAML union types to. Please let us know if this is an issue for > you, and you need help working around it. First, add the OpenAPI-generated client to your project: **`composer.json`** ```json composer.json "repositories": [ { "type": "path", "url": "baml_client" } ], "require": { "boundaryml/baml-client": "*@dev" } ``` You can now use this code to call a BAML function: ```PHP setResume("Marie Curie was a Polish and naturalised-French physicist and chemist who conducted pioneering research on radioactivity"); try { $result = $apiInstance->extractResume($extract_resume_request); print_r($result); } catch (Exception $e) { echo 'Exception when calling DefaultApi->extractResume: ', $e->getMessage(), PHP_EOL; } ``` #### Ruby Use `ruby -Ilib/baml_client app.rb` to run this: **`app.rb`** ```ruby app.rb require 'baml_client' require 'pp' api_client = BamlClient::ApiClient.new b = BamlClient::DefaultApi.new(api_client) extract_resume_request = BamlClient::ExtractResumeRequest.new( resume: <<~RESUME John Doe Education - University of California, Berkeley - B.S. in Computer Science - graduated 2020 Skills - Python - Java - C++ RESUME ) begin result = b.extract_resume(extract_resume_request) pp result edu0 = result.education[0] puts "Education: #{edu0.school}, #{edu0.degree}, #{edu0.year}" rescue BamlClient::ApiError => e puts "Error when calling DefaultApi#extract_resume" pp e end ``` #### Rust > **Tip** > > If you're using `cargo watch -- cargo build` and seeing build failures because it can't find > the generated `baml_client`, try increasing the delay on `cargo watch` to 1 second like so: > > ```bash > cargo watch --delay 1 -- cargo build > ``` First, add the OpenAPI-generated client to your project: **`Cargo.toml`** ```toml Cargo.toml [dependencies] baml-client = { path = "./baml_client" } ``` You can now use `cargo run`: ```rust use baml_client::models::ExtractResumeRequest; use baml_client::apis::default_api as b; #[tokio::main] async fn main() { let config = baml_client::apis::configuration::Configuration::default(); let resp = b::extract_resume(&config, ExtractResumeRequest { resume: "Tony Hoare is a British computer scientist who has made foundational contributions to programming languages, algorithms, operating systems, formal verification, and concurrent computing.".to_string(), }).await.unwrap(); println!("{:#?}", resp); } ``` [discord]: https://discord.gg/BTNBeXGuaS [openapi-feedback-github-issue]: https://github.com/BoundaryML/baml/issues/892 [npx-windows-issue]: https://github.com/nodejs/node/issues/53538 [openapi-client-types]: https://github.com/OpenAPITools/openapi-generator#overview [openapi]: https://www.openapis.org/