# How to Integrate Bolt.new with Azure Machine Learning

- Tool: Bolt.new
- Difficulty: Intermediate
- Time required: 30 minutes
- Last updated: April 2026

## TL;DR

To use Azure Machine Learning with Bolt.new, deploy your ML model to an Azure ML managed online endpoint, then call the scoring URI from a Next.js API route in Bolt using the endpoint's API key. Azure ML endpoints are standard REST APIs — outbound calls work in Bolt's WebContainer preview. Add your scoring URI and API key to the .env file, prompt Bolt to generate the API route and prediction UI, then deploy to Netlify or Vercel.

## Call Custom ML Models from Bolt.new via Azure Machine Learning Endpoints

Azure Machine Learning managed online endpoints turn any trained model — scikit-learn classifiers, PyTorch neural networks, custom XGBoost models — into a REST API with auto-scaling, authentication, and monitoring built in. Unlike pre-built AI services such as OpenAI or Azure Cognitive Services, Azure ML endpoints host your own models, giving you full control over the model logic, input schema, and output format. This makes Azure ML the right choice when you have proprietary training data, domain-specific models, or compliance requirements that prevent sending data to third-party LLM providers.

The integration with Bolt.new follows the standard pattern: Bolt generates a Next.js API route that accepts user input from the frontend, formats it into the payload structure your Azure ML endpoint expects, calls the scoring URI with the endpoint API key in the Authorization header, and returns the prediction result to the React component. Because Azure ML endpoints are standard HTTPS REST APIs, outbound calls work perfectly in Bolt's WebContainer preview — you can validate your integration without deploying.

The input payload format for Azure ML endpoints uses a specific structure: { "input_data": { "columns": [...], "data": [[...]] } } for tabular models, or a custom schema defined in your scoring script. Bolt can generate correct payload shapes once you share your endpoint's expected schema. Azure ML also supports real-time single predictions and batch scoring jobs — this tutorial covers both patterns so you can choose the right approach for your use case.

## Before you start

- An Azure account with an Azure Machine Learning workspace created
- A trained ML model deployed to an Azure ML managed online endpoint (not a batch endpoint)
- The scoring URI and primary API key from your Azure ML endpoint (found in Azure ML Studio under Endpoints, then the Consume tab)
- A Bolt.new project using Next.js (request Next.js explicitly when starting a new Bolt project if not already using it)
- Basic familiarity with your model's expected input schema (column names, data types, payload format)

## Step-by-step guide

### 1. Get Your Azure ML Endpoint Scoring URI and API Key

Before writing any code in Bolt, you need two values from your Azure ML managed online endpoint: the scoring URI and the primary API key. Log in to the Azure portal at portal.azure.com and navigate to your Machine Learning workspace. Inside the workspace, open Azure ML Studio by clicking 'Launch studio'. In the left navigation, click 'Endpoints' under the Assets section. Find your deployed online endpoint in the list and click on it. On the endpoint detail page, click the 'Consume' tab. Here you'll see the REST endpoint URL — the scoring URI, which looks like https://your-endpoint-name.eastus.inference.ml.azure.com/score — and the Primary key. Copy both values. The scoring URI is the URL your API route will POST to. The primary key goes in the Authorization header as 'Bearer YOUR_KEY'. Keep this page open — you'll also want to check the 'Test' tab to see example input and output payloads for your specific model. Understanding the expected payload format, including column names, data types, and whether the endpoint expects the standard input_data format or a custom schema, before prompting Bolt will make the generated code work correctly on the first attempt rather than requiring corrections.

