ENGINEERING
Add AI to Power Automate without AI Builder credits
Why AI Builder credits get expensive fast
Power Automate ships with AI Builder actions — Extract information, Categorize text, Summarize text — that call Microsoft's own models. They work, and they're the easiest path if you never plan to scale past a handful of runs a day. The catch is the pricing model: AI Builder runs on prepaid credit packs that expire on a cycle, not a per-call rate you can size against actual usage. A flow that classifies a burst of a few thousand tickets in one afternoon can eat a month's allocation in an afternoon, and unused credits don't roll forward cleanly once the pack expires. For a flow that runs against variable volume — a shared support inbox, an invoice queue that spikes at month-end — that's a hard number to forecast, and an easy one to blow through without warning.
The alternative most teams don't realize is already available: point the built-in HTTP action at any OpenAI-compatible endpoint, including one you run yourself. No AI Builder license, no credit pack, no per-environment cap tied to your Power Platform tier. You pay for tokens, metered per API key, against a budget you set — the accounting model you'd expect from any API bill, not a pack that resets on Microsoft's schedule.
The HTTP action, wired to your gateway
This doesn't require anything exotic. Power Automate's HTTP action already speaks REST, and a Chat Completions endpoint is REST:
Method: POST
URI: https://gateway.your-company.com/v1/chat/completions
Headers:
Authorization: Bearer <key>
Content-Type: application/json
Body:
{
"model": "your-model",
"messages": [
{ "role": "system", "content": "Classify the ticket into one of: billing, technical, sales." },
{ "role": "user", "content": "@{triggerBody()?['body']}" }
],
"max_tokens": 200
}
That's the whole integration on the request side. The response comes back as standard OpenAI-shaped JSON, and the next step is a Parse JSON action against a schema you generate once from a sample response, followed by whatever downstream action needs the result — typically a direct reference into choices[0].message.content.
What this looks like in a flow
The concrete case we see most often: a flow triggered on a new email or a new item in a shared mailbox, one HTTP action that asks the model to classify the message and pull out three or four structured fields, a Parse JSON step, and then a Dataverse "Add a new row" or a SharePoint "Create item" action that writes the classification and extracted fields alongside the original message. No AI Builder model to train, no separate prompt library to maintain — the prompt lives in the flow's HTTP body, versioned with the flow itself.
The same shape covers extraction, not just classification. Swap the system prompt for one that asks the model to return a small JSON object — vendor name, invoice number, total, due date — and instruct it to answer with JSON only. Parse JSON turns that straight into named outputs you can drop into a SharePoint column or a Dataverse row with no extra transform step in between. It's the same three actions as the classification case; only the prompt and the downstream schema change.
Notes from running this in production
- The HTTP action is a premium connector. Using it in a flow requires a Power Automate premium or per-flow plan — a real cost, separate from AI Builder credits, worth checking against what your tenant already licenses before promising this is "free."
- Don't put the key in the action's URI or body. Store it as an environment variable in the solution the flow ships in, or reference it from Azure Key Vault if your tenant already uses Key Vault references for other connections. Either way, the key shouldn't be visible to anyone who opens the flow in edit mode.
- Set a retry policy on the action. Gateways rate-limit, and the HTTP action supports a retry policy directly on the step — exponential interval, a handful of attempts. That turns a transient 429 into a few seconds of delay instead of a failed run.
- Constrain the model's output before you parse it. Tell it explicitly to answer with JSON only, no surrounding prose — otherwise Parse JSON will fail intermittently on a response that starts with "Sure, here's the classification:" instead of a brace. A Try/Catch scope around the HTTP-and-parse pair, with a fallback branch that flags the item for manual review, keeps one malformed response from failing the whole run.
Try it on ours
Our gateway (iSol API) speaks this exact Chat Completions shape — no AI Builder credits, no separate model to train. US$ 99/month, 14-day trial.