Malloy Documentation
search

Build custom applications that query your Malloy models via HTTP.

Building a React app? Use the Publisher SDK instead—it wraps these APIs in ready-to-use components with automatic rendering.


Explore the API

Publisher includes an interactive Swagger UI at:

http://localhost:4000/api-doc.html

Use it to browse endpoints, see request/response schemas, and try API calls directly in your browser.

Full OpenAPI specification: api-doc.yaml


What You Can Do

The REST API lets you:

Capability Description
Browse models List environments, packages, and models available on the server
Get model schema Retrieve sources, measures, dimensions, and views defined in a model
Execute queries Run Malloy queries and get JSON results
Explore databases List schemas, tables, and columns from connected databases
Check health Verify server status and initialization

Quick Example

Run a query against a model. The environment and package below are the samples Publisher serves out of the box, so this works as-is against a server started with no arguments (npx @malloy-publisher/server). If you passed --server_root or --config, substitute your own environment, package and model names.

curl -X POST "http://localhost:4000/api/v0/environments/examples/packages/storefront/models/storefront.malloy/query" \
  -H "Content-Type: application/json" \
  -d '{"query": "run: order_items -> { aggregate: order_count is count(), total_revenue is sum(sale_price) }", "compactJson": true}'

Response:

{
  "result": "[{\"order_count\":25356,\"total_revenue\":2098177.9700000403}]",
  "resource": "/api/v0/environments/examples/packages/storefront/models/storefront.malloy/query"
}

Note that result is a JSON string, not an object, so parse it before use: JSON.parse(body.result).

compactJson: true gives you the plain array of row objects shown above. Leave it out (the default) and result contains the full Malloy result instead: the same rows plus the schema and per-cell type metadata that the renderer needs to draw charts and tables.


Common Patterns

Fetch and Display Data

The query goes in the request body, not the query string. The endpoint accepts POST only.

async function fetchMetrics() {
  const response = await fetch(
    'http://localhost:4000/api/v0/environments/examples/packages/storefront/models/storefront.malloy/query',
    {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        query: 'run: order_items -> { aggregate: total_revenue is sum(sale_price) }',
        compactJson: true,
      }),
    }
  );
  const body = await response.json();
  return JSON.parse(body.result); // -> [{ total_revenue: 2098177.9700000403 }]
}

Use Pre-defined Views

Instead of writing queries inline, reference views defined in your model:

// storefront.malloy defines: view: business_overview is { ... }
const query = 'run: order_items -> business_overview';

This keeps business logic in the model, not scattered across API calls.


When to Use REST vs SDK

Use REST API when... Use Publisher SDK when...
Building backend services Building React frontends
Non-JavaScript environments Want automatic rendering
Need full control over requests Want pre-built components
Integrating with existing systems Rapid dashboard development

Next Steps