**Expected result:** You have your Azure ML scoring URI (https://...inference.ml.azure.com/score) and primary API key copied and ready to add to your .env file.

### 2. Add Azure ML Credentials to Your .env File

In Bolt.new, environment variables are stored in a .env file in the project root. Open the file tree in your Bolt project by clicking the folder icon in the sidebar or using the Files panel, then open the .env file. If it does not exist yet, create it in the project root. Add two variables: AZURE_ML_SCORING_URI with your endpoint's scoring URI, and AZURE_ML_API_KEY with your primary key. In a Next.js project in Bolt, server-side environment variables used in API routes do not need a prefix — just AZURE_ML_SCORING_URI and AZURE_ML_API_KEY are correct. Never use a NEXT_PUBLIC_ prefix for these values, as that would expose them to the browser. Important Bolt.new caveat: the .env file is visible in the Bolt file tree and is NOT encrypted. It is suitable for development credentials but you must set environment variables in your hosting platform (Netlify or Vercel) separately before deploying, and you should never commit the .env file to a public GitHub repository. After saving the .env file, you may need to restart the Bolt dev server for the new variables to be picked up by the running Next.js instance.

```
# .env (project root — do NOT commit to public repos)
AZURE_ML_SCORING_URI=https://your-endpoint-name.eastus.inference.ml.azure.com/score
AZURE_ML_API_KEY=your-primary-key-here
```

**Expected result:** The .env file exists in your project root with both AZURE_ML_SCORING_URI and AZURE_ML_API_KEY set. The Next.js dev server can read them via process.env in API routes.

### 3. Prompt Bolt to Generate the API Route and Prediction UI

With credentials in place, use the Bolt chat to generate the API route and frontend components in a single prompt. Be specific about your model's input schema — list the exact column names and types your Azure ML endpoint expects. The more detail you provide about the input and output format, the more accurate the generated code will be. Bolt will create a Next.js API route at app/api/predict/route.ts that reads the scoring URI and API key from process.env, formats the request payload in the structure your Azure ML endpoint expects — usually { input_data: { columns: [...], data: [[...]] } } for tabular data — sends a POST request to the Azure ML scoring URI with the Authorization header, and returns the prediction result as JSON to the frontend. The API route acts as a proxy: the browser never sees your Azure ML credentials. The frontend component Bolt generates sends user input to /api/predict, receives the prediction, and displays the result. Because the Azure ML scoring URI is a standard HTTPS endpoint, the outbound call from the Bolt WebContainer works during development — you can see real predictions in the preview before deploying.

```
// app/api/predict/route.ts
import { NextRequest, NextResponse } from 'next/server';

export async function POST(request: NextRequest) {
  const scoringUri = process.env.AZURE_ML_SCORING_URI;
  const apiKey = process.env.AZURE_ML_API_KEY;

  if (!scoringUri || !apiKey) {
    return NextResponse.json(
      { error: 'Azure ML credentials not configured' },
      { status: 500 }
    );
  }

  const inputData = await request.json();

  // Format payload for Azure ML tabular endpoint
  const payload = {
    input_data: {
      columns: Object.keys(inputData),
      data: [Object.values(inputData)],
    },
  };

  const response = await fetch(scoringUri, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${apiKey}`,
    },
    body: JSON.stringify(payload),
  });

  if (!response.ok) {
    const errorText = await response.text();
    console.error('Azure ML error:', response.status, errorText);
    return NextResponse.json(
      { error: `Azure ML endpoint returned ${response.status}` },
      { status: response.status }
    );
  }

  const result = await response.json();
  return NextResponse.json({ prediction: result });
}
```

**Expected result:** The API route at /api/predict accepts POST requests with input features, calls the Azure ML endpoint, and returns predictions. The prediction form renders in the Bolt preview and returns real model predictions when submitted.

### 4. Handle Batch Predictions for Multiple Records

For scenarios where users need to score many records at once — uploading a CSV of customers, properties, or transactions — Azure ML managed online endpoints support batch payloads containing multiple rows in a single request. The payload structure extends the same input_data format: the data array contains multiple sub-arrays, one per record. This is far more efficient than making one API call per record and avoids hitting Azure ML's per-minute rate limits. In Bolt, prompt the AI to add a CSV parsing step before the API call. The frontend reads the uploaded file using the browser's File API, parses it into an array of row objects, maps the values into the Azure ML batch payload format, and sends a single POST request to /api/predict. The API route formats all rows into one Azure ML payload and returns an array of predictions — one per input row. Important: Azure ML managed online endpoints have a default payload size limit of approximately 1.5MB and a request timeout of around 60 seconds. For truly large datasets, Azure ML batch endpoints are the better choice — they run asynchronously as jobs and are designed for bulk scoring. For real-time online endpoints, keep batch requests under a few hundred rows to stay within limits and maintain acceptable response times.

```
// app/api/predict/route.ts — handles both single and batch predictions
import { NextRequest, NextResponse } from 'next/server';

export async function POST(request: NextRequest) {
  const scoringUri = process.env.AZURE_ML_SCORING_URI;
  const apiKey = process.env.AZURE_ML_API_KEY;

  if (!scoringUri || !apiKey) {
    return NextResponse.json(
      { error: 'Azure ML credentials not configured' },
      { status: 500 }
    );
  }

  const body = await request.json();

  // Support both single prediction and batch
  const isBatch = Array.isArray(body.rows);
  const columns: string[] = body.columns ?? Object.keys(isBatch ? body.rows[0] : body);
  const data: unknown[][] = isBatch
    ? body.rows.map((row: Record<string, unknown>) => columns.map((col) => row[col]))
    : [columns.map((col) => body[col])];

  const payload = { input_data: { columns, data } };

  const response = await fetch(scoringUri, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${apiKey}`,
    },
    body: JSON.stringify(payload),
  });

  if (!response.ok) {
    const errorText = await response.text();
    return NextResponse.json(
      { error: `Azure ML returned ${response.status}: ${errorText}` },
      { status: response.status }
    );
  }

  const result = await response.json();
  // Azure ML returns an array for batch; normalize to array for consistent frontend handling
  const predictions = Array.isArray(result) ? result : [result];
  return NextResponse.json({ predictions });
}
```

**Expected result:** Users can upload a CSV file, preview the data in a table, click Score All Rows, and see a results table with a Prediction column appended — all processed in a single API call to the Azure ML endpoint.

### 5. Deploy to Netlify or Vercel with Azure ML Environment Variables

When you're ready to move from the Bolt preview to a public URL, deploy the app to Netlify or Vercel. The Azure ML integration works perfectly in the Bolt WebContainer preview for outbound API calls, but a deployed URL is required for sharing the app with users. In Netlify: click Deploy in Bolt or connect your GitHub repo in the Netlify dashboard, then go to Site Configuration → Environment Variables and add AZURE_ML_SCORING_URI and AZURE_ML_API_KEY with your actual values. Do not rely on the .env file for production — hosting platform environment variables are encrypted and injected at build and runtime, unlike the plain-text .env file visible in Bolt's file tree. In Vercel: go to your project Settings → Environment Variables, add both variables for the Production environment. After adding the variables, trigger a new deployment — the running functions on an existing deployment do not automatically pick up newly added environment variables. Test your deployed prediction form to confirm the API route calls the Azure ML endpoint correctly from the production serverless function. The Next.js API route that Bolt generated runs as a Netlify Function or Vercel Serverless Function — the Azure ML API key stays server-side and never appears in the browser network tab or page source. Keep in mind that Azure ML endpoints remain active and billed as long as you have compute allocated. If this app is for a demo or low-traffic use case, consider scaling the endpoint to zero instances when not in use via Azure ML Studio to avoid ongoing compute charges.

```
// components/PredictionForm.tsx — with loading and error states for production
'use client';
import { useState } from 'react';

interface PredictionResult {
  predictions: number[];
}

export function PredictionForm() {
  const [inputs, setInputs] = useState({
    age: '',
    annual_income: '',
    credit_score: '',
    loan_amount: '',
  });
  const [result, setResult] = useState<PredictionResult | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    setLoading(true);
    setError(null);
    setResult(null);

    try {
      const response = await fetch('/api/predict', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          age: Number(inputs.age),
          annual_income: Number(inputs.annual_income),
          credit_score: Number(inputs.credit_score),
          loan_amount: Number(inputs.loan_amount),
        }),
      });

      if (!response.ok) {
        const err = await response.json();
        throw new Error(err.error ?? 'Prediction failed');
      }

      const data: PredictionResult = await response.json();
      setResult(data);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'An unexpected error occurred');
    } finally {
      setLoading(false);
    }
  }

  return (
    <form onSubmit={handleSubmit} className="space-y-4 max-w-md">
      {(Object.keys(inputs) as Array<keyof typeof inputs>).map((key) => (
        <div key={key}>
          <label className="block text-sm font-medium capitalize">
            {key.replace(/_/g, ' ')}
          </label>
          <input
            type="number"
            value={inputs[key]}
            onChange={(e) => setInputs((prev) => ({ ...prev, [key]: e.target.value }))}
            className="mt-1 block w-full rounded border border-gray-300 px-3 py-2"
            required
          />
        </div>
      ))}
      <button
        type="submit"
        disabled={loading}
        className="w-full bg-blue-600 text-white py-2 rounded hover:bg-blue-700 disabled:opacity-50"
      >
        {loading ? 'Getting prediction...' : 'Get Prediction'}
      </button>
      {error && <p className="text-red-600 text-sm mt-2">{error}</p>}
      {result && (
        <div className="p-4 bg-green-50 rounded border border-green-200 mt-4">
          <p className="font-semibold">Prediction: {result.predictions[0]}</p>
        </div>
      )}
    </form>
  );
}
```

**Expected result:** The app is deployed to Netlify or Vercel, the Azure ML environment variables are set in the hosting dashboard, and the prediction form returns real model predictions from the deployed serverless function.

## Best practices

- Never expose your Azure ML API key in client-side code — always proxy requests through a Next.js API route that reads the key from process.env on the server, never with a NEXT_PUBLIC_ prefix
- Store AZURE_ML_SCORING_URI and AZURE_ML_API_KEY in Netlify or Vercel environment variable settings for production, not only in the .env file which is visible in plain text in Bolt's file tree
- Use the Test tab in Azure ML Studio to verify your endpoint's exact expected input schema before writing Bolt prompts — mismatched column names cause 400 errors and are the most common integration failure
- Set a minimum instance count of 1 on your Azure ML endpoint if your app has user-facing latency requirements — scaling to zero saves cost but introduces cold-start delays of 30 seconds or more on the first request
- Implement a request timeout using AbortController in your API route so a slow or unavailable Azure ML endpoint does not leave the user's browser hanging indefinitely
- Validate and coerce input types before sending to Azure ML — the endpoint expects numeric values as JavaScript numbers, not strings from HTML form inputs
- Monitor your Azure ML endpoint costs in the Azure portal — managed online endpoints with dedicated compute instances run and bill continuously regardless of request volume
- For high-volume batch scoring needs, use Azure ML batch endpoints (asynchronous jobs) rather than sending large payloads to the real-time online endpoint which has a 1.5MB payload size limit

## Use cases

### Real-Time Prediction Form

A user fills in a form with input features — for example, customer age, purchase history, and account type — and your app returns a churn probability score from a model deployed on Azure ML. The prediction happens in under a second with a managed online endpoint.

Prompt example:

```
Build a customer churn prediction form in my app. The form collects: customer_age (number), monthly_spend (number), contract_type (dropdown: Monthly/Annual), support_tickets (number). On submit, send these values to my Azure ML endpoint at AZURE_ML_SCORING_URI and display the churn probability as a percentage. Show a green badge if risk is under 30%, yellow for 30-70%, red for over 70%. Use AZURE_ML_API_KEY from environment variables in the API route.
```

### Batch CSV Scoring

A user uploads a CSV file containing multiple rows of input data. Your app reads the file, sends all rows to the Azure ML endpoint in a single batch request, and displays the prediction results in a table. Ideal for scoring hundreds of records at once without making individual API calls per row.

Prompt example:

```
Add a CSV batch upload feature to my app. The user uploads a CSV file with columns: sqft, bedrooms, bathrooms, year_built, neighborhood. Parse the CSV on the frontend, send all rows as a batch payload to my Azure ML housing price prediction endpoint at AZURE_ML_SCORING_URI using the API key from AZURE_ML_API_KEY. Display the predicted prices in a sortable table alongside the original input rows. Show a loading spinner while the batch prediction is running.
```

### Image Classification

A user uploads an image and your app sends it to an Azure ML computer vision endpoint that returns a predicted class label and confidence score. The result is displayed below the uploaded image with the top-3 predicted categories.

Prompt example:

```
Build an image classification feature. The user clicks Upload Image and selects a JPG or PNG file. Convert the image to base64, send it to my Azure ML image classification endpoint at AZURE_ML_SCORING_URI with the API key AZURE_ML_API_KEY. The endpoint returns { "predictions": [{ "label": "string", "confidence": "number" }] }. Display the uploaded image preview and show the top 3 predicted labels with confidence bars below the image.
```

## Troubleshooting

### API route returns 401 Unauthorized or 403 Forbidden when calling the Azure ML endpoint

Cause: The Authorization header value is incorrect — the API key is wrong, the key has been rotated since you copied it, or the header format does not match the endpoint's authentication mode (Key vs AMLToken).

Solution: In Azure ML Studio, go to Endpoints, select your endpoint, open the Consume tab, and copy the primary key again — keys can be regenerated and your copy may be stale. Confirm your .env file has the exact value with no trailing spaces or surrounding quotes. The Authorization header format for key-based auth must be 'Bearer YOUR_KEY' — not 'api-key YOUR_KEY' or just 'YOUR_KEY'. If the endpoint uses AMLToken authentication instead of Key, you need an Azure AD access token from a service principal rather than a static API key.

```
// Correct authorization header for Azure ML key-based authentication
headers: {
  'Content-Type': 'application/json',
  'Authorization': `Bearer ${process.env.AZURE_ML_API_KEY}`,
}
```

### API route returns 400 Bad Request with an error message about invalid input, missing columns, or schema mismatch

Cause: The payload structure or column names do not match what the Azure ML scoring script expects. Azure ML tabular endpoints are strict about column names, ordering, and data types — a single misspelled column name causes the entire request to fail.

Solution: Go to Azure ML Studio, open your endpoint, and click the Test tab. Copy the exact column names shown in the sample input payload. The names must match your training data schema exactly — capitalization, underscores, and spelling all matter. Also confirm whether your endpoint expects the standard { input_data: { columns, data } } format or a custom JSON structure defined in your scoring script's run() function.

```
// Column names must exactly match the training schema — check Azure ML Studio Test tab
const payload = {
  input_data: {
    columns: ['Age', 'AnnualIncome', 'CreditScore', 'LoanAmount'], // exact names from training
    data: [[Number(age), Number(income), Number(credit), Number(loan)]],
  },
};
```

### The prediction form returns predictions in the Bolt preview but the API route returns errors after deploying to Netlify or Vercel

Cause: AZURE_ML_SCORING_URI and AZURE_ML_API_KEY are set in the local .env file for development but were not added to the hosting platform's environment variable settings before deploying. The deployed serverless function cannot find the variables.

Solution: In Netlify, go to Site Configuration → Environment Variables and add both AZURE_ML_SCORING_URI and AZURE_ML_API_KEY. In Vercel, go to project Settings → Environment Variables and set them for the Production environment. After adding the variables, trigger a new deployment — existing deployed functions do not automatically pick up newly added environment variables.

### The Azure ML endpoint takes 30 or more seconds to respond, or the fetch call times out with no response

Cause: The managed online endpoint has scaled down to zero instances and is cold-starting, or the compute instance type is undersized for the model's inference requirements. Standard_DS1_v2 instances can be too slow for larger models.

Solution: In Azure ML Studio, open your endpoint and check the Deployment settings — if minimum instance count is 0, increase it to 1 to prevent cold starts. For persistent timeout issues, add a request timeout using AbortController in the API route, and consider upgrading to a larger compute SKU. For demos and low-traffic use cases, setting minimum instances to 1 is the easiest fix.

```
// Add a 30-second timeout to the Azure ML fetch call
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 30000);

try {
  const response = await fetch(scoringUri, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${apiKey}` },
    body: JSON.stringify(payload),
    signal: controller.signal,
  });
  clearTimeout(timeout);
  // ... handle response
} catch (err) {
  clearTimeout(timeout);
  if (err instanceof Error && err.name === 'AbortError') {
    return NextResponse.json({ error: 'Azure ML endpoint timed out after 30 seconds' }, { status: 504 });
  }
  throw err;
}
```

## Frequently asked questions

### Can I call my Azure ML endpoint directly from the frontend in Bolt.new?

Technically possible but strongly discouraged. Calling the Azure ML endpoint directly from the browser would expose your API key in the network tab and browser source, allowing anyone to call your endpoint and incur charges on your Azure account. Always route requests through a Next.js API route that reads the key from process.env on the server side.

### Does calling Azure ML from Bolt's WebContainer preview require any special configuration?

No special setup is needed. Azure ML managed online endpoints are standard HTTPS REST APIs, and outbound HTTP calls work fine from Bolt's WebContainer during development. Add your scoring URI and API key to the .env file, create the API route, and predictions will return in the Bolt preview immediately — no deployment required for testing outbound calls to Azure ML.

### What input format does my Azure ML endpoint expect?

For tabular models deployed with AutoML or MLflow, the standard format is { input_data: { columns: ['col1', 'col2'], data: [[val1, val2]] } }. For custom scoring scripts, the format depends on what your score.py run() function expects. Check the Test tab in Azure ML Studio — it shows a working sample payload for your specific deployment that you can copy directly into your Bolt prompt.

### How do I reduce Azure ML endpoint costs when the app is not in active use?

In Azure ML Studio, navigate to your endpoint's Deployment settings and set the minimum instance count to 0. This scales the endpoint to zero when idle, stopping compute charges. The tradeoff is a cold-start latency of 30 seconds or more when the first request arrives after a period of inactivity. For user-facing apps, keep minimum instances at 1. For background or batch use cases, zero minimum instances is cost-effective.

### Can Bolt.new work with Azure ML endpoints that use Azure Active Directory authentication instead of a static API key?

Yes, but it requires additional setup. Instead of a static API key, you need to obtain an Azure AD access token using a service principal. Create an App Registration in Azure, assign it access to the ML workspace, and store the client ID and client secret in your .env file. Then prompt Bolt to use the @azure/identity package with ClientSecretCredential to obtain a bearer token before each request. This is more complex than key-based auth but necessary for enterprise environments with strict identity requirements.

### What happens in the Bolt preview if my Azure ML endpoint is scaled to zero instances?

The first request after a cold start will time out or take 30-60 seconds to respond because Azure ML needs to spin up a container and load your model. Subsequent requests are fast once the instance is warm. During development, set minimum instances to 1 in Azure ML Studio to avoid cold starts. Add a request timeout with AbortController in your API route so the Bolt preview does not hang if the endpoint is cold.

---

Source: https://www.rapidevelopers.com/bolt-ai-integrations/azure-machine-learning
© RapidDev — https://www.rapidevelopers.com/bolt-ai-integrations/azure-machine-learning
