Add Vela without owning customer provider keys.
Use @vela/sdk to open Hosted Connect, bind the customer
delegation chosen by your app, authorize each model execution, call the
OpenAI-compatible relay, and report the result for audit.
- Vela stays the control plane for delegation, revocation, spend limits, and audit.
- OpenRouter remains the execution backend behind short-lived relay access.
- The SDK keeps framework code small: your app owns identity, session, chat UI, and model history.
Do not store raw customer provider keys in the developer app. The app stores
customerTenantId and delegationId, then asks Vela
for scoped relay access before each model call.
Integration flow
-
1
Register app
Developer Console issues the App ID and App token used by the SDK client.
-
2
Connect customer
Hosted Connect creates or reuses a customer delegation.
-
3
Bind scope
The app stores and restores the chosen customer and delegation IDs.
-
4
Prepare call
Vela checks status, policy, model, ZDR, and spend before execution.
-
5
Report result
The app sends completed or failed execution results back to audit.
Quickstart
Start with @vela/sdk. Add @vela/ai-sdk only for
AI SDK routes that want chat model and stream callback wiring helpers.
pnpm add @vela/sdk
pnpm add @vela/ai-sdk ai
VELA_APP_ID=app_example
VELA_APP_TOKEN=vela_sk_example
# Optional for local Vela API development.
VELA_BASE_URL=http://localhost:4000
import { createVelaClientFromEnvironment, createVelaEnvironmentDiagnosticsResponse, createVelaErrorResponse, createVelaIntegration, getVelaEnvironmentDiagnostics } from "@vela/sdk";
const CHAT_ESTIMATED_COST_USD = 0.05;
export async function POST(req: Request) {
const environment = getVelaEnvironmentDiagnostics({ env: process.env });
if (!environment.ok) {
return createVelaEnvironmentDiagnosticsResponse(environment);
}
try {
const executionScope = await resolveExecutionScopeForRequest(req);
if (!executionScope) {
return Response.json({ error: "Vela execution scope is not configured." }, { status: 400 });
}
const client = createVelaClientFromEnvironment({ env: process.env });
const vela = createVelaIntegration({ client, executionScope });
const prepared = await vela.prepareExecutionWithResponse({
estimatedCostUsd: CHAT_ESTIMATED_COST_USD,
});
if (prepared.outcome !== "allow") {
return prepared.response;
}
const result = await callModel({
model: prepared.openAiCompatibleModel,
...prepared.openAiCompatibleClientOptions,
});
await prepared.reportCompletedWithUsage(extractUsage(result));
return Response.json({ result });
} catch (error) {
return createVelaErrorResponse(error, {
fallbackMessage: "Unexpected Vela chat error.",
});
}
}