Smarter APIs, SDKs and Integrations
Everything that you can do in the web console, you can also do from your own software, and a deployed LLMClient’s chat can appear on web sites that aren’t built with Smarter at all. This section documents the pieces that make that possible. They come in three layers, and each layer is built from the one before it:
The APIs define what a Smarter resource is, and how software asks the platform for it. Everything else in this section is built from them.
The SDKs and developer tools are for programmers, as the APIs are. They are clients of the APIs, generated from their contract: libraries for Python, Node.js and Go, the
smartercommand-line program, and the VS Code extension.The website integrations are for people who generally don’t program against Smarter: the owners and administrators of a WordPress, Drupal or Shopify site, a Google Tag Manager container, or a documentation site. Each one adds a deployed LLMClient’s chat to their site from a settings screen.
The design goals that the APIs and the SDKs share come after them, followed by what to do if you want to write an SDK for another language.
The APIs
API |
What it is |
|---|---|
The resource model. A YAML or JSON document that declares what a resource (an LLMClient, a Plugin, a Guardrail, a Secret, …) should be. Every client creates and changes resources by applying manifests. |
|
The REST API that every client calls, under |
|
The machine-readable description of the Smarter API: an OpenAPI 3.1 document, and a JSON Schema and example manifest for every SAM kind. Clients in any language are generated from it. |
The three are layered. SAM says what a resource is, the Smarter API is how a client asks for it, and the OpenAPI contract is the written agreement between the platform and its clients.
SDKs and Developer Tools
SDK or tool |
What it is |
|---|---|
A Python library, |
|
A TypeScript library for Node.js, |
|
A Go module, |
|
A command-line program, like |
|
The editor for manifests: validation as you type, completion and help from the same JSON Schemas, and the CLI’s validate, apply and deploy commands. |
The CLI and the SDKs are clients of the OpenAPI contract, and nothing else: none of them has access to the platform that your own software doesn’t have.
Smarter’s SDKs follow the same design, whatever their language. The Python SDK was the first of them, and is the reference implementation: the Node.js and Go SDKs have its features, resources, verbs and errors, number their architecture decisions as it does, and are tested against the same recorded responses of the platform.
Website Integrations
The website integrations bring a deployed LLMClient to sites that are built on other platforms.
They don’t call the Smarter API themselves. Each one is built on Smarter Chat’s embed script, one <script> tag that any web page can use, and writes that tag
for you from a settings screen, so a site owner needs no code and no knowledge of Smarter beyond
the address of their LLMClient.
Integration |
What it is |
|---|---|
A WordPress plugin that adds the chat to a WordPress site: a launcher on every page, a block and a shortcode. |
|
A Drupal module that adds the chat to a Drupal site: a launcher on every page, and a block. |
|
A Shopify app whose theme app extension adds the chat to a store, from the theme editor. |
|
A tag template that adds the chat to any site with a Google Tag Manager container. |
|
Plugins for Docusaurus, MkDocs and Sphinx, and a recipe for VitePress, that add the chat to every page of a documentation site. |
Design Goals
The goals below are common to the Smarter API and to every official client. They are what you can rely on when you integrate with Smarter, and they are the requirements for anyone who writes a new SDK.
One source of truth: Pydantic models
Every request and response of the Smarter API is a Pydantic model in the platform’s code, and the platform builds its responses from those models (ADR-031). A manifest kind’s model validates every manifest of that kind (ADR-005), and a resource’s REST model is built from its database row, with exactly the row’s fields.
Nothing about the API is described by hand. The OpenAPI document and the SAM JSON Schemas are generated from the same models, and a client’s types are generated from those files. A field that the platform adds, renames or removes therefore changes the contract, then the clients’ types, in that order, and never silently.
A contract that can’t drift
The contract is committed to the platform’s repository, and the platform’s tests fail when it is
out of date, or when a real response of the platform doesn’t validate against it. A breaking change
to the API is therefore visible as a diff of openapi.json or of a sam/<Kind>.schema.json,
in the same pull request as the change that caused it. See
The API Contract.
The SDKs check the other side. Each SDK copies the contract from the platform, at a commit or a release tag, and its own tests fail when it sends a request that the contract doesn’t describe, or when its models no longer read the contract’s examples.
Declarative writes, typed reads
Clients create, change and delete resources by applying manifests, which the brokers validate before anything is changed. The same manifest gives the same result whether it is applied from the CLI, an SDK, a CI/CD job or the web console, and it can be kept in version control and reviewed like code.
The REST API publishes typed reads of each resource family, and the few actions that a manifest can’t express, such as a Guardrail’s dry run, a call to an MCP server’s tool, or adding documents to a Vectorstore. It doesn’t publish a second, imperative way to write a resource.
Same vocabulary in every language
Each SDK is idiomatic in its own language: snake_case in Python, camelCase in TypeScript, exported
types in Go. Its vocabulary is the platform’s: the same resource kinds, and the same verbs as the
CLI (apply, validate, get, describe, delete, deploy, undeploy,
logs). Someone who knows smarter apply -f guardrail.yaml can guess
client.manifests.apply("guardrail.yaml").
Every SAM kind has a typed model in every SDK, generated from the kind’s JSON Schema rather than written by hand, so a new kind or field reaches every language the same way.
Strict platform, tolerant clients
The platform is strict about what it accepts and what it returns: its models forbid fields that they don’t declare, so nothing leaves the platform by accident. The clients are tolerant: their models keep fields that they don’t declare yet, so an SDK keeps working when a newer platform adds a field to a response.
A JSON Schema can’t express every business rule that the platform’s models apply. An SDK’s models
check a manifest’s structure, and the platform’s validate command checks the rest.
One credential, one configuration
Every client authenticates with a Smarter API key, sent as Authorization: Token <api key>, and
can do whatever the key’s user can do. See Authentication.
The SDKs read the CLI’s configuration file, ~/.smarter/config.yaml, and the same
SMARTER_API_KEY and SMARTER_BASE_URL environment variables, so a developer who has run
smarter configure needs no other setup. Every client works with any Smarter platform, not only
platform.smarter.sh: yours, on your laptop or on Kubernetes.
Typed errors
Every error response of the Smarter API has a documented schema: the
Smarter Journal’s error envelope for the manifest API, the
Chat API Contract’s error for the chat API, and
{"detail": "..."} for the REST reads. A journaled error names the platform’s exception class,
e.g. SAMBrokerErrorNotFound.
The SDKs turn these into one hierarchy of exceptions, or its equivalent in the language, with one root that catches them all, and a subclass for each HTTP status (ADR-012).
Streaming, the same way everywhere
A prompt can take a while. A client that asks for text/event-stream receives its progress as
Server-Sent Events, then one result, which is exactly the JSON that a non-streaming client receives.
The SDKs offer both, and Smarter Chat uses the same stream.
Testable without a platform
An SDK’s unit tests never reach a platform: they answer its requests with sanitized copies of real responses, and validate those against the contract. Separate live tests run the SDK against a real platform. They are the only tests that need an api key, and the only ones that make billable LLM requests.
The same practices as the platform
The SDKs are developed the way the platform is: semantic versioning, conventional commits, pre-commit hooks, docstrings that are published here, the platform’s architecture decisions, and Agent Skills that describe how each repository is developed, for people and for AI coding agents.
Writing an SDK for Another Language
Start from the contract, not from the platform’s code:
Copy
openapi.jsonandsam/*.jsonfrom smarter/apps/api/v1/contract, at a release tag, with a command that can refresh them.Generate the SAM models from the SAM JSON Schemas, and the API’s types from
openapi.json. Prefer a generator that reads OpenAPI 3.1; see Generating a Client.Test that every kind’s example manifest parses with its generated model, and that every request that the SDK sends is an operation of
openapi.json.Follow the design goals above, and the Python SDK as the reference implementation, from its configuration lookup to its exception hierarchy. The Node.js and Go SDKs show how its design translates into other languages.
SDKs and Developer Tools