Scout Client SDK

Early access feature

The "Automations" feature is in early access and only available to select customers. If you are interested in getting access, please contact us.

ScoutClient invokes Scout, Uniform's AI agent, from server-side code. It lets you put an agent that already understands your project behind a job, a service, or a bot of your own.

Call Scout from a server, not from the browser

ScoutClient needs an API key or bearer token that carries real permissions on your project, so putting it in client-side code exposes those credentials.

The Uniform AI API also allows cross-origin browser requests only from the Uniform dashboard, so a call made from your own site's origin is blocked by the browser before it reaches Scout. To reach Scout from a browser app, proxy the request through your own backend.

ScoutClient ships in @uniformdev/automations-sdk.

npm install @uniformdev/automations-sdk

A client needs a project and credentials. Pass either an apiKey or a bearerToken.

import { ScoutClient } from '@uniformdev/automations-sdk/ai'; const scout = new ScoutClient({ projectId: process.env.UNIFORM_PROJECT_ID, apiKey: process.env.UNIFORM_API_KEY, }); const { text } = await scout.invoke({ message: 'Review the homepage hero copy against our brand guidelines.', });

invoke runs one turn and resolves when the turn completes, which is what you want when no one is watching output arrive. It returns the final assistant message as text, along with the full thread so far as messages.

Scout runs with the permissions of the credentials you pass and consumes AI credits like any other Scout usage. If the team is out of credits, invoke throws.

Set aiApiHost if your project is not in the default US region.

Omit threadId for a one-shot turn and Scout starts a new thread. Pass the same threadId across calls to build a multi-turn conversation, where Scout keeps the context of everything said earlier in the thread.

const threadId = crypto.randomUUID(); await scout.invoke({ threadId, message: 'Find entries missing a meta description.' }); const { text } = await scout.invoke({ threadId, message: 'Now draft one for each of them.' });

Pass an outputSchema when you need a machine-readable result rather than prose. Scout must record a conforming result as its final action, and invoke throws if it finishes without one.

import * as z from 'zod'; const { structuredOutput } = await scout.invoke({ message: 'Give me 5 jokes about content management', // you can use zod 4 schemas or JSON schema; a zod schema also types `structuredOutput` outputSchema: z.object({ jokes: z.array(z.string()) }), }); // structuredOutput is typed as { jokes: string[] } structuredOutput.jokes.forEach((joke) => console.log(joke));

invoke buffers the whole turn, which is the wrong shape when a person is waiting on the other end. The endpoint speaks the Vercel AI SDK UI message stream protocol when you call it with Accept: text/event-stream, so you can relay Scout's output to a chat UI or a Slack bot as it arrives.

Use getRequest to get the endpoint URL and auth headers for a thread, then forward the stream on to your client from a route you own. Keeping this on your server is what holds the credentials back and avoids the cross-origin restriction described above.

// in a route on your own backend const { url, headers } = scout.getRequest(threadId); const upstream = await fetch(url, { method: 'POST', // getRequest does not set accept, so ask for the stream yourself headers: { ...headers, accept: 'text/event-stream' }, body: JSON.stringify({ messages }), }); return new Response(upstream.body, { headers: { 'content-type': 'text/event-stream' } });

Point the AI SDK's DefaultChatTransport, or readUIMessageStream, at your own route to consume the relayed stream.

The client is a convenience over a single endpoint, POST /projects/{projectId}/threads/{threadId}/messages, which you can call from any language.

curl -X POST https://ai.uniform.global/projects/$PROJECT_ID/threads/$THREAD_ID/messages \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"messages":[{"id":"1","role":"user","parts":[{"type":"text","text":"Tell me a joke"}]}]}'

The response is buffered JSON by default. Send Accept: text/event-stream instead to receive a Vercel AI SDK UI message stream, as described in streaming to a chat interface. Authenticate with either an Authorization: Bearer header or an x-api-key header.

A code automation constructs the client from its own identity rather than from environment variables. See calling Scout from an automation